UART Atmega8 шлет мусор...

Обсуждаем контроллеры компании Atmel.
Ответить
Открыл глаза
Сообщения: 59
Зарегистрирован: Сб янв 14, 2012 11:05:46

Сообщение AR_AROV »

Хочу соединить Atmega8 и Atmeg16 по UART... не могу никак добиться чтоб в терминале было то что посылаю...
Спойлер

Код: Выделить всё

#define F_CPU 8000000UL // Òàêòîâàÿ ÷àñòîòà
#define BAUDRATE 9600 // Ñêîðîñòü UART

//ìàêðîñû äëÿ çàäåðæåê
#define _delay_us(us) 	__delay_cycles((F_CPU / 1000000) * (us));
#define _delay_ms(ms) 	__delay_cycles((F_CPU / 1000) * (ms));

#include <ioavr.h>
#include <ina90.h>
#include "lcd_lib.c"

#define bit(n) (1 << (n))


#define u_on  (PORTD |= bit(2))
#define u_off (PORTD &= ~bit(2))

//button
#define m1    (PINC & bit(0))
#define m2    (PINC & bit(1)) 

#define z1    (PINC & bit(2)) 
#define z2    (PINC & bit(3)) 

#define r1    (PINC & bit(4)) 
#define r2    (PINC & bit(5)) 

//îäíîáàéòíûé áóôåð
volatile unsigned char usartRxBuf = 0;

//èíèöèàëèçàöèÿ usart`a

void USART_Init(void)
{
  UBRRH = (F_CPU/BAUDRATE/16-1) >> 8;
  UBRRL = (F_CPU/BAUDRATE/16-1);
  
//  UBRRH = 0;
//  UBRRL = 51; //ñêîðîñòü îáìåíà 9600 áîä
//  UCSRA = ( 1 << U2X); //óäâîíåíèå ñêîðîñòè
  UCSRB = ( 1 << TXEN ) | ( 1 << RXEN );
  UCSRB = ( 1 << RXCIE ) | ( 1 << RXEN ) | ( 1 << TXEN ); //ðàçð. ïðåðûâ ïðè ïðèåìå, ðàçð ïðèåìà, ðàçð ïåðåäà÷è.
  UCSRC = ( 1 << URSEL ) | ( 0 << UCSZ2 ) | ( 1 << UCSZ1 ) | ( 1 << UCSZ0 ); //ðàçìåð ñëîâà 8 ðàçðÿäîâ
  // UCSRC = ( 1 << URSEL ) | ( 0 << UPM1 ) | ( 0 << UPM0 );
  UCSRC = ( 1 << URSEL ) | ( 0 << USBS ); //ñòîï áèò 1
  _delay_ms(200);
}

//îòïðàâêà ñèìâîëà ïî usart`ó
void USART_SendChar(unsigned char symbol)
{
  while(! (UCSRA & (1<<UDRE)) );
  UDR = symbol;
}

void USART_SendStr(char *str)
{
  unsigned char c;
  while( ( c = *str++ ) != 0 ) {
    USART_SendChar( c );
  }
}
//÷òåíèå áóôåðà
__monitor unsigned char USART_GetChar(void)
{
  unsigned char tmp = usartRxBuf;
  usartRxBuf = 0;
  return tmp;  
}

//ïðèåì ñèìâîëà ïî usart`ó â áóôåð
#pragma vector=USART_RXC_vect
__interrupt void usart_rxc_my(void) 
{
  usartRxBuf = UDR; 
} 

//unsigned char sym;

int main( void )
{ 
  _SEI();
  
  //Âõîäû
  DDRC = 0x00;
  PORTC = 0x00;
  
  //Âûõîäû
  DDRD = 0xFF;
  PORTD = 0x00;
  
  USART_Init ();
  LCD_Init ();
  int But;
  
  while(1){
    if (m1 != 0){
      LCD_SendString(": 1");  
      USART_SendStr("1\r\n");
      _delay_ms(100);
    } 
    else if (m2 != 0){
      LCD_SendString(": 2");  
      USART_SendChar('2');
      _delay_ms(100);
    }
    else if (z1 != 0){
      LCD_SendString(": 3");  
      USART_SendChar(3);
      _delay_ms(100);
    }
    else if (z2 != 0){
      LCD_SendString(": 4");  
      USART_SendChar(0);
      _delay_ms(100);
    }
    else {
      PORTC = 0x00;
      LCD_Clear();
    }
  } 
  return 0;
}
Вот мой г*код для Atmega8 который посылает символ при нажатии на кнопку... помогите пожалуйста... не могу пнять в чем дело
Вложения
Screenshot_4.png
(50.41 КБ) 316 скачиваний
Последний раз редактировалось AR_AROV Ср июл 08, 2015 00:24:45, всего редактировалось 1 раз.
Реклама
Держит паяльник хвостом
Сообщения: 933
Зарегистрирован: Ср апр 13, 2011 11:09:20
Откуда: Екатеринбург

Сообщение Alkul »

AR_AROV писал(а):Хочу соединить Atmega8 и Atmeg16 по UART... не могу никак добиться чтоб в терминале было то что посылаю...
Когда есть сомнения, всегда полезно упростить код, избавившись от неоднозначностей.
Например, вот это - что?

Код: Выделить всё

USART_SendChar('2');
USART_SendChar(3);
Почему для одной функции разный формат аргумента? Где правильно?

Уберите опрос кнопок, в главном цикле программы после всех инициализаций попробуйте сделать ассемблерную вставку вида

Код: Выделить всё

ldi R16,0x33
out UDR,R16
а потом зациклите код в бесконечном цикле. На экран LCD, конечно, ничего не выведется, а вот в терминал должна быть выведена цифра 3. Если это так - проверяйте корректность работы с функциями USART_SendChar. Если нет - проверяйте инициализацию USART.

А вообще, прежде, чем посылать что-то в регистр UDR (то бишь, прежде, чем передавать байт через USART), нужно убедиться, что регистр UDR свободен и не находится в процессе передачи байта. Где это у Вас?
Реклама
Открыл глаза
Сообщения: 59
Зарегистрирован: Сб янв 14, 2012 11:05:46

Сообщение AR_AROV »

Все исправил, передача работает... осталось с приемом разобраться...

Приемник... Atmega16, 8MHz от внутреннего генератора... молчит как рыба (((
Спойлер

Код: Выделить всё

#define F_CPU 8000000UL // Тактовая частота
#define BAUDRATE 9600 // Скорость UART

//макросы для задержек
#define _delay_us(us) 	__delay_cycles((F_CPU / 1000000) * (us));
#define _delay_ms(ms) 	__delay_cycles((F_CPU / 1000) * (ms));

#include <ioavr.h>
#include <ina90.h> 
//#include "usart.c"

//#define CPU_CLK_Hz 1000000UL // Тактовая частота
//#define __delay_ms(x) __delay_cycles(x*(CPU_CLK_Hz/1000)) // Задержка в мс

#define bit(n) (1 << (n))

#define _01on  (PORTA |= bit(0))
#define _01off (PORTA &= ~bit(0))

#define _02on  (PORTA |= bit(1))
#define _02off (PORTA &= ~bit(1))

#define _03on  (PORTA |= bit(2))
#define _03off (PORTA &= ~bit(2))

#define _04on  (PORTA |= bit(3))
#define _04off (PORTA &= ~bit(3))

#define _05on  (PORTA |= bit(4))
#define _05off (PORTA &= ~bit(4))

#define _06on  (PORTA |= bit(5))
#define _06off (PORTA &= ~bit(5))

#define _07on  (PORTA |= bit(6))
#define _07off (PORTA &= ~bit(6))

#define _08on  (PORTA |= bit(7))
#define _08off (PORTA &= ~bit(7))

#define _09on  (PORTC |= bit(0))
#define _09off (PORTC &= ~bit(0))

#define _10on  (PORTC |= bit(1))
#define _10off (PORTC &= ~bit(1))

#define _11on  (PORTC |= bit(2))
#define _11off (PORTC &= ~bit(2))

#define _12on  (PORTC |= bit(3))
#define _12off (PORTC &= ~bit(3))

#define _13on  (PORTC |= bit(4))
#define _13off (PORTC &= ~bit(4))

#define _14on  (PORTC |= bit(5))
#define _14off (PORTC &= ~bit(5))

//button
#define molot_vpered    (PINB & bit(0))
#define molot_nazad     (PINB & bit(1)) 

#define zahvat_vpered   (PINB & bit(2)) 
#define zahvat_nazad    (PINB & bit(3)) 

#define zaslonka_verh   (PINB & bit(4)) 
#define zaslonka_vniz   (PINB & bit(5))

#define zacep_zahvat    (PINB & bit(6))
#define zacep_otpustit  (PINB & bit(7))

#define igla_verh       (PIND & bit(2)) 
#define igla_vniz       (PIND & bit(3))

//однобайтный буфер
volatile unsigned char usartRxBuf = 0;

//инициализация usart`a

void USART_Init(void)
{
  UCSRC = 0;
  //  UBRRH = (F_CPU/BAUDRATE/16-1) >> 8;
  //  UBRRL = (F_CPU/BAUDRATE/16-1);
  
  //  UBRR = floor(F_CPU/(16*BAUDRATE))-1;
  
  UBRRH = 0;
  UBRRL = 51; //скорость обмена 9600 бод
  //  UCSRA = ( 1 << U2X); //удвонение скорости
  
  UCSRB = ( 1 << RXCIE) | ( 1 << TXCIE) | ( 1 << RXEN ) | ( 1 << TXEN ); //разр. прерыв при приеме, разр приема, разр передачи.
  UCSRC = ( 1 << URSEL) | ( 0 << UCSZ2 ) | ( 1 << UCSZ1 ) | ( 1 << UCSZ0 ); //размер слова 8 разрядов
  UCSRC = ( 0 << UPM1 ) | ( 0 << UPM0 ) | ( 0 << USBS );  // контроль четности выкл //стоп бит 1
  _delay_ms(200);
}

//отправка символа по usart`у
void USART_SendChar(unsigned char symbol)
{
  while( (UCSRA & (1<<UDRE)) == 0) {}; 
  UDR = symbol;
}

void USART_SendStr(char *str)
{
  unsigned char c;
  while( ( c = *str++ ) != 0 ) {
    USART_SendChar( c );
  }
}
//чтение буфера
__monitor unsigned char USART_GetChar(void)
{
  unsigned char tmp = usartRxBuf;
  usartRxBuf = 0;
  return tmp;  
}

//прием символа по usart`у в буфер
#pragma vector=USART_RXC_vect
__interrupt void usart_rxc_my(void) 
{
  while( ( UCSRA & ( 1 << RXC ) ) == 0) {};
  usartRxBuf = UDR; 
} 

int main( void )
{ 
  _SEI();
  //  unsigned char sym;
  unsigned char but;
  USART_Init();
  
  //Входы
  DDRB = 0x00;
  PORTB = 0x00;
  DDRD = 0x00; //=0 //0xC0=1100 0000
  PORTD = 0x00;
  
  //Выходы
  DDRA = 0xFF;
  PORTA = 0x00;
  DDRC = 0xFF;
  PORTC = 0x00;
  
  while(1)
  { 
    //but = 0; 
    but = USART_GetChar();
    
    //    //molot ->
    //    if (molot_vpered != 0) but = 1;
    //    //molot <-
    //    if (molot_nazad != 0) but = 2;
    //    //zahvat ->
    //    if (zahvat_vpered != 0) but = 3;
    //    //zahvat <-
    //    if (zahvat_nazad != 0) but = 4;
    //    //zaslonka up
    //    if (zaslonka_verh != 0) but = 5;
    //    //zaslonka down
    //    if (zaslonka_vniz != 0) but = 6;
    //    //zatcep +
    //    if (zacep_zahvat != 0) but = 7;
    //    //zatcep -
    //    if (zacep_otpustit != 0) but = 8;
    //    //zapor +
    //    if (igla_verh != 0) but = 9;
    //    //zapor 1
    //    if (igla_vniz != 0) but = 10;
    
    switch (but){
    case 1: _05on;
    _03on;
    _delay_ms(500);
    _02on;
    break;
    case 2: _06on;
    _03on;
    _delay_ms(500);
    _02on;
    break;
    case 3: _09on;
    _delay_ms(500);
    _01on;
    break;
    case 4: _10on;
    _delay_ms(500);
    _01on;
    break;
    case 5: _07on;
    _delay_ms(500);
    _02on;
    break;
    case 6: _08on;
    _delay_ms(500);
    _02on;
    break;
    case 7: _11on;
    _04on;
    _delay_ms(500);
    _01on;
    break;
    case 8: _12on;
    _04on;
    _delay_ms(500);
    _01on;
    break;
    case 9: _11on;
    _delay_ms(500);
    _01on;
    break;
    case 10: _12on;
    _delay_ms(500);
    _01on;
    break;
    //    case 0:  PORTA = 0x00;
    //             PORTC = 0x00;
    //             break;
    } 
  }
  return 0;
}

Передача... Atmga8, в терминале все ок... только он при однократном нажатии постоянно шлет данные... не могу понять почему (((
Спойлер

Код: Выделить всё

#define F_CPU 8000000UL // Тактовая частота
#define BAUDRATE 9600 // Скорость UART

//макросы для задержек
#define _delay_us(us) 	__delay_cycles((F_CPU / 1000000) * (us));
#define _delay_ms(ms) 	__delay_cycles((F_CPU / 1000) * (ms));

#include <ioavr.h>
#include <ina90.h>
#include "lcd_lib.c"

#define bit(n) (1 << (n))

#define u_on  (PORTD |= bit(2))
#define u_off (PORTD &= ~bit(2))

//button
#define m1    (PINC & bit(0))
#define m2    (PINC & bit(1)) 

#define z1    (PINC & bit(2)) 
#define z2    (PINC & bit(3)) 

#define r1    (PINC & bit(4)) 
#define r2    (PINC & bit(5)) 

//однобайтный буфер
volatile unsigned char usartRxBuf = 0;

//инициализация usart`a

void USART_Init(void)
{
  UCSRC = 0;
    
  UBRRH = 0;
  UBRRL = 51; //скорость обмена 9600 бод
//  UCSRA = ( 1 << U2X); //удвонение скорости
//  UCSRB = (1<<TXEN)|(1<<TXCIE); // (разрешил передачу и прерывание на одном МК) 
//  UCSRB = (1<<RXEN)|(1<<RXCIE); // (разрешил приём и прерывание на втором МК)
  UCSRB = ( 1 << RXCIE ) |( 1 << TXCIE ) | ( 1 << RXEN ) | ( 1 << TXEN ); //разр. прерыв при приеме, разр приема, разр передачи.
  UCSRC = ( 1 << URSEL ) | ( 0 << UCSZ2 ) | ( 1 << UCSZ1 ) | ( 1 << UCSZ0 ); //размер слова 8 разрядов
  UCSRC = ( 0 << UPM1 ) | ( 0 << UPM0 ) | ( 0 << USBS );  // контроль четности выкл //стоп бит 1
  _delay_ms(200);
}

//отправка символа по usart`у
void USART_SendChar(unsigned char symbol)
{
  while( (UCSRA & (1<<UDRE)) == 0) {}; 
  UDR = symbol;
  symbol = 0;
}

void USART_SendStr(char *str)
{
  unsigned char c;
  while( ( c = *str++ ) != 0 ) {
    USART_SendChar( c );
  }
}
//чтение буфера
__monitor unsigned char USART_GetChar(void)
{
  unsigned char tmp = usartRxBuf;
  usartRxBuf = 0;
  return tmp;  
}

//прием символа по usart`у в буфер
#pragma vector=USART_RXC_vect
__interrupt void usart_rxc_my(void) 
{
  usartRxBuf = UDR; 
} 

//unsigned char sym;

int main( void )
{ 
  _SEI();
  
  //Входы
  DDRC = 0x00;
  PORTC = 0x00;
  
  //Выходы
  DDRD = 0xFF;
  PORTD = 0x00;
  
  USART_Init ();
  
  LCD_Init ();
  int but;
  
  while(1){
    
    but = 0; 
    
    if (m1 != 0) but = 1;
    if (m2 != 0) but = 2;
    if (z2 != 0) but = 3;
    if (z2 != 0) but = 4;
    
    switch (but){
    case 1:
      LCD_SendString(": 1");  
      USART_SendStr("1\n\r");
    break; 
    case 2:
      LCD_SendString(": 2");  
      USART_SendChar('2');
    break; 
    case 3:
      LCD_SendString(": 3");  
      USART_SendChar('3');
      _delay_ms(100);
    break; 
    case 4:
      LCD_SendString(": 4");  
      USART_SendChar('4');
    break;
    case 0:
      //PORTC = 0x00;
      LCD_Clear();
    break;
    }
  } 
  return 0;
}

Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

не могу понять почему (((
Потому что :

Код: Выделить всё

while(1){
 ...
 ...
 ...
}
Реклама
Эиком - электронные компоненты и радиодетали
Открыл глаза
Сообщения: 59
Зарегистрирован: Сб янв 14, 2012 11:05:46

Сообщение AR_AROV »

не могли бы показать правильный кусок кода?
Реклама
Держит паяльник хвостом
Сообщения: 933
Зарегистрирован: Ср апр 13, 2011 11:09:20
Откуда: Екатеринбург

Сообщение Alkul »

AR_AROV писал(а):Приемник... Atmega16, 8MHz от внутреннего генератора... молчит как рыба (((
Не увидел глобального разрешения прерываний.
В ассемблере это делается командой Как на Си - не знаю.
Реклама
Открыл глаза
Сообщения: 59
Зарегистрирован: Сб янв 14, 2012 11:05:46

Сообщение AR_AROV »

int main( void )
{
_SEI();
..................
Ответить

Вернуться в «AVR»