Изучить и исследовать методы программирования на языке Си линейных дисплеев на семисегментных светодиодных индикаторах. Исследовать методику проверки работы микроконтроллерных устройств с линейными дисплеями в среде моделирования Proteus, страница 2

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.