Только в этом месяце - скидки на паяльники и электронику с нашими кодами (123avr.com) :
![]() |
|
Совет - умейте правильно находить информацию!
|
Цель задачи:
LCD бывают от 1 до 4 строк длиной до 40-ка символов. Смотрите каталог электронных компонентов.
Для выполнения задачи необходимы :
Делаем :Для того чтобы МК мог обмениваться данными с компьютером (ПК) или другим терминальным устройством - т.е. принимать и отправлять данные (обычно это байты, т.е. 8-ми битные числа) нужно : 1) соединить его физически с ПК по схемам и способами описанными в задаче 4 или с симулятором 2) настроить == сконфигурировать USART МК
-
установить скорость передачи данных в
бодах такую же как на ПК (из перечня скоростей стандартных
для ПК) или как в симуляторе с погрешностью до 1% - включить прием и/или передачу данных - это можно делать по мере необходимости в программе. Стандартные скорости обмена вашего ПК можно посмотреть через "панель управления" -> "система" -> "COM-порт" -> "свойства"
Пример настройки и включения USART ATmega16 на прием и передачу для любого компилятора Си
Формат передачи данных (см. ДШ Frame Formats) в примере: // Communication Parameters: 8 Data, 1 Stop, No Parity
Кусок кода выше я привел для примера. Я очень советую вам использовать мастер начального кода компилятора - Он сам сгенерирует вам все в нужном виде и правильно настроит USART. Главное - мастер покажет вам допустима ли ошибка в скорости передачи при использовании не UART'оских кварцев. От слов к делу ...Запустите компилятор CodeVisionAVR, затем генератор начального, конфигурирующего кода программы для МК - "CodeWizardAVR" - кликнув серую шестеренку слева от красного жучка...
Выберите в разделе Chip -
МК ATmega16 и частоту кварца 11.059 МГц и переходите на закладку USART
Число
100 означает - создать буфер в оперативной
памяти МК на 100 символов.
Скорость обмена данными - "БадРэйт" - установили 115200. Скорость USART может быть только одна в каждый момент в МК и для приема и для передачи. Если вам нужно принимать на скорости отличной от передачи то вы не сможете это делать одновременно и должны будете по необходимости включать либо передатчик либо приемник и устанавливать нужную скорость. Но я бы посоветовал вам просто взять МК с двумя USART например ATmega64 и ATmega128. Больше ни чего менять в панели USART не нужно. Переходим к закладке LCD - мы подключим жидкокристаллический индикатор на 2 строки по 16 символов с встроенным контроллером HD44780 - это очень распространенные индикаторы (см. стр. 1 курса).
Для подключения LCD вам достаточно указать желаемый порт МК и количество символов в строке. Количество строк указывать не нужно.
С
лева указаны выводы МК, а в правой
колонке указаны выводы LCD - их нужно
соединить между собой. Кроме того нужно
соединить "земли" и подать питание
на индикатор и подать напряжение
контраста - делать это надо в
соответствии с ДШ
В закладке PORTA сделайте PA3 выходом - мы можем использовать его для индикации различных событий при отладке. Всегда предусматривайте простые средства диагностики вашего устройства не требующие дополнительного оборудования ! К выводу МК можно подключить светодиод и разным режимом его горения отображать разную информацию, а можно выводить какую либо информацию на эту ножку в формате rs232. Теперь
В
меню файл "КодВизада" выберите "генерэйт
сэйв энд экзит", и создайте в папке компилятора
специальную папку для файлов задачи : Затем сохраните в ней созданный начальный код программы usart.c и файл проекта z5.prj Посмотрите текст программы созданный генератором самостоятельно. Вам уже многое должно быть понятно ! Программа. Рассмотрим участок программы создающий буфер для принимаемых МК по USART символов.
Затем с помощью первого блока определений #define компилятору сообщены номера битов по ДШ используемых в программе при работе с USART Определения отдельных битов есть в компиляторах ICC, IAR и других, но их нет в CodeVisionAVR поэтому я сделал для вас заголовочный файл m8_128.h - скачайте его добавьте в программу вот так:
#include <mega16.h>
//обычный хидер Теперь вы сможете использовать примеры на Си из ДШ прямо так как они там написаны ! Второй блок определений #define делает программу более понятной и читаемой человеком давая осмысленные названия малопонятным битовым маскам например: понятная человеку фраза DATA_REGISTER_EMPTY в тексте программы на Си будет заменена препроцессором перед компиляцией на битовую маску (1<<UDRE) с помощью которой можно проверить событие "регистр данных пуст" определяя состояние бита UDRE.
"Истина" будет означать что UDRE равен "1" и значит регистр данных пуст.
Дальше ...
Благодаря использованию директивы препроцессора #define мы сможем в случае необходимости изменения размера буфера, сделать это поменяв число 100 только в этой строке - не смотря на то, что используется оно в нескольких местах программы. Вывод: #define - это удобно! и снижает вероятность ошибок. Позволяет просто модифицировать программу - используйте ! Следующей строкой объявлен символьный массив : char rx_buffer[размер массива в символах]; размером по заказанному нами буферу. Символьный в нашем случае - потому что char указывает на типа данных - беззнаковый символьный - это числа от 0 до 255 - по таблице ASCII им соответствуют определенные символы - (таблицу ASCII см. стр. 5 курса). Напомню: В массиве нумерация элементов
начинается с НУЛЯ ! rx_buffer[0] а последний : rx_buffer[99]
СТОП !
Вспомните
и скажите вслух - что такое
глобальная переменная, каковы ее свойства, какие еще Последняя строка обсуждаемого куска кода (выше, на голубом фоне) объявляет битовую переменную bit rx_buffer_overflow;
это
флаг (можно сказать - признак) переполнения буфера - если
Битовые
переменные могут быть только
глобальными ! т.е. они объявляются в начале программы до фигурных скобок
{ } и доступны программе
в любом ее месте. Это в CVAVR, а в других компиляторах
с битовыми переменными
Дальше функция-обработчик прерывания № 12 :
{
далее
остальное Локальные переменные доступны только в той функции в которой объявлены ! Значит в разных функциях могут быть локальные переменные с одинаковыми именами ! Но я не советую вам так делать - запутаетесь.Значение Локальных переменных без модификатора static не сохраняется к следующему вызову функции, и нам не известно что в них содержится при создании - т.е. им нужно присвоить некоторое значение если мы не сделали это при объявлении.
Вот программа и присваивает им значения в следующих двух строках:
status
= UCSRA; В
status
копируется число из
UCSRA
- это регистр
В
data
копируется число из
UDR
- это регистр для принимаемых данных.
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) Код программы написанный здесь будет
выполнятся ТОЛЬКО если условие в
};
Если
же при приеме байта возникла любая из
ошибок : Пусть ошибок не было, тогда ...
Выполняется
код в скобках {
} после if() Вот
он со скобками :
А
потому что
переменная
rx_wr_index
if (++rx_wr_index == RX_BUFFER_SIZE) я бы не советовал писать на Си начинающему так как накрапал мастер - но КодВизад создан профессионалом и потому нам нужно просто разобрать и понять что этот код делает. Во
первых я добавил фигурные скобки
{
}; - чтобы четко
было видно Советую вам ! Всегда дополняйте if() while() for() Фигурными скобками
{ }; Итак : Выражение-условие в if() означает: префиксный (так как ++ написаны перед переменной) инкремент переменной rx_wr_index - т.е. добавление 1 к тому, что содержится в переменной. И затем проверяется равенство уже нового значения rx_wr_index с установленным нами размером буфера.
rx_wr_index = 0; // обнуляет индекс. Как видите индекс может стать нулем, как был в начале программы, и в том случае если мы долго не забирали символы из буфера и он переполнился !
Далее еще одна проверка условия и действие по результату:
if (++rx_counter == RX_BUFFER_SIZE)
Если равно - значит буфер переполнился и будут выполнены две строки кода
rx_counter=0;
Всё - обработка прерывания завершена.
Теперь
программа отправится в то место где она
находилась ГЛАВНОЕ ! Так как мы выполнили функцию обработчик прерывания до конца, опять установится бит I в регистре SREG - это разрешит прерывания в МК глобально и те прерывания которые разрешены индивидуально опять смогут прерывать ход программы. Далее в тексте программы идет созданная мастером начального кода альтернативная обычно используемой в CodeVisionAVR функция "получить символ" - функция "получить символ из созданного буфера" - getchar() НО, будет ли она включена препроцессором компилятора в компилируемый текст программы определяет конструкция из директив препроцессора: #ifndef #define ... #endif Вы уже должны понимать как работает эта конструкция ! Поясню: Если мы делаем программу не для отладки на встроенном в CodeVisionAVR симуляторе терминала, а для реального МК или для внешнего симулятора - то в тексте программы не было определено: #define _DEBUG_TERMINAL_IO_ поэтому будет выполнена строка : #define _ALTERNATE_GETCHAR_ и остальные строки на голубом фоне ниже будут включены в компилируемую программу препроцессором.
Подробно
рассмотрим "тело"
новой функции говорит нам,
что функция возвращает значение
типа char Сразу после скобки { объявлена локальная (существующая и доступная только в этой функции) переменная символьного типа char с названием: data Следующая строка: while (rx_counter == 0); это цикл
ожидания поступления символа в буфер. В
ней программа будет
Если
в буфере были символы или появился
символ, программа перейдет data = rx_buffer[rx_rd_index]; Тут все просто: = означает присвоить переменной слева от = результат выражения справа от = Значит программа возьмет символ из буфера (из массива rx_buffer[]) с порядковым номером rx_rd_index и поместит его в data
if (++rx_rd_index == RX_BUFFER_SIZE) Так как мы считали символ из буфера нужно уменьшить число символов в нем подлежащих считыванию.
#asm("cli") // запретить
прерывания глобально Обратите внимание что перед декрементом мы запрещаем прерывания, а после прерывания включаем опять. Зачем ? Вот фо ??? воскликнул бы англоязычный читатель ... А затем, что в обработчике прерывания есть инкремент rx_counter - и если на декременте возникнет прерывание мы можем зациклится в этом месте программы и получить ошибку в числе символов в буфере. последняя строчка функции
return data; т.е. если мы напишем такой вызов функции: nechto = getchar(); то после возврата из функции в переменной nechto окажется то, что было помещено в data в функции. Я подробно рассмотрел код создающий буфер для поступающих в МК данных. Далее программа типична для создаваемых КодВизадом. Как принимать и отправлять данные по USART AVR
Варианты кода для отправки и получения данных с помощью USART, например на ПК. Прочитайте
самостоятельно
раздел "Standard C Input/Output Functions" help CodeVisionAVR (или того компилятора
который будете использовать)
// Standard Input/Output functions В нашей программе этот хидер уже подключен мастером !
1) отправить один символ типа char можно так:
putchar('G');
Любая
из этих трех строк кода выводит на
ножку TXD число 71. На терминале ПК вы
увидите соответствующий этому числу
символ G Запомните форму записи чисел ! Таблица символов и их кодов есть на странице Си для МК Кроме того один символ или число от 0 до 255 можно отправить с МК так:
while(!(UCSRA & (1<<UDRE)));
Это
же можно написать в одну строчку:
Не рекомендую !
2) отправить строку символов можно вот так: putsf("Hello, world!");
На
ножку TXD будут выведены все символы
между кавычками (в примере их 13) и еще
символ "конец
строки" - его код 0x0A а называется
он LF от англ. "лайн фид"
putsf("\x41\x54\x44\x3e\x53\x4d\x31\x3b\x0D\x41");
На
ножку TXD будут выведены все символы
между кавычками (в примере их 10) и еще
символ "конец
строки" - его код 0x0A а называется
он LF от англ. "лайн фид" ATD>SM1;<CR>A<LF> цветом я отметил что это ОДИН символ ! в терминале VMLAB она будет выведена в две строки так: ATD>SM1;<CR> В терминале ПК не отображающем не печатные символы будет такой результат:
ATD>SM1; Символы (данные) которые МК будет передавать позже будут печататься уже с начала новой строки. 3) отправить информационные сообщения программы можно так: Вначале нужно описать эти сообщения - они буду размещаться во FLASH (в EEPROM) MK - т.е. это не переменные а КОНСТАНТЫ !
flash char string_1[]="Prog
Start"; // Declare your global variables here printf(string_1); На
ножку TXD будут выведены все символы
между кавычками (в примере их 10) без
добавления символа "конец
строки"
4) Вывести данные и поясняющий, оформляющий эти данные текст удобно с помощью printf() это мощная функция и полное ее описание почитайте в Help компилятора. Примеры использования printf() в папке C:\CVAVR\Examples\ Например вывод температуры :
char
sign='+'; //датчик дал
положительное число
temp = 57.8 C и курсор перейдет в начало новой строки.
Происходит
это так:
Внимание ! Чтобы отлаживать в PROTEUS функции PRINTF и SCANF зайдите в меню CVAVR - "прожект" - "конфига" - "С компилер" и в списках этих функций выберите "Long..." или "Float..." и затем "ОК" конечно ...
Прием
данных поступающих в USART МК на ножку RXD у нас происходит автоматически в буфер. getchar() Примеры :
gdvix
= getchar();
if
(getchar() == 'G'){
while
(getchar() == 'F');
if
(rx_counter)
{
if
(rx_counter > (RX_BUFFER_SIZE/2))
{
Что
бы вывести самый старый символ из буфера на ножку TXD напишите так: Если написать так :
while(1){
то МК будет отправлять приходящее на ножку RXD на ножку TXD
- так Вы сможете попробовать это в симуляции !
Как выводить данные на символьный LCD - ЖКИ Советую посмотреть АпНоут ANM069 от ATMEL Для использования LCD нужно указать компилятору к каким ножкам МК он подключен в устройстве. Вот наша (типовая) схема включения:
- указать компилятору сколько символов в строке имеет LCD дисплей.
// Alphanumeric LCD Module functions
lcd_init(16); инициализирует именно ЖКИ (LCD) где 16 символов на строку Мы можем указать в какую позицию выводить символ вот так: lcd_gotoxy(4,1); и вывод символов начнется с 5-й позиции во второй строке. Счет строк и символов начинается с НУЛЯ ! Давайте добавим в нашу программу вывод приветствия на LCD
В результате на LCD будет выведен такой текст :
это
скриншот симуляции в VMLAB
lcd_clear();
lcd_putchar('F'); lcd_putsf(string_1); Объявление и текст этой строки были даны выше !
Так же вы можете работать с другими опционально подключаемыми к МК устройствами ! Все файлы для компилятора и для симуляции в VMLAB того что рассмотрено в задаче вы можете скачать в архиве - z5.rar
Алфавитно-цифровые ЖК-модули фирмы Data Vision
Если вам что-то не понятно, пожалуйста перечитайте задачу еще раз и просмотрите рекомендованный материал.
Как устроен микроконтроллер AVR
--- ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ НИЖЕ-----
Проекты на микроконтроллерах AVR и PIC Электронные устройства, Схемы, Прошивки, исходники
Новый!•
Владислав Шаповаловн. Продвинутые радио-часы/будильник с
термометрами на графическом LCD.
Лекции по курсу "Цифровые устройства" 1. Введение. 2. Логические элементы. 3. Арифметические основы цифровой техники.
4. Комбинационные устройства. 5. Генераторы. 6. Последовательностные устройства. 6.2 регистры. 6.3 Счетчики. 7. Индикаторы. 9. Синтезаторы частоты.
10. Микросхемы цифровой обработки сигналов. 10.2 Микросхемы прямого цифрового синтеза радиосигналов. 11. Примеры реализации цифровых устройств. 11.2 Последовательные порты.
Курс лекций "Микропроцессоры" 1. Введение. 2. Принципы работы микропроцессоров.
3. Микроконтроллеры семейства MCS-51.
4. Написание программ для микроконтроллеров 5. Язык программирования высокого уровня C-51. 6. Язык программирования ASM-51.
7. Отладка программного обеспечения микроконтроллерного устройства. |
|
Copyright 2009-2019 123avr.com