Учебный курс. UART/USART. Получение первых результатов. Сопрягаем микроконтроллер с компьютером

26/12/2009 - 23:46

Задача

   Связать микроконтроллер с компьютером. Микроконтроллер должен принимать по USART`у символ, отображать его на LCD и отвечать компьютеру “Ok”.

Аппаратная часть

   Микроконтроллер ATmega8535 имеет в своем составе модуль универсального синхронно/асинхронного приемопередатчика -  USART. С его помощью между компьютером и микроконтроллером можно организовать обмен данными по последовательному каналу. Раньше в компьютерах для этих целей использовались COM порты, однако на современных машинах они уже большая редкость. Если на вашем компьютере все-таки есть такой порт, то для подключения микроконтроллера, понадобится преобразователь уровней ТТЛ – RS232. Его можно собрать на микросхеме MAX232AEPE
схема преобразователя TTL-RS232
  Если COM порта нет, будем подключаться к USB. Для облегчения работы с этим интерфейсом и для поддержки старых устройств, использовавших RS232, производители микросхем выпускают специальные USB-UART преобразователи. Один из вариантов подобного преобразователя представлен на схеме ниже (микросхема FT232BM). При подключении его к компьютеру, система попросит драйвера. Их можно скачать на сайте производителя. 
схема USB-UART преобразователя
Схема для нашего примера (без переходника)
схема для нашего примера 

Программная часть

   Для работы с  USART`ом нам нам понадобятся 4 функции. Три пользовательские, которые мы сможем вызывать:

Функция инициализации
Функция отправки символа
Функция чтения приемного буфера

   И одна для обработки прерывания USART`а:

Обработчик прерывания по завершению приема

Функция инициализации

  Как и любой другой периферийный модуль, USART перед использованием нужно настроить. Для этого в микроконтроллере ATmega8535 есть 5 регистров – UBRRH, UBRRL, UCSRA, UCSRB, UCSRC.

//инициализация usart`a
void USART_Init(void)
{
  UBRRH = 0;
  UBRRL = 51; //скорость обмена 9600 бод
  //разр. прерыв при приеме, разр приема, разр передачи.
  UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);  
  //обращаемся к регистру UCSRS, размер слова – 8 бит
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}

UCSRB
регистр UCSRB

  Принятый символ USART модуль сохраняет в регистре данных UDR. Оттуда мы его потом переписываем в буфер. Выполняется это в прерывании, а для этого оно должно быть разрешено. Устанавливаем бит – RXCIE – разрешение прерывания по завершению приема  в единицу.
   Биты TXCIE и UDRIE – разрешают прерывания по завершению передачи и прерывания при очистке регистра данных соответственно. Эти прерывания мы сейчас использовать не будем.
  Модуль USART состоит из трех основных частей – блока тактирования, блока передатчика и блока приемника. Для разрешения работы приемника и передатчика нужно установить в единицу биты RXEN и TXEN соответственно.
  Размер слова данных передаваемых/принимаемых модулем USART может варьироваться от 5 до 9 разрядов и определяется битами UCSZ2..UCSZ0. В регистре UCSRB находится только бит UCSZ2. Остальные биты находятся в регистре UCSRC. Мы будем использовать 8-ми разрядные слова, а значит эти три бита должны быть установлены так -  011.
   Биты RXB8 и TXB8 – это 8-ой разряд принимаемых/передаваемых данных соответсвенно. Они используются, если размер слова данных – 9 бит.
 
//разр. прерывания при приеме, разр. приема, разр. передачи
UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);

UCSRC
регистр UCSRC

   У микроконтроллера ATmega8535 регистр UCSRC размещен по тому же адресу что и регистр UBRRH (это тоже регистр модуля USART, вместе с регистром UBRRL он определяет скорость обмена), поэтому при обращении к ним нужно выполнять ряд дополнительных действий для выбора конкретного регистра. За это отвечает бит URSEL. Если он установлен в 1 обращение производится к UCSRC. Устанавливаем его.
   UMSEL – определяет режим работы модуля USART – синхронный, асинхронный. У нас режим работы асинхронный, разряд должен быть сброшен.
  UPM1, UPM0 – определяют режимы работы схем контроля и формирования четности. Используются для повышения надежности передачи данных. В нашем случае контроль четности выключен – биты должны быть сброшены.
  USBS – количество стоп битов. Для нашего случай бит сброшен.
  UCSZ1, UCSZ0 – формат посылок. О них мы уже говорили выше. Для 8-ми разрядного слова эти биты должны быть установлены в единицы.
   UCPOL – полярность тактового сигнала. Пропускаем мимо, потому что разряд используется только при работе в синхронном режиме.
 
//обращаемся к регистру UCSRS, размер слова – 8 бит
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);

UBRR – UBRRH:UBRRL
регистр UBRR

  Скорость обмена данными определяется содержимым регистра UBRR. Это 12 разрядный регистр и он физически размещается в двух регистрах ввода/вывода - UBRRH:UBRRL. Скорость обмена выбирается из ряда стандартных значений, в нашем примере она равна 9600 бод. Значение UBRR для обычного асинхронного режима (есть еще асинхронный режим с удвоенной скоростью обмена) вычисляется по формуле:
 
UBRR = (Fck/(16*BAUD)) – 1
где Fck – тактовая частота микроконтроллера, BAUD скорость обмена в бодах
 
   Для нашего случая UBRR = 8000000/(16*9600) – 1 = 51. Это округленное значение, поэтому реальная скорость обмена будет отличаться от 9600. Рекомендуется использовать такие значение регистра UBRR, при которых получаемая скорость передачи отличается от требуемой на величину < 0.5%. Большая ошибка будет снижать помехозащищенность линии передачи.
 
  UBRRH = 0;
  UBRRL = 51; //скорость обмена 9600 бод

UCSRA
регистр UCSRA

  Этот регистр в основном содержит флаги устанавливаемые самим модулем USART. Единственный флаг который нам понадобится в программе – UDRE – флаг опустошения регистра данных. Он устанавливается в 1 при пустом буфере передатчика. Установленный флаг означает, что в регистр данных можно загружать новое значение.

 Функция посылающая символ

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

   Передача данных USART`ом инициируется записью данных в буферный регистр передатчика – регистр данных UDR. (Работа передатчика естественно должна быть разрешена). Но перед тем как записать данные, нужно убедиться что передатчик освободился и готов к получению нового слова данных. Для этого в цикле while мы проверяем бит UDRE регистра UCSRA.

 Обработчик прерывания по завершению приема

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

Когда модуль USART принял данные, вызывается соответствующее прерывание. В прерывании мы переписываем содержимое регистра UDR в буфер usartRxBuf. Старое значение буфера при этом затрется, но так как мы используем медленный посимвольный обмен, потерь данных не будет

Функция чтения приемного буфера

//чтение буфера
unsigned char USART_GetChar(void)
{
  unsigned char tmp = usartRxBuf;
  usartRxBuf = 0;
  return tmp;  
}

Копируем значение буфера в локальную переменную, очищаем его. Локальную переменную возвращаем.

Необходимый минимум готов. Оформляем его в виде программного модуля.

usart.h
usart.c

Основная программа

Основная программа будет выглядеть так. Надеюсь дополнительных комментариев она не требует.

//*****************************************
//  Author(s)...: Pashgan    http://ChipEnable.Ru   
//  Target(s)...: ATMega8535
//  Compiler....: IAR EWA 5.11A
//  Description.: UART/USART. Получение первых результатов
//******************************************

#include <ioavr.h>
#include "lcd_lib.h"
#include "usart.h"

int main( void )
{
  unsigned char sym;
 
  USART_Init();
  LCD_Init();
  __enable_interrupt();
  LCD_SendString("uart:");
 
  while(1){
    sym = USART_GetChar(); //читаем буфер
    if (sym){                         //если что-то приняли, то
      LCD_Goto(6,0);
      LCD_WriteData(sym); //отображаем на lcd принятый символ
      USART_SendChar('O'); //отвечаем компу "Ok "
      USART_SendChar('k');  
      USART_SendChar(' ');  
    }
  }    
  return 0;
}

Для проверки результатов работы микроконтроллера потребуется программа - терминал. Вы можете скачать ее в разделе полезный софт. Если лень собирать схему и возиться с реальным железом, можно проверить программу в Proteus`e.  

Файлы

Comments   

# alexandershahbazov 2009-12-27 20:00
Есть ли какие-либо определенные подходы
если поток данных между МК и ПК насыщен
( например идут данные разной структуры ,
при этом идет посылка определенных команд
) .
Или тут все зависит от мастерства программировани я .
На ПК я использую VB6 . Там почти все
делаю через обработчик событий CommEvent .
Может быть на ПК в этом случае есть более
фунциональный язык .
Со стороны МК использую CodeVision .
# Pashgan 2009-12-28 04:31
Использовать приемный и передающие fifo буферы. А для "распознавания" принятых данных - state machine(автомат ) на таблицах или switch`е. Больше тут ничего не придумаешь.
# skiff 2009-12-29 13:50
Доброго времени суток!alexander shahbazov можете объяснить(на форуме) по подробнее про использование обработчика событий CommEvent(компонент MSComm1). Я сам программирую в VB6, с недельку назад разобрался с USART-ом на Mege8535. Буду очень благодарен! :-)
# alexandershahbazov 2009-12-29 21:27
Dim chr As String

ATmega8.InputLen=1
ATmega8.RThreshold=1

Private Sub ATmega8_OnComm()
Select Case ATmega8.CommEvent
Case comEvReceive
chr = ATmega8.Input
'Здесь уже кому что надо
End Select
End Sub
# skiff 2009-12-30 11:52
Спасибо alexandershahba zov!
# Guest 2010-02-05 08:37
Собрал на mege48. При приеме символов не отображает практически ничего - черный квадратик. если отправлять с терминала строку с абзацем - показывает абзац.
При отправке на компе принимается группа из 6-7 символов. притом 5 из них одинаковые, а остальные какие-то кракозяблы. Ну никак это не похоже на ОК...
Вчем мой косяк?
# Pashgan 2010-02-05 17:31
- Проект в статье написан для mega8535. Для другого микроконтроллер а его нужно перекомпилировать.
- Кракозябы часто возникают, когда скорость обмена мк и компа не совпадают. У меня в схеме тактовая частота мк - 8МГц, скорость обмена - 9600.
# Guest 2010-02-05 18:24
Угу. Перекомпилирова л естественно под 48й кристалл. Фьюзы стоят на внутренний 8 мгц по-умолчанию. скорость 9600. а кракозяблы остались...
# Pashgan 2010-02-05 20:10
Какой компилятор?
У mega48 названия битов и регистров модуля USART отличаются от mega8535 и при перекомпиляции из нужно исправлять. Скинь мне проект на microsmaster'со бака'rambler.ru , я гляну его
# Guest 2010-06-10 12:13
Собрал на меге168 работает хорошо.
Только мах232 почемуто на 3,3В не работает.Знаю что 5В надо, но другом проекте другой мах232 работал отлично.
# Guest 2010-07-05 13:01
Помогите настроить проект под Atmega8515? я новичек и что-то не разберусь IAR выдает
Error[Pe020]: identifier "UCSZ1" is undefined
Error[Pe020]: identifier "UCSZ0" is undefined
Error[Pe020]: identifier "UDRE" is undefined
# Даниил 2014-01-04 06:52
Quoting Guest:
Помогите настроить проект под Atmega8515? я новичек и что-то не разберусь IAR выдает
Error[Pe020]: identifier "UCSZ1" is undefined
Error[Pe020]: identifier "UCSZ0" is undefined
Error[Pe020]: identifier "UDRE" is undefined

Разрешаем использование имен битов определенных в хидер файле
В General Options > System ставим галочку Enable bit definitions in I/O-Include files.
# Guest 2010-10-02 19:47
интерестно, в нете в некоторых схемах одни соединяют ноги разьема rs232 некоторые нет, в чем разница и что лучше?
# Pashgan 2010-10-17 19:17
Полная версия стандарта RS-232 включает 9 сигналов. В большинстве случаев пользуются сокращенным вариантом - 3 провода (RXD, TXD, GND). Просто так удобнее.
# Гость 2010-12-15 14:33
Изучаю работу UART по Вашему примеру :) Но возникла проблема при приеме символов. На передачу все работает замечательно, а прием отсутствует :( В прерывание заходит "через раз" и регистр UDR имеет нулевое значение. Выставляется ошибка кадрирования. Все собрано "в железе" контроллер AtMega162 (программа естественно исправлены на него). Это вероятней всего аппаратная проблема?
# Pashgan 2010-12-19 19:39
Может быть проблема в несогласованнос ти скоростей обмена данными терминала и мк. Ну то есть в терминале выставлена одна скорость, а микроконтроллер посылает/приним ает данные с другой. От чего тактируется мк и какая у него частота?
# Новичок 2010-12-25 12:30
Привет всем, не уверен, что правильно понял схему:
1. prog connector - это программатор?
2. txd и rxd - это uart/usart переходник?
Спасибо за ответы)
# Pashgan 2011-02-12 16:00
Да, все правильно
# InterAct 2011-02-12 11:08
Привіт!
Заюзав ваш приклад використання USART
та знайшов помилку.... незнаю як в старих версіях WinAvr але в нових версіях оголошувати переривання потрібно
ISR(USART_TXC_v ect)а не ISR(USART_TX_vect)
ISR(USART_RXC_vect)а не ISR(USART_TX_ve ct)... до цього в мене просто 'завісав' МК Atmega8...
# Pashgan 2011-02-12 16:06
Может быть. Я пользуюсь WinAVR 20090313 и объявляю прерывания согласно avr-libc.
# Новичок 2011-03-06 13:49
Написал программу. МК(mega8) передает символы на ПК через usb-uart переходник(bm80 51) только если подключен программатор (avr910).Без него не пересылает. Кто-нибудь сталкивался с подобным?
# Pashgan 2011-03-06 21:53
У тебя вывод Reset на микроконтроллер е случайно не болтается в воздухе?
# Новичок 2011-03-08 20:36
Подал на него "+5"- все равно, - без программатора, подключенного к ПК символы по Usart'у не передаются.
# Pashgan 2011-03-15 19:43
Может проблема в настройках терминала?
# Новичок 2011-03-25 07:46
Pashgan, понял я в чем дело. Чуть голову не сломал от раздумий :-) . UART я подключал как показано на схеме: RXD и TXD, без земли (она не указана).Подсое динил землю - все заработало :-) .
# Miha 2011-04-07 06:53
По-моему, загружать главный цикл примитивной отправкой сообщения - не совсем рационально, там и так достаточно работы будет. Гораздо интереснее заставить это делать сам USART. Для этого не вызываем SendChar(...) столько раз, сколько символов в буфере отправки, а пользуем прерывание по опустошению UDR. Когда нам требуется отправить сообщение - грузим UDR байтом из буфера по нулевому индексу и сразу разрешаем прерывание UDR. Цепочка такая: первый байт проваливается-U DR опустошается-во зникает прерывание-в прерывании считывается второй байт-прерывание сбрасывается-по опустошению UDR возникает прерывание-... и т.д. Только в прерывании проверять на равенство взятого из буфера байта 0 - признак конца строки. Если взяли 0 - ничего не отправляем и глушим прерывание сбросом бита UDRE.
Таким образом, USART самостоятельно выгребет весь буфер и сам себя успокоит.
Идея любезно подсказана DI HALT'ом. (dihalt.ru)
# VRS11 2011-04-14 23:48
А что означает если по USART всегда передается 00000000, и ничего не принимается не при каких условиях?
# Miha 2011-05-05 00:50
так постоянно нули передавать ещё проще - грузи их по прерыванию UDR и всё
а на практике такая потребность часто возникает?
# Aleksei 2011-09-15 07:57
перекомпилирова л под атмега8 , передаешь на комп символ"Q" приходит "T".
# MacMaffy 2011-11-16 15:33
подключил Вашу программу, символ отсылаю, в ответ приходит - это первое.
Второе, пишу if (sym == 'q') {LED=1;)
if (sym == 'w') {LED=0;)
Вообще не работает, тыкаю на любую кнопку загарается LED и не гаснет
# Илья 2012-01-13 13:56
А FT232BM подключать напрямую к контроллеру или тоже через MAX232 ?
# Макс 2012-04-02 13:15
Quoting Илья:
А FT232BM подключать напрямую к контроллеру или тоже через MAX232 ?

Подключать на прямую без МАХ232 но лучше FT232BM заменить на FT232RL. У RL обвязки никакой не надо там всего 2 конденсатора по питанию достаточно (а цена одинаковая).

К стати не соединяйте Экран USB разъемов с землей, FT232 к этому очень чувствительна и может начать сбоить(типа устройство не опознано) На ноутбуке этого не будет на на стационарном компе может получится.
Я очень долго с этим мучился.
К стати спасибо за доходчивое объяснения)))
# son313 2012-01-16 10:14
Всем привет. Я еще пока очень зелен в МК. Как в AVR Studio 5 быть с этой программой? К примеру прерывание если правильно понимаю __enable_interr upt(); он не понимает. Читал на форумах что в разных компиляторах все команды на одном и том же языке вводятся по разному. Как узнать все эти разности? Может есть где описание типа к примеру для AVR Studio 5 эта команда так будет выглядеть, а для WINAVR вот так. Может кто встречал в интернете подобное. За ранее всем благодарен.
# son313 2012-01-16 16:01
Если кто знает, как в AVR studio 5 при наборе кода сделать что бы выпадал список с подсказками как например вот в этом видео на пятой минуте просмотра http://www.youtube.com/watch?v=3Koa6oy53Os&feature=related . Всем еще раз спасибо
# Friman 2012-03-12 14:10
Здравствуйте!
Пишу диплом, и практически сразу стллкнулся с проблемой. Пишу в iar а отлаживаю в протеусе и авр-студии. Необходимо отправлять 3-и 2-ух байтных числа, как только отправляю байт (например все единицы), приходят одни нули. При проверке в студии обнаружил, что когда помещаю число в UDR, на следующем цикле UDR обнуляется. Прочитал что на самом деле для передачи используется другой регистр, а UDR на подобии буфера. Тогда попробовал присваивать UDR одно число и в следующей строчке другое, но UDR всё равно обнуляется, а не ждёт пока регистр отправки отправит предыдущий.
Думаю вопрос глупый, и что я банально что-то упустил из виду=)
# dmitr-panov 2012-10-27 08:27
ISR(USART_RXC_vect)
у меня так работает - avr-libc 1:1.7.1-2
# Илья89 2013-08-27 04:52
Спасибо тебе Паша!
# Винни 2013-09-27 20:32
присоединяюсь к вопросу- как проверить полученный символ? вот так-
if (data=='A')
{
stat=1;
}
if (data=='B')
{
stat=0;
}
while (stat)

не получается(
# Pashgan 2013-09-28 20:10
Так же как и в примере
Code:
sym = USART_GetChar(); //читаем буфер
if (sym){ //если что-то приняли, то
LCD_Goto(6,0);
LCD_WriteData(sym); //отображаем на lcd принятый символ
USART_SendChar('O'); //отвечаем компу "Ok "
USART_SendChar('k');
USART_SendChar(' ');
}


Если не получается, то может быть скорость неправильно настроена.
# Винни 2013-09-29 20:30
Quoting Pashgan:

Code:
sym = USART_GetChar(); //читаем буфер
if (sym){ //если что-то приняли, то



Если не получается, то может быть скорость неправильно настроена.

в том то и дело, что мне надо проверить не факт приема чего-то, а на конкретный символ.
# Pashgan 2013-09-30 18:32
Я имел ввиду так
Code:
if (sym == 'A'){
...
}
# Ton 2014-03-18 04:57
Подскажите как настроить UART 8515-ый - UBRRH, UBRRL, UCSRA, UCSRB, UCSRC. Спасибо
# Ton 2014-03-18 05:01
Code:
UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
UCSRC = (1 << URSEL) | (3 << UCSZ0);

возможно верно?
# Pashgan 2014-03-18 20:11
Под какие параметры настроить нужно?
# Ton 2014-03-19 04:43
Делаю вроде по аналогии, но без дисплея. На переходнике USB-UART светодиод моргает - символ отправлен... но Ок нет =( Земля и от LPT программатора и от переходника подключены, питание есть, но молчок

кристалл mega8515, скорость 9600, частота 8000000

Code:
UBRRH=0;
UBRRL=51; //скорость обмена 9600 бод
UCSRB=(1<<RXCIE)|(1<<RXEN)|(1<<TXEN); //разр. прерыв при приеме, разр приема, разр передачи.
UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //размер слова 8 разрядов
}
# Ton 2014-03-19 06:01
поменял на:
1843200 hz, 115200 бод, плучилось 0

светодиоды на переходнике горят оба - символ отправлен и что-то принято, но в одном терминале (keterm) отобраюжаются буквы, в другом SimpleTerm - вопросы, в третьем Advanced Serial Port Monitor - те же буквы. В терминалах выбирал 115200 бод.
# Ton 2014-03-19 06:07
Code: UBRRH=0;
UBRRL=0; //скорость обмена 115200 бод
UCSRB=(1<<RXCIE)|(1<<RXEN)|(1<<TXEN); //разр. прерыв при приеме, разр приема, разр передачи.
UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //размер слова 8 разрядов
# Pashgan 2014-03-19 09:33
Я взял проект, поменял тип микроконтроллер а на mega8515 и запустил компиляцию. В Протеусе полученная прошивка сразу же заработала (тактовая 8 МГц, скорость обмена 9600). В железе нет возможности проверить.
# Ton 2014-03-19 10:25
Спасибо. Протеус так протеус...
# Ton 2014-03-19 13:28
Через что подать символ по UART в Протеусе? В протеусе добавил компонент com, подключил к 8515... и непонятные символы пошли в ответ
# JoJo 2014-03-19 13:36
Там есть компонент - виртуальный терминал.
# serfeld 2014-05-24 09:31
Здравствуйте!По дскажите,пожалу йста как организовать мультипроцессор ный обмен между мастером и двумя слейвами.Принци п понимаю,смотрел пример из datasheet на mega8.В Proteus удалось добится только одноразового аппаратного сброса MPCM при прохождении "1" в 9-ом разряде.Дальше- затык.В железе не пробовал пока...
# serfeld 2014-05-25 07:37
Разобрался.В Proteus заработало.Проб лема была в ручной установк MPCM.Спасибо!
# dim 2014-07-09 16:47
Как правильно принять несколько бит или строку?
# dim 2014-07-09 17:23
то есть несколько байт
# _Артём_ 2014-07-10 06:18
Quoting dim:
то есть несколько байт

Просто всё - разрешаете прерывание по приёму байта, в прерывании пишите данные в кольцевой буфер, а в основной программе обрабатываете принятые данные.
# dim 2014-07-10 13:51
Гдето я наверно накосячил, так же и пытался сделать
если у кого есть такой кусочек кода для приема, буду благодарен)
# _Артём_ 2014-07-11 06:33
Quoting dim:
Гдето я наверно накосячил, так же и пытался сделать
если у кого есть такой кусочек кода для приема, буду благодарен)

Например так:
Code:
#define RX_BUFFER_SIZE 100
volatile uint8_t RxBuffer[RX_BUFFER_SIZE];
volatile uint8_t RxNext, RxFirst;
ISR(USARTC0_RXC_vect)
{
uint8_t rx_next=RxNext;
RxBuffer[rx_next]=USARTC0.DATA;
if (++rx_next>=RX_BUFFER_SIZE)
rx_next=0;
RxNext=rx_next;
}

void UsartReceive()
{
uint8_t rx_first=RxFirst, rx_next=RxNext;
while (rx_first!=rx_next) {
uint8_t new_byte=RxBuffer[rx_first];
// обработка данных
//
if (++rx_first>=RX_BUFFER_SIZE)
rx_first=0;
}
RxFirst=rx_first;
}
# dim 2014-07-11 17:03
Спасибо, буду ковырять косяк, вроде похоже делал, но принимает только первый байт, второй почему-то ноль
С примером проще разбираться))
# Misha 2015-10-21 12:58
здравствуйте, разглядывал много схем с уарт преобразователя ми, и что увидел, на некоторых есть резисторы на линиях rx и tx, на некоторых нету, а на некоторых есть резистор только на одной линии, так вот собственно нужны ли всё таки там резисторы? и зачем?
предпологаю для защиты, например по уарту "плюётся" еденичка, а на втором конце по случайности "мёртвая" земля
# Misha 2015-10-21 13:31
и какая сторона в состоянии покоя подтягивает линию к 5-ти вольтам?
мне кажется tx подтягивает к 5-ти вольтам, а rx всегда может только слушать линию(то есть всегда в высокоимпедансн ом состоянии)?
# Антип 2015-12-27 10:21
Здравствуйте Pashgan, собрал Вашу схему на mega8515 немного поменял код - все отлично работает. Пошел дальше сделал программу на ПК которая отсылает побайтно содержимое бинарника и сразу столкнулся с проблемой: программа не принимает 0х00 и виснет, так как от контроллера нет ответа. Я попытался в файле usart.c в прерывании подписать еще одну переменную, которая принимает значение 1 при событии приема байта. Вообще корректно ли так делать или нет? С++ начал учить совсем недавно. Далее, попытался переделать функцию USART_GetChar на возвращение структуры состоящей из двух символов буфера и флага приема байта. Пытался компилировать в CVAVR но ни чего не получилось - вообще не пойму в чем проблема вот код
Code:
#include "usart.h"
//однобайтный буфер
volatile unsigned char usartRxBuf = 0;
unsigned char fl = 0;
struct my_strct {unsigned char buf; unsigned char flg;};
#define RXCIE 7
#define RXEN 4
#define TXEN 3
#define URSEL 7
#define UCSZ1 2
#define UCSZ0 1

//инициализация usart`a
void USART_Init(void)
{
UBRRH = 0;
UBRRL = 71; //скорость обмена 9600 бод для 11,0592МГц в даташите
UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN); //разр. прерыв при приеме, разр приема, разр передачи.
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //размер слова 8 разрядов
}
#define UDRE 5
//отправка символа по usart`у
void USART_SendChar(unsigned char sym)
{
while(!(UCSRA & (1<<UDRE)));
UDR = sym;
}

//чтение буфера
my_strct USART_GetChar(void)// на это место компилятор ругается '(' expected
{
my_strct my;
//unsigned char tmp;
unsigned char saveState = SREG;
#asm("cli");
my.buf=usartRxBuf;
my.flg=fl;
//tmp = usartRxBuf;
usartRxBuf = 0;
fl=0;
SREG = saveState;
return my;
//return tmp;
}

//прием символа по usart`у в буфер
interrupt [USART_RXC] void usart_rxc_my(void)
{
usartRxBuf = UDR;
fl=1;
}
# Антип 2015-12-29 13:32
Ответ не нужен, спасибо. Разобрался сам...

У вас недостаточно прав для комментирования.