Работа с микроконтроллером и 3 индикаторами.
Данная статья будет полезна для начинающих разработчиков устройств на основе микроконтроллеров (МК). В основу взят МК DSPIC33FJ32GP204 фирмы Microchip и 3 7-сегментных индикатора. Суть такова: при включении на каждом индикаторе загорается число, т.к. приделы числа могут быть от 0 до 999, то разумно было взять число посередине – 500. Т.е. на первом индикаторе загорается цифра 5, на втором и третьем – 0. Кнопками происходит уменьшение или увеличение исходного числа на 56 (чтобы быстрее просмотреть все цифры). Схема в Proteus выглядит следующим образом:
ris 1.jpg
На скриншоте видим горящей только цифру 5, однако, в Proteus происходит мигание и мы видим всё число целиком, таковы уж особенности данной программы. В реальности же переключение происходит с большой частотой, и мы просто его не улавливаем и никаких переключений не замечаем: для нас все индикаторы горят одновременно. В программе используются 3 прерывания и один таймер. Ниже приведены отрывки кода с комментариями.
Подключаем библиотеку для работы с нашим МК
#include "p33Fxxxx.h" Н
настраиваем генератор
_FOSCSEL(0x02);
_FOSC(0xE2);
присваиваем адреса выходов переменным для обозначения индикаторов
#define LED1 _RB1
#define LED2 _RB2
#define LED3 _RB3
обозначаем количество числовых индикаторов
#define N 3
int chislo;
переменная для обозначения работающего в данный момент индикатора
char state; в данном массиве происходит запись цифр в двоичном коде, который потом будет использоваться для загорания нужных сегментов индикатора (нумерация сегментов идёт по часовой стрелке, начиная с верхнего, а последним будет центральный сегмент)
char num[]={
0b0111111, // 0
0b0000110, // 1
0b1011011, // 2
0b1001111, // 3
0b1100110, // 4
0b1101101, // 5
0b1111101, // 6
0b0000111, // 7
0b1111111, // 8
0b1101111, // 9
};
инициализируем массив индикаторов
int mas[N];
ниже у нас идёт подпрограмма для разбивания числа по индикаторам, думаю никаких затруднений она у вас не вызовет
void razlog(int chis)
{
int i;
for (i=0; i<N; i++)
{
mas[i]=chis%10;
chis=chis/10;
}
}
далее начинается основная программа
int main(void)
{
ставим подтягивающие резисторы на входы с кнопками
_CN2PUE=1;
_CN29PUE=1;
все входы обозначаем цифровыми
AD1PCFGL=0xffff;
настраиваем нужные порты
PORTA=0;
LATA=0;
TRISA=0b1001;
PORTB=0;
LATB=0;
TRISB=0;
тут у нас настройки прерывания INT1 и INT2 для кнопок, в настройках необходимо указать, что оно будет по заднему фронту
RPINR0=0x1000;
_INT1EP=1;
_INT1IE=1;
RPINR1=0x0013;
_INT2EP=1;
_INT2IE=1; а здесь идёт инициализация Таймера 2 и его прерывания
T2CONbits.TON=1;
T2CONbits.TCS=0;
T2CONbits.TGATE=0;
T2CONbits.TCKPS=0b00;
_T2IE=1;
PR2=0x5000;
LED1=1;
LED2=1;
LED3=1;
указываем что сначала должен загореться третий индикатор
state=1;
а тут находится число, которое будет выводиться при запуске
chislo=500;
необходимо начать бесконечный цикл, чтобы у нас не заканчивалась работа МК, в нём достаточно только разложить число, которое будет выводиться на экран
while (1)
{
razlog(chislo);
}
}
обработка прерывания Таймера 2, с помощью которого для каждого индикатора отводится определённое число и происходит поочерёдное загорание и затухание каждого индикатора
void __attribute__( (__interrupt__, auto_psv) ) _T2Interrupt()
{
LED1=1;
LED2=1;
LED3=1;
PORTB &= 0x01FF;
switch(state)
{
case 1:
PORTB |= (num[mas[0]]<<9);
LED1=0;
break;
case 2:
PORTB |= (num[mas[1]]<<9);
LED2=0;
break;
case 3:
PORTB |= (num[mas[2]]<<9);
LED3=0;
break;
}
if (state==N)
state=1;
else
state++;
сбрасываем флаг прерывания таймера TMR0
_T2IF=0;
}
обработка прерывания INT1, в нём при нажатии верхней кнопки предыдущее число увеличивается на 56
void __attribute__( (__interrupt__, auto_psv) ) _INT1Interrupt()
{
chislo+=56;
_INT1IF=0;
}
обработка прерывания INT2, а здесь при нажатии нижней кнопки происходит уменьшение числа на 56
void __attribute__( (__interrupt__, auto_psv) ) _INT2Interrupt()
{
chislo-=56;
_INT2IF=0;
}
Вот и всё! Скачать схему в Proteus и исходники в MPLAB можно ниже.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.