Время зажигания для динамической индикации выбрано 20 мс (50 Гц), чтоб не мерцало и успевали зажигаться светодиодные сегменты
// Сегменты индикатора расположены так:
// a
// f b
// g
// e c
// d dp (dp или h - точка)
//определяем переменные для светодиодных 7-ми сегментных индикаторов, где a,b,c,d,f,f,g - сегменты:
#define d_e (1<<7)
#define d_d (1<<6)
#define d_h (1<<5)
#define d_c (1<<4)
#define d_g (1<<3)
#define d_b (1<<2)
#define d_a (1<<1)
#define d_f (1<<0)
//определяем каждую цифру, т.е. какие сегменты надо зажечь, чтоб получить нужную цифру (символ):
#define dig_0 (d_e|d_d|d_c|d_b|d_a|d_f|0)
#define dig_1 (0|0|d_c|d_b|0|0|0)
#define dig_2 (d_e|d_d|0|d_b|d_a|0|d_g)
#define dig_3 (0|d_d|d_c|d_b|d_a|0|d_g)
#define dig_4 (0|0|d_c|d_b|0|d_f|d_g)
#define dig_5 (0|d_d|d_c|0|d_a|d_f|d_g)
#define dig_6 (d_e|d_d|d_c|0|d_a|d_f|d_g)
#define dig_7 (0|0|d_c|d_b|d_a|0|0)
#define dig_8 (d_e|d_d|d_c|d_b|d_a|d_f|d_g)
#define dig_9 (0|d_d|d_c|d_b|d_a|d_f|d_g)
// добавим в массив для удобства:
unsigned char sifra[]={dig_0,dig_1,dig_2,dig_3,dig_4,dig_5,dig_6,dig_7,dig_8,dig_9};
// но можно высчитать какое 10-тичне значение соответствует каждой цифре и записать коротко:
unsigned char sifra[]= {16,115,36,33,67,129,128,51,0,1}; //в десятичной
PORTD = ~0b00000110;//знак инверсии для индикаторов с общим анодом, т.е. 1 - не горит на выходе порта D, 0 - горит.
#include <avr/io.h>
#include <avr/interrupt.h>
volatile unsigned char Razryad1,Razryad2,Razryad3,Danie;
unsigned char sifra[10]= {16,115,36,33,67,129,128,51,0,1};
ISR(TIMER0_COMP_vect) { // прерывание по совпадению
static unsigned char Vibor_Razryada;
Vibor_Razryada ;
switch (Vibor_Razryada) { // выводим разряды
case 1:
PORTB = sifra [ Razryad1 ];
PORTD |=(1<<6);
PORTD &=~(1<<4);
break;
case 2:
PORTB = sifra [ Razryad2 ];
PORTD |=(1<<5);
PORTD &=~(1<<6);
break;
case 3:
PORTB = sifra [ Razryad3 ];
PORTD |=(1<<4);
PORTD &=~(1<<5);
Vibor_Razryada = 0;
break;
}
}
Peresot ( volatile unsigned char Temp ) {// функция для разложения данных (числа) на сотни, десятки, единицы
asm("cli"); // запрещаем глобальное прерывание, очень желательно, чтоб глюков не было
Razryad1 = 0;
Razryad2 = 0;
while(Temp>=100){Temp=Temp-100; Razryad1 ;} // вычисляем сотни
while(Temp>=10 ){Temp=Temp-10; Razryad2 ;} // вычисляем десятки
Razryad3 = Temp; // единицы
asm("sei"); // разрешение глобального прерывания
}
int main(void){
TCCR0 &=(1<<6);
TCCR0 &=~(1<<WGM00);
TCCR0 |=(1<<WGM01); // сброс таймера при совпадении
TIMSK |=(1<<1); //разрешить прерывание по совпадению для таймера-счётчика0
OCR0=255; //сбрасывать, когда будет = 255 - это 20 мс
DDRB = 255; // порт B на выход, для управления сегментами
PORTB = 255; // все выходы в 1 (чтоб не горели сегменты, схема с общим анодом)
DDRD |=(1<<6)|(1<<5)|(1<<4); // ножки порта D на выход для управления тремя разрядами с общим анодом
PORTD &=~(1<<6); PORTD &=~(1<<5); PORTD &=~(1<<4); // устанавливаем их в ноль
Danie = 145; // данные, которые отображаются на индикаторе
asm("sei"); // разрешение глобального прерывания, обязательно, а то вектор не будет работать
while(1)
{
asm("nop");
Peresot(Danie); // созданная нами функция для разложения данных (числа) на сотни, десятки, единицы
asm("nop");
}
}
#define F_CPU 8000000L
#include <avr/io.h>
#include <util/delay.h>
//---------------------------------------------
void segchar (unsigned char seg)
{
switch (seg)
{
case 1: PORTD = 0b11111001; break;
case 2: PORTD = 0b10100100; break;
case 3: PORTD = 0b10110000; break;
case 4: PORTD = 0b10011001; break;
case 5: PORTD = 0b10010010; break;
case 6: PORTD = 0b10000010; break;
case 7: PORTD = 0b11111000; break;
case 8: PORTD = 0b10000000; break;
case 9: PORTD = 0b10010000; break;
case 0: PORTD = 0b11000000; break;
}
}
//---------------------------------------------
int main(void){
unsigned char i;
unsigned butcount=0,butstate=0; // butstate - состояние кнопки
DDRD = 0xFF;
DDRB = 0x00;
PORTD = 0b00000000;
PORTB = 0b00000001;
while(1){
for (i=0;i<10;i ){
while(butstate==0){
if (!(PINB&0b00000001)){//кнопка нажата
if (butcount < 5){butcount ;} // от дребезга нажатия кнопки
else{
i=0; // обнуляем счётчик
butstate=1; // кнопка нажималась, выходим из цикла
}
}
else{
if (butcount > 0){butcount--;} // от дребезга отжатия кнопки
else{butstate=1;} // кнопка нажималась, выходим из цикла
}
}
segchar(i);
_delay_ms(500);
butstate = 0;
}
}
}