AVR:Пример c:Динамическая индикация

Материал из roboforum.ru Wiki
Перейти к: навигация, поиск


Пример динамической индикации.

<source lang="c">

  1. include "iom16.h"
  2. include "inavr.h"
  3. include "stdio.h"
  4. include "stdlib.h"
  5. include "port.h"

//#include "math.h"

////////////////////////////////////////////////////////////////////////// //**********************************************************************// // Т е с т С т е н д а N i x - 6 // // П р о в е р к а п о р т о в . // // Д и н а м и ч е с к а я и н д и к а ц и я . // //**********************************************************************// //////////////////////////////////////////////////////////////////////////

uint8_t static Ekr[2][NUMBRZR]; // Образ экрана (0/1) struct {

uint8_t       Sek    : 1;      // Секунда прошла (1)
} Flag;                  // Флаги


  1. pragma vector=TIMER0_COMP_vect // Регенерация картинки. Частота регенерации FREGENER*NUMBRZR

__interrupt static void Regeneration(void) {

 uint8_t    static  cnt;                 // Номер отображаемого разряда
 uint16_t    static  forsek;             // Счётчик для формирования секундных импульсов
 
 PORTRZR0 = HIDE;                        // Погасить дисплей 0 на время изменения информации
 PORTRZR1 = HIDE;                        // Погасить дисплей 1 на время изменения информации
 cnt++; if(cnt==NUMBRZR) cnt=0;          // Следующий разряд
 PORTSEG0 = DecDecimal[Ekr[0][cnt]];     // Преобразовать цифру и вывести в семисегментном коде в соответствующий порт
 PORTSEG1 = DecDecimal[Ekr[1][cnt]];     // Преобразовать цифру и вывести в семисегментном коде в соответствующий порт
 PORTRZR0 = DecAdr[cnt];                 // Зажечь нужный разряд дисплея
 PORTRZR1 = DecAdr[cnt];                 // Зажечь нужный разряд дисплея
 forsek++; if(forsek==FREGENER*NUMBRZR){
 forsek=0;                     // Если переполнение
 Flag.Sek =1;                  // То установить флаг
 }

}


void show(uint8_t nekr,uint32_t data) // Преобразовать число в "образ" {

 uint32_t  i;                   // рабочая
 int8_t  j;                     // рабочая
 
 i=MAXDEC/DECIMAL;              // инициализировать
 for(j=NUMBRZR-1;j>=0;j--){
 Ekr[nekr][j] = data/i;         // Вычислить очередной разряд
 data = data%i;                 // Вычислить остаток
 i=i/DECIMAL;                   // Перейти к следующему основанию
 }

}


__task void main( void ) {

 uint32_t  i=0,j=MAXDEC;          // Отображаемая переменная
 // Инициализация портов
 DDRSEG0 = 0xff;              // Все порты на вывод
 DDRSEG1 = 0xff;              // Все порты на вывод
 DDRRZR0 = 0xff;              // Все порты на вывод
 DDRRZR1 = 0xff;              // Все порты на вывод
 // Инициализация таймера 0 (Регенерация дисплея с частотой FREGENER)
 TCCR0 = 0x0c;                    // Запустить таймер 0 в режиме СTC с прескалером 256
 OCR0 = FCLK/NUMBRZR/256/85;      // FCLK/NUMBRZR/256/85 Гц
 TIMSK = 0x2;                     // Прерывание от сравнения разрешить
 i=0;                             // Инициализировать значения
 j=MAXDEC-1;                      // Инициализировать значения
 show(0,i);                       // Инициализировать картинку 0
 show(1,j);                       // Инициализировать картинку 1
 __enable_interrupt();            // Разрешить прерывания (Начать отображение)


 for(;;){
   i++; if(i>=MAXDEC)i=0;      // На первый дисплей выводить с увеличением
 show(0,i);                       // Изменить картинку
   j--; if(j==0) j=MAXDEC-1;      // На второй дисплей выводить с уменьшением
 show(1,j);                       // Изменить картинку
 while(!Flag.Sek);                // Пауза 1 секунда
 Flag.Sek=0;                      // Ждать слелующего раза
 }

} </source>

Avr primer dyn 1.jpg

Скачать все файлы проекта

Автор: SasaVitebsk
E-Mail: sasa@c32dvina.com
Профиль на электрониксе: SasaVitebsk