|
Соединить 2 atmega168 по USART, тактуются от одного источника |
|
|
|
Mar 4 2008, 09:27
|
Частый гость
 
Группа: Участник
Сообщений: 113
Регистрация: 8-10-07
Пользователь №: 31 170

|
Вообщем действительно USART работал у меня в асинхронном режиме (по умолчанию). Убрал проводок от XCK1 к XCK2 - ничего не изменилось. Т.е. сейчас соединены: Rx1-Tx2 Tx2-Rx1 земли и питание общие. Так же изменил baudrate, чтобы скорость была близка к 4800. Точность 12500000/(16*(162+1.0))/4800*100=99.853% Вот код для основного МК: Код #define F_CPU 12500000UL // 12.5 MHz
/* Initialize UART */ void USART0_Init( unsigned int baudrate ) { /* Set the baud rate */ UBRR0H = (unsigned char) (baudrate>>8); UBRR0L = (unsigned char) baudrate;
/* Enable UART receiver and transmitter */ UCSR0B = ( ( 1 << RXEN0 ) | ( 1 << TXEN0 ) );
/* Set frame format: 8 data 2stop */ UCSR0C = (1<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00); //For devices with Extended IO }
/* Read and write functions */ unsigned char USART0_Receive( void ) { /* Wait for incomming data */ while ( !(UCSR0A & (1<<RXC0)) ); /* Return the data */ return UDR0; }
void USART0_Transmit( unsigned char data ) { /* Wait for empty transmit buffer */ while ( !(UCSR0A & (1<<UDRE0)) ); /* Start transmittion */ UDR0 = data; }
void init_all(void){
/***initialize clock***/ // Set the clock speed to 8MHz // set the clock prescaler. First write CLKPCE to enable setting of clock the next four instructions. CLKPR=(1<<CLKPCE); CLKPR=0; // 8 MHz delay_ms(20);
// change clkout from 6.25MHz to 12.5MHz. Тактуется все от 25MHz. Получается 25/2=12.5Mhz delay_ms(10); USART0_Init(162); /* 12500000/(16*(162+1.0))/4800*100=99.853 Set the baudrate to 4800 using a 12,5MHz int osc */
/***enable interrupt***/ sei(); }
int main(void){ init_all();
USART0_Transmit(3); // передать 2 МК число 3 uint8_t XXX[3]; XXX[0]= USART0_Receive;
//записать XXX[0] в память
return (0); } //end main А вот код для 2 МК (почти то же самое) Вчера ограничил задачу - принять число - и столько раз мигнуть светодиодом Код #define F_CPU 12500000UL // 12.5 MHz
/* Prototypes */ void USART0_Init( unsigned int baudrate ); unsigned char USART0_Receive( void ); void USART0_Transmit( unsigned char data );
/* Initialize UART */ void USART0_Init( unsigned int baudrate ) { /* Set the baud rate */ UBRR0H = (unsigned char) (baudrate>>8); UBRR0L = (unsigned char) baudrate;
/* Enable UART receiver and transmitter */ UCSR0B = ( ( 1 << RXEN0 ) | ( 1 << TXEN0 ) );
/* Set frame format: 8 data 2stop */ UCSR0C = (1<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00); //For devices with Extended IO }
void USART0_Transmit( unsigned char data ) {
/* Wait for empty transmit buffer */ while ( !(UCSR0A & (1<<UDRE0)) );
/* Start transmittion */ UDR0 = data; }
/* Read and write functions */ unsigned char USART0_Receive( void ) {
/* Wait for incomming data */ while ( !(UCSR0A & (1<<RXC0)) );
/* Return the data */ return UDR0; }
void init_all(void){
/***initialize clock***/ //Set the clock speed to 8MHz // set the clock prescaler. First write CLKPCE to enable setting of clock the next four instructions. CLKPR=(1<<CLKPCE); CLKPR=0; // 8 MHz delay_ms(3000); //change clkout from 6.25MHz to 12.5MHz USART0_Init(162); /* 12500000/(16*(162+1.0))/4800*100=99.853 error Set the baudrate to 4800 using a 12,5MH*/
/***enable interrupt***/ sei(); }
void led_on( unsigned int cikle){
uint8_t i=0; while(i<cikle){ /* led on, pin=0 */ PORTC &= ~(1<<PC5); delay_ms(500); /* set output to 5V, LED off */ PORTC|= (1<<PC5); delay_ms(500); i++; } }
/* Main - a simple test program*/ void main( void ) { init_all();
/* INITIALIZE */ /* enable PC5 as output */ DDRC|= (1<<DDC5);
led_on(3); //Тут все верно при старте мигает 3 раза delay_ms(1000);
for(;;){ /* Forever */
unsigned charinput=USART0_Receive(); led_on(charinput); } } Мигает по прежнему 14 раз каждый раз. А должно 3. Но хоть стабильность в этом вопросе. Подскажите, почему доходит не то что нужно?
Сообщение отредактировал Filov - Mar 4 2008, 09:45
|
|
|
|
|
Mar 4 2008, 09:49
|
Профессионал
    
Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008

|
Ну, во первых, посмотрите осциллографом, что у вас и как передается, на какой реально скорости и т.п. Я бы сделал постоянную передачу символа в цикле, а на приеме просто бы зажигал светодиод если число совпало с ожидаемым, тогда и осцилом можно проверить, да и меняя константу можно выяснить, это действительно 14 принимается или это просто какое то левое начальное значение переменной. Ну и замечания по коду, не всегда существенные, но все же..  unsigned charinput - это какой тип данных будет? по-умолчанию? int? а передаете из функции вы что - char. Обьявление переменных внутри цикла - это плохой тон для контроллеров, лучше везде использовать тип char если это подходит, т.к. контроллер 8и разрядный и для него именно char является нативным типом, а не int как обычно принято у 16/32 разрядных процов, а судя по коду именно с ними вы раньше имели дело. Функция main возвращает void обычно, потому что в МК некуда выходить если у вас просто программа а не ОСь стоит.
--------------------
|
|
|
|
|
Mar 4 2008, 09:53
|
Частый гость
 
Группа: Участник
Сообщений: 113
Регистрация: 8-10-07
Пользователь №: 31 170

|
Цитата(GDI @ Mar 4 2008, 12:49)  Ну, во первых, посмотрите осциллографом, что у вас и как передается, на какой реально скорости и т.п., Нашел вот какой-то старый. попробую использовать... Цитата(GDI @ Mar 4 2008, 12:49)  unsigned charinput - это какой тип данных будет? по-умолчанию? int? а передаете из функции вы что - char. Тьфу опростоволосился похоже.  Цитата(GDI @ Mar 4 2008, 12:49)  Обьявление переменных внутри цикла - это плохой тон для контроллеров, лучше везде использовать тип char если это подходит, т.к. контроллер 8и разрядный и для него именно char является нативным типом, а не int как обычно принято у 16/32 разрядных процов, а судя по коду именно с ними вы раньше имели дело. Да, некрасиво, понимаю. Но обычно когда начинает хоть как-то работать переношу объявление переменных в нужное место. А так - замучаешься - ведь не все сразу получается... Цитата(GDI @ Mar 4 2008, 12:49)  Функция main возвращает void обычно, потому что в МК некуда выходить если у вас просто программа а не ОСь стоит. Ясно.
Сообщение отредактировал Filov - Mar 4 2008, 09:54
|
|
|
|
|
Mar 4 2008, 09:57
|
Профессионал
    
Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008

|
Цитата Кстати не во всех чипах есть режим SPI, (напримре в Atmega128 нет sad.gif ). Это я знаю, сам с новыми еще не работал  , но у автора мега168, а там это режим есть. ..как быстро отвечает автор, не успел сообщение запостить а он уже отвечает... я, кстати пост тот поправил, перечитайте..
--------------------
|
|
|
|
|
Mar 4 2008, 10:04
|
Частый гость
 
Группа: Участник
Сообщений: 113
Регистрация: 8-10-07
Пользователь №: 31 170

|
Цитата(GDI @ Mar 4 2008, 12:57)  Это я знаю, сам с новыми еще не работал  , но у автора мега168, а там это режим есть. Кстати этот режим тоже любопытнаю штука  Буду его тоже пробовать позже  Цитата(GDI @ Mar 4 2008, 12:57)  ..как быстро отвечает автор, не успел сообщение запостить а он уже отвечает... я, кстати пост тот поправил, перечитайте.. Ну так что лучше работать или на форуме сидеть????  Константу менял - передавал 1 - мигало 2 раза 2 - мигало 12 раз 3 - мигало 14 раз. Действительно попробую в цикле. И unsigned charinput заменю на unsigned char charinput Ж). Может чего и выйдет.
|
|
|
|
|
Mar 4 2008, 10:47
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Filov @ Mar 4 2008, 12:04)  Константу менял - передавал 1 - мигало 2 раза 2 - мигало 12 раз 3 - мигало 14 раз. А теперь давайте посмотрим что такое 2, 12 и 14. 2 - 0x02 == 00000010 вместо 000000001 12 - 0x0C == 00001100 вместо 000000010 14 - 0x0E == 00001110 вместо 000000011 У вас установлены разные бодрейты. Отличие в скорости на глаз в 1.5..2 раза. Совет - напишите и залейте одну и ту же программу в оба МК. Если так и будет сбоить - значит настройки осциллятора разные. Прошейте одинаково fuses. Еще - совсем не важно вычислять бодрейт когда МК работают от одного источника тактирования, нужно чтобы число записываемое в UBRR было одинаковым для обоих МК, а скорость можно ставить максимально допустимую.
|
|
|
|
|
Mar 5 2008, 09:39
|
Частый гость
 
Группа: Участник
Сообщений: 113
Регистрация: 8-10-07
Пользователь №: 31 170

|
Цитата(defunct @ Mar 4 2008, 13:47)  А теперь давайте посмотрим что такое 2, 12 и 14.
2 - 0x02 == 00000010 вместо 000000001 12 - 0x0C == 00001100 вместо 000000010 14 - 0x0E == 00001110 вместо 000000011
У вас установлены разные бодрейты. Отличие в скорости на глаз в 1.5..2 раза.
Совет - напишите и залейте одну и ту же программу в оба МК. Если так и будет сбоить - значит настройки осциллятора разные. Прошейте одинаково fuses. Спасибо большое! У Вас глаз-алмаз! Вытащил проводочек ко которому идут клоки с первого МК - не работет - все ОК. Из второго - продолжает мигать! Соостветсвенно не были правильно установлены fuses и вместо внешних 12.5MHz чип работал на 8MHz. Отличие в скорости в 1.5 раза. Вообщем извлек еще раз урок - что не стоит быть излишне самоуверенным, а проверять, проверять и еще раз проверять. Но зато хоть разобрался как USART работает. Цитата(defunct @ Mar 4 2008, 13:47)  Еще - совсем не важно вычислять бодрейт когда МК работают от одного источника тактирования, нужно чтобы число записываемое в UBRR было одинаковым для обоих МК, а скорость можно ставить максимально допустимую. Т.е. можно ставить регистры UBRR0(H,L) в 1 ? Цитата(mdmitry @ Mar 4 2008, 13:48)  Atmega1281,2561 UART в режиме MASTER SPI, а не Slave. Будьте внимательны Это я вроде понял, только мне непонятна одна вешь - на что влияет бодрейт когда я использую USART как SPI? Допустим хочу соедениться по SPI с чипом который имеет частоту тактования X. Какой бодрейт мне стоит указать? ------------- Господа, спасибо за Ваши ответы. Они прям открыли мне глаза на USART!
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|