Студопедия

Главная страница Случайная страница

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Пример 4. Вывод цифр от 0 до 99.






Преобразование двоичных чисел в двоично-десятичные (BCD)

#define F_CPU 1000000UL

#include < avr/io.h>

#include < avr/iom16.h>

#include < util/delay.h>

#include < avr/interrupt.h>

 

unsigned char number[] =

{

0x3f, //0

0x06, //1

0x5b, //2

0x4f, //3

0x66, //4

0x6d, //5

0x7d, //6

0x07, //7

0x7f, //8

0x6f //9

};

 

//числа для вывода на индикатор

volatile unsigned char data1 = 0;

volatile unsigned char data2 = 0;

unsigned char counterProg = 0;

int main(void)

{

//порт, к которому подкл. Сегменты

PORTA = 0xff;

DDRA = 0xff;

 

//порт, к которому подкл. Катод

PORTB = 0;

DDRB = (0< < 1)|(0< < 0);

 

//инициализация таймера Т0 частота прерываний 100Гц при кварце 8МГц

TIMSK = (1< < TOIE0);

TCCR0 = (1< < CS02)|(0< < CS01)|(1< < CS00);

TCNT0 = 0xb2;

sei();

 

 

while(1)

{

//программный счетчик секунд

counterProg++;

if (counterProg == 100) counterProg = 0;

data1 = counterProg % 10;

data2 = counterProg/10;

_delay_ms(500);

}

return 0;

}

 

//прерывания таймера Т0 - вывод на индикатор

ISR(TIMER0_OVF_vect)

{

static unsigned char count = 0;

TCNT0 = 0xb2;

//гасим оба разряда

PORTB & = ~((1< < 1)|(1< < 0));

//выводим в порт код цифры и зажигаем следующий разряд

if (count == 0)

{

PORTA = number[data2];

PORTB |= (1< < 1);

}

if (count == 1)

{

PORTA = number[data1];

PORTB |= (1< < 0);

}

count++;

if (count == 2) count = 0;

}

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

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

#define PORT_IND PORTB

#define DDR_IND DDRB

#define PORT_K PORTD

#define DDR_K DDRD

#define KAT1 0

#define KAT2 1

volatile unsigned char data[2];

void IND_Init(void)

{

//порт к которому подкл. Сегменты

PORT_IND = 0xff;

DDR_IND = 0xff;

//порт, к которому подкл. Катоды

PORT_K & = ~((1< < KAT2)|(1< < KAT1));

DDR_K |= (1< < KAT2)|(1< < KAT1);

//очистка буфера

data[0] = 0;

data[1] = 0;

}

 

Порты, к которым подключен семисегментный индикатор, определены с помощью директивы #define– в будущем это позволит быстро править код. Вместо двух переменных data1, data2 удобнее использовать массив unsigned char data[2].

Функция преобразования

void IND_Conv (unsigned char value)

{

unsigned char tmp;

tmp = value % 10;

data[0] = number[tmp];

tmp = value/10;

data[1] = number[tmp];

}

 

Процедура преобразования чисел аналогична описанной выше. Единственное отличие – в буфере (data[]) мы теперь сохраняем не результат преобразования, а коды цифр. Зачем делать в прерывании то, что можно сделать в основном цикле программы?

 

 


Поделиться с друзьями:

mylektsii.su - Мои Лекции - 2015-2024 год. (0.008 сек.)Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав Пожаловаться на материал