|
Связь между двумя mega48 по UART |
|
|
|
Sep 13 2012, 06:52
|
Группа: Участник
Сообщений: 10
Регистрация: 13-09-12
Пользователь №: 73 520

|
Здравствуйте, уважаемые разработчики. Подскажите, пожалуйста новичку.
Разрабатываю устройство на основе двух МК (meg48 и mega48P). Один изх них (mega48P) использую для обработки кнопок, и управления. Другой (mega48) - торлько для индикации (7-сегментный СИД-дисплей). Связь между ними осуществляю по UART. Индикационный контроллер (mega48) нработает в режиме SLAVE и только слушает UART. Контроллер управления (mega48P) работает в режиме MASTER и только передаёт сообщения SLAVE . Приём сообщений SLAVE осуществляет по прерыванию RX_Complete.
В SLAVE объявляю прерывание по приёму .equ URXCaddr rjmp USART_Receive
Инициализация UARTа в SLAVE :
USART_Init: clr temp out UBRR0H, temp ldi temp, $C ;частота тактирования 1МГц, содержимое UBRR0H=0, UBRR0L=12 => скорость передачи данных 4800bps out UBRR0L, temp ldi temp, (1<<RXEN0) ; только приёмник out UCSR0B,temp ldi temp, (1<<USBS0)|(3<<UCSZ00); формат передачи: 8data, 2stop bit out UCSR0C,temp
Инициализация UARTа MASTER :
USART_Init: clr temp out UBRR0H, temp ldi temp, $C ;частота тактирования 1МГц, содержимое UBRR0H=0, UBRR0L=12 => скорость передачи данных 4800bps out UBRR0L, temp ldi temp, (1<<TXEN0) ; только передатчик out UCSR0B,temp ldi temp, (1<<USBS0)|(3<<UCSZ00); формат передачи: 8data, 2stop bit out UCSR0C,temp
Приём данных SLAVEом :
USART_Receive: sbis UCSR0A, RXC0 ; Wait for data to be received rjmp USART_Receive in temp, UDR0; Get and return received data from buffer reti
Передача данных MASTERом :
USART_Transmit: sbis UCSR0A,UDRE0 ; Wait for empty transmit buffer rjmp USART_Transmit ldi temp, 5 out UDR0,temp ; sends the data ret
Кварцевый резонатро не использую Фьюзы в обоих МК не программировал, поэтому источник тактирования обоих контроллеров - внутренний, установленный по умолчанию (The device is shipped with internal RC oscillator at 8.0MHz and with the fuse CKDIV8 programmedб resulting in 1.0MHz system clock.).
Ноги RxD и TxD обоих МК перекрестил - RxD MASTERа скоммутировал с TxD SLAVE, ТxD MASTERа скоммутировал с RxD SLAVE. Целостность линий RxD MASTERа -> TxD SLAVE и ТxD MASTERа -> RxD SLAVE тестировал мультиметром непосредственно на лапах контроллеров.
Всё компилируется, но не работает, сволочь. В чём может быть причина?
Заранее спасибо за помощь
P.S. Си владею плохо - буду очень благодарен за примеры на асме
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 14)
|
Sep 13 2012, 08:13
|
Группа: Участник
Сообщений: 10
Регистрация: 13-09-12
Пользователь №: 73 520

|
Цитата(mempfis_ @ Sep 13 2012, 10:23)  Код Кварцевый резонатро не использую Фьюзы в обоих МК не программировал, поэтому источник тактирования обоих контроллеров - внутренний, установленный по умолчанию (The device is shipped with internal RC oscillator at 8.0MHz and with the fuse CKDIV8 programmedб resulting in 1.0MHz system clock.). Для начала попробуйте откалибровать встроенную RC-цепочку внеся в OSCCAL соответствующее значение в обоих процессорах. Ассемблером владел до того как перешёл на С уже всё забыл. Могу предложить поискать на форуме примеры реализации fifo-uart. Сами процедуры инициализации uart взять из документации как заведомо рабочие. Спасибо за интерес к моей проблеме. Есть какие-то советы по калибровке? Калибровать методом тыка - изменил один битик- посметрел что будет? Или есть какие-то методики? Всё остальное правильно? Ноги RxD и TxD обоих МК перекрестил - RxD MASTERа скоммутировал с TxD SLAVE, ТxD MASTERа скоммутировал с RxD SLAVE. Это правильное решение? Д.
Сообщение отредактировал D_K_ - Sep 13 2012, 08:16
|
|
|
|
|
Sep 13 2012, 08:41
|

Профессионал
    
Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409

|
Цитата(D_K_ @ Sep 13 2012, 11:13)  Есть какие-то советы по калибровке? Калибровать методом тыка - изменил один битик- посметрел что будет? Или есть какие-то методики? Значения OSCCAL хранятся в процессоре. Их нужно считать программатором, запомнить и заносить в OSCCAL каждый раз при старте программы. Это заводская калибровка. Почитайте раздел 7.6 Calibrated Internal RC Oscillator. И может быть попробуйте отправлять байты и принимать для начала поллингом - как в примере из документации (chapter 18, все примеры 100% рабочие). Как наладите - переходите на прерывания. Код Ноги RxD и TxD обоих МК перекрестил - RxD MASTERа скоммутировал с TxD SLAVE, ТxD MASTERа скоммутировал с RxD SLAVE. Это правильное решение? Да. Передающая нога одного процессора соединяется с приёмной другого. Для UART понятие MASTER/SLAVE не совсем подходит т.к. UART без ограничений на обоих процессорах может одновременно отправлять-принимать данные. Вот для SPI да - там есть разделение на MASTER/SLAVE т.к. один процессор (MASTER) обеспечивает тактовой частотой второй процессор (SLAVE). P.S. Ещё пару вопросов - Вы настроили стек? Разрешили прерывания sei? Сохраняете состояние SREG и восстанавливаете его при выходе из прерывания? Если приведёте полный код программы с метки reset то думаю Вам быстрее помогут в решении проблемы.
Сообщение отредактировал mempfis_ - Sep 13 2012, 08:41
|
|
|
|
|
Sep 13 2012, 11:07
|
Группа: Участник
Сообщений: 10
Регистрация: 13-09-12
Пользователь №: 73 520

|
Цитата P.S. Ещё пару вопросов - Вы настроили стек? Разрешили прерывания sei? Сохраняете состояние SREG и восстанавливаете его при выходе из прерывания? Если приведёте полный код программы с метки reset то думаю Вам быстрее помогут в решении проблемы. Да, всё сделал. Полный код программы смогу выложить только вечером. Ещё раз спасибо за помощь.
Сообщение отредактировал D_K_ - Sep 13 2012, 11:07
|
|
|
|
|
Sep 13 2012, 13:22
|
Группа: Участник
Сообщений: 10
Регистрация: 13-09-12
Пользователь №: 73 520

|
Цитата(kovigor @ Sep 13 2012, 15:37)  UARTы будут нормально связываться только если температурный режим обоих МК будет близким, в противном случае частоты генераторов разных МК "разбегутся," и достаточно сильно, что может привести к сбоям в работе UART. См. график зависимости частоты встроенного в МК генератора от температуры в даташите ... Спасибо за интерес к моей теме. Оба МК находятся на одной плате в 2-х см друг от друга. Д.
|
|
|
|
|
Sep 13 2012, 13:56
|

Профессионал
    
Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339

|
Что-то я так и не увидел , где это SLAVE разрешили работать по прерыванию. Нетути Как-то инит должен смотреться так Код ldi temp,1<<RXCIE0|0<<TXCIE0|0<<UDRIE0|1<<RXEN0|1<<TXEN0 outr UCSR0B,temp Да и sei чего-то нет
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Sep 13 2012, 20:40
|
Группа: Участник
Сообщений: 10
Регистрация: 13-09-12
Пользователь №: 73 520

|
Цитата(ILYAUL @ Sep 13 2012, 16:56)  Что-то я так и не увидел , где это SLAVE разрешили работать по прерыванию. Нетути Как-то инит должен смотреться так Код ldi temp,1<<RXCIE0|0<<TXCIE0|0<<UDRIE0|1<<RXEN0|1<<TXEN0 outr UCSR0B,temp Да и sei чего-то нет Да, RXCIE0 я проворонил, каюсь. ILYAUL, спасибо за подсказку. А вот sei всё-таки было. Полный текст программы выкладываю ниже. Тем на менее, после исправления обмен данными всё-таки не наблюдается. Видимо, действительно нужно калибровать встроенный RC-генератор . Полные тексты программ MASTER.include "m48Pdef.inc" .equ button1pin=$5 .equ button2pin=$4 .equ button3pin=$0 .equ button4pin=$1 .equ button5pin=$2 .equ button6pin=$3 .def temp = R16 .def flag = R17 .def Digit1 = R18 .def Digit2 = R19 .def Digit3 = R20 .def LED = R21 .def wait = R22 .def UART_Data=R23 .org 0 rjmp reset .org OVF1addr rjmp overflow ;========================================================== ;Initiation ;========================================================== reset: ldi r25,Low(RAMEND) out spl, r25 ldi r25,High(RAMEND) out sph, r25 ldi temp,$5 sts tccr1b,temp ldi temp,$1 sts timsk1,temp ldi temp, $31 out ddrb,temp ser temp out ddrd,temp ldi temp, $3F out ddrc,temp clr flag clr Digit1 clr Digit2 clr Digit3 clr LED clr UART_Data USART_Init: clr temp sts UBRR0H,temp ldi temp,$C sts UBRR0L,temp ldi temp, (1<<TXEN0) sts UCSR0B,temp ldi temp, (1<<USBS0)|(3<<UCSZ00) sts UCSR0C,temp sei ;============================================= ;main programm ;============================================= loop: rjmp loop ;============================================= ;timer interrupt ;============================================ overflow: ldi temp, $FE sts tcnt1h,temp ldi temp, $08 sts tcnt1l,temp USART_Transmit_: lds temp,UCSR0A sbrs temp,UDRE0 rjmp USART_Transmit_ ldi UART_Data,5 sts UDR0,UART_Data reti ;========================== Полные тексты программ SLAVE.include "m48def.inc" .equ Dig1_Katode=2 .equ Dig2_Katode=3 .equ Dig3_Katode=4 .equ RXC0_bit=7 .def temp = R16 .def wait = R18 .def digitnumber=r20 .def Digit1=r21 .def Digit2=r22 .def Digit3=r23 .def LED=r24 .org 0 rjmp reset .org URXCaddr rjmp USART_Receive reset: ldi r25,Low(RAMEND) out spl, r25 ldi r25,High(RAMEND) out sph, r25 ldi temp,$4 sts tccr1b,temp ldi temp,$1 sts timsk1,temp ser temp out ddrb,temp ser temp out ddrd,temp ser temp out ddrc,temp clr digitnumber clr Digit1 clr Digit2 clr Digit3 clr LED USART_Init: clr temp sts UBRR0H, temp ldi temp, $C ; USART speed 4800bps sts UBRR0L, temp ldi temp,1<<RXCIE0|0<<TXCIE0|0<<UDRIE0|1<<RXEN0|1<<TXEN0 sts UCSR0B,temp ldi temp, (1<<USBS0)|(3<<UCSZ00); 8data, 2stop bit sts UCSR0C,temp sei ;============================================= ;DISPLAY ;============================================= loop: inc digitnumber cpi digitnumber,1 breq digit1_disp cpi digitnumber,2 breq digit2_disp cpi digitnumber,3 breq digit3_disp ldi Digit1,3 ldi Digit2,4 ldi Digit3,7 clr digitnumber digit1_disp: sbi portd,Dig1_Katode sbi portd,Dig2_Katode sbi portd,Dig3_Katode out eearl,Digit1 sbi eecr,0 in temp, eedr out portb,temp sbi portd,Dig1_Katode sbi portd,Dig2_Katode cbi portd,Dig3_Katode rjmp display_exitt digit2_disp: sbi portd,Dig1_Katode sbi portd,Dig2_Katode sbi portd,Dig3_Katode out eearl,Digit2 sbi eecr,0 in temp, eedr out portb,temp sbi portd,Dig1_Katode cbi portd,Dig2_Katode sbi portd,Dig3_Katode rjmp display_exitt digit3_disp: sbi portd,2 sbi portd,3 sbi portd,4 out eearl,Digit3 sbi eecr,0 in temp, eedr out portb,temp cbi portd,2 sbi portd,3 sbi portd,4 display_exitt: rcall wait_ rjmp loop ;============================================ ;UART data receive complete interrupt ;============================================ USART_Receive: lds temp, UCSR0A sbrs temp, RXC0_bit ; Wait for data to be received rjmp USART_Receive lds Digit1, UDR0; Get and return received data from buffer reti ;============================================ ; time delay for dynamic indication wait_: ldi wait, $FF w0: dec wait brne w0 ret Именно эти коды я загружал в МК. Результат - на дисплее SLAVE "743" вместо желаемых "745".
Сообщение отредактировал D_K_ - Sep 13 2012, 20:45
|
|
|
|
|
Sep 14 2012, 06:10
|
Группа: Участник
Сообщений: 10
Регистрация: 13-09-12
Пользователь №: 73 520

|
Каюсь....Грешен... Выше прокричал на весь мир о том, что счётчик состояния при уходе в прерывания сохранил в стеке, а по факту этого не сделал. Стыдоба..... Как только это сделал - все заработало без калибровки RC-генератора. Отсутсвие необходимости в калибровке объясняю родственной и территориальной близостью обоих МК. Как только чуток разгребусь - выложу работающую версию программы. Авсоь поможет какому нибудь-новичку типа меня. Спасибо всем кто был со мной в это тяжёлое время!!!
Сообщение отредактировал D_K_ - Sep 14 2012, 06:11
|
|
|
|
|
Sep 14 2012, 06:27
|

Местный
  
Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040

|
ldi temp,$4 sts tccr1b,temp ldi temp,$1 sts timsk1,temp В "слэйве" не мешает каждые 16 секунд попадание на 0xFFFF в незаполненной таблице векторов прерываний?
|
|
|
|
|
Sep 14 2012, 09:21
|
Группа: Участник
Сообщений: 10
Регистрация: 13-09-12
Пользователь №: 73 520

|
Цитата(zombi @ Sep 14 2012, 09:45)  Зачем вообще использовать уарт??? чем SPI не устраивает? проводов столькоже и калибровать ничего не надо. Работа на будущее - в этом проекте достаточно одностороннего обмена, но уже через несколько недель может понадобиться полнодуплексный обмен. А отладочная плата и черновой вариант программы - вот они, уже есть. Цитата(RabidRabbit @ Sep 14 2012, 09:27)  ldi temp,$4 sts tccr1b,temp ldi temp,$1 sts timsk1,temp В "слэйве" не мешает каждые 16 секунд попадание на 0xFFFF в незаполненной таблице векторов прерываний?  Не должно бы - адрес обработки прерывания по переполнению счётчика ведь не задан: .org 0 rjmp reset .org URXCaddr rjmp USART_Receive Описаны только адреса обработчика ресета и прерывания по приёму данных. Или я не прав? Внесите, пожалуйста, ясность. Но в любом случае это кусок кода - мусор оставшийся от предыдущей версии программы и его, естественно, буду вычищать.
|
|
|
|
|
Sep 14 2012, 09:32
|

Местный
  
Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040

|
Цитата(D_K_ @ Sep 14 2012, 13:21)  Описаны только адреса обработчика ресета и прерывания по приёму данных. Или я не прав? Внесите, пожалуйста, ясность. Но в любом случае это кусок кода - мусор оставшийся от предыдущей версии программы и его, естественно, буду вычищать. Ага, всё, что не задано, остаётся нетронутым (0xFFFF), поэтому, если не стоит цели выжать лишние байты памяти программ из таблицы векторов прерываний, лично я заполняю неиспользованные переходы командами RETI, а можно, например, зажигать лампочку. Таймер запущен, разрешены прерывания по переполнению, разрешены прерывания - значит будет прерывание  Т.е. отсутствие команды перехода в зарезервированном месте вовсе не запрещает соответствующее прерывание.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|