Смекни!
smekni.com

Разработка универсального шестиканального термометра (стр. 2 из 2)

unsigned char num_ch=6; // счетчик каналов от 0 до MAX_CH-1

int ampl=0; // амплитуда с выхода АЦП

unsigned char strobe_count=0; // счетчик строба измерения

unsigned char count_50=1; // счетчик 500 ms

unsigned char t0_ext=1; // дополнительный делитель для TCNT0

unsigned char bufer_led[bufer_led_size]; // 0 - led`s 1-4 BCD

char txd_bufer[txd_buf_len]={' ',TAB,' ',' ',' ',CR,LF,0 }; // буфер передачи

// N : - 2 4

char txd_index=txd_buf_len-1;

#define dis_measure_ok 1 // 0x0002 // измерение завершилось 1

#define dis_measure 2 // 0x0004 // запущено измерение(счет) 2

unsigned char dis_flag=(1<<dis_measure); // флаги диспетчера

#define adc_start {ADCSR|=(1<<ADSC);}

__flash const unsigned char table_ascii[]={'0','1', '2', '3', '4', '5', '6', '7', '8','9', 'E', 'r', 'o', ' ', ' ', ' '};

void d2_bcd(long val);

void measure_a(void);

void display_parm(void);

void count_time_gen_init(void);

void count_time_ind_init(void);

void fotm_trx(void);

void transmit(void);

C_task void main(void)

{// main

count_50=count_50_init; // init count 500 ms

// инициализация АЦП

ADMUX=(1<<REFS0);// Vref=VACC

ADCSR=((1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0));

// инициализация UART

UBRRH=ubr19200>>8;

UBRRL=ubr19200;

UCSRB= (1<<TXEN)|(1<<RXEN); //разр прием/перед

UCSRC = 0;// Async. mode, 8N1

// num_ch=6; // иниц счетчика каналов

// init and start TCNT0

t0_ext=t0_ext_init;

TCNT0=t0_init;

TIMSK |= ((1<<TOIE0)|(1<<TOIE1)); // irq T0, T1 enable

_SEI(); // global irq enable

TCCR0=((1<<CS01)|(1<<CS00)); // start TCNT0 CLK/64(частота тактирования таймеров)

_WDR(); //сбросить сторожевик

WDTCR|=((1<<WDE)|(1<<WDP0)|(1<<WDP1));//включить сторожевик 130 ms

for(;;); // LOOP FOREVER

}// end of main

#pragma vector=ADC_vect

__interrupt void ADC_proc (void)

{

// АЦП закнчил преобразование

_SEI();

_WDR(); // сброс сторожевого таймера

ampl=ADC;

dis_flag |= (1<<dis_measure_ok);

//set_mux;

}

#pragma vector=TIMER0_OVF_vect

__interrupt void ovf0_proc (void)

{

//диспетчер

TCNT0=t0_init; // перезапуск TCNT0

_SEI(); // разрешить сложенные прерывания

t0_ext-=1;

if (!t0_ext)

{// счетчик досчитал

t0_ext=t0_ext_init; //перезапуск дополнительного делителя

//отработка 10 ms

// счетчик на 500 ms

count_50 -=1;

_WDR(); //сбросить сторожевик

if(!count_50){// äîñ÷èòàë

count_50=count_50_init;

// отработка 500 ms

if(count_time_ind) count_time_ind--;

if(count_time_gen) count_time_gen--;

// конец отработки 500 ms

} // end if(!count_50

// измерение и обработка его результатов

if (!count_time_ind)

{

if (!count_time_gen)

{

count_time_gen_init();

if(++num_ch>=MAX_CH){ num_ch=0;} // сканирование каналов

}

measure_a(); // измерять температуру пока не будет измерено

if (dis_flag & (1<<dis_measure_ok)){// измерение окончено

//расчет очередного измерения

ampl=a_term*(ampl+b_term); //расчитать текущий параметр Y=a*(f+b)

display_parm(); // формирование знакомест

fotm_trx(); // формирование буфера для передачи

count_time_ind_init(); // инициализация счетчика иедикации

dis_flag &= ~(1<<dis_measure_ok); // по окончинии индикации возможно изменение

} // end if измерение окончено

}//end if (!count_time_ind)

transmit(); // выдача в COM PORT содержимого индикатора

}// end of счетчик досчитал (t0_ext)

}// end of ovf0_proc

void fotm_trx(void)

{ // формирование буфера передачи

txd_bufer[0]=table_ascii[bufer_led[1]]; // номер канала

txd_bufer[2]=table_ascii[bufer_led[2]]; // параметр

txd_bufer[3]=table_ascii[bufer_led[3]]; //параметр

txd_index=0;

}

void transmit(void)

{

if (txd_bufer[txd_index]){

UDR=txd_bufer[txd_index++];

}

}

void measure_a(void)

{

ADMUX=num_ch; // номер канала в мультиплексор АЦП

adc_start;

}

void display_parm(void)

{// отображение на терминале значения параметра

bufer_led[1]=num_ch+1; // выдать номер канала (1...6 вместо 0...5)

d2_bcd(ampl);//вызов программы обработки числа

}// end of display_parm

void d2_bcd(long val)

{// 2-10

bufer_led[2]=val/10;

if (!bufer_led[2]) bufer_led[2]=blank_symb;

bufer_led[3]=val%10;

}// end of d2_bcd

term.h

void count_time_gen_init(void){

count_time_gen=time_gen;

}

void count_time_ind_init(void){

count_time_ind=time_ind;

}

#define tcnt1_freq 4000000 // частота тактирования таймера

#define bufer_led_size 5 // длина буфера индикатора

#define blank_symb 0x0F // символ гашения

#define txd_buf_len 8 // äдлина буфера передачи RS232

#define CR 13 // перевод строки

#define LF 10 // в начало строки

#define TAB 9 // табуляция

#define ubr19200 12 // 19200 бит/с при 4МГц кварце

#define t0_init (256-125) // для загрузки в таймер диспетчера

#define t0_ext_init 5 // 125*5=625

#define count_50_init 50 // для загрузки в счетчик 500 ms

#define MAX_CH 6

#define a_term 0.4883//коэффициент пересчета

#define b_term -559// коэффициент пересчета

#define time_gen 10 //5 сек время переключения каналов

#define time_ind 10 //5 сек время индикации

Описание программы

Работа программы основывается на решении следующих задач:

1. общая настройка портов ввода/вывода, таймеров, конфигурация и т.д.

2. настройка АЦП.

1) внутренний источник напряжения 5V

2) прерывания от компаратора

3) коэффициент деления 128(частота 31 250 ГЦ)

4) непрерывное преобразование

3. настройка UART

1) асинхронный режим

2) прерывания по передаче вкл.

3) скорость обмена 9600 Бод(бит в секунду)

4. прерывания по таймеру, формирование задержки 500мс.

5. прерывание АЦП от компаратора

6. формирование буфера передачи данных (3 байта – 1-й байт- №канала, 2-й, 3-й байт - данные), отправка буфера передачи данных

Содержимое буфера передачи данных отображается на экране ,с помощью программы Hiper Terminal.

Описание применения программы.

Программа позволяет обрабатывать данные ,полученные с термодатчика и выводить их на экран через последовательный RS-232. В очередном порядке выводится номер канала и температура и ,измеренную данным каналом.


ПРИЛОЖЕНИЕ 3

Копия экрана


ПРИЛОЖЕНИЕ 4

Реальная модель устройства