UART MEGA168PA

Обсуждаем контроллеры компании Atmel.
Ответить
Опытный кот
Сообщения: 768
Зарегистрирован: Сб ноя 08, 2008 18:32:36

Сообщение vovik15 »

Здравствуйте уважаемые форумчане! Вот уже целую неделю бьюсь с настройкой юарта. Перепробывал много разных кодов из интернет. Дело в том,что при включении питания в терминал прилетает сообщение,все как и задумано. А при отправке любого символа из терминала на мк происходит что то странное. Контроллер в ответ начинает слать пробелы без остановки. Пишу в авр студио 5.Код привожу, подскажите что здесь не так? Огромное спасибо!

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

#include <avr/io.h>
#include <avr/interrupt.h> //для работы с прерываниями
unsigned char flag;//флаг успешного приема сообщения

ISR(USART_RXC_vect )
{   
    unsigned char data,status;
    data = UDR0; //читаем регистр данных
    status=UCSR0A; //читаем регистр флагов UCSRA в переменную status
	flag=1;//поднять флаг приема данных

}//конец приема по uart

void UART_Send_Char(unsigned char c)
{//передача символа по UART
while (!(UCSR0A&(1<<UDRE0))) ;
UDR0 = c;
}

void UART_Send_Str(char str[])
{//передача строки по UART
unsigned char i = 0;
   while (str[i]!='\0')
   {
    UART_Send_Char(str[i]);
    i++;
   }
}

int main(void)
{
ChipConfig();//конфигурация мк
UART_Init();//инициализация UART
flag=0; //сбросить флаг успешного приема
sei(); // Глобально разрешаем прерывания
UART_Send_Str("MKPROG.RU"); //передать строку

while(1)
{//начало бесконечного цикла

	if(flag)
	{
		UART_Send_Str("priem"); //передать строку
		flag=0;
	}

}//конец бесконечного цикла
}//конец программы


void UART_Init(void)
{
UBRR0H = 0; //UBRR = 8000000/(16*9600) – 1 = 51 (при 8мгц)
UBRR0L = 0x67; //скорость обмена 9600 бод  (0x67 при 16мгц)	
UCSR0B = (1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0);//разр. прерыв при приеме, разр приема, разр передачи.
UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);//размер слова – 8 бит (UCSR0C регистр формата пакета)
//UCSR0A = 0; //очистить все флаги
UDR0 = 0; //обнулить регистр uart
}

void ChipConfig (void)
{// конфигурация Мк
    PORTB=0x00; //Обнуление портов
	PORTC=0x00; 
	PORTD=0x00;
	
	DDRB=0b11111111; //все линии на выход
	DDRC=0b11111110; //PC0 на вход. Вход ADC0
    DDRD=0b11110010; //PD2 и PD3 на вход (кнопки Power и Level) PD0 RX вход
}

Контактная информация:
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

volatile unsigned char flag;
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Опытный кот
Сообщения: 768
Зарегистрирован: Сб ноя 08, 2008 18:32:36

Сообщение vovik15 »

Исправил тип переменной,не помогло. Железо 100% исправно,проверял с новым контроллером то же самое. В сторону пк данные идут замечательно, но вот принять не получается. Может быть у кого нибудь найдется отлаженный кусок кода?
Контактная информация:
afz
Опытный кот
Аватара пользователя
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Сообщение afz »

ISR(USART_RX_vect ), а не _RXC_ По крайней мере, моя Студия 4.19 на _RXC_ выдала ворнинг, я глянул в Нете, для ATmega168P (PA в студии 4.19 нет), там _RX_, а не _RXC_.

Добавлено after 5 minutes 21 second:
Да, снятый в этой программе прерывания байт данных надо тоже размещать в переменной volatile char, описанной вне всех программ, как и flag.

А еще моя Студия 4.19 вываливала кучу ворнингов, пока я не переставил функцию main() в конец исходника.
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Реклама
Эиком - электронные компоненты и радиодетали
Опытный кот
Сообщения: 768
Зарегистрирован: Сб ноя 08, 2008 18:32:36

Сообщение vovik15 »

Странно,у меня не одного варнинга,все компилируется без проблем. Скажите,а чем rx отличается от rxc? И так ли важно ставить маин в конец кода?
Контактная информация:
Реклама
afz
Опытный кот
Аватара пользователя
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Сообщение afz »

Скажите,а чем rx отличается от rxc?
Ну, наверное тем, что оно прописано в avr/iom168pa.h (вызывается из avr/io.h). В отличие от. Открой дерево проекта, найди в нем iom168pa.h и щелкни дважды по нему. Вектора описаны в конце.

Вообще, ISR(<вектор>) - это макрос, который делает функцию специального ("прерывательного") формата, с именем вектора. Так вот, USART_RXC_vect в таблице векторов не нашлось, GCC сгенерил функцию с таким названием, но она, что называется, "повисла в воздухе", ее некому вызывать. О чем меня и предупредили. В итоге получилось, что прерывания UART'овского ресивера разрешены, а программы обслуживания нет, вот оно и гонит. Как раз та самая ситуация, которую мы недавно обсуждали здесь, там, правда, асм, а не си.
Странно,у меня не одного варнинга,все компилируется без проблем.
Может где-то отключены? Типа дефолтное значение у новых Студий другое. Или сам отключил, да забыл.
И так ли важно ставить маин в конец кода?
Любая функция перед ее вызовом должна быть объявлена. Стандартные функции, которые ты можешь вызвать, объявлены в заголовочных файлах (.h). А тут GCC компилирует main(), попадается строчка

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

UART_Init();//инициализация UART
и черт его знает, что это такое...

Нет, конечно, можно добавить перед функцией main() строчку

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

void UART_Init(void);
Только проще располагать функцию в исходнике до первого ее вызова.

В общем, найди и включи предупреждения. И старайся всегда добиваться, чтобы их не было, они не зря выдаются.

Добавлено after 1 hour 55 minutes 57 seconds:
Обновил у себя тулчейн - у меня стоял avr-toolchain-installer-3.3.0.710, поставил 3.3.1.1020 (последний 3.3, который отдается из атмеловского архива Микрочипа). Появилась ATmega168PA/ С удивлением обнаружил, что вектор USART Rx Complete для нее называется USART__RX_vect (два подчеркивания между USART и RX). В отличие от Меги 168P. Интересно, это ошибка, или как? У кого стоит студия поновее, гляньте, плз, как оно там?

Да, ATmega48PA в 3.3.0.710 была (я тут еще один проект смотрел), у нее было USART_RX_vect, а после обновления тоже стало USART__RX_vect (с двумя подчеркиваниями).

В общем, чтобы не ошибиться, название вектора для конкретного камня берем из соответствующего заголовочного файла. Смотрим в avr/io.h, какой там .h инклюдится для нашего камня, смотрим в этот .h и выбираем соответствующее имя вектора.

Добавлено after 51 minute 57 seconds:
Заглянул сам в Студию 6.2, увы, 3.3.1.1020 с ошибками. В новой Студии двойные подчеркивания из имен для векторов убрали. Переношу обсуждение в тему "AVR Studio в вопросах и ответах".
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Реклама
Опытный кот
Сообщения: 768
Зарегистрирован: Сб ноя 08, 2008 18:32:36

Сообщение vovik15 »

огромное спасибо вам за развернутый ответ. Проблема действительна была в неправильном векторе прерывания,все заработало!

Добавлено after 24 minutes 55 seconds:
И есче один момент. При включении питания при передаче по юарт, первый символ содержит в себе какой то мусор,как от этого избавится?
Контактная информация:
afz
Опытный кот
Аватара пользователя
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Сообщение afz »

огромное спасибо вам за развернутый ответ.
Пожалуйста. А плюсик нажать? Который слева?.. :)
первый символ содержит в себе какой то мусор
Вероятно, вот это

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

UDR0 = 0; //обнулить регистр uart
лишнее. В программе UART_Init().
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Ответить

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