#include<reg52.h>
//#include "STC12c5A.h"
//#include "1602.h"
//#include "2402.h"
#include "math.h"
#define uchar unsigned char
#define uint unsigned int
typedef unsigned char BYTE;
typedef unsigned int WORD; uchar code tablewei[]={0xfd,0xfb,0xf7,0xef};int shuzhi[4]={0};
/*Declare SFR associated with the ADC */
sfr ADC_CONTR = 0xBC; //ADC control register
sfr ADC_RES = 0xBD; //ADC hight 8-bit result register
sfr ADC_RESL = 0xBE; //ADC low 2-bit result register
sfr P1M1=0x91;
sfr P1M0=0x92;
sfr P1ASF=0X9D;
sfr EADC=0XB6;
sfr AUXR1=0XA2;
//sfr P1ASF = 0x9D; //P1 secondary function control register
/*Define ADC operation const for ADC_CONTR*/
#define ADC_POWER 0x80 //ADC power control bit
#define ADC_FLAG 0x10 //ADC complete flag
#define ADC_START 0x08 //ADC start control bit
#define ADC_SPEEDLL 0x00 //540 clocks
#define ADC_SPEEDL 0x20 //360 clocks
#define ADC_SPEEDH 0x40 //180 clocks
#define ADC_SPEEDHH 0x60 //90 clocks
//声明常量
#define ALCH 80 //醉驾标准80mg/L
//K_MG_MV和K_ZERO为传感器校准系数,要根据每个MQ-3模块校准
#define K_MG_MV 160/60 //传感器灵敏度系数,可以自行校准
#define K_ZERO 0 //传感器零点漂移
//定义按键
sbit Key_Up = P3^2;
sbit Key_Down = P3^3;
//定义LED报警灯
sbit Led_Warn1 = P3^4;
sbit Led_Warn2 = P3^5;
//液晶
sbit RS=P2^7;
sbit RW=P2^6;
sbit E=P2^5;
//蜂鸣器
sbit beep=P3^7;
// 24C02
sbit SCL=P1^0;
sbit SDA=P1^1;
//定义乙醇传感器TTL电平输出引脚
sbit DOUT = P1^4;
//定义标识
volatile bit FlagStartAL = 0; //开始转换标志
volatile bit FlagKeyPress = 0; //有键弹起标志
//全局变量定义
uchar Threshold; //酒精浓度上限报警值
uint ALCounter; //酒精转换计时器
int 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 );
void DELAY(unsigned int t)
{
while(t!=0)
t--;
}
/******************************
IIC DRIVE
******************************/
void IICStart(void)
{
SCL=0;
DELAY(1);
SDA=1; SCL=1; DELAY(1);
SDA=0; DELAY(1);
SCL=0;
}
void IICStop(void)
{
SDA=0;SCL=1; DELAY(1);
SDA=1; DELAY(1);
SCL=0; }
void SEND0(void)
{
SDA=0;
SCL=1;
DELAY(1);
SCL=0;
}
void SEND1(void)
{
SDA=1;
DELAY(1);
SCL=1;
DELAY(1);
SCL=0;
}
bit Check_Ack(void)
{
unsigned char errtime=250;
DELAY(1);
SCL=1;
DELAY(1);
CY=SDA;
while(CY) {
errtime--;
CY=SDA;
if (!errtime)
{
IICStop();
return 1;
}
}
DELAY(1);
SCL=0;
return 0;
}
void Write_byte(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
if((dat<<i)&0x80)
SEND1();
else
SEND0();
}
}
unsigned char Read_byte(void) {
unsigned char i,temp=0;
for(i=0;i<8;i++)
{
SDA=1;
SCL=1;
DELAY(1);
if(SDA==1)
{
temp=temp<<1;
temp=temp|0x01;
}
else
temp=temp<<1;
SCL=0;
}
return temp;
}
/************************************
EEPROM DRIVE
Addr:from 0x00-->
*************************************/
unsigned char rdeeprom(unsigned char addr)
{ unsigned char temp=0;
bit flag=0;
IICStart();
Write_byte(0xa0);
Check_Ack();
Write_byte(addr);
Check_Ack();
IICStart();
Write_byte(0xa1);
Check_Ack();
temp=Read_byte();
SEND1();
IICStop();
return temp;
}
void wrteeprom(unsigned char addr,unsigned char dat)
{
IICStart();
Write_byte(0xa0);
Check_Ack();
Write_byte(addr);
Check_Ack();
Write_byte(dat);
Check_Ack();
IICStop(); }
void delay()
{
int i,j;
for(i=0; i<=10; i++)
for(j=0; j<=2; j++);
}
uchar Convert(uchar In_Date)
{
/*
uchar i, Out_Date = 0, temp = 0;
for(i=0; i<8; i++)
{
temp = (In_Date >> i) & 0x01;
Out_Date |= (temp << (7 - i));
}
return Out_Date;
*/
return In_Date;
}
void enable(uchar del)
{
P0 = Convert(del);
RS = 0;
RW = 0;
E = 0;
delay();
E = 1;
delay();
}
void write(uchar del)
{
P0 = Convert(del);
RS = 1;
RW = 0;
E = 0;
delay();
E = 1;
delay();
}
void L1602_init(void) {
enable(0x01);
enable(0x38);
enable(0x0c);
enable(0x06);
enable(0xd0);
}
void L1602_char(uchar hang,uchar lie,char sign)
{
uchar a;
if(hang == 1) a = 0x80;
if(hang == 2) a = 0xc0;
a = a + lie - 1;
enable(a);
write(sign);
}
void L1602_string(uchar hang,uchar lie,uchar *p)
{
uchar a;
if(hang == 1) a = 0x80;
if(hang == 2) a = 0xc0;
a = a + lie - 1;
enable(a);
while(1) {
if(*p == '\0') break;
write(*p);
p++;
}
}
//显示整型的温湿度数据用,共占用4位,其中一位符号位
void L1602_int(uchar hang, uchar lie, int num)
{
uint temp;
uint gewei,shiwei,baiwei,sign;
//首先将4位清空
L1602_char(hang, lie+0, ' ');
L1602_char(hang, lie+1, ' ');
L1602_char(hang, lie+2, ' ');
L1602_char(hang, lie+3, ' ');
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);
}
}
//数据初始化
void Data_Init()
{
ALCounter = 0;
ALValue = 0;
Led_Warn1 = 1;
Led_Warn2 = 1;
keyvalue = 0;
keyUp = 1;
keyDown = 1;
beep=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; //
}
//ADC初始化
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; /