基于单片机的酒精浓度测试仪
if (num >= 0) {
sign = 0; } else {
sign = 1; }
temp = abs(num); baiwei = temp / 100;
temp = temp - baiwei*100; shiwei = temp / 10;
gewei = temp - shiwei*10; num = abs(num); if (num>=100) {
if (sign == 1) //负数 { L1602_char(hang, lie, '-'); }
L1602_char(hang, lie+1, baiwei+48); L1602_char(hang, lie+2, shiwei+48); L1602_char(hang, lie+3, gewei+48); }
else if (num>=10) {
if (sign == 1) { L1602_char(hang, lie+1, '-'); } L1602_char(hang, lie+2, shiwei+48); L1602_char(hang, lie+3, gewei+48); } else {
if (sign == 1) { L1602_char(hang, lie+2, '-'); }
L1602_char(hang, lie+3, gewei+48); } }
#include \
- 31 -
基于单片机的酒精浓度测试仪
#include \#include \#include \
#define uchar unsigned char #define uint unsigned int
//声明常量
#define ALCH 80 //醉驾标准80mg/L
//K_MG_MV和K_ZERO为传感器校准系数,要根据每个MQ-3模块校准
#define K_MG_MV 160/66 //传感器灵敏度系数,每毫克/L对应的10毫伏数 #define K_ZERO 15 //传感器零点漂移,约130mV
//定义按键
sbit Key_Up = P3^6; sbit Key_Down = P3^7;
//定义LED报警灯 sbit Led_Warn1 = P3^4; sbit Led_Warn2 = P3^5;
//定义乙醇传感器TTL电平输出引脚 sbit DOUT = P1^4;
//定义标识
volatile bit FlagStartAL = 0; //开始转换标志 volatile bit FlagKeyPress = 0; //有键弹起标志
//全局变量定义
uchar Threshold; //酒精浓度上限报警值 uint ALCounter; //酒精转换计时器 long ALValue; //酒精测量值 float ALtemp; //计算临时变量
uint keyvalue, keyUp, keyDown; //键值
char * pSave; //EEPROM存盘用指针
//函数声明
void Data_Init(); void Timer0_Init(); void Port_Init(); void ADC_Init(); uchar GetADVal(); void KeyProcess(uint );
- 32 -
基于单片机的酒精浓度测试仪
//数据初始化 void Data_Init() {
ALCounter = 0; ALValue = 0; Led_Warn1 = 1; Led_Warn2 = 2; keyvalue = 0; keyUp = 1; keyDown = 1; }
//定时器0初始化,中断时间约2毫秒
//计算:晶振11.0592MHz,定时器时钟11059200/12=921600,每毫秒922个脉冲 // 16位定时器初值65536-1844=63692=0xf8cc void Timer0_Init() {
ET0 = 1; //允许定时器0中断 TMOD = 1; //定时器工作方式选择 TL0 = 0xcc; //
TH0 = 0xf8; //定时器赋予初值,大约为2毫秒中断1次 TR0 = 1; //启动定时器 }
//定时器0中断
void Timer0_ISR (void) interrupt 1 using 0 {
TL0 = 0xcc;
TH0 = 0xf8; //定时器赋予初值
//每1秒钟启动一次AD转换 ALCounter ++;
if (ALCounter >= 500) {
FlagStartAL = 1; ALCounter = 0; } }
void Port_Init() {
P1M0 = 0x80; //10000000,P1.7作为AD输入 P1M1 = 0x80; //
- 33 -
基于单片机的酒精浓度测试仪
}
void ADC_Init() {
uint i;
P1ASF = 0x80; //设P1.7为AD输入 ADC_RES = 0; //清先前的结果
ADC_CONTR|=0x80; //POWER=1,打开ADC电源 for(i=5000;i>0;i--) ; //延时
ADC_CONTR = ADC_CONTR&0xE0; //1110,0000 清ADC_FLAG,ADC_START位和低3位
ADC_CONTR = ADC_CONTR&0xf8|0x07; //设置当前通道号为P1.7 for(i=2500;i>0;i--) ; //延时 }
//进行AD转换,得到当前酒精值 uchar GetADVal() {
uint i;
ADC_CONTR&=0xf7;
for(i=250;i>0;i--); //待输入电压稳定后开始转换 //ADC_RES = 0;
ADC_CONTR |= 0x08; //ADC_Start=1, 启动转换
while((ADC_CONTR&0x10)==0); //等待转换结束ADC_FLAG=1 ADC_CONTR&=0xe7; //清ADC_FLAG和ADC_START位,停止转换 return ADC_RES; }
//存入设定值
void Save_Setting() {
pSave = (char *)&Threshold; //地址低位对应低8位,高位对应高8位 wrteeprom(0, *pSave); //存醉酒阈值低8位 DELAY(300); pSave ++;
wrteeprom(1, *pSave); //存醉酒阈值高8位 DELAY(300); }
//载入设定值
void Load_Setting() {
pSave = (char *)&Threshold;
- 34 -
基于单片机的酒精浓度测试仪
*pSave++ = rdeeprom(0); *pSave = rdeeprom(1);
if ((Threshold>=255)||(Threshold<0)) Threshold = 80; }
//按键处理程序,参数为键值,1为Up键,2为Down键 void KeyProcess(uint num) {
switch (num) {
case 1:
if (Threshold<255) Threshold++; break; case 2:
if (Threshold>1) Threshold--; break; default: break; }
L1602_int(2,9,Threshold); Save_Setting(); }
void main() {
uint i,j;
EA = 0;
Data_Init(); //数据初始化
Timer0_Init(); //定时器0初始化 Port_Init(); //端口初始化 ADC_Init(); //ADC初始化 EA = 1;
L1602_init();
L1602_string(1,1,\ L1602_string(2,1,\ \ //延时
for (i=0;i<1000;i++) for (j=0;j<1000;j++) {;} //清屏
L1602_string(1,1,\ \ L1602_string(2,1,\ \ L1602_string(1,1,\ mg/L\
- 35 -