Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: USART & Atmega128A
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
ADEPTPS
Постановка задачи:
Есть Atmega162, которая непрерывно посылками светит по USART.
Нужно выцепить определенный байт из посылки.

Задача 1: Просто что-нибудь поймать по USART

CODE

#include <avr/io.h>
#include <avr/delay.h>
#include "lcd.h"
#include <stdio.h>
#include "stdafx.h"

typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned long dword;
void uart0_init(void) // инициализация uart
{
DDRE = (DDRE | 2) & ~1; // выводы порта - PE0 in, PE1 out

UCSR0B = 0x00; // временно запретить uart
UCSR0A = 0x00;
UCSR0C = 0x06;
UBRR0L = 0x17; // скорость 19200
UBRR0H = 0x00;
UCSR0B = 0x18; // запуск
}


void uartsend(byte c) // посылка байта
{
while(!(UCSR0A & (1<<UDRE0)));
UDR0 = c;
}

byte uartrecv() // прием байта
{
while(!(UCSR0A & (1<<RXC0)));
return UDR0;
}

void main(void)
{
UCHAR i;
DDRE = 0x00;
char text[6];
unsigned int n=0;
double ut = 0;
CLI();
lcd_init();
lcd_write("Autorising...");
seconds(1);
lcd_init();
lcd_write("Autorising...");
seconds(1);
uart0_init();
DDRD = (1 << 4);
SEI();
while (1)
{
ut = uartrecv();
dtostrf(ut,6,0,text);
lcd_send(COMMAND, LCD_CLEAR);
DDRD = (1 << 4);
lcd_write(text);
DDRD = 0x00;
seconds(1);
}

}


Что здесь не так?
=GM=
seconds(1); убрать
Палыч
Цитата(ADEPTPS @ Jan 19 2012, 12:02) *
Что здесь не так?

1. В этом МК регистры UBRR0H и UCSR0C имеют один адрес и различаются битом URSEL
2. При задании скорости нужно задавать вначале UBRR0H, а затем UBRR0L
3. Если поток, действительно, непрерывный, то можно "не попасть" на начало очередного байта при включении "подслушки".
ADEPTPS
Цитата(Палыч @ Jan 19 2012, 12:21) *
1. В этом МК регистры UBRR0H и UCSR0C имеют один адрес и различаются битом URSEL

Что мне с этим делать?

Отладчик показывает, что программа стопорится на:
byte uartrecv() // прием байта
{
while(!(UCSR0A & (1<<RXC0))); <<<<<<<<<<<<<<<<<<<<ЗДЕСЬ
return UDR0;
}
Палыч
Цитата(ADEPTPS @ Jan 19 2012, 12:51) *
Что мне с этим делать?


Например, что-то такое:
Код
UCSR0C = 0x06 | (1 << URSEL);


Цитата(ADEPTPS @ Jan 19 2012, 12:51) *
Отладчик показывает ...

Убедится (осциллографом, например), что сигнал доходит до МК.
ADEPTPS
Цитата(Палыч @ Jan 19 2012, 13:04) *
Код
UCSR0C = 0x06 | (1 << URSEL);

URSEL???? у меня Atmega128!!! у нее URSEL по крайней мере по даташиту отсутствует

Цитата
Убедится (осциллографом, например), что сигнал доходит до МК.

Это я проверил первым делом!
Палыч
Цитата(ADEPTPS @ Jan 19 2012, 13:35) *
у меня Atmega128!!!

Так бы сразу и говорили... А то, в первом посте речь про m162 была, запутало всё...

Снять фуз M103C !
ADEPTPS
Цитата(Палыч @ Jan 19 2012, 13:54) *
Снять фуз M103C !

Снят!

Цитата
UCSR0C = 0x06;
UBRR0L = 0x17; // скорость 19200
UBRR0H = 0x00;


Оставить как было?
Палыч
Цитата(ADEPTPS @ Jan 19 2012, 14:05) *
Оставить как было?

Правильнее: строки с UBRR0L и UBRR0H поменять местами, но в данном случае это ничему не помешает (и не поможет).

Осталось убедиться, что МК "заведён" от кварца, а не от внутреннего генератора.
ADEPTPS
Цитата(Палыч @ Jan 19 2012, 14:27) *
Осталось убедиться, что МК "заведён" от кварца, а не от внутреннего генератора.

Как это сделать нормально?
_Артём_
Цитата(ADEPTPS @ Jan 19 2012, 12:47) *
Как это сделать нормально?

Подключить программатор.
Прочитать fuse (источник тактирования у m128 задаётся фузами и не может менятся на лету).
smalcom
я думаю для задач обмена данными по UART нужно как минимум включать UART.
ADEPTPS
Используется внешнее тактирование судя по фьюзам.

Моя задача вообще имеет решение?
Navovvol
Да тактирование тут ни причем, мусор бы все равно приходил. Как я понял программа стопориться в цикле ожидания байта. Значит надо поменять местам Rx Tx. И вообще для наглядности лучше через прерывание по завершению приема байта сделать.
Палыч
Цитата(Navovvol @ Jan 20 2012, 10:58) *
Да тактирование тут ни причем, мусор бы все равно приходил. Как я понял программа стопориться в цикле ожидания байта.
Если тактовая частота МК в разы меньше, чем штатная, то мусор, как раз бы, и не приходил, а МК "повис" бы на ожидании прихода байта.
Цитата(Navovvol @ Jan 20 2012, 10:58) *
Значит надо поменять местам Rx Tx.
Предлагаете применять "метод тыка"? biggrin.gif ТС убедился, что сигнал доходит до МК (см.пост №6)
Navovvol
Цитата(ADEPTPS @ Jan 20 2012, 08:16) *
Используется внешнее тактирование судя по фьюзам.

Моя задача вообще имеет решение?

Внешний кварц 7.3728 МГц ?
ADEPTPS
да
Navovvol
на Atmega162 вывод PD1(или PB3) соединен с пином PE0 Atmeg'и128A ?
ADEPTPS
Да, но я уже нашел другой способ получения информации.

Тема временно закрыта!
Aktus
Всем добрый день.

Пишу вроде бы простейшую прогу для ATmega128A в Atmel Studio 6.1. Просто передаю в комп 1 байт по UART.
Сначала делаю следующим образом:

Код
#include <avr/io.h>

#define UBRR_9600 47

unsigned char s[1] = "A";

int main(void)
{
    UBRR0H = 0;
    UBRR0L = UBRR_9600;
    UCSR0B = (1<<TXEN0);
    UCSR0C = (1<<USBS0)|(1<<UCSZ00);
    
    UDR0 = s[0];
    
    while(1)
    {
    }
}

Всё нормально, но вместо символа "A" (0x41) в окне терминала (Advanced Serial Port Monitor) вижу "Б" (0xC1) sm.gif Почему-то устанавливается в 1 старший бит.

А теперь то же самое, но через прерывание:

Код
#include <avr/io.h>
#include <avr/interrupt.h>

#define UBRR_9600 47

unsigned char s[1] = "A";

int main(void)
{
    UBRR0H = 0;
    UBRR0L = UBRR_9600;
    UCSR0B = (1<<UDRIE0)|(1<< TXEN0);
    UCSR0C = (1<<USBS0)|(1<<UCSZ00);
    
    sei();
    
    while(1)
    {
    }
}

ISR(USART0_UDRE_vect)
{
    UDR0 = s[0];
}

Здесь в терминале вообще ничего не вижу, хотя, по идее, должна быть бесконечная посылка символа "A".
Ассемблерный код в обоих случаях одинаковый и, вроде бы, правильный:
Код
UDR0 = s[0];
LDS R24, 0x0100
OUT 0x0C, R24

Может кто-то сталкивался? Можете что-нибудь подсказать?
RabidRabbit
UCSR0C = (1<<USBS0)|(1<<UCSZ00);

Table 80. UCSZn Bits Settings
UCSZn2 UCSZn1 UCSZn0 Character Size
0 ____ 0 ____ 0 ____ 5-bit
0 ____ 0 ____ 1 ____ 6-bit


По-моему, 6 битов - Ваш случай...

А кстати, в плане занудства, для подобных вопросов существует раздел для начинающих...
Aktus
RabidRabbit, косяк признаю. Большое спасибо. Про раздел для начинающих понял, учту.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.