get_sb = PORTA & 0b00111000; // ввод из порта А и выделение
// разрядов A3, A4
switch(get_sb)
{
case 0b00111000 : goto no_sb; // переход на метку no_sb
case 0b00110000 : goto u1; // переход на метку u1
case 0b00101000 : goto u2; // переход на метку u2
case 0b00011000 : goto u3;
default : goto error; // переход на метку error
no_sb: // контакты обеих кнопок (SB1, SB2) разомкнуты
{
char b;
for( b = 0; b < 8; b++)
displayRAM[ b ] = 0x7F;
}
break; // выход из оператора switch
u1: // нажата кнопка SB1
{
char b;
displayRAM[ 0 ] = 0b00111110; // код символа U
displayRAM[ 1 ] = 0x06; // код цифры 1
displayRAM[ 2 ] = 0; // код бланкирования
displayRAM[ 3 ] = 0; // код бланкирования
volts = get_volts( ADC_CH0 ); // измерение напряжения U1
for( b = 4; b < 8; b++)
{
if ( b == 4) // если индикатор 4-й, то вставка в код
// десятичной точки
displayRAM[ b ] = table[ (int) volts ] | 0b10000000;
else
displayRAM[ b ] = table[ (int) volts ];
volts -= (int) volts;
volts *= 10;
}
}
break; // выход из оператора switch
u2: // нажата кнопка SB2
{
char b;
displayRAM[ 0 ] = 0b00111110; // код символа U
displayRAM[ 1 ] = 0x5B; // код цифры 2
displayRAM[ 2 ] = 0; // код бланкирования
displayRAM[ 3 ] = 0; // код бланкирования
volts = get_volts( ADC_CH1 ); // измерение напряжения U2
for( b = 4; b < 8; b++)
{
if( b== 4) // если индикатор 4-й, то вставка в код
// десятичной точки
displayRAM[ b ] = table[ (int) volts ] | 0b10000000;
else
displayRAM[ b ] = table[ (int) volts ];
volts -= (int) volts;
volts *= 10;
}
}
break; // выход из оператора switch
u3: // нажата кнопка SB2
{
char b;
displayRAM[ 0 ] = 0b00111110; // код символа U
displayRAM[ 1 ] = 0x4F; // код цифры 3
displayRAM[ 2 ] = 0; // код бланкирования
displayRAM[ 3 ] = 0; // код бланкирования
volts = get_volts( ADC_CH2 ); // измерение напряжения U2
for( b = 4; b < 8; b++)
{
if( b== 4) // если индикатор 4-й, то вставка в код
// десятичной точки
displayRAM[ b ] = table[ (int) volts ] | 0b10000000;
else
displayRAM[ b ] = table[ (int) volts ];
volts -= (int) volts;
volts *= 10;
}
}
break; // выход из оператора switch
error: // нажаты одновременно кнопки SB1 и SB2
{
char b;
displayRAM[ 0 ] = 0b01111001; // код символа E
displayRAM[ 1 ] = 0b01010000; // код символа r
displayRAM[ 2 ] = 0b01011100;
displayRAM[ 3 ] = 0b01010000;
for( b = 4; b < 8; b++)
displayRAM[ b ] = 0; // код бланкирования
}
}
}
}
void init(void) // функция инициализации МК
{
PORTA = 0;
TRISA = 0b00111111;
PORTB = 0xFF;
TRISB = 0;
PORTC = 0;
TRISC = 0;
/* Открыть модуль АЦП: тактирование от генератора МК, коэффициент деления частоты генератора FOSC равен 4; правое выравнивание результата АЦ-преобразования; один аналоговый канал AN0; опорные напряжения UREF+ = UDD , UREF- = USS ; выбирается канал 0 (вход AN0); запрещаются прерыва-ния от АЦП */
OpenADC(ADC_FOSC_4 & ADC_RIGHT_JUST & ADC_1ANA_0REF,
ADC_CH0 & ADC_INT_OFF);
/* Инициализация таймера 0: разрешить прерывание по переполнению, внутренний источник счетных импульсов, 8- разрядный режим, коэффици-ент деления прескалера 1 : 8 */
OpenTimer0(TIMER_INT_ON & T0_SOURCE_INT &
T0_8BIT & T0_PS_1_8);
WriteTimer0( 0 ); // очистить регистры таймера 0
INTCONbits.GIE = 1; // общее разрешение прерываний
}
float get_volts(unsigned char channel) // функция измерения напряжения
{
SetChanADC( channel ); // выбор канала модуля АЦП
Delay10TCYx( 2 ); // задержка на 20 мкс
ConvertADC( ); // запуск АЦ-преобразования
while( BusyADC( ) ); // ожидание готовности данных
volts = ReadADC( ) * 0.00489; // получение результата в вольтах
return volts;
}
void timer0_isr(void) // функция обработки прерывания по
// переполнению таймера 0
{
PORTB = 0xFF; // погасить дисплей
PORTC = displayRAM[ a ];
PORTB = select; // включение выбранного индикатора
select = (select << 1) | 0b00000001; // сдвиг кода выборки влево и
// вставка 1 в младший разряд кода
a++;
if( a == 8) // если индикатор был последний
{
a = 0; // начать сканирование дисплея
select = 0b11111110; // с начала
}
INTCONbits.TMR0IF = 0; // сбросить флаг прерывания от таймера 0
}
Вывод: Изучили и исследовали методы программирования на языке Си линейных дисплеев на семисегментных светодиодных индикаторах. Исследовали методику проверки работы микроконтроллерных устройств с линейными дисплеями в среде моделирования Proteus.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.