| |||||||
Опубликовано 2010-02-27 09:55:03 автором MRS Подключение к микроконтроллеру семисегментного индикатора. Урок AVR 3В предыдущем уроке мы научились мигать светодиодом. Этот урок ненамного сложнее, здесь мы научимся мигать 7 светодиодами. Но не просто семь светодиодов, а семисегментный индикатор. Семисегментные индикаторы - это светодиоды, размещенные в определённом порядке, так что зажигая одновременно несколько светодиодов, можно формировать на индикаторе символы и цифры. Индикаторы бывают с общим катодом (минусом) и с общим анодом (плюсом). Это значит, что все семь светодиодов соединены плюсом или минусом. Например, возьмём индикатор с общим катодом и попробуем на нём что-нибудь вывести, например цифру 1. Для этого нам нужно включить светодиоды B и С. Берем наш atmega8 и подключаем к семисегментнику по схеме
Пишем простую программу, которая выведет цифру 1 #include <mega8.h> void main(void) { PORTB=0x00; DDRB=0b00000001; //делаем ножку PB0 выходом PORTD=0b00000110; // выводим на ножки PB1 и PB2 лог единицу, чтобы зажечь цифру 1 DDRD=0b01111111; //Делаем ножки PB0-PB6 выходами while (1) {} } #include <mega8.h> #include <delay.h> unsigned char numder[]= //определяем массив, в котором индекс будет соответствовать выводимой цифре { 0b00111111, //цифра 0 0b00000110, //цифра 1 0b01011011, //цифра 2 0b01001111, //цифра 3 0b01100110, //цифра 4 0b01101101, //цифра 5 0b01111101, //цифра 6 0b00000111, //цифра 7 0b01111111, //цифра 8 0b01101111, //цифра 9 }; void out(unsigned char num) { PORTD=numder[num]; } void main(void) { unsigned char i=0; PORTB=0x00; DDRB=0b00000001; //делаем ножку PB0 выходом PORTD=0b0000000; DDRD=0b01111111; //Делаем ножки PB0-PB6 выходами while (1) { out(i++); delay_ms(1000);//задержка в 1 секунду } } Результат Семисегментным индикатором можно управлять статически и динамически. При статическом управлении информация на разряды выводится постоянно, до этого мы рассматривали статическое управление. Динамическое управление - это поочередное зажигание разрядов индикатора с частотой, которую не воспринимает человеческий глаз. Схема подключения в этом случае выглядит так: Теперь в нашем коде мы меняем всего одну строчку DDRB=0b00000001; на DDRB=0b00000011; //делаем ножку PB0 и PB1 выходом и смотрим результат. У нас на обоих разрядах выводятся одинаковые цифры, а нам нужно, например, на первом выводить цифру 1, а на втором цифру 7. Когда на первом мы будем выводить цифру "один", второй разряд при этом выключен. В следующий момент времени выключаем первый, а на второй выводим цифру "7". Для отключения поочередно первого и второго разрядов мы будем устанавливать разные лог уровни на PD0 и PD1. #include <mega8.h> #include <delay.h> unsigned char numder[]= //определяем массив, в котором индексу будут соответствовать бити на порте D { 0b00111111, //цифра 0 0b00000110, //цифра 1 0b01011011, //цифра 2 0b01001111, //цифра 3 0b01100110, //цифра 4 0b01101101, //цифра 5 0b01111101, //цифра 6 0b00000111, //цифра 7 0b01111111, //цифра 8 0b01101111, //цифра 9 }; void out(unsigned char num) { PORTD=numder[num]; } void main(void) { unsigned char z=0; PORTB=0x00; DDRB=0b00000011; //делаем ножку PB0 и PB1 выходом PORTD=0b0000000; DDRD=0b01111111; //Делаем ножки PB0-PB6 выходами while (1) { if (z==0) //если z=0, то выводим первую цифру { out(1); //выводим 1 PORTB=0b00000001; // включаем семисегментник, который висит катодом на ножке PB0 } if (z==1) //если z=1 выводим вторую цифру { out(7); // выводим цифру 7 PORTB=0b00000010; // Включаем семисегментник на ножке PB1 } if (++z>1) z=0; // увеличиваем z на единицу и проверяем, не больше ли он 1. Если больше, то в z записываем 0 delay_ms(40); //Делаем задержку в 40 милисекунд, это 25 выводов за секунду } } Давайте все это приаккуратим:
#include <mega8.h> #include <delay.h> unsigned char chislo[2]; //определяем массив из двух элементов типа char беззнаковый(unsigned) unsigned char numder[]= //определяем массив, в котором индексу будут соответствовать бити на порте D { 0b00111111, //цифра 0 0b00000110, //цифра 1 0b01011011, //цифра 2 0b01001111, //цифра 3 0b01100110, //цифра 4 0b01101101, //цифра 5 0b01111101, //цифра 6 0b00000111, //цифра 7 0b01111111, //цифра 8 0b01101111, //цифра 9 }; unsigned char i=0; // переменная для определения, на какой разряд семисегментника выводить число // прерывания по переполнению timer0 interrupt [TIM0_OVF] void timer0_ovf_isr(void) { PORTD=numder[ chislo[i] ]; PORTB=i+1; //включаем определённый разряд семисегментника if (++i>1) i=0; } void out(unsigned char num) { /*сначала нам нужно определить, из скольких десятков и единиц состоит выводимое число. Например, передали мы "45", нам надо его разложить на 4 и 5, чтобы на первый разряд семисегментника вывести цифру 4, а на второй - 5 */ chislo[0]=num%10; //оператор % дает остаток от целочисленного деления, например 34%10 будет 4 chislo[1]=num/10; // узнаем, сколько десятков в числе } void main(void) { unsigned char z=0; // переменная, которая будет выводится на дисплей PORTB=0x00; DDRB=0b00000011; //делаем ножку PB0 и PB1 выходом PORTD=0b0000000; DDRD=0b01111111; //Делаем ножки PB0-PB6 выходами TCCR0=0x03; //устанавливаем предделитель таймера TCNT0=0x64; // число, с которого таймер начинает считать до 255 TIMSK=0x01; // прерывания по переполнению таймера 0 #asm("sei") //разрешаем прерывания while (1) { out(z++); // выводим значение переменной z и увеличиваем ее на 1 delay_ms(1000); //Делаем задержку в 40 милисекунд, это 25 выводов за секунду } } В следующей статье расскажу, как к микроконтроллеру подключить lcd дисплей. Комментарии - (4)
Добавить комментарийДля отправки комментария вы должны авторизоваться. |