Обсуждаем контроллеры компании Atmel.
Ответить

UART MEGA168PA

Пт авг 03, 2018 13:48:17

Здравствуйте уважаемые форумчане! Вот уже целую неделю бьюсь с настройкой юарта. Перепробывал много разных кодов из интернет. Дело в том,что при включении питания в терминал прилетает сообщение,все как и задумано. А при отправке любого символа из терминала на мк происходит что то странное. Контроллер в ответ начинает слать пробелы без остановки. Пишу в авр студио 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 вход
}

Re: UART MEGA168PA

Пт авг 03, 2018 13:52:02

volatile unsigned char flag;

Re: UART MEGA168PA

Пт авг 03, 2018 14:00:34

Исправил тип переменной,не помогло. Железо 100% исправно,проверял с новым контроллером то же самое. В сторону пк данные идут замечательно, но вот принять не получается. Может быть у кого нибудь найдется отлаженный кусок кода?

Re: UART MEGA168PA

Пт авг 03, 2018 15:38:45

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() в конец исходника.

Re: UART MEGA168PA

Пт авг 03, 2018 21:53:37

Странно,у меня не одного варнинга,все компилируется без проблем. Скажите,а чем rx отличается от rxc? И так ли важно ставить маин в конец кода?

Re: UART MEGA168PA

Сб авг 04, 2018 07:04:29

Скажите,а чем 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 в вопросах и ответах".

Re: UART MEGA168PA

Сб авг 04, 2018 20:14:28

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

Добавлено after 24 minutes 55 seconds:
И есче один момент. При включении питания при передаче по юарт, первый символ содержит в себе какой то мусор,как от этого избавится?

Re: UART MEGA168PA

Вс авг 05, 2018 02:02:12

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

первый символ содержит в себе какой то мусор
Вероятно, вот это
Код:
UDR0 = 0; //обнулить регистр uart
лишнее. В программе UART_Init().
Ответить