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

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> Соединить 2 atmega168 по USART, тактуются от одного источника
GDI
сообщение Mar 4 2008, 07:22
Сообщение #16


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

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Имхо, в синхронном режиме USART очень похож на SPI(не даром есть режим работы USARTа в режиме SPI), отличия незначительные, SPI просто байты передает по клоку в ОБЕ СТОРОНЫ, а УСАРТ еще и стартовые и стоповые биты но тоже в ОБЕ СТОРОНЫ, а уважаемый =GM= путает понятия мастер-слейв и дуплекс-полудуплекс.


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
Filov
сообщение Mar 4 2008, 09:27
Сообщение #17


Частый гость
**

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
GDI
сообщение Mar 4 2008, 09:49
Сообщение #18


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

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Ну, во первых, посмотрите осциллографом, что у вас и как передается, на какой реально скорости и т.п.
Я бы сделал постоянную передачу символа в цикле, а на приеме просто бы зажигал светодиод если число совпало с ожидаемым, тогда и осцилом можно проверить, да и меняя константу можно выяснить, это действительно 14 принимается или это просто какое то левое начальное значение переменной.

Ну и замечания по коду, не всегда существенные, но все же.. smile.gif
unsigned charinput - это какой тип данных будет? по-умолчанию? int? а передаете из функции вы что - char. Обьявление переменных внутри цикла - это плохой тон для контроллеров, лучше везде использовать тип char если это подходит, т.к. контроллер 8и разрядный и для него именно char является нативным типом, а не int как обычно принято у 16/32 разрядных процов, а судя по коду именно с ними вы раньше имели дело. Функция main возвращает void обычно, потому что в МК некуда выходить если у вас просто программа а не ОСь стоит.


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
KRS
сообщение Mar 4 2008, 09:50
Сообщение #19


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(GDI @ Mar 4 2008, 10:22) *
Имхо, в синхронном режиме USART очень похож на SPI(не даром есть режим работы USARTа в режиме SPI)

Кстати не во всех чипах есть режим SPI, (напримре в Atmega128 нет sad.gif ). Есть еще существенное отличие от SPI в SPI сами посылки (фреймы) туда и обратно синхронны и жестко привязаны к количеству клоков, поэтому нет стартовых и стоповых бит, а в UART передача асинхронна (клоки просто sapmling point задают) поэтому клоки идут постоянно и нужны и старт бит и стоп.
Go to the top of the page
 
+Quote Post
Filov
сообщение Mar 4 2008, 09:53
Сообщение #20


Частый гость
**

Группа: Участник
Сообщений: 113
Регистрация: 8-10-07
Пользователь №: 31 170



Цитата(GDI @ Mar 4 2008, 12:49) *
Ну, во первых, посмотрите осциллографом, что у вас и как передается, на какой реально скорости и т.п.,


Нашел вот какой-то старый. попробую использовать...

Цитата(GDI @ Mar 4 2008, 12:49) *
unsigned charinput - это какой тип данных будет? по-умолчанию? int? а передаете из функции вы что - char.


Тьфу опростоволосился похоже. sad.gif

Цитата(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
Go to the top of the page
 
+Quote Post
GDI
сообщение Mar 4 2008, 09:57
Сообщение #21


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

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Цитата
Кстати не во всех чипах есть режим SPI, (напримре в Atmega128 нет sad.gif ).

Это я знаю, сам с новыми еще не работал smile.gif, но у автора мега168, а там это режим есть.

..как быстро отвечает автор, не успел сообщение запостить а он уже отвечает... я, кстати пост тот поправил, перечитайте..


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
Filov
сообщение Mar 4 2008, 10:04
Сообщение #22


Частый гость
**

Группа: Участник
Сообщений: 113
Регистрация: 8-10-07
Пользователь №: 31 170



Цитата(GDI @ Mar 4 2008, 12:57) *
Это я знаю, сам с новыми еще не работал smile.gif, но у автора мега168, а там это режим есть.


Кстати этот режим тоже любопытнаю штука smile.gif Буду его тоже пробовать позже smile.gif

Цитата(GDI @ Mar 4 2008, 12:57) *
..как быстро отвечает автор, не успел сообщение запостить а он уже отвечает... я, кстати пост тот поправил, перечитайте..


Ну так что лучше работать или на форуме сидеть???? smile.gif

Константу менял - передавал
1 - мигало 2 раза
2 - мигало 12 раз
3 - мигало 14 раз.

Действительно попробую в цикле. И unsigned charinput заменю на unsigned char charinput Ж). Может чего и выйдет.
Go to the top of the page
 
+Quote Post
defunct
сообщение Mar 4 2008, 10:47
Сообщение #23


кекс
******

Группа: Свой
Сообщений: 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 было одинаковым для обоих МК, а скорость можно ставить максимально допустимую.
Go to the top of the page
 
+Quote Post
mdmitry
сообщение Mar 4 2008, 10:48
Сообщение #24


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



Цитата(Filov @ Mar 4 2008, 13:04) *
Кстати этот режим тоже любопытнаю штука smile.gif Буду его тоже пробовать позже smile.gif

Atmega1281,2561 UART в режиме MASTER SPI, а не Slave. Будьте внимательны


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
Filov
сообщение Mar 5 2008, 09:39
Сообщение #25


Частый гость
**

Группа: Участник
Сообщений: 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!
Go to the top of the page
 
+Quote Post
mdmitry
сообщение Mar 5 2008, 15:55
Сообщение #26


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



Цитата(Filov @ Mar 5 2008, 12:39) *
Это я вроде понял, только мне непонятна одна вешь - на что влияет бодрейт когда я использую USART как SPI? Допустим хочу соедениться по SPI с чипом который имеет частоту тактования X. Какой бодрейт мне стоит указать?

Вы ставите желаемую скорость с помощью UBRR. Он MASTER и, соответственно, тактирует ведомого. Сделать USART ведомым в режиме SPI невозможно. Читайте внимательно описание контроллера.
Проблем с работой нет. Тонкость только в правильном задании режима (всего 4), чтобы ведомый понимал.


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
defunct
сообщение Mar 5 2008, 16:30
Сообщение #27


кекс
******

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



Цитата(Filov @ Mar 5 2008, 11:39) *
Т.е. можно ставить регистры UBRR0(H,L) в 1 ?

Да, плюс установить бит удвоенной скорости (U2X в UCSRA).
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th July 2025 - 06:49
Рейтинг@Mail.ru


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