Цель
задачи 03:
1) Создать программу для МК AT90s2313
измеряющую 50 раз в секунду частоту
сигнала подаваемого на "ножку" МК и
отсылающую полученные данные по rs232 (например
на COM порт ПК)
2) проверить работу программы на
эмуляторе Visual Micro Lab
3)
научиться генерировать Си код
инициализации периферии МК с помощью
программы-мастера "Application Builder"
входящей в состав компилятора ImageCraft
Для выполнения задачи
необходимо:
- Установленный
компилятор ImageCraft
- Установленный программный эмулятор Visual
Micro Lab
- Data Sheet на МК AVR AT90s2313
- свободное
время и желание.
Давайте зададим диапазон частот
входного сигнала от 500 до 2000 Гц (в
дальнейшем он может быть изменен вами по
желанию).
Напрямую МК
может измерять временные интервалы - т.е.
мерить мы будем период сигнала - у нас он
лежит в пределах от 500 мкС до 2000 мкС
Будем
использовать для хранения результата
каждого измерения два байта - т.е.
диапазон чисел от 0 до 65535.
Результаты
будут выводится в окно "терминал"
контрольной панели эмулятора - старший
байт (HB), затем младший (LB).
Окно "терминал"
эмулирует работу COM порта ПК.
Результат каждого измерения будет
выводиться в новой строке.
- сохраните
файлы задачи 01 из папки work - затем
очистите ее.
- Запускаем
компилятор ICC
- нажмите предпоследнюю иконку "Application
Builder" - этот удобный инструмент
позволяет создать Си код для
конфигурирования МК под нашу задачу.
Прочитайте
раздел Хелп ICC
по "Application Builder" |
- в секции CPU установите 2313,
а в комментариях: "Измерение
частоты сигнала с выводом на rs232"
- перейдем в секцию Timer0
поставьте галочку использовать Timer0
частоту поставьте 50 Гц
(50 раз в секунду)
выберем коэфицент пред-делителя 1024
- во столько раз реже чем тикает МК будет
отсчитывать Таймер_0.
Получи сообщение что реальная частота
составит 50,08 Гц а ошибка
будет 0,2 %
Что с этим делать?
можно подобрать частоту кварца в
разделе CPU, можно сделать частоту
прерываний выше и после прерывания
останавливать таймер - досчитывать
нужное время и снова пускать таймер...
Можно наконец учесть это в ПО обработки
результатов на ПК.
Способов
много - выбирай любой...
Мы изменим в
разделе CPU частоту кварца на 3.6864
МГц - это позволит нам поддерживать и
безошибочно точную скорость на rs232 (см.
ДатаШит стр.49) из списка стандартных.
вернемся в раздел Timer0 - видим частота
точная, ошибка ноль.
переходим на ярлык UART (универсальный
асинхронный приемник передатчик - это
аппаратный rs232).
Давайте оценим нужную нам
скорость передачи информации.
За 1 с нам нужно передать 50 раз по 2
байта информации, причем не стоит сильно
тормозить работу МК
50 х 2 х 8 = 800 бит
в сек. + служебные биты да
помножить на хороший запас по скорости...
выберем 9600 не ошибемся.
выбираем.
ставим две
галочки - использовать UART0 и разрешить
передачу.
Нажимаем "ОК" и получаем код
программы любезно сгенерированный по
нашему желанию.
Посмотрим на него повнимательней.
Ага... а после "#include"
прототипов функций нет! значит
компилятор их не требует - учтем на
будущее.
Хотя лучше перечислять
прототипы - как это было в исходном
коде задачи_01. Программа
становится более читаемой - т.к. функцию main
можно разместить выше текста самих
функций, прототипы которых уже
перечислены.
И после прототипов можно
закомментировать, что функции делают -
легче понять, как работает программа.
Вот это интересно:
PORTD = 0x7F;
7F это
0111 1111 - но бит_7 PORTD
(не существует как-бы! (стр. 3
Дата Шит и подробней 56- )
TCCR0 = 0x00; //stop
timer
TCNT0 = 0xB8; //считать от184
до 255
TCCR0 = 0x05; //start timer
о! теперь знаем на будущее как
остановить и как запустить таймер_0,
как установить с какого числа начинать
ему счет...
подробней по
регистру TCNT0 см.
ДШ стр. 30
Прерывания...
#pragma interrupt_handler timer0_ovf_isr:7
эта строка
просто указывает компилятору название
функции timer0_ovf_isr
которая будет вызываться при
возникновении прерывания №
7.
Мы могли бы назвать ее и по своему
усмотрению - главное сохранить формат
объявления!)
Это прерывание по переполнению TIMER0
при этом
будет вызываться вот эта функция -
обработчик прерывания:
void timer0_ovf_isr(void)
{
//TIMER0 has overflowed
TCNT0 = 0xB8; //обновить
число начал счета
}
т.е. каждые 20 мс мы будем попадать в
тело этой функции, измерять частоту
сигнала и отправлять результат на rs232.
Таймер0 мы
запустили при инициализации периферии -
теперь он считает постоянно от 0 до 255
снова 0 и так далее.
При переходе от 255 в 0 возникает
прерывание по переполнению таймера - т.е.
выставляется флаг прерывания -
соответствующий бит становится равным
"1" - говорят "устанавливается"
"сбросить"
бит - значит сделать его нулем - "0"
Мы должны
считать не от 0 а от числа 0xB8
= 184 до 255 т.е. каждые 72 тика таймера
достигаем переполнения и возникает
прерывание.
посчитаем: 3.6864 МГц
делим на 1024 и на 72 получим... да 50 Гц
Почитайте код дальше
самостоятельно -
подумайте, что он означает.
Не должно остаться вопросов
без ответа - спрашивайте!.
Продолжим...
сохраните файл как work.c
в папке work
создайте новый проект work.prj
(см. задачу 01)
в папке work.
добавьте в
проект файл исходного кода work.c
"Application Builder" -
парень хороший, полезный
но туповатый!
так что откройте меню:
проект - опции - цель
и укажите компилятору МК
AT90s2313
сам он это не делает почему-то
|
Запустим
компиляцию проекта кнопкой "билд
..."
Ага... получили сообщение об ошибке:
отсутствует главная функция main
Нужно было в Аппилдере
нужный флажок отметить...
Напишем ее ручками...
void main (void)
{
}
и вставим в
самый низ исходника программы.
Ок!
Теперь компиляция проходит успешно - все
формальности Си соблюдены, ходя МК
ничего не делает по этой программе.
Теперь
нужно чтобы программа что ни будь делала.
Добавим:
void main (void)
{
init_devices();
while(1);
}
Теперь после
запуска МК произойдет инициализация
переферии и мы засядем в бесконечном
цикле while(1)
но 50 раз в секунду мы будем попадать в
функцию обработчик прерывания - timer0_ovf_isr(void)
Давайте в эмуляторе измерим период
возникновения прерываний!
Для этого в
"тело" функции timer0_ovf_isr(void)
впишем код который заставит МК сделать
импульс - переход "1" - "0" -
"1" - на выводе PB5 например.
для этого нужно сделать выходом PB5
DDRB = 0x20; // 0010 0000
...а затем сделать импульс
PORTB
= 0x20; // 0010 0000
бит5=1
на PB5 появился
высокий уровень "1"
сделаем паузу, чтоб импульс был заметен:
ctr=0;
// обнулим переменную счетчик
while(ctr<200) //
пока ctr<200 делаем
{...}
{
ctr++; // увеличть счетчик
на 1
}
паузу сделали
"в лоб" - просто посчитали до 200
обратите
внимание:
после while(ctr<200) - нет точки с
запятой! |
PORTB
= 0; // 0000 0000
бит5=0
на PB5 появился
низкий уровень "0"
ctr=0; //
обнулили счетчик
о! пусть МК, что ни будь
выводит в окно терминала по rs232, например:
putchar('R');
putchar('x');
в окне терминала будет последовательность печататься:
RxRxRx...
добавьте объявление
переменной для счетчика вверху текста
программы, после #include
unsigned char ctr;
окончательно
функция - обработчик прерывания
будет таким:
void timer0_ovf_isr(void)
{
TCNT0 = 0xB8;
DDRB = 0x20; // 0010 0000
PORTB = 0x20; // 0010 0000
while(ctr<200)
{
ctr++;
}
PORTB = 0;
ctr=0;
putchar('R');
putchar('x');
}
Компилируем
программу.
Поработаем
с эмулятором
Visual Micro Lab
сохраните
файлы задачи 02
и скопируйте только что полученный файл work.hex
в папку work эмулятора.
отредактируем файл проекта эмулятора work.prj
- нам нужно подключить терминал для
контроля посылаемой по rs232 информации.
; Файл-проект
Эмуляции программы
; частота -> rs232
;
; После запуска программы в
порт_B
; бит5, выводятся импульсы с
периодом
; 20 мс а на терминал символы
;
; RxRxRxRx..........
;
.MICRO "AT90S2313" ; Указали
МК
.POWER VDD=5 VSS=0 ; Питание 5
вольт
.CLOCK 3.6864 meg
;частота кварца 3.6864 Mhz
.PROGRAM "work.hex" ; что
"прошито" в МК
.TRACE
.STORE 1000m
; ////////////////////////
;
; N E W ! ! !
;
; ////////////////////////
;
; Virtual TTY terminal. Must cross connect
X_MyRS232
TTY(9600 8) PD0 PD1
; PD0 от RS232
в МК - окно Rx
;
; PD1 от МК в
RS232 - окно Tx
;
; в контрольной
панели эмулятора
;
; Импульс
на бит_5 порта_B и сигнал
; передачи
последовательной
; информации с ножки PD1
; будем наблюдать
; в окне виртуального
осцилографа
; эмулятора - "Scope"
.PLOT V(PB5) V(PD1)
сохраните
изменения файла проекта.
- запустите
эмулятор
- откройте проект
- билданите проект
- откройте контрольную панель
- откройте осциллограф
- стартуйте светофором
- спасибо за совет
- стартуйте еще раз... по-е-е-e-хали...
В терминале
идут буковки, а в "скопе" вибрируют
сигналы - красота...
- остановите
"красным стопом"
- разверните "скоп" на весь экран
попробуйте определить по
осциллограмме передачи символов их
двоичные коды.
дальше...
- "прокрутите" экран на середину
эмуляции
- подгоните развертку чтоб видеть два
импульса полностью
Замерьте расстояние между фронтами или
спадами импульсов.
скока?
У меня ровно 20 мС получилось.
Все работает
по программе!
Продолжение
следует... будем учиться частоту
измерять в задаче
04.
можете
скачать все рабочие файлы
в архиве zad_3_1.zip
|