Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Мультипроцессорные режим ATmega88/168
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Dёня
Здравствуйте господа!

На шине один передающий контроллер (PIC18F252, 10MHz+PLL), один принимающий (ATmega168, 20MHz). Установлен режим мультипроцессорный:
Должно быть:
мега принимает свой адрес, распознает его, выставляет прием данных (lds rh_ucsra, UCSR0A; andi rh_ucsra, ~(1 << MPCM0); sts UCSR0A, rh_ucsra) и далее принимает блок данных длиной 256 байт, после приема запрещает прием данных.
Что выходит:
мега распознает адрес... принимает данные, причем принимает только первых 89 (!) байт и далее перестает принимать данные, затем опять принимает свой адрес, причем у него установлен (!) бит MPCM0. Распознает адрес, сбрасывает MPCM0, и т.д.
Бит MPCM0 я не выставляю, т.к. выставляется он только при условии приема 256-ти байт.
Скорости обмена выставлял в разных диапазонах - от 19.2К до 1.25М.
Пробовал и по UARTу непосредственно и по RS485.
Данные при приеме не искажаются (проверяю цифровым осциллографом 100MHz), в контроллере 89 принятых байт верные.
Алгоритм передачи-приема работает в симуляторе при любых скоростях...
_dem
Код в студию, может быть не там копаете, и ошибка в распределении памяти ?
demiurg_spb
Цитата(Dёня @ Oct 8 2008, 12:00) *
Установлен режим мультипроцессорный.

А может ну его это режим.
И по старинке modbus?
Dёня
Вот исходник...
Dёня
Те кто применял адресуемый UART,
вообще, принимает ATmega88/168 блоки данных, больше 100 байт??!?
GDI
А даташит и эррата что ан этот счет говорят?
AndyBig
Принимает без проблем, что-то у вас не то в коде...
Я использовал этот режим в обмене данными между модулями, все было без затык, размеры пакетов были от 16 до 150 байт.
Правда, использовалась связка Atmega64 -> Atmega8
Но между 8 и 88 мегами разница не глобальная, насколько я помню smile.gif
Dёня
Эратты я не встречал на эти камни, а в даташите про адресуемый UART всего-то пару абзацев.
В пике похожим образом построен UART - там принимает по 256 байт, но производительности пика не хватает для проекта...
Кстати в даташите не все понятно: когда ведомый не получил все данные и не установил MPCM, и следующим байтом идет адрес, MPCM сам выставляется?!?!
Николай Иванович Приходько
MPCM сбрасывается автоматом только при получении адресного байта (т.е. байта с установленным 9-м битом). А устанавливать его (ну в смысле бит MPCM (так же как и 9-й бит при передаче)) надо ручками. Вот и весь сказ. Что теперь не понятно? Какие-то ещё проблемы остались?
AndyBig
Нет, сам не выставляется. Бит MPCM должена устанавливать и очищать сама программа.
Смысл в следующем: устанавливаете этот бит и ждете прерывания от УАРТа (или просто ждете приема символа). Пока по шине не пройдет байт адреса (с выставленным старшим битом), УАРТ ничего не примет. Приняли байт адреса, сравнили со своим адресом, если совпал - очищаете бит MPCM и дальше принимаете весь пакет данных - фиксированной длины или переменной, но тогда в начале пакета должна быть обозначена его полная длина. Приняли пакет данных, опять установили бит MPCM и ждете следующего приема байта.
В процессе приема можно контролировать принимаемые данные на установленный старший бит в очередном принятом байте - флаг RXB8 в регистре UCSRB. Если установлен - значит пришел байт адреса, следовательно по каким-то причинам принят не весь пакет данных. Тогда действуете как Вам удобнее - или сразу сравниваете пришедший адрес со своим и далее как описывалось, или рапортуете хосту об ошибке...

Цитата
MPCM сбрасывается автоматом только при получении адресного байта (т.е. байта с установленным 9-м битом)

Где описано такое поведение этого флага?
Dёня
Спасибо за разъяснение, впринципе так я и полагал:

Код
    lds    rh_ucsra, UCSR0A
    lds    rh_ucsrb, UCSR0B
    lds    rh_udr, UDR0

    sbrs    rh_ucsrb, RXB80
    rjmp    UARTInt_Data

UARTInt_Address:
UARTInt_Address_Err:
    ldi    rh_dataInt, BUFFER_bUART_SIZE
    cp    rl_countUARTRx, rh_dataInt
    breq    UARTInt_Address_Err_

Point1:
    sbr    rh_flags, 1 << BUFFER_bUART_RECEIVE_ERROR
    rjmp    UARTInt_
UARTInt_Address_Err_:

    cpi    rh_udr, MODULE_bADDRESS
    brne    UARTInt_

    andi    rh_ucsra, ~(1 << MPCM0)
    sts    UCSR0A, rh_ucsra
    rjmp    UARTInt_
UARTInt_Address_:

UARTInt_Data:
    st    rx+, rh_udr
    dec    rl_countUARTRx
    brne    UARTInt_

Point2:
    sbr    rh_flags, 1 << BUFFER_bUART_READ_DONE
    
    ori    rh_ucsra, 1 << MPCM0
    sts    UCSR0A, rh_ucsra
    rjmp    UARTInt_
UARTInt_Data_:
UARTInt_:


До точки Point2 прога доходит только если принимается < 90 байт
Если например ставить прием 100 байт из 256 приходящих то в точке Point1 rl_countUARTRx == 11
Николай Иванович Приходько
Цитата(AndyBig @ Oct 8 2008, 16:57) *
Где описано такое поведение этого флага?

Ой. И правда облажался. Действительно и сбрасвать его тоже ручками надо. Ентот MPCM. Прошу прощения, дядько. smile.gif И на старуху бывает проруха
AndyBig
Сорри, в ассемблере совсем не силен smile.gif
Николай Иванович Приходько
Цитата(Dёня @ Oct 8 2008, 17:17) *
До точки Point2 прога доходит только если принимается < 90 байт
Если например ставить прием 100 байт из 256 приходящих то в точке Point1 rl_countUARTRx == 11

А где Вы инИтите rl_countUARTRx ?
Dёня
Инициализация счетчика в начале программы:
Код
Main_Init_UART:
; Addressed UART, Receive only (9 bit), 1Mbaud(1.25Mbaud)
    ldi    rh_init, 0
    sts    UBRR0L, rh_init
    sts    UBRR0H, rl_zero
    ldi    rh_init, 1 << MPCM0
    sts    UCSR0A, rh_init
    ldi    rh_init, 1 << RXEN0 | 1 << RXCIE0 | 1 << UCSZ02
    sts    UCSR0B, rh_init
    ldi    rh_init, 0b11 << UCSZ00
    sts    UCSR0C, rh_init
Main_Init_UART_:

И в подпрограммах:
Код
Main_BufferUARTSwap:    
    sbrs    rh_flags, BUFFER_bUART_READ_DONE
    rjmp    Main_BufferUARTSwap_

    rcall    BufferUARTSwap
Main_BufferUARTSwap_:

Main_BufferUARTError:
    sbrs    rh_flags, BUFFER_bUART_RECEIVE_ERROR
    rjmp    Main_BufferUARTError_
    
    cbr    rh_flags, 1 << BUFFER_bUART_RECEIVE_ERROR
    rcall    BufferUARTReset
Main_BufferUARTError_:

;*******************************

BufferUARTSwap:
; swap Rx<->Tx
    movw    rh_init, rl_pointUARTRx
    movw    rl_pointUARTRx, rl_pointUARTTx
    movw    rl_pointUARTTx, rh_init
; pointRx->indexRx
    movw    rh_indexUARTRx, rl_pointUARTRx
; pointTx->indexTx
    movw    rh_indexUARTTx, rl_pointUARTTx

    ldi    rh_init, BUFFER_bUART_SIZE
    mov    rl_countUARTRx, rh_init

    cbr    rh_flags, 1 << BUFFER_bUART_READ_DONE
    sbr    rh_flags, 1 << BUFFER_bUART_WRITE_DONE

BufferUARTSwap_:
    ret

BufferUARTReset:
    movw    rh_indexUARTRx, rl_pointUARTRx

    ldi    rh_init, BUFFER_bUART_SIZE
    mov    rl_countUARTRx, rh_init

BufferUARTReset_:
    ret
Dёня
Тема закрыта.
Нашел ошибку.
Прога изначальна писалась на ATmega8, потом на 88 и 168
Код
#ifdef    proj_8
.include <m8def.inc>
#endif
#ifdef    proj_168
.include <m168def.inc>
#endif
#ifdef    proj_88
.include <m88def.inc>
#endif
;*****************
.dseg    

.org    SRAM_START

bufferPWMTx_bIndex:    .byte    2
bright_bValue:        .byte    1

;***** Массивы
.org    RAM_bBUFFER_START_ADDRESS

buffer0_abArray:    .byte    BUFFER_wUART_SIZE
buffer1_abArray:    .byte    BUFFER_wUART_SIZE


bufferXXX_abArray - задает буффер для блоков памяти приема-передачи
Код
; UART Rx
    ldi    rh_indexUARTRxL, low(buffer0_abArray)
    ldi    rh_indexUARTRxH, high(buffer0_abArray)
    movw    rl_pointUARTRx, rh_indexUARTRx
; UART Tx
    ldi    rh_indexUARTTxL, low(buffer1_abArray)
    ldi    rh_indexUARTTxH, high(buffer1_abArray)
    movw    rl_pointUARTTx, rh_indexUARTTx

    ldi    rh_init, BUFFER_bUART_SIZE
    mov    rl_countUARTRx, rh_init


SRAM_START - прописано в mXXXdef.inc, RAM_bBUFFER_START_ADDRESS - осталась привязана к 8-ой меге, RAM_bBUFFER_START_ADDRESS == 0x68.

Прошу прощения за беспокойство.
AndyBig
Ошибки, возникающие при copy-paste - обычное дело smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.