Встраиваемые системы. Проектирование приложений на микроконтроллерах семейства 68HC12/HCS12 с применением языка С - Стивен Барретт
Шрифт:
Интервал:
Закладка:
#include <912b32.h>
#include <stdio.h>
void delay_100us(void);
void ADC_convert(void);
void delay_5ms(void);
void main(void) {
asm(" .area vectors (abs)n" /*код инициализации вектора reset B32 */
" .org 0xFFF8n"
" .word 0x8000, 0x8000, 0x8000, 0x8000n"
" .text");
initialize_LCD(); /*инициализация ЖК дисплея */
ATDCTL2 = 0x80; /*подача питания на АЦП, разрешение прерываний */
delay_5ms(); /*ожидание входа АЦП в рабочий режим */
ATDCTL3 = 0x00;
ATDCTL4 = 0x01; /*8-разрядный результат, время выборки 2 АЦП */
/*clk, коэффициент деления 4 */
ADC_convert(); /*АЦП преобразование */
}
/********************************************************************/
/* void ADC_convert(void): функция, осуществляющая одно преообразо- */
/* вание и сохраняющая доступ пользователя к нему. Затем функция */
/* преобразует текущий результат в цифровое значение. Таким образом */
/* каждое отдельное число может быть выделено, преобразовано в ASCII*/
/* код и выведено на ЖКД */
void ADC_convert() {
unsigned int sumadr;
unsigned int avg_bin_voltage;
unsigned int int_voltage;
unsigned int tens_int;
unsigned int ones_int;
unsigned int tenths_int;
unsigned int hundredths_int;
double voltage, abs_voltage;
char tens;
char ones;
char tenths;
char hundredths;
ATDCTL5 = 0x06; /*проводится 4 преобразования, канал 6 */
while((ATDSTAT & 0x8000)!= 0x8000) {
/*Подождите окончания преобразования */
}
/*усреднение по четырем результатам */
sumadr = ADR0H + ADR1H + ADR2H + ADR3H;
avg_bin_voltage = sumadr/4;
/* преобразование результата в напряжение, лежащее в диапазоне от */
/* 0.00 до 5.00 В */
voltage = (avg_bin_voltage/256)*5;
/*приведение напряжения к диапазону от -10.00 до +10.00 В */
/*обращение процесса, выполняемого аналоговым интерфейсом */
abs_voltage = (fabs)((voltage - 2.5) * 4);
/*преобразование результата в целое число в диапазоне от -1000 */
/* до +1000 */
int_voltage = (100*voltage);
/*Выделение и преобразование наибольшей значащей цифры в */
/* ASCII код десятичного значения, прибавление 48, */
/* результат дает ASCII код */
tens_int = int_voltage/1000;
tens = (char)(tens_int + 48);
/*Выделение и преобразование следующей наибольшей значащей цифры в */
/* ASCII код десятичного значения, прибавление 48, */
/* результат дает ASCII код*/
ones_int = int_voltage/100;
ones = (char)(ones_int + 48);
/*Выделение и преобразование следующей наибольшей значащей цифры в */
/* ASCII код десятичного значения, прибавление 48, */
/* результат дает ASCII код */
tenths_int = (int_voltage - ones_int*100)/10;
tenths = (char)(tenths_int + 48);
/*Выделение и преобразование следующей наибольшей значащей цифры в */
/* ASCII код десятичного значения, прибавление 48, */
/* результат дает ASCII код */
hundredths_int = (int_voltage - ones_int*100 - tenths_int*10)/1;
hundredths = (char)(hundredths_int + 48);
/*Вывод результата на ЖКД */
if (voltage < 0) putchars('-'); /*Вывести отрицательный знак*/
else putchars('+'); /*Вывести положительный знак*/
putchars(tens);
putchars(ones);
putchars('.');
putchars(tenths);
putchars(hundredths);
putchars(' ');
putchars('V');
}
/********************************************************************/
/********************************************************************/
/*задержка в 100 мкс, на базе таймера с частотой 8 МГц */
/********************************************************************/
void delay_100us(void) {
int i;
for (i=0; i<50; i++) {
asm("nop");
}
}
/********************************************************************/
/*задержка в 5 мс, на базе таймера с частотой 8 МГц */
/********************************************************************/
void delay_5ms(void) {
int i;
for (i=0; i<50; i++) {
delay_100us();
}
}
/********************************************************************/
/*Функции инициализации посылают на ЖКД необходимую стартовую */
/* последовательность. Формируется последовательность команд инициали-*/
/* зации соответствующих техническим данным производителя дисплея. */
/********************************************************************/
void initialize_lcd(void) {
delay_5ms();
delay_5ms();
delay_5ms(); /*задержка на 15 мс перед включением ЖКД */
putcommands(0x38); /*установочный интерфейс */
delay_5ms();
putcommands(0x38);
delay_100us();
putcommands(0x38);
putcommands(0x38);
putcommands(0x0C);
putcommands(0x01); /*Очистить дисплей */
putcommands(0x06); /*Установить режим увеличения адреса на единицу*/
putcommands(0x0E); /*Включить дисплей,вывести мигающий курсор */
putcommands(0x02); /*Возврат */
}
/********************************************************************/
/* Функция вывода инициализирует порт данных, создает сигналы RS и */
/* разрешения и посылает их на соответствующий порт */
/********************************************************************/
void putchars(unsigned char c) {
DDRP = 0xFF; /*установить Port P как выходной */
DDRDLC = DDRDLC | 0x0C; * установить PORTDLC[3:2] как выходной */
PORTP = c; /* присвоить знак С порту данных */
PORTDLC= PORTDLC|0x08 /* установить RS в 1 для данных */
PORTDLC= PORTDLC|0x04 /* установить E в 1 ( PORTDLC[5] = 1) */
PORTDLC = 0; /* установить E и RS в 0 */
delay_5ms(); /* подождать 5мс */
}
/********************************************************************/
/*Функция putcommand пересылает данные в контроллер на ЖК дисплея */
/********************************************************************/
void putcommands(unsigned char d) {
DDRP = 0xFF; /*установить порт PORTP в качестве выходного */
DDRDLC = DDRDLC|0x0C; /*установить выводы PORTDLC[3:2] */
/* в качестве выходных */
PORTDLC = PORTDLC & 0xF7; /* команда RS = 0 */
PORTP = d; /*передача команды на на ЖКД */
PORTDLC = PORTDLC|0x04; /*E = 1 */
PORTDLC =0; /*E = 0 */
delay_5ms(); /*пауза 5 мс */
}
/********************************************************************/
/*Функция lcd_print посылает строку на ЖК дисплей */
/********************************************************************/
void lcd_print(char *string) {
putcommands(0x02); /*установка курсора на первую строку */
/*putcommand для выделения строки */
while(*(string) != ' ') {
putchars(*string);
string++;
}
}
/********************************************************************/
/*задержка в 5 мс, на базе таймера с частотой 8 МГц */
/********************************************************************/
void delay_5ms(void) {
int i;
for (i=0; i<50; i++) {
delay_100us();
}
}
/********************************************************************/
/********************************************************************/
/*задержка в 100 мкс, на базе таймера с частотой 8 МГц */
/********************************************************************/
void delay_100us(void) {
int i;
for(i=0; i<50; i++) {
asm("nop");
}
}
/********************************************************************/
7.3.6. Измерение неэлектрических величин
В представляемых примерах функция вольтметра состоит просто в измерении напряжения с выхода датчика некоторого внешнего физического параметра.
Датчик температуры. Например, мы можем подключить к МК 68HC12 градуированный по шкале Фаренгейта прецизионный датчик температуры LM34, выпускаемый компанией National Semiconductor. Этот датчик имеет постоянный коэффициент преобразования в +10 мВ на градус Фаренгейта, в диапазоне от –50 до +300 Ф. Схема подключения LM34 приведена на рис. 7.14. Она состоит из собственно датчика LM34 и цепи фильтра, образованной резистором и конденсатором. Такая схема обеспечивает прямое преобразование измеряемой температуры. Например, при 70 Ф, LM34 создает выходной сигнал в 700 мВ. Это напряжение умножается на 100, чтобы обеспечить прямое преобразование напряжения в вольтах в температуру, выраженную в градусах Фаренгейта для вывода на дисплей. Это значение должно затем быть преобразовано в ASCII код для вывода на ЖК дисплей.