Привет уважаемые, у меня проблема с uart. Подключил Атмега8 через uart к ноутбуку, в терминале отправляю поочерёдно 1 2 3 4 5, а в ответ получаю в том же терминале L f & s M. Пробовал 3 терминала, во всех одинаково. Схема подключения стандартная, как во многих примерах, Атмега8 с кварцевым резонатором на 8 МГц, 2 конденсатора на 22 пФ, питание от USB ноутбука, 1 кОм резистор между RESET и +5 В, Rx Tx подключил к Tx Rx переходника (кабель USB - COM), кабель в ноутбук, дрова стоят. Кабель проверял, Tx Rx замыкал, всё отправленное возвращается в точности. Первый контроллер был SMD, выпаял запаял аналогичный, опять то же, потом собрал ту же схему на DIP - опять то же. Минус виртуального ком порта и схемы пробовал соединять, ничего не меняется (они все равно в USB одного и того же ноутбука вставляются), внутрисхемный программатор отцеплял. Фьюзы уже по всякому перепробовал от отчаяния. В код вижене стоит правильная частота, в коде правильная, фьюзы вроде правильные, но не помогает. Пробовал и на внутренней частоте 4 и 8, и с разными кварцами 4, 8, и с идеальными частотами которые без помех, всё одно, выводит совсем не то что посылаю, а если подаю питание контроллера не от ноута а от от телефонной зарядки 5 В на 2,1 А, то идуд непрерывно кракозябли в терминал, пока общий минус не соединён у источника питания и USB-COM кабеля. Разные программы уже перепробовал, и просто UDR = '1' и ="1" ни что не помогает, менял местами Rx Tx. Пробовал в протеусе, там и фьюзы нормально и программа нормально идёт, там всё работает без проблем, но вот в реальности ерунда выходит. Купил для сравнения Ардуино УНО, там сразу эта программа с тем же кабелем USB-COM в терминале всё возвращает, светодиодиком пробовал мигать по входящим данным 1 и 0 итд уже 4 дня гуглю везде сравниваю, у всех проблемма обычно с частотой подключения или контроллера, вроде всё перепроверил. Пытаюсь на 9600 подключаться но в общем весь диапазон перебрал на всякий случай, но 9600 явно адекватнее идёт, с неё и расчёт в программе. ПОМОГИТЕ пожалуйста кто сможет допереть что не так кроме кривых рук! Вот код: #include <mega8.h> #include <io.h> #include <delay.h> #include <stdio.h> #define F_CPU 8000000 // Рабочая частота контроллера #define BAUD 9600 // Скорость обмена данными #define UBRRL_value (F_CPU/(BAUD*16))-1 int init_UART(void) // Инициализация { UBRRL = UBRRL_value; //Младшие 8 бит UBRRL_value UBRRH = UBRRL_value >> 8; //Старшие 8 бит UBRRL_value UCSRA=0b00000000; UCSRB=0b00011000; UCSRC=0b10000110; } void send_Uart(unsigned char c) // Отправка байта { while(!(UCSRA&(1<<UDRE))) // Устанавливается, когда регистр свободен {} UDR = c; } void send_Uart_str(unsigned char *s)// Отправка строки { while (*s != 0) send_Uart(*s++); } void send_int_Uart(unsigned int c)// Отправка числа от 0000 до 9999 { unsigned char temp; c=c%10000; temp=c/100; send_Uart(temp/10+'0'); send_Uart(temp%10+'0'); temp=c%100;; send_Uart(temp/10+'0'); send_Uart(temp%10+'0'); } unsigned char getch_Uart(void)// Получение байта { while(!(UCSRA&(1<<RXC))) // Устанавливается, когда регистр свободен {} return UDR; } void main(void) { char data; PORTB=0x00; DDRB=0x01; init_UART(); // инициализация UART delay_ms(1000); // задержка 1c send_Uart_str("abc-defg");// отправка строки send_Uart(13); // перенос строки send_int_Uart(2013); // отправка числа send_Uart(13); // перенос строки while(1) { if(UCSRA&(1<<RXC)) // если пришёл байт по UART { send_Uart(getch_Uart()); PORTB = 0b00000001; delay_ms(50); PORTB = 0b00000000; } } }
Сумбурно всё описали -- мозги свернёшь.... Простой блинк (мигание светодиодом) работает? Светодиод мигает с правильной частотой? Как показывает практика -- это ни разу не показатель. Пройдёмся по замеченным ошибкам. F-CPU задают не здесь -- код будет собран криво. Нужно передавать в качестве параметра -DF_CPU=... компилятору. Это не перенос строки, перенос строки -- '\n' или 10 или 0xA. Это возврат каретки -- '\r' или 13 или 0xD.
Спасибо, убрал #define F_CPU 8000000 поставил #define UBRRL_value (8000000/(BAUD*16))-1 вместо старого Светодиод впаял, в код воткнул delay_ms(1000); PORTB = 0b00000001; delay_ms(1000); PORTB = 0b00000000; Светодиод секунду горит, секунду не горит - совпадает.
-D это другой способ сделать то же самое. Единственное. что этот дефайн надо перенести на первую строку.
ну, я уже вообще #define F_CPU 8000000 исключил. не понимаю в чём ещё может быть проблема, уже вроде всё перепробовал. Может есть у кого ещё какие мысли, что может быть не так?
Скрины приложил. В код вижн АВР код пишу, все настройки там же, через него же компилировал и прошивал (скрины приложил). Что значит IDE и boards? Как поменять частоту? В теории, если частота в двое выше, то при другой скорости соединение должно работать нормально? Я просто весь диапазон перебрал уже
Всем спасибо, проблему решили: http://radiokot.ru/forum/viewtopic.php?f=57&t=137600&p=2909139#p2909139