Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Общение ATtiny2313 и компа по UART
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
aivs
Изучаю UART, задействовал 2 МК attiny2313. Первый МК каждую секунду отправляет символ на Второй МК по UART, Второй МК принимает символ и показывает на экране HD44780, это работает, вот код:
Первый МК отправляет:
Код
#define F_CPU 8000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <util/delay.h>

void USART_Init( unsigned int baudrate );
unsigned char USART_Receive( void );
void USART_Transmit( unsigned char data );

int main( void ) //Главная функция
{    
  const unsigned int BAUDRATE = 9600;  
  const unsigned int BAUDDIVIDER = F_CPU/(16*BAUDRATE)-1;
  USART_Init(BAUDDIVIDER);// Скорость соединения 9600 бит/с
  
  _delay_ms(1000);
  while(1){
    USART_Transmit(0x68); //Отправка символа
    _delay_ms(1000);
    USART_Transmit(0x65); //Отправка символа
    _delay_ms(1000);
    USART_Transmit(0x6C); //Отправка символа
    _delay_ms(1000);
    USART_Transmit(0x6C); //Отправка символа
    _delay_ms(1000);
    USART_Transmit(0x6F); //Отправка символа
    _delay_ms(1000);
    USART_Transmit(0x78); //Команда очистки
    _delay_ms(1000);
  }
}


void USART_Init( unsigned int baudrate ) //Функция инициализации USART
{
    UBRRH = (unsigned char) (baudrate>>8);                  
    UBRRL = (unsigned char) baudrate;
    UCSRA = (1<<U2X); //Удвоение скорости
    UCSRB = ( ( 1 << RXEN ) | ( 1 << TXEN ) ); //Разрешение на прием и н апередачу через USART
    UCSRC = (1<<USBS) | (3<<UCSZ0);
}


unsigned char USART_Receive( void ) //Функция приема данных
{
    while ( !(UCSRA & (1<<RXC)) );     //Ожидание приема символа
    return UDR; //Возврат символа
}

void USART_Transmit( unsigned char data ) //Функция отправки данных
{
    while ( !(UCSRA & (1<<UDRE)) ); //Ожидание опустошения буфера приема
    UDR = data; //Начало передачи данных                    
}


Второй МК принимает и выводит на экран:
Код
#define F_CPU 8000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include "lcd_lib.h"        // библиотека для работы с LCD HD44780

void USART_Init( unsigned int baudrate );
unsigned char USART_Receive( void );
void USART_Transmit( unsigned char data );

int main( void ) //Главная функция
{
  lcd_init();// инициализация LCD
  _delay_ms(10);
  lcd_clr();// очистить LCD
  lcd_gotoxy(0, 0); // Переходим к 0 ячейки
  
  const unsigned int BAUDRATE = 9600;  
  const unsigned int BAUDDIVIDER = F_CPU/(16*BAUDRATE)-1;
  USART_Init(BAUDDIVIDER);// Скорость соединения 9600 бит/с
  
  unsigned char symbol;
  while(1) {
    symbol = USART_Receive();
    // Если пришел символ 0x00, то очищаем
    if (symbol == 0x78) {
      lcd_clr();
      lcd_gotoxy(0, 0);
    }
    else {
      lcd_dat(symbol);    // Показываем полученный символ на LCD
    }
  }
}


void USART_Init( unsigned int baudrate ) //Функция инициализации USART
{
    UBRRH = (unsigned char) (baudrate>>8);                  
    UBRRL = (unsigned char) baudrate;
    UCSRA = (1<<U2X); //Удвоение скорости
    UCSRB = ( ( 1 << RXEN ) | ( 1 << TXEN ) ); //Разрешение на прием и н апередачу через USART
    UCSRC = (1<<USBS) | (3<<UCSZ0);
}


unsigned char USART_Receive( void ) //Функция приема данных
{
    while ( !(UCSRA & (1<<RXC)) );     //Ожидание приема символа
    return UDR; //Возврат символа
}

void USART_Transmit( unsigned char data ) //Функция отправки данных
{
    while ( !(UCSRA & (1<<UDRE)) ); //Ожидание опустошения буфера приема
    UDR = data; //Начало передачи данных                    
}


Теперь я решил по UART подключиться компом к этим МК, на макетке собрал переходник RS232-->UART из MAX232 и 4 кондеров, подключаюсь и вижу в minicom, что символы приходят каждую секунду, но это не те символы что отправляет МК:


Скорость везде выставил 9600, да и по minicom видно что символы приходят каждую секунду, но не те, в чем может быть проблема?
mempfis_
Вы используете внутреннюю RC-цепочку или внешний кварц?
Если внутреннюю, то выполняете калибровку?
Процедуру инициализации проверяли? в Документации на процессор приводится корректная процедура на С.
Я точно не помню есть ли в АТtiny2313 во фьюзах делитель на 8.
Также Вы уверены что ваш переходник UART-USB работает корректно?


aivs
Переходник сделан на микросхема MAX232 на Com порт, замыкаю RX и TX и передаю с компа буквы, они успешно возвращаются обратно, внешний кварц не использую, но два МК между собой нормально передают данные, а на комп не хотят.

Вот дамп с компа, судя по всему это не мой hello:
Код
[root@ArchLinux octopress]# cat /dev/ttyS0 | hexdump -C
00000000  00 c0 c0 e0 c0 00 e0 c0  c0 c0 e0 00 00 c0 e0 00  |................|
00000010  c0 00 00 e0 e0 c0 c0 c0  e0 c0 c0 00 e0 c0 00 e0  |................|
00000020  e0 c0 e0 00 e0 e0 c0 c0  00 e0 c0 e0 e0 e0 00 c0  |................|
00000030  00 e0 c0 00 c0 c0 c0 00  c0 c0 c0 c0 e0 e0 00 00  |................|
00000040  c0 c0 00 00 c0 e0 00 c0  c0 e0 c0 c0 e0 c0 c0 00  |................|
00000050  00 c0 e0 00 c0 e0 c0 c0  e0 00 00 e0 e0 00 e0 00  |................|
00000060  00 c0 c0 c0 00 00 c0 c0  00 e0 c0 c0 c0 e0 00 00  |................|
00000070  e0 c0 e0 e0 00 c0 e0 c0  e0 c0 00 00 e0 e0 00 c0  |................|


Длина провода от МК до ПК 1.5 метра, может слишком длинный ?
Палыч
Цитата(aivs @ Apr 16 2013, 18:38) *
Скорость везде выставил 9600, да и по minicom видно что символы приходят каждую секунду, но не те, в чем может быть проблема?


Посмотрите: чему равно BAUDDIVIDER ? Думаю, что будите "приятно удивлены"...
aivs
Если что, я уже укоротил провод в два раза, это не помогло.

BAUDDIVIDER = F_CPU/(16*BAUDRATE)-1;
8 000 000/(16*9600)-1 = 52.08333 - 1 = 51

Так, в чем проблема? единичку не нужно вычитать, или что?
Палыч
Цитата(aivs @ Apr 16 2013, 19:44) *
BAUDDIVIDER = F_CPU/(16*BAUDRATE)-1;
8 000 000/(16*9600)-1 = 52.08333 - 1 = 51

Так, в чем проблема? единичку не нужно вычитать, или что?

Это - Вы "руками" посчитали. А, транслятор как посчитал ?
kovigor
Цитата(aivs @ Apr 16 2013, 18:44) *
Если что, я уже укоротил провод в два раза, это не помогло.

Конечно, на таких частотах длина провода почти ни на что не влияет. Осциллограф-то есть у вас ? Если да, то посмотрите им, на какой на самом деле скорости идет передача от МК. Ну или перепроверяйте/пересчитывайте делители ...
aivs
Разобрался, я не глядя взял первую попавшуюся функцию инициализации и не разобравшись в ней попытался использовать.
Теперь я сам переписал функцию инициализации, заодно во всем разобрался, теперь связь с компом налажена
USART_Init() для attiny2313

Код
#define F_CPU 8000000UL
#define USART_BAUDRATE 9600
#define UBRR_VALUE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

void USART_Init(void) //Функция инициализации USART
{
  UBRRH = (uint8_t) (UBRR_VALUE>>8); // Set baudrate
  UBRRL = (uint8_t) UBRR_VALUE;
  UCSRB = (1<<RXEN) | (1<<TXEN); //Разрешение на прием и н апередачу через USART
  UCSRC = (1<<USBS) | (3<<UCSZ0); // Set frame format to 8 data bits, no parity, 1 stop bit
}
ufrs12
Подскажите, пожалуйста, в чем проблема? Собрал такую схему в протеусе:
http://www.imgzilla.ru/image.uploads/2015-...c4ad899c1e3.jpg
с такой прошивкой:
Код
#define F_CPU 8000000UL
#define USART_BAUDRATE 9600
#define UBRR_VALUE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <util/delay.h>

unsigned char USART_Receive( void )
{
    while ( !(UCSRA & (1<<RXC)) );
    return UDR;
}
void USART_Init(void)
{
    UBRRH = (uint8_t) (UBRR_VALUE>>8);
    UBRRL = (uint8_t) UBRR_VALUE;
    UCSRB = (1<<RXEN) | (1<<TXEN);
    UCSRC = (1<<USBS) | (3<<UCSZ0);
}

void USART_Transmit( unsigned char data )
{
    while ( !(UCSRA & (1<<UDRE)) );
    UDR = data;
}
int main(void)
{
    USART_Init();
    _delay_ms(1000);
        while(1)
        {
            USART_Transmit(0x68);
            _delay_ms(1000);
            USART_Transmit(0x65);
            _delay_ms(1000);
            USART_Transmit(0x6C);
            _delay_ms(1000);
            USART_Transmit(0x6C);
            _delay_ms(1000);
            USART_Transmit(0x6F);
            _delay_ms(1000);
            USART_Transmit(0x78);
            _delay_ms(1000);
    }
}

В терминале тишина...
Александр1
Цитата(aivs @ Apr 16 2013, 18:01) *
... внешний кварц не использую, но два МК между собой нормально передают данные, а на комп не хотят.

Если в двух МК используются RC-генераторы с одинаковыми настройками, то неважно на каких скоростях они общаются, главное, что на равных. А если подключить ПК, то частоты могут не совпасть: у ПК скорость стандартная и стабилизирована каврцем, а у МК RC-генератор мог "уйти" в сторону от стандартной скорости. Вот и не понимают друг друга.

Цитата(mempfis_ @ Apr 16 2013, 17:54) *
Я точно не помню есть ли в АТtiny2313 во фьюзах делитель на 8.

Есть: CKDIV8.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.