В данном уроке мы с Вами подключим семисегментный индикатор использую сдвиговый регистр SN74HC595 . Схема подключения:
В нашем случаи, так как у нас 3 светодиодных индикатора, нам необходимо вначале вывести нужное число на индикатор, а потом подать логическую единицу на нужный ключ, который включит правильный номер индикатора. После чего выключить его, выставить снова нужную цифру и снова включить нужный нам индикатор. Таким образом нам понадобиться еще прерывание по таймеру, внутри которого мы будем включать по очереди наши индикаторы. Как работать с прерываниями по таймерам, можно посмотреть Урок№9.
Транзисторные ключи для включения/выключения индикаторов подключаем к выходам PC2, PC3 и PC4.
Программный код:
#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
void zdvig (char z);
void num(unsigned int value);
void vibor(unsigned int m);
int i=0;
int n=0;
int t[3];
volatile unsigned long millis;
ISR (TIMER1_COMPA_vect){// прерывание по таймеру
switch (i){
case 0:
PORTC&=~(1<<PC2);
PORTC&=~(1<<PC3);
PORTC&=~(1<<PC4);
vibor(t[0]);
PORTC|=(1<<PC2);
break;
case 1:
PORTC&=~(1<<PC2);
PORTC&=~(1<<PC3);
PORTC&=~(1<<PC4);
vibor(t[1]);
PORTC|=(1<<PC3);
break;
case 2:
PORTC&=~(1<<PC2);
PORTC&=~(1<<PC3);
PORTC&=~(1<<PC4);
vibor(t[2]);
PORTC|=(1<<PC4);
break;
}
i++;
if(i==3){i=0;}
}
int main(void){
DDRB = 0b00111100;//ножки SPI на выход
PORTB= 0b11000011;//низкий уровень
SPCR = ((1<<SPE)|(1<<MSTR));//Включим шину, объявим ведущим
SPDR = 0b00000000;
DDRC = 0b00011100;//pc2 3 4
PORTC= 0b11011100;//низкий уровень
TCCR1B |= (1<<WGM12); // устанавливаем режим СТС (сброс по совпадению)
TIMSK |= (1<<OCIE1A); //устанавливаем бит разрешения прерывания 1ого счетчика по совпадению с OCR1A(H и L)
TCCR1B |= (1<<CS10);
sei();
while (1){
num(n);
n++;
_delay_ms(5);
if (n ==999){
n=0;
}
}
}
void zdvig(char z) {
SPDR = z;
while(!(SPSR & (1<<SPIF)));//подождем пока данные передадутся
//сгенерируем отрицательный фронт для записи в STORAGE REGISTER
PORTB |= (1<<PB2); //высокий уровень
PORTB &= ~(1<<PB2); //низкий уровень
}
void num(unsigned int value){
t[2]=((value/100)%10);
t[1]=((value/10)%10);
t[0]=(value%10);
}
void vibor(unsigned int m){
switch (m){
case 0:
zdvig(0b11010111);
break;
case 1:
zdvig(0b00010001);
break;
case 2:
zdvig(0b10100111);
break;
case 3:
zdvig(0b10110101);
break;
case 4:
zdvig(0b01110001);
break;
case 5:
zdvig(0b11110100);
break;
case 6:
zdvig(0b11110110);
break;
case 7:
zdvig(0b10010001);
break;
case 8:
zdvig(0b11110111);
break;
case 9:
zdvig(0b11110101);
break;
}
}