реклама на сайте
подробности

 
 
> Связь между двумя mega48 по UART
D_K_
сообщение Sep 13 2012, 06:52
Сообщение #1





Группа: Участник
Сообщений: 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. Си владею плохо - буду очень благодарен за примеры на асме
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 14)
mempfis_
сообщение Sep 13 2012, 07:23
Сообщение #2


Профессионал
*****

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



Код
Кварцевый резонатро не использую Фьюзы в обоих МК не программировал, поэтому источник тактирования обоих контроллеров - внутренний, установленный по умолчанию (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 взять из документации как заведомо рабочие.
Go to the top of the page
 
+Quote Post
D_K_
сообщение Sep 13 2012, 08:13
Сообщение #3





Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Sep 13 2012, 08:41
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
D_K_
сообщение Sep 13 2012, 11:07
Сообщение #5





Группа: Участник
Сообщений: 10
Регистрация: 13-09-12
Пользователь №: 73 520



Цитата
P.S. Ещё пару вопросов - Вы настроили стек? Разрешили прерывания sei? Сохраняете состояние SREG и восстанавливаете его при выходе из прерывания?
Если приведёте полный код программы с метки reset то думаю Вам быстрее помогут в решении проблемы.



Да, всё сделал. Полный код программы смогу выложить только вечером.
Ещё раз спасибо за помощь.

Сообщение отредактировал D_K_ - Sep 13 2012, 11:07
Go to the top of the page
 
+Quote Post
kovigor
сообщение Sep 13 2012, 12:37
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(D_K_ @ Sep 13 2012, 09:52) *
Кварцевый резонатро не использую Фьюзы в обоих МК не программировал, поэтому источник тактирования обоих контроллеров - внутренний, установленный по умолчанию (The device is shipped with internal RC oscillator at 8.0MHz and with the fuse CKDIV8 programmedб resulting in 1.0MHz system clock.).

UARTы будут нормально связываться только если температурный режим обоих МК будет близким, в противном случае частоты генераторов разных МК "разбегутся," и достаточно сильно, что может привести к сбоям в работе UART. См. график зависимости частоты встроенного в МК генератора от температуры в даташите ...
Go to the top of the page
 
+Quote Post
D_K_
сообщение Sep 13 2012, 13:22
Сообщение #7





Группа: Участник
Сообщений: 10
Регистрация: 13-09-12
Пользователь №: 73 520



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



Спасибо за интерес к моей теме. Оба МК находятся на одной плате в 2-х см друг от друга.
Д.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Sep 13 2012, 13:56
Сообщение #8


Профессионал
*****

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



Что-то я так и не увидел , где это SLAVE разрешили работать по прерыванию. Нетути
Как-то инит должен смотреться так
Код
ldi temp,1<<RXCIE0|0<<TXCIE0|0<<UDRIE0|1<<RXEN0|1<<TXEN0
outr UCSR0B,temp

Да и sei чего-то нет


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
kovigor
сообщение Sep 13 2012, 14:46
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(D_K_ @ Sep 13 2012, 16:22) *
Спасибо за интерес к моей теме. Оба МК находятся на одной плате в 2-х см друг от друга.
Д.

Тогда и два МК не нужны. Ставьте один, возможно, чуть более мощный ...
Go to the top of the page
 
+Quote Post
D_K_
сообщение Sep 13 2012, 20:40
Сообщение #10





Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
D_K_
сообщение Sep 14 2012, 06:10
Сообщение #11





Группа: Участник
Сообщений: 10
Регистрация: 13-09-12
Пользователь №: 73 520



Каюсь....Грешен... Выше прокричал на весь мир о том, что счётчик состояния при уходе в прерывания сохранил в стеке, а по факту этого не сделал. Стыдоба.....

Как только это сделал - все заработало без калибровки RC-генератора. Отсутсвие необходимости в калибровке объясняю родственной и территориальной близостью обоих МК.

Как только чуток разгребусь - выложу работающую версию программы. Авсоь поможет какому нибудь-новичку типа меня.


Спасибо всем кто был со мной в это тяжёлое время!!! wink.gif

Сообщение отредактировал D_K_ - Sep 14 2012, 06:11
Go to the top of the page
 
+Quote Post
RabidRabbit
сообщение Sep 14 2012, 06:27
Сообщение #12


Местный
***

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



ldi temp,$4
sts tccr1b,temp
ldi temp,$1
sts timsk1,temp

В "слэйве" не мешает каждые 16 секунд попадание на 0xFFFF в незаполненной таблице векторов прерываний? sm.gif
Go to the top of the page
 
+Quote Post
zombi
сообщение Sep 14 2012, 06:45
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата(D_K_ @ Sep 13 2012, 09:52) *
... Индикационный контроллер (mega48) нработает в режиме SLAVE и только слушает UART. Контроллер управления (mega48P) работает в режиме MASTER и только передаёт сообщения SLAVE .

Зачем вообще использовать уарт??? чем SPI не устраивает?
проводов столькоже и калибровать ничего не надо.
Go to the top of the page
 
+Quote Post
D_K_
сообщение Sep 14 2012, 09:21
Сообщение #14





Группа: Участник
Сообщений: 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 в незаполненной таблице векторов прерываний? sm.gif



Не должно бы - адрес обработки прерывания по переполнению счётчика ведь не задан:

.org 0
rjmp reset

.org URXCaddr
rjmp USART_Receive

Описаны только адреса обработчика ресета и прерывания по приёму данных. Или я не прав? Внесите, пожалуйста, ясность. Но в любом случае это кусок кода - мусор оставшийся от предыдущей версии программы и его, естественно, буду вычищать.

Go to the top of the page
 
+Quote Post
RabidRabbit
сообщение Sep 14 2012, 09:32
Сообщение #15


Местный
***

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



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


Ага, всё, что не задано, остаётся нетронутым (0xFFFF), поэтому, если не стоит цели выжать лишние байты памяти программ из таблицы векторов прерываний, лично я заполняю неиспользованные переходы командами RETI, а можно, например, зажигать лампочку. Таймер запущен, разрешены прерывания по переполнению, разрешены прерывания - значит будет прерывание sm.gif Т.е. отсутствие команды перехода в зарезервированном месте вовсе не запрещает соответствующее прерывание.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 10:14
Рейтинг@Mail.ru


Страница сгенерированна за 0.0162 секунд с 7
ELECTRONIX ©2004-2016