Только в этом месяце - скидки на паяльники и электронику с нашими кодами (123avr.com) :




Страницы курса:

Уроки

Задания


index.htm
01.htm
02.htm
03.htm
04.htm
05.htm
06.htm
07.htm
08.htm
09.htm


z1.htm
z2.htm
z3.htm
z4.htm
z5.htm
z6.htm
z7.htm
z8.htm
z9.htm
z10.htm
z11.htm

New! - ФОРУМ!

Совет - умейте правильно находить информацию!


Задача - упражнение   5

Цель задачи: 

  • 1)  Создать программу для  микроконтроллера ATmega16 принимающую и передающую данные по интерфейсу rs232  с помощью USART встроенного в AVR ATmega  на COM-порт ПК. Схемы и компоненты для сопряжения МК с COM-портом ПК, так же программы для управления и лога данных смотрите  в задаче 4

  • 2)  Закрепить навыки создания программы  в CVAVR с помошью мастера начального кода и продолжить учится   использовать язык Си для микроконтроллеров


  • 3)  Научиться подключать и управлять символьным ЖКИ - LCD 16x2 (c  контроллером  hd44780) - они очень популярны ! 

LCD бывают от 1 до 4 строк длиной до 40-ка символов.  Смотрите каталог электронных компонентов.

 

Для выполнения задачи необходимы :

Делаем :

Для того чтобы МК мог обмениваться данными с компьютером (ПК) или другим терминальным устройством - т.е.  принимать и отправлять данные  (обычно это байты, т.е. 8-ми битные числа) нужно : 

1) соединить его физически с ПК по схемам и способами  описанными в задаче 4 или с симулятором      

2) настроить == сконфигурировать USART  МК   

- установить скорость передачи данных в бодах такую же как на ПК  (из перечня скоростей стандартных для ПК) или как в  симуляторе   с погрешностью до 1%       

- установить формат передачи данных как на подключаемом  устройстве - это ПК, терминал или симулятор.

- включить прием и/или передачу данных - это можно делать по мере необходимости в программе.

Стандартные скорости обмена вашего ПК можно посмотреть через "панель управления" -> "система" -> "COM-порт" -> "свойства"

 

     
 

Для обеспечения с достаточной точностью скорости обмена обычно требуются кварцы специальных UART'овских частот - их можно найти в таблице ДШ в разделе USART. 

Не советую использовать внешний или встроенный RC-генератор для тактирования МК при обмене с ПК - их точность слишком мала и наверняка будут сплошные ошибки в передаче. 

Мастер настройки USART МК в  CVAVR (картинка ниже!) подсвечивает недопустимо большую ошибку в скорости передачи КРАСНЫМ цветом !

 
     

Пример настройки и включения USART ATmega16 на прием и передачу для любого компилятора Си 

 

Credit Star


     
 

// USART initialization
// Communication Parameters: 8 Data, No Parity, 1 Stop  8N1
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous

UCSRA=0x00;
UCSRB=0x98;
UCSRC=0x86;

// USART Baud rate: 115200  для кварца 11,059 МГц
UBRRH=0x00;
UBRRL=0x05;

 
     

 

Формат передачи данных (см. ДШ Frame Formats) в примере: 

// Communication Parameters: 8 Data, 1 Stop, No Parity

 

     
 

Сокращенно называют 8N1 - это формат по умолчанию для ПК.  

В таком формате передача байта начинается (естественно передающим устройством!) со "стартового бита" - это лог. "0" на ножке TXD для  USART МК и +5...+15 вольт для COM порта ПК на время одного бода. 

Время одного бода это результат деления 1 сек на скорость передачи в бодах.

Затем на ножку TXD выводятся все 8 бит передаваемого байта начиная с бит_0. 

Каждый бит держится на TXD в течении времени передачи одного бода - за это время приемник должен определить и запомнить этот уровень. 

Далее идет "стоп бит"  - это лог. "1" на ножке TXD для  USART МК и -5...-15 вольт для COM порта ПК на время одного бода. 

На передачу одного байта в формате  8N1 требуется время  -  10 бод.

 

     

Кусок кода выше я привел для примера. Я очень советую вам использовать мастер начального кода компилятора - Он сам сгенерирует вам все в нужном виде и правильно настроит USART. Главное - мастер покажет вам допустима ли ошибка в скорости передачи при использовании не UART'оских кварцев.

От слов к делу ... 

Запустите компилятор CodeVisionAVR, затем генератор начального, конфигурирующего кода программы для МК  - "CodeWizardAVR" - кликнув серую шестеренку слева от красного жучка... 

  Выберите в разделе Chip - МК ATmega16 и частоту кварца 11.059 МГц и  переходите на закладку USART  

- сделайте такие установки:


 


 Поставьте 3 галочки :
 
- включить приемник (Ресивер), 
- прерывание по приему символа и 
- включить передатчик (Трансмиттер). 

Число 100 означает - создать буфер в оперативной памяти МК на 100 символов. 

     
 

Чтобы не терять приходящие от ПК символы и не загружать МК постоянной проверкой - не получен ли новый символ в UDR 

удобно  использовать прерывание номер 12 "USART Rx Complete"  (стр. 43 ДШ)   его  вызывает завершение приёма символа в регистр UDR  и еще  создать буфер в который МК может в функции обработчике прерывания 12 положить принятый символ. А когда по программе понадобится или МК освободится от другой задачи, он сможет  брать символы уже из этого буфера. Буфер устроен по принципу FIFO "фёст ин - фёст аут" а по-русски:  "первый пришел первый вышел" это значит что байт который пришел в FIFO буфер первым, первым же и выходит из него. 

FIFO - это что-то типа трубы с одной стороны загружаемой шарикам диаметром чуть меньше внутреннего диаметра трубы и вынимаемыми с другой стороны трубы. Емкость такого FIFO будет равна целому частному от деления длины трубы на диаметр шарика. Шарик - это байт.

Генератор начального кода компилятора CodeVisionAVR сделает конфигурацию МК ПРАВИЛЬНО ! и быстро.

 
     


Буфер может быть ЛЮБОГО нужного вам размера - его ограничивает  лишь объем оперативной памяти МК. Советую вам сделать буфер в 2 раза больше того что вы считаете нужным по предварительным прикидкам.

Скорость обмена данными - "БадРэйт" - установили 115200. 

Скорость USART может быть только одна в каждый момент в МК и для приема и для передачи.  

Если вам нужно принимать на скорости отличной от передачи то вы не сможете это делать одновременно и должны будете по необходимости включать либо передатчик либо приемник и устанавливать нужную скорость. Но я бы посоветовал вам просто взять МК с двумя USART например ATmega64 и ATmega128. Больше ни чего менять в панели USART не нужно.

Переходим к закладке LCD - мы подключим жидкокристаллический индикатор на 2 строки по 16 символов с встроенным контроллером HD44780 - это очень распространенные индикаторы (см. стр. 1 курса).  

 

 

Для подключения LCD  вам достаточно указать желаемый порт МК и количество символов в строке. Количество строк указывать не нужно. 

С лева указаны выводы МК, а в правой колонке указаны выводы LCD - их нужно соединить между собой. Кроме того нужно соединить "земли" и подать питание на индикатор и подать напряжение контраста - делать это надо в соответствии с ДШ 
на LCD.

 

     
 

ATMEL сделал АпНоут  ANM069 "How to Interface a LCD Display to a TSC80251 Microcontroller" советую скачать и почитать. 

 
     

В закладке PORTA   сделайте  PA3 выходом - мы можем использовать его для индикации различных событий при отладке.

Всегда предусматривайте простые средства диагностики вашего устройства не требующие дополнительного оборудования !  К выводу МК можно подключить светодиод и разным режимом его горения отображать разную информацию, а можно выводить какую либо информацию на эту ножку в формате rs232.

Теперь 

В меню файл "КодВизада" выберите "генерэйт сэйв энд экзит",  и создайте в папке компилятора специальную папку для файлов задачи : 

C:\CVAVR\z5
  

Затем сохраните в ней созданный начальный код программы  usart.c и файл проекта   z5.prj  

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

Си для МК на стр. 5 курса

Программа.

 Рассмотрим участок программы создающий буфер для принимаемых  МК по USART символов.

 

     
 

/*****************************************************
Chip type : ATmega16
Program type : Application
Clock frequency : 11,059000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 256

*****************************************************/

#include <mega16.h>

// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x1B
;PORTA
#endasm

#include <lcd.h>

#define
RXB8 1
#define
TXB8 0
#define
UPE  2
#define
OVR  3
#define
FE   4
#define
UDRE 5
#define
RXC  7

#define
FRAMING_ERROR (1<<FE)
#define
PARITY_ERROR (1<<UPE)
#define
DATA_OVERRUN (1<<OVR)
#define
DATA_REGISTER_EMPTY (1<<UDRE)
#define
RX_COMPLETE (1<<RXC)

 
     


Как я рассказывал на странице 5  "язык Си для МК" - программа на Си начинается с заголовка, затем вставляются тексты внешних файлов-библиотек с помощью команды препроцессора
#include <текстовый файл>  

Затем с помощью первого блока определений #define компилятору сообщены номера битов по ДШ используемых в программе при работе с USART

Определения отдельных битов есть в компиляторах ICC, IAR и других, но их нет в CodeVisionAVR поэтому я сделал для вас заголовочный файл m8_128.h  - скачайте его добавьте в программу вот так:

#include <mega16.h> //обычный хидер

#include <
m8_128.h> //мой хидер для битов

Теперь вы сможете использовать примеры на Си из ДШ прямо так как они там написаны !

Второй блок определений #define делает программу более понятной и читаемой человеком давая осмысленные названия малопонятным битовым маскам 

например:  понятная человеку фраза  DATA_REGISTER_EMPTY в тексте программы на Си будет заменена препроцессором перед компиляцией на битовую маску   (1<<UDRE)  с помощью которой можно проверить  событие "регистр данных пуст" определяя состояние бита  UDRE.

 

     
 

Битовая маска   (1 << Название_бита_по_ДШ)

Это число у которого все биты равны "0" а бит с номером  как номер бита Название_бита_по_ДШ  равен "1". 

Получается маска сдвигом числа 1 из позиции бит_0 в лево на количество бит как номер бита Название_бита_по_ДШ 

Подробнее про операции над битами в задаче 1 курса. Битовая маска может иметь несколько единиц и нулей.

 
     


Теперь чтобы проверить свободен ли 
UDR - регистр данных USART - достаточно сделать логическое "И" числа в регистре  UCSRA  с маской  DATA_REGISTER_EMPTY

"Истина" будет означать что UDRE  равен "1" и значит регистр данных пуст.


Внимание!
Генератор начального кода CVAVR выдает бит UPE - на самом деле в ATmega8 -16 -32 в регистре UCSRA бит_2 называется PE.  На работу программы это не влияет.

Дальше ... 

 

     
 

// Буфер - USART Receiver buffer
#define RX_BUFFER_SIZE 100

char rx_buffer[RX_BUFFER_SIZE];

#if RX_BUFFER_SIZE<256
unsigned char rx_wr_index, rx_rd_index, rx_counter;
#else
unsigned
int rx_wr_index, rx_rd_index, rx_counter;
#endif

// This flag is set on USART Receiver 
bit rx_buffer_overflow; // buffer overflow

 
     


В начале строка задающая нужный пользователю размер буфера - это может быть число от 1 (0 - это бессмысленно пожалуй)  до 65535 - это максимальное положительное число из двух байтов.

Благодаря использованию директивы препроцессора #define мы сможем в случае необходимости изменения размера буфера, сделать это поменяв число 100 только в этой строке - не смотря на то, что используется оно в нескольких местах программы.

Вывод: 

#define   - это удобно! и снижает вероятность ошибок. Позволяет просто модифицировать программу - используйте !

Следующей строкой объявлен символьный массив : 

char rx_buffer[размер массива в символах];

размером по заказанному нами буферу. 

Символьный в нашем случае - потому что char указывает на типа данных - беззнаковый символьный - это числа от 0 до 255 - по таблице ASCII им соответствуют определенные символы  - (таблицу ASCII  см. стр. 5 курса).

Напомню:

В массиве нумерация элементов начинается с НУЛЯ !
Значит первый элемент этого массива  на 100 элементов:         

rx_buffer[0]        а последний :         rx_buffer[99]

 

     
 

Далее очень интересно ! 

Обратите внимание что и в директивах препроцессора можно использовать конструкцию -  if  else    

#if условие 
подставить в текст программы если условие "истина"
#else
подставить если условие "ложь"
#endif

только не нужны скобки (   ) и {   }, перед ключевыми словами ставьте знак  #  и закончить конструкцию нужно так как в примере !

Используйте в любом месте программы где нужно.

 
     


С помощью этой конструкции в зависимости от размера буфера выбирается подходящий тип (байт или два байта)  трех глобальных переменных  необходимых для работы с буфером. 

СТОП  !

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

Последняя строка обсуждаемого куска кода (выше, на голубом фоне) объявляет битовую переменную 

bit rx_buffer_overflow;

это флаг (можно сказать - признак) переполнения буфера - если 

rx_buffer_overflow
    

"установится" т.е. станет "1"   -  плохо дело !  - мы долго не забирали символы из буфера и он переполнился, значит мы потеряли некоторые символы которые пришли раньше. 

Битовые переменные могут быть только глобальными ! т.е. они объявляются в начале  программы до фигурных скобок   {    }   и доступны программе в любом ее месте. Это в CVAVR, а в других компиляторах с битовыми переменными
может быть и по другому. 

 

     
 

Совет !  Не жадничайте ! 

Используйте под флаги переменные типа char  вместо битовых. Они во всех компиляторах одинаковы - значит не запутаетесь. Если вы выбрали правильный МК то с недостатком памяти вы не столкнетесь.

 
     

 

Дальше     

функция-обработчик прерывания № 12 : 

 

     
 

// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{

char
status, data;

status=UCSRA;
data=UDR;

if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
  {
rx_buffer[rx_wr_index]=data;


if (++rx_wr_index == RX_BUFFER_SIZE)
     
{  // я добавил эти скобки
   rx_wr_index=0;
     
}; // для лучшей читаемости

if (++rx_counter == RX_BUFFER_SIZE)
    {
    rx_counter=0;
    rx_buffer_overflow=1;
    };

  };
}

 
     


Эта функция называется
usart_rx_isr()  и вызывается при возникновении прерывания  USART_RXC (см. ДШ на МК) по приему символа в регистр  UDR   это регистр данных USART, причем два регистра данных и приемника и  передатчика называются одинаково.  Т.е. программа МК перестает делать то что делала, сохраняет некоторые данные необходимые для продолжения работы с этого места после возврата  из обработчика прерывания и начинает выполнять функцию обработчик прерывания  -      usart_rx_isr()

 
Разберем что делает функция-обработчик прерывания 12.


Вначале объявлены две локальные переменные символьного типа 
  status    и dataЛокальные - значит они объявлены сразу после открывающей скобки какой либо функции :  

{
  объявление локальных переменных 

далее остальное 
тело функции   
}  

Локальные переменные доступны только в той  функции в которой объявлены !   Значит в разных функциях могут быть локальные переменные с одинаковыми именами !  Но я не советую вам так делать -  запутаетесь.Значение Локальных переменных без модификатора static не сохраняется к следующему вызову функции, и нам не известно что в них содержится при создании - т.е. им нужно присвоить некоторое значение если мы не сделали это при объявлении. 

Вот программа и присваивает им значения в следующих двух строках:

status = UCSRA;
data = UDR;

В  status  копируется число из UCSRA  - это регистр 
                     управления и статуса - состояния  USART  (стр. 162 ДШ).

В  data  копируется число из UDR  - это регистр для принимаемых данных. 
(стр. 161 ДШ).


Затем  проводится  проверка правильно ли USART MK принял 
то что пришло на ножку RXD от ПК или другого устройства :

if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
   {

Код программы написанный здесь будет   выполнятся ТОЛЬКО если условие в           
скобках    if("истина")  -       значит "НЕ НОЛЬ"

      };
 

     
 

Условие в скобках  у  if  довольно сложное

Используя сведения со страницы 5  "Си для МК" - попробуем разобраться что это условие означает.

Структура условия такова:

if ( (   2 (  1  ))  3   )

оно состоит из нескольких выражений заключенных в скобки,  побитных логических операций в 1 и 2 и логической операции 3.

Начнем с самых глубоких скобок - красных  В них написано:

    FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN

Если вы внимательно читали задачу (я очень надеюсь!) то знаете,  что каждое словосочетание благодаря директивам  #define   в начале программы означает сдвиг единицы на некоторое количество позиций в лево - т.е. установку только некоторого одного бита в нулевом байте.  

Советую порисовать на бумажке байты и биты !

Т.е. мы имеем :

               число | число | число

Так как эти три числа соединены побитным "ИЛИ"  (напомню: это означает что только "0" и "0" дают "0") то в результате мы получим число где 3 бита будут равны "1"  - а номера этих битов будут 4, 3 и 2.

Теперь разберем какой результат даст вычисление содержимого синих скобок.

В них проводится побитная операция "И" (напомню: это означает что только "1" и "1" дают "1")  содержимого переменной status с тем числом которое является результатом красных скобок.

Значит если в status  (а значит и в регистре UCSRA)  -  хотя бы один из битов 4, 3 или 2 будет "установлен" - т.е. равен "1"  результат "И" будет не равен нулю. 

Нулю результат красных скобок  может быть равен - только если все три бита в UCSRA  были равны "0" - т.е. если данные были приняты без аппаратно детектируемой ошибки !

При этом же условии третье действие :  логическая операция ==0 даст результат "истина" так как ноль и правда равен нулю, значит :

То что написано в скобках  {  } после  if()  будет выполняться при безошибочном принятии данных.

 
     

Если же при приеме байта возникла любая из ошибок : 

FRAMING_ERROR    PARITY_ERROR     DATA_OVERRUN

то факт принятия данных  игнорируется и следующий код функции обработки прерывания закончен - т.е. программа выходит из прерывания не помещая "криво" принятый байт в буфер и возвращается к тому месту где возникло прерывание № 12.

Пусть ошибок не было, тогда ...

Выполняется код в скобках   {  }  после  if()  

Разберемся что он делает. 

Вот он со скобками :

     
 

{
rx_buffer[rx_wr_index]=data;


if (++rx_wr_index == RX_BUFFER_SIZE)
     
{  // я добавил эти скобки
   rx_wr_index=0;
     
}; // для лучшей читаемости

if (++rx_counter == RX_BUFFER_SIZE)
    {
    rx_counter=0;
    rx_buffer_overflow=1;
    };
};

 
     


Первая строка кода помещает принятый байт в буфер - конкретно в элемент массива
rx_buffer  с  порядковым номером rx_wr_index   - этот номер называют индексом массива. 

В начале программы индекс 
rx_wr_index  равен нулю.  Почему ? 

А потому что  переменная  rx_wr_index 
                              была  объявлена как глобальная.  

 

     
 

Глобальным переменным при объявлении компилятор присваивает значение 0 , если конечно вы не присвоили ей явно другое значение, 

например вот так:

char kakayto_peremennaya = 78

"Какой то переменной" при объявлении присвоено значение   78

 
     


При следующих прерываниях по приему данных значение индекса будет меняться ! Если мы будем достаточно быстро забирать данные из буфера то иногда индекс будет опять становится  нулем.


Далее идет интересная конструкция :

if (++rx_wr_index == RX_BUFFER_SIZE)
     
{  // я добавил эти скобки
   rx_wr_index=0;
     
}; // для лучшей читаемости

я бы не советовал писать на Си начинающему так как накрапал мастер - но КодВизад создан профессионалом и потому нам нужно просто разобрать и понять что этот код делает.

Во первых я добавил фигурные скобки { }; - чтобы четко было видно 
какой код выполняется при "истине" в скобках  (    )  за 
if

Советую вам !       Всегда дополняйте

if() while() for()   

Фигурными скобками   {      };

Разумные исключения :  while(1);  и  for(;;);

Итак :  Выражение-условие в  if()  означает: префиксный (так как ++ написаны перед переменной) инкремент переменной rx_wr_index  - т.е. добавление 1 к тому, что содержится в переменной. И затем проверяется равенство уже нового значения rx_wr_index с установленным нами размером буфера. 

 

     
 

Напомню что добавление некоторого числа к содержимому переменной не всегда увеличивает ее значение !

Если к переменной типа char  хранящей число 255 прибавить хотя бы 1
и результат записать в эту переменную - то в ней будет 0.

Вы очевидно понимаете что 255 + 1 = 256  

256 в двоичном виде 1 0000 0000  т.е. только бит_8 равен "1" а биты_7_0 все равны "0". При записи числа 256 в восьми-битную переменную типа char   в нее поместятся как раз 8 нулей и поэтому в ней будет НОЛЬ.

 
     


Если перед
if индекс   rx_wr_index   был равен 99 то после инкремента индекс станет равен 100  и проверка на равенство с  RX_BUFFER_SIZE  даст "истину" - значит будет выполняться то, что написано в фигурных скобках после if  - это строка:

rx_wr_index = 0; // обнуляет индекс.  

Как видите индекс может стать нулем, как был в начале программы, и в том случае если мы долго не забирали символы из буфера и он переполнился !

 

     
 

Я бы вот так написал этот участок кода : 

rx_wr_index ++; // инкремент индекса

// сравнение уже увеличенного значения индекса
if (rx_wr_index == RX_BUFFER_SIZE)
     
 
   rx_wr_index=0;
     
}; 

Мне кажется, что так - по шагам - писать и читать  
программу проще, особенно начинающим.

 
     

 

Далее еще одна проверка условия и действие по результату:

if (++rx_counter == RX_BUFFER_SIZE)
    {
    rx_counter=0;
    rx_buffer_overflow=1;
    };


Здесь ++ стоят перед переменной rx_counter - значит это префиксный инкремент  -  т.е. к значению переменной добавляется 1 и затем уже проверяется равно ли текущее содержимое переменной размеру буфера.

Если равно - значит буфер переполнился и будут выполнены две строки кода

rx_counter=0;
// Обнулить  счетчик принятых байтов в буфере

rx_buffer_overflow=1;
// Установить флаг переполнения буфера

     
 

Важно понять !  Операции ++  и - - изменяют то, что хранится в переменной ! Несмотря на отсутствие оператора присваивания.

 
     


Значит переменная 
rx_counter изменится на  1 не зависимо от истинности условия в скобках у   if()

Всё - обработка прерывания завершена. 

Теперь программа отправится в то место где она находилась 
в момент возникновения прерывания №12             

ГЛАВНОЕ !   Так как мы выполнили функцию обработчик прерывания до конца,  опять установится бит I в регистре SREG  - это разрешит прерывания в МК глобально и те прерывания которые разрешены индивидуально опять смогут прерывать ход программы.

Далее в тексте программы идет созданная мастером начального кода альтернативная обычно используемой в CodeVisionAVR функция "получить символ" - функция "получить символ из созданного буфера" - getchar()

НО, будет ли она включена препроцессором компилятора в компилируемый текст программы определяет конструкция из директив препроцессора:

#ifndef   #define   ...   #endif

Вы уже должны понимать как работает эта конструкция !

Поясню: Если мы делаем программу не для отладки на встроенном в CodeVisionAVR симуляторе терминала, а для реального МК или для внешнего симулятора - то в тексте программы не было определено:

#define _DEBUG_TERMINAL_IO_

поэтому будет выполнена строка : 

#define _ALTERNATE_GETCHAR_

и остальные строки на голубом фоне ниже будут включены в компилируемую программу препроцессором.

 

     
 

#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver buffer
// взять символ из созданного буфера USART 

#define _ALTERNATE_GETCHAR_


#pragma used+

char getchar(void)
{
char data; // локальная переменная

while (rx_counter==0);

data = rx_buffer[rx_rd_index];

if (++rx_rd_index == RX_BUFFER_SIZE) 
{
rx_rd_index=0;
};  // я добавил {  }; для вящей читаемости

#asm
("cli")
--rx_counter;
#asm("sei")

return data;
}

#pragma used-

#endif

// Standard Input/Output functions
#include <stdio.h>

// Declare your global variables here

 
     

 

Подробно рассмотрим "тело" новой функции

Первая строчка :              char getchar(void)

говорит нам, что функция возвращает значение типа      char  
и при вызове не требует передачи в нее значений  - вот поэтому:   (void)

Сразу после скобки  {  объявлена локальная (существующая и доступная только в этой функции) переменная символьного типа  char  с названием:    data  

Следующая строка: 

while (rx_counter == 0);

это цикл ожидания поступления символа в буфер. В ней программа будет 
"сидеть" а точнее "молотить" пока нет прерывания и нет символа в буфере, 
ведь  rx_counter   это счетчик символов находящихся в буфере.

     
 

думаю вы уже понимаете что 

while (rx_counter == 0);

равносильно:

while (!(rx_counter));

Если не понятно, перечитайте Си для МК

Не откладывайте на потом !

 
     

 

Если в буфере были символы или появился символ, программа перейдет 
на следующую строку:

data = rx_buffer[rx_rd_index];

Тут все просто:  =  означает присвоить переменной слева от = результат выражения справа от =     Значит программа возьмет символ из буфера (из массива rx_buffer[]) с порядковым номером  rx_rd_index  и поместит его в   data 

 
Далее происходит увеличение индекса буфера на 1 и если результат будет равен размеру буфера - индекс обнуляется.

if (++rx_rd_index == RX_BUFFER_SIZE) 
{
rx_rd_index=0;
};  // я добавил {  }; для вящей читаемости  

Так как мы считали символ из буфера нужно уменьшить число символов в нем подлежащих считыванию. 

#asm("cli")   // запретить прерывания глобально
--rx_counter; // вычесть 1 из rx_counter
#asm("sei")   // разрешить прерывания глобально

Обратите внимание что перед декрементом мы запрещаем прерывания, а после прерывания включаем опять.

Зачем ?    Вот фо ??? воскликнул бы англоязычный читатель ...

А затем, что в обработчике прерывания есть инкремент rx_counter  - и если на декременте возникнет прерывание мы можем зациклится в этом месте программы и получить ошибку в числе символов в буфере.

последняя строчка функции

return data;

означает что функция вернет то что находится в переменной  data

т.е. если мы напишем такой вызов функции:

nechto = getchar();

то после возврата из функции  в переменной  nechto  окажется то, что было помещено в   data   в функции.

Я подробно рассмотрел код создающий буфер для поступающих в МК данных.

Далее программа типична для создаваемых КодВизадом.

Как  принимать и отправлять данные по USART AVR

Варианты кода для отправки и получения данных с помощью USART, например на ПК. Прочитайте самостоятельно раздел "Standard C Input/Output Functionshelp  CodeVisionAVR (или того компилятора который будете использовать)
и включите заголовок - хидер  :

// Standard Input/Output functions
#include <stdio.h>

В нашей программе этот хидер уже подключен мастером !

 

1) отправить один символ типа  char  можно так: 

putchar('G');     
putchar(71);
putchar(0x47);

Любая из этих трех строк кода выводит на  ножку TXD число 71. На терминале ПК вы увидите соответствующий этому числу  символ  G 

В 16-тиричном виде это число 0x47 

Запомните форму записи чисел !

Таблица символов и их кодов есть на странице Си для МК

Кроме того один символ или число от 0 до 255 можно отправить с МК так:

while(!(UCSRA & (1<<UDRE)));
// дождитесь освобождение регистра передачи 

// Отправьте число одним из 3-х вариантов 
UDR = 'G'
UDR =
71;
UDR = 0x47;

Это же можно написать в одну строчку:

while(!(UCSRA & (1<<UDRE))); UDR = 'G';

Не рекомендую !
Считаю менее понятным начинающему и комментарий написать негде.

2) отправить строку символов можно вот так: 

putsf("Hello, world!"); 

На ножку TXD будут выведены все символы между кавычками (в примере их 13) и еще символ "конец строки" - его код 0x0A а называется он LF от англ. "лайн фид"  

Следующие данные будут выводится на терминале ПК (или на его симуляторе TTY в VMLAB или в CVAVR) с начала следующей строки.

 

     
 

Символ "конец строки" (его код 0x0A и называется он LF)  можно передать вот так:
putchar('\n');  или так   putchar(
0x0A);

 
     


Строку символов для отправки можно записать и в виде последовательности шестнадцатеричных значений:  

putsf("\x41\x54\x44\x3e\x53\x4d\x31\x3b\x0D\x41"); 

На ножку TXD будут выведены все символы между кавычками (в примере их 10) и еще символ "конец строки" - его код 0x0A а называется он LF от англ. "лайн фид" 

Будет передаваться такая последовательность из 11 символов: 

ATD>SM1;<CR>A<LF>            цветом я отметил что это ОДИН символ ! 

в терминале VMLAB она будет выведена в две строки так:

ATD>SM1;<CR>
A<LF>

В терминале ПК не отображающем не печатные символы будет такой результат:  

ATD>SM1;
A

Символы (данные) которые МК будет передавать позже будут печататься уже с начала новой строки.

3) отправить информационные сообщения программы можно так: 

Вначале нужно описать эти сообщения - они буду размещаться во FLASH (в EEPROM) MK - т.е. это не переменные а КОНСТАНТЫ !

flash char string_1[]="Prog Start";
flash char string_2[]="The END";

// Declare your global variables here 
Теперь вы можете выводить сообщения в нужном вам месте программы так:

printf(string_1);

На ножку TXD будут выведены все символы между кавычками (в примере их 10без добавления символа "конец строки

     
 

Что бы ваши сообщения гарантировано выводились с начала строки - добавьте символ "конец строки" (его код 0x0A и  называется он LF) перед вашим сообщением вот так: 

flash char string_1[]="\nProg Start";

 
     

4) Вывести данные и поясняющий, оформляющий эти данные текст удобно  с помощью   printf() это мощная функция и полное ее описание почитайте в Help компилятора.

Примеры использования   printf() в папке   C:\CVAVR\Examples\

Например вывод температуры  :

char sign='+'; //датчик дал положительное число
int  temp=578; //число с датчика темп. LM75

printf("temp = %c%i.%u C\r\n",sign,temp/10,temp%10);


На терминал ПК будет выведено :

temp = 57.8 C

и курсор перейдет в начало новой строки.

Происходит это так: 

На терминал выводится то что находится между кавычками
"  " 

  • - текст temp =  выводится без изменений. Знак = окружают пробелы !

  • - вместо  %c будет вставлен символ из переменной   sign

  • - вместо  %i будет вставлен результат  temp/10 без дробной части 

  • - точка так и будет точкой 

  • - вместо %u будет результат (temp%10)  это дробная часть от деления

  • - далее пробел - он так и будет пробелом 

  • - затем символ C - он им же и останется

  • - потом стоит комбинация  \r\n - она выводит символы CR и LF их коды 0x0D  
      0x0A. Благодаря этому следующие данные будут выводится с начала строки через строчку ниже.

Внимание !  Чтобы отлаживать в PROTEUS функции PRINTF и SCANF зайдите в меню CVAVR - "прожект" - "конфига"  - "С компилер" и в списках этих функций выберите "Long..." или "Float..." и затем "ОК" конечно ...


     
 

Если UART MK настроен как сказано выше, то 

Вот пример для компиляторов ImageCraft ICC и  CodeVisionAVR использования функции   printf()

Если переменная   val    содержит число 166   то 

printf("val = %d",val);

Выведет на терминал ПК:       val = 166

и ...

printf("val = 0x%X",val);

Выведет на терминал ПК:    val = 0xA6


Подробней о  printf() читайте в  Help  компилятора.

 
     

Прием данных поступающих в USART  МК на ножку RXD у нас происходит автоматически в буфер. 

В том месте программы
где вам нужно вставить наиболее давно пришедший в буфер символ (число) впишите такую строчку:

getchar()

Примеры :

gdvix = getchar();
/* наиболее старый символ из буфера 
поместить в некоторую переменную gdvix  */

if (getchar() == 'G'){
/* выполнить ЭТОТ код если наиболее старый 
символ из буфера окажется буквой  G  */

                     };

while (getchar() == 'F');
/* взять из буфера наиболее старый 
символ и если это не F то повторять действие, 
а если это F пойти на следующий код программы */

 

     
 

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

 
     

                  

if (rx_counter) {
/* выполнить ЭТОТ код если в буфере есть не считанные символы, данные */
                };

if (rx_counter > (RX_BUFFER_SIZE/2)) {
/* выполнить ЭТОТ код если буфер уже 
заполнен больше чем на половину */

                };

Что бы вывести самый старый символ из   буфера на ножку TXD напишите так:

putchar(getchar());

Эту строчку  и три первых примера выше - можно использовать 
и без буфера, но программа будет засиживаться в них до тех 
пор пока не будет получен символ ! 
Будет ждать данные ...

Если написать так :

while(1){
putchar(getchar());
        };

то  МК будет отправлять приходящее на ножку RXD на ножку TXD   - так
можно проверить работоспособность соединения USART с компьютером.

Вы сможете попробовать это в симуляции !

 

Как  выводить данные на символьный LCD  - ЖКИ

Загрузите 1 страничку с описанием команд управления ЖКИ LCD на контроллере HD44780 и совместимых с ним.

Советую посмотреть АпНоут ANM069 от ATMEL

Для использования LCD нужно указать компилятору к каким ножкам МК он подключен в устройстве.

Вот наша (типовая) схема включения:


 

- указать компилятору сколько символов в строке имеет LCD дисплей.


Всё это любезно сделал генератор начального кода CVAVR :

// Alphanumeric LCD Module functions

#asm
.equ __lcd_port=0x1B ;PORTA
#endasm 

#include <lcd.h

// подключить"хидер"(заголовок,библиотеку)для LCD


А уже в программе строка: 

lcd_init(16);

инициализирует именно ЖКИ (LCD) где 16 символов на строку 

Мы можем указать в какую позицию выводить символ вот так:

lcd_gotoxy(4,1);

и вывод символов начнется с 5-й  позиции во второй строке.

Счет строк и символов начинается с НУЛЯ !

Давайте добавим в нашу программу вывод приветствия на LCD


lcd_gotoxy(5,0);

lcd_putsf("Hello");

lcd_gotoxy(2,1);

lcd_putsf("123avr.com");

lcd_putsf("u");

 

В результате на LCD будет выведен такой текст :

это скриншот симуляции в VMLAB    

Смотрите
- "чекбокс" "Break on com..." позволяет останавливаться  симуляции при ошибке в командах на LCD.
Внимание !   Я специально разделил вывод   ru  чтобы показать, что следующий символ  u  выводится в позицию следующую за последним выведенным символом.


Прочитайте раздел LCD Functions  в Хлпе компилятора!


Очистить экран ЖКИ вы можете вызвав функцию:

lcd_clear();

Вывести символ, например F на ЖКИ

lcd_putchar('F');

Вывести на LCD строку символов из EEPROM  MK можно вот так:

lcd_putsf(string_1);

Объявление и текст этой строки были даны выше !

 

     
 

Вы можете использовать один   
LCD  в нескольких устройствах !  

Подключая его через разъем при необходимости. 

Для этого вам нужно сделать любой свободный вывод МК  PxN - входом с подтяжкой, и в разъеме от LCD поставить перемычку с этого "пина" на GND.
 
Если вы подключите LCD к вашему устройству - ножка PxN заземлится - 
значит на ней появится "0".

Теперь нужно в программе поместить ВСЕ строки работающие 
с  LCD  внутрь  скобок  {      }    у  оператора 
if  вот так:

if(!(PINX & (1 << N)){
    /*  тут код работающий с LCD 
    Он будет выполняться только 
       если на
PxN есть "0"       */
                                                     }

Если LCD не подключен, то на PxN будет "1" и программа не будет выполнять  код работающий с  ЖКИ  индикатором. 

 
     

Так же вы можете работать с другими опционально подключаемыми к МК устройствами !

Все файлы для компилятора и для симуляции в  VMLAB того что рассмотрено в задаче вы можете скачать в архиве  -  z5.rar

  • При остановках симуляции в  VMLAB просто нажимайте на светофор ...  

  • Терпение! инициализация ЖКИ в симуляторе дело не быстрое. 

  • Посмотрите симулируя прогу в VMLAB осциллограммы приема и отправки данных по USART.

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

Алфавитно-цифровые ЖК-модули фирмы Data Vision

Разрешение

Модель

Размер модуля

Размер символа

8x2

DV0802

58.0x32.0x10.0

2.945x5.545

16x1

DV16100

80.0x36.0x10.0

3.07x6.56

DV16110

122.0x33.0x10.0

4.84x8.06

DV16120

151.0x40.0x14.7

14.5x6.0

16x2

DV16210

122.0x44.0x10.0

4.84x8.06

DV16230

85.0x30x10.0

2.78x4.89

DV16235

85.0x35.0x10.0

2.95x5.55

DV16236

85.0x36.0x10.0

2.95x5.55

DV16244

84x44.0x10.0

2.95x5.55

DV16252

80x36.0x10.0

2.78x4.89

DV16257

85.0x33x10.0

2.78x4.89

DV16275

100.0x39x13.0

4.07x7.76

DV16276

100.0x39x13.0

4.07x7.76

16x4

DV16400

87.0x60.0x10.0

2.95x4.75

20x1

DV20100

182.0x36x10.0

6.70x9.40

20x2

DV20200

116.0x36.0x10.0

3.20x5.55

DV20210

180.0x40.0x10.5

6.00x9.66

DV20211

182.5x60.0x20.0

5.9x12.7

DV20220

109x39.0x10.0

3.20x5.55

DV20206-1

86.0x39.0x14.0

3.2x5.55

20x4

DV20400

98.0x60.0x10.0

2.95x4.75

DV20410

146.0x63x10.5

4.84x9.22

24x2

DV24200

118.0x36.0x10.0

3.20x5.55

40x2

DV40200

182.0x34x10.0

3.20x5.55

40x4

DV40400

190.0x54.0x10.5

3.54x4.89


ЗАДАЧА    ОКОНЧЕНА !


     
 

Если вы еще не скачали ВСЕ примеры применения МК AVR  прошу вас, сделайте это ОБЯЗАТЕЛЬНО - ЭТО СПРАВОЧНИК для вас !

 
     

 Если вам что-то не понятно, пожалуйста перечитайте задачу еще раз и просмотрите рекомендованный материал.  

 

Дальше ->    Задача 6

 

Все задачи-упражнения курса

 

Как устроен микроконтроллер AVR

 

--- ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ НИЖЕ----- 

 

 

Проекты на микроконтроллерах AVR и PIC

Электронные устройства, Схемы, Прошивки, исходники

 

Новый! Владислав Шаповаловн. Продвинутые радио-часы/будильник с термометрами на графическом LCD.
Новый! Дмитрий Подколзин. Стенд для тестирования компьютерных АТХ блоков питания.
Новый! Одинец Александр Леонидович. Автономное 32-канальное программируемое светодинамическое устройство с последовательным интерфейсом.
Новый! Виталий Петренко, Александр Гаркавец. Цифровой вольтметр постоянного тока 0…..+100В.
Виталий Петренко, Александр Гаркавец. Частотомер - цифровая шкала КВ, УКВ с ЦАПЧ с восьмиразрядным индикатором 0,01 Гц - 1000 МГц.
Мосин Дмитрий. Часы на ATmega8.
Габидуллин Ильдар. Регулятор яркости лампы накаливания на микроконтроллере AT89C2051.
Павельчук Александр. Приставка на PIC для проверки телефонных аппаратов.
Ибрагимов Максим Рафикович. Простой VGA/Видео адаптер.
Независимая Группа Инженеров Астраханского Государственного Технического Университета. Черный ящик-2.
Красносельский Денис. Прибор для прозвонки многожильных кабелей.
Шабров Дмитрий. Комбинированный прибор радиолюбителя.
Фурсов Андрей, Мелихов Виктор. Пакетный FFSK-модем (rev.2.0).
Протопопов Александр Петрович. Жако - многофункциональный говорящий выключатель освещения с голосовым управлением..
Мирский Владислав. Программа-драйвер для ЖКИ на базе контроллера HD44780..
Новоселов Игорь. Устройство для выделения сигнала точного времени из радио «Маяк».
Бабанин Валерий Борисович. АЦП на стабилитронах (статья).
Протопопов Александр. Игровой автомат "Видеослот" с возможностью замены игр и встроенной защитой.
Шабров Дмитрий. Зарядное устройство для малогабаритных аккумуляторов с индикацией напряжения и тока.
Протопопов Александр. Часы с метеостанцией и дистанционным управлением.
Кокунин А. Датчики температуры DS18B20: исследования работы..
Борисевич Алексей. Цифровое устройство управления инкубатором.
Грицик Олег. Цифровой FM-приемник с электронной регулировкой громкости и тембра.
Шабров Дмитрий. Блок персонального вызова.
Александр Петрович Протопопов. Игровой автомат "Столб" с независимой системой игровых каналов.
Александр Петрович Протопопов. Устройство размена купюр для игровых автоматов.
Александр Петрович Протопопов. Многофункциональное устройство управления домашними приборами.
Буров Михаил. Часы-звонок с заменяемыми мелодиями.
Красносельский Денис Александрович. Стоп сигнал «Бегущие огни».
    Новый!Обновление проекта Стоп сигнал «Бегущие огни».
Шабров Дмитрий. Блок жизнеобеспечения аквариума.
Литовченко Алексей. Автономная охранная система на базе ТМ.
Широков Игорь Игоревич. Контроллер доступа "Tiny KTM".
Шабров Дмитрий. Автомобильный тахометр.
    Новый!Обновление проекта Автомобильный тахометр.
Шабров Дмитрий. Автомобильная сигнализация с радиоканалом, плавающим кодом и домашним комплектом для мониторинга состояния датчиков.
Александр Протопопов. Универсальный сенсорный выключатель с дистанционным управлением.
Александр Протопопов. Автоматический контроллер для просмотра стереоизображения.
Александр Протопопов. Евро-АОН "NEO" - конвертор в стандарт Caller ID (CLIP) для импортных радиотелефонов.
Дмитрий Фитисов. Timer on PIC16F628.
Александр Протопопов. Игровой автомат с системой "Джек Пот" и блоком дистанционного управления и контроля по мобильной связи.
Владислав Мирский. Часы с цифровой подстройкой хода.
Бабанин Валерий Борисович. Интерфейс RS-232 с возможностями SPI для микроконтроллерных систем
Черешнюк Виктор. Регулятор температуры для инкубатора
Александр Квашин. Цифровой термометр
    Новый!Обновление проекта Цифровой термометр.
Владислав Мирский. Калькулятор
Александр Корниленко. 16-канальный логический анализатор "ЛогикАн"
Шабронов Андрей Анатольевич. Фотосчетчик продукции транспортера
Нарчук Александр. Цифровой 4-х канальный регулятор для усилителя на TDA7313
Кияшко Владимир Анатольевич. Анемометр - измеритель скорости ветра
Владислав Мирский. Пианино
Юрис Гризанс. Генератор логических уровней
Вадим и Кирилл Красновы. Прибор для контроля за работой водителей. ("ЧЕРНЫЙ ЯЩИК")
Павел Дичин. Простой четырёхканальный зарядник на микропроцессоре PIC16F876
Александр Протопопов. Интеллектуальная автомобильная система с голосовыми меню и изменяемыми голосовыми сообщениями, предназначенная для дистанционного контроля датчиков охраны и других приборов, управления прогревом двигателя и бортовыми устройствами
Александр Протопопов. Программатор для записи голосовых сообщений в микросхему K9F3208W0A (Samsung)
Ридико Леонид Иванович. УМЗЧ ВВ с упрощённой системой управления
Пионер. Повышающий преобразователь напряжения на AVR
Ридико Леонид Иванович. УМЗЧ ВВ с микроконтроллерной системой управления
Ширяев Алексей Евгеньевич. Технический автоответчик
Альберт Екимов. Микропроцессорный блок управления стиральной машиной
Ридико Леонид Иванович. Контроллер шагового двигателя
Александр Протопопов. Коммуникатор — автоматическое устройство для обмена короткими текстовыми сообщениями
Александр Середовский. Таймер для загрузчика сырья в опытно-технологическую установку по производству антифрикционной присадки "Форум ©"
Анисимов Сергей Владимирович. Система сбора информации от удаленных объектов посредством интерфейса RS485
Владимир Попов. Таймер с выводом на TV, коммутацией Video, накоплением сумм времени и числа запусков
Ридико Леонид Иванович. Генератор прямоугольных импульсов на основе AVR
Сергей Смирнов. Программное дeкодирование DTMF по принципу АОН на базе микроконтроллера PIC16F628
Виктор Бачул. Определитель номера для цифровых АТС PERFECTA
Сергей Фролов. Устройство «ВИДЕОТЕКСТ FRS1.00»
Александр Елисеев. Как сделать простой модуль контроллера 10-и позиционного LED индикатора и IR пульта RC-5 на PIC16F627
Михаил Буров. Музыкальный звонок с заменяемыми мелодиями
Юрий Сафонов. Универсальный велосипедный путевой прибор на PIC контроллере
Ридико Леонид Иванович. Программатор термометра/термостата DS1821
Юрий Горский. Передача отладочной информации из PIC-контроллера через COM-порт
Юрий Сафонов. Бегущая строка на PIC контроллере
Игорь Коваль. Конвертер интерфейсов ИРПС -> RS485 с исправлением однократных ошибок
Ридико Леонид Иванович. Применение 7-сегментных ЖКИ – модулей
Александр Елисеев. Как сделать простой осциллограф двоичного сигнала на AVR
Александр Корниленко. Книгочей
Игорь Ткачук. CompuPIC
Александр Протопопов. Система автоматизации технологического оборудования
Коновалов В. А. Адаптер двухканального светового шнура
Ридико Леонид Иванович. Стабилизатор частоты вращения коллекторного двигателя
Ридико Леонид Иванович, Лапицкий Виктор Петрович. Электронный замок с ключами iButton
Евгений Солошенко. Контроллер двухцветного светового шнура Flexilight
Игорь Коваль. Электронные часы с будильником на микроконтроллере AT90S2313-10PI
Сергей Сергеев. Автоматический регистратор — выключатель освещения
Андрей Воробьёв. Маршрутный компьютер-тестер для автомобилей ВАЗ
Александр Елисеев. Как сделать простой программатор для PIC-ов и AVR-ов
Александр Фомин. Программатор для микроконтроллеров AT89C51/52/55
Сергей Ростовцев. Простой программатор
Ридико Леонид Иванович. Эмулятор ПЗУ — отладчик для MCS-51
Михаил Буров. Часы-будильник с ЖК-индикатором
Игорь Баранов, Константин Терпогосов. Метеотермометр MT-50
Олег Локсеев. Преобразователь и зарядное устройство в одном флаконе
Александр Протопопов. Устройство полной защиты ламп освещения
Артём Скворцов. 128-канальный аналоговый коммутатор
Александр Алехин. Бортовой компьютер М1.5.4. Версия 1.01
Ридико Леонид Иванович. Простая система настройки для УКВ ЧМ приёмника
Ридико Леонид Иванович. Имитатор touch-memory DS1990A
Ридико Леонид Иванович. Автомобильные часы-термометр-вольтметр
Ридико Леонид Иванович. Применение кода RC-5
Ридико Леонид Иванович. Низкочастотный синусоидальный генератор с шагом сетки 0,01 Гц
Александр Волович. Контроллер графического ЖКИ высокого разрешения
Олег Пушкарёв. Приёмник POCSAG кода
Александр Елисеев, Станислав Картонович. Как сделать автосигнализацию с бесконтактными ключами на PIC16C505 с использованием компилятора HI-TECH C 7.85
Алексей Кургузов. Многоточечный термометр
Олег Пушкарёв. Вывод бегущей строки на ЖКИ дисплей 2х24
Александр Протопопов. Сенсорный электронный регулятор громкости
Михаил Буров. Музыкальный звонок
Виктор Заикин. Двухканальный счётчик импульсов — Data Logger Z43001
Игорь Максимов. Универсальная цифровая шкала — частотомер с функцией ЦАПЧ
Игорь Максимов. Малогабаритный частотомер-цифровая шкала до 200 МГц с ЖКИ дисплеем
Дмитрий Александрович Лихачёв. 10BASE-2 Ethernet REPEATER (демо-версия)
Алексей Чумаков. Внутрисхемный SPI-программатор для Atmel At89S8252 на LPT порт
Леонид Иванович Ридико. Два микроконтроллерных регулятора мощности
Александр Алехин. «Индикатор М1.5.4»
Леонид Иванович Ридико. Цифровой термометр с датчиками DS1820 или DS1821
Леонид Иванович Ридико. Если Вы потеряли Touch Memory...
Гуревич Ф.А. Простейшее микропроцессорное устройство ввода-вывода
Александр Елисеев. Как сделать считыватель ЖК дисплея
Вячеслав Кулаков. Микро-АТС 1х5 и мини-АТС 2х8
Александр Протопопов. Игровая приставка для велотренажера
Александр Елисеев. Как сделать простой программатор с использованием DELPHI 5
Александр Протопопов. Устройство передачи абонентского номера телефона
Александр Елисеев. Как сделать простой радиобрелок с плавающим кодом, паролем и бегущими огнями
Александр Волович. Генератор сигналов произвольной формы
Андрей А. Левкин. Устройство «Бегущая строка»
Олег Пушкарёв. Часы на базе индикатора HT1610
Александр Елисеев. Как сделать простую систему бесконтактной идентификации
Александр Елисеев. Простой АОН для «PANAPHONE»
Александр Елисеев. Терморегулятор
Вячеслав Кулаков. Кодовый замок для телефонной линии (антипират)
Группа разработчиков Центра фотохимии РАН. Иономер И-500
Eвгений Гиль. Проигрыватель компакт-дисков на базе дисковода CD-ROM
Андрей Левкин. Датчик присутствия людей

 

 

Лекции по курсу "Цифровые устройства"

1. Введение.

  1. Области применения и особенности цифровых устройств

  2. Описание цифровых схем.

2. Логические элементы.

  1. Логические элементы.

  2. Диодно-транзисторная логика (ДТЛ).

  3. Транзисторно-транзисторная логика (ТТЛ).

  4. Логика на комплементарных МОП транзисторах (КМДП).

  5. Согласование логических микросхем между собой.

  6. Регенераторы цифровых сигналов.

3. Арифметические основы цифровой техники.

  1. Системы счисления.

  2. Преобразование целых чисел из одной системы счисления в другую.

  3. Преобразование дробных чисел из одной системы счисления в другую.

4. Комбинационные устройства.

  1. Законы алгебры логики.

  2. Принципы аппаратурной реализации таблицы истинности.

  3. Декодеры

  4. Кодеры

  5. Мультиплексоры

  6. Демультиплексоры

5. Генераторы.

  1. Усилительные свойства инвертора.

  2. Осцилляторные схемы генераторов.

  3. Мультивибраторы.

  4. Особенности кварцевой стабилизации частоты генераторов.

  5. Одновибраторы.

6. Последовательностные устройства.
6.1 триггеры.

  1. Построение триггерных схем,

  2. RS-триггеры,

  3. D-триггеры,

  4. T-триггеры,

  5. JK-триггеры,

6.2 регистры.

  1. Параллельные регистры

  2. Последовательные регистры

  3. Универсальные регистры

6.3 Счетчики.

  1. Асинхронные двоичные счётчики

  2. Недвоичные счётчики с обратной связью

  3. Недвоичные счётчики с предварительной записью

  4. Синхронные кольцевые счётчики.

  5. Синхронные двоичные счётчики.

7. Индикаторы.

  1. Виды индикаторов.

  2. Светодиодные индикаторы.

  3. Жидкокристаллические индикаторы

  4. Динамическая индикация.

9. Синтезаторы частоты.

  1. Цифровой фазовый детектор

  2. Цифровой частотный детектор

  3. Цифровой фазовый компаратор.

  4. Цепи фазовой подстройки частоты.

  5. Умножители частоты

10. Микросхемы цифровой обработки сигналов.
10.1 Основные блоки цифровой обработки сигналов.

  1. Двоичные сумматоры

  2. Умножители

  3. Постоянные запоминающие устройства.

  4. Цифровые фильтры.

10.2 Микросхемы прямого цифрового синтеза радиосигналов.

  1. Фазовые аккумуляторы

  2. Полярные модуляторы

  3. Квадратурные модуляторы.

  4. Интерполирующие цифровые фильтры.

11. Примеры реализации цифровых устройств.
11.1 Электронные часы.

  1. Разработка структурной схемы

  2. Разработка принципиальной схемы

11.2 Последовательные порты.

  1. DSP-порт

  2. SPI-порт

 

Курс лекций "Микропроцессоры"

1. Введение.

  1. Что такое микроконтроллеры, микропроцессоры и сигнальные процессоры.

  2. Области применения микроконтроллеров.

2. Принципы работы микропроцессоров.

  1. Сумматоры по модулю два. Построение многоразрядных арифметических сумматоров

  2. Виды двоичных кодов.

  3. Построение арифметико-логических устройств.

  4. Построение шинных формирователей.

  5. Масочные ПЗУ, ППЗУ, РПЗУ, ЭСППЗУ, FLASH - память

  6. Построение ОЗУ.

  7. Команды микропроцессора

  8. Блок обработки сигналов микропроцессора.

  9. Микрокоманды.

  10. Системная шина микропроцессора.
    Подключение ОЗУ и ПЗУ к системной шине микропроцессора.
    Дешифратор адреса.
    Понятие адресного пространства и распределения памяти микропроцессорного устройства.

  11. Подключение внешних устройств к микропроцессору.

  12. Принципы построения параллельного порта.

  13. Принципы построения последовательных портов

  14. Принципы построения таймеров.

3. Микроконтроллеры семейства MCS-51.

  1. Представители семейства MCS-51.

  2. Архитектура микроконтроллеров MCS-51.

  3. Система команд микроконтроллеров MCS-51. Виды адресации.

  4. Инструкции микроконтроллеров семейства MCS-51.

  5. Особенности построения параллельных портов микроконтроллеров MCS-51.

  6. Особенности построения памяти микроконтроллеров семейства MCS-51.

  7. Внутренние таймеры микроконтроллера, особенности их применения.

  8. Устройство и особенности применения последовательного порта микроконтроллеров семейства MCS-51.

4. Написание программ для микроконтроллеров

  1. Языки программирования для микроконтроллеров.

  2. Применение подпрограмм при программировании.

  3. Понятие подпрограммы процедуры и подпрограммы функции.

  4. Применение комментариев.

  5. Понятие структурного программирования.

  6. Понятие многофайлового программирования.

  7. Понятие многомодульного программирования.

  8. Написание программ для микроконтроллеров

  9. Отладка программ для микроконтроллеров

5. Язык программирования высокого уровня C-51.

  1. Язык программирования C-51

  2. Структура программ на языке программирования C-51

  3. Символы языка программирования C-51.

  4. Идентификаторы и константы.

  5. Выражения в операторах.

  6. Операторы.

  7. Объявление простых переменных.

  8. Объявление массивов и структур.

  9. Указатели.

  10. Объявление подпрограмм.

  11. Области действия переменных.

  12. Построение многомодульных программ.

6. Язык программирования ASM-51.

  1. Основные определения.

  2. Правила написания операторов на языке ассемблер.

  3. Символы, идентификаторы и числа языка ASM-51.

  4. Директивы языка ASM-51.

  5. Реализация подпрограмм процедур и подпрограмм функций на языке ассемблер.

  6. Способы реализации структурных операторов на языке ассемблер.

  7. Построение многомодульных программ на языке программирования ASM-51.

  8. Использование сегментов в языке программирования ассемблер.

7. Отладка программного обеспечения микроконтроллерного устройства.

8. Проектирование цифровых устройств на микроконтроллерах

  1. Разработка структурной схемы.

  2. Разработка принципиальной схемы.

  3. Написание программы для разрабатываемого микропроцессорного устройства

  4. Пример проекта программы

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Rating All.BY Rambler's Top100 ћ≈“ј - ”краина. –ейтинг сайтов



Copyright 2009-2019 123avr.com