如果仿真打不开,把Proteus升级到8.13版本。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include<reg51.h>
- #include<intrins.h>
- #include<oled.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar Get_AD_Result(); //模数转换结果
- uint boundaries=80;//初始酒精报警设定为80
- uint vt;
- uchar AD;
- uint x,y;
- //ADC0832引脚定义
- sbit CS = P1^0;
- sbit CLK = P1^2;
- sbit DIDO = P1^1;
- sbit K1 = P2^2;
- sbit K2 = P2^3;
- sbit LEDR=P0^0;
- sbit Beep=P2^7;
- void Delayms(unsigned int n)//延时函数
- {
- unsigned int i,j;
- for(j=n;j>0;j--)
- for(i=112;i>0;i--);
- }
- void main()
- {
- OLED_Init();//初始化OLED
- OLED_ColorTurn(0);//0正常显示,1 反色显示
- OLED_DisplayTurn(1);//0正常显示 1 屏幕翻转显示
-
- OLED_ShowChinese(0,0,0,16);
- OLED_ShowChinese(16,0,1,16);
- OLED_ShowChinese(32,0,2,16);
- OLED_ShowChinese(48,0,3,16);
- OLED_ShowChinese(64,0,4,16);
- OLED_ShowChinese(80,0,5,16);//显示酒精浓度测试
- Delayms(2000);
- OLED_Clear();
- OLED_ShowChinese(0,0,0,16);//显示酒
- OLED_ShowChinese(16,0,1,16);//显示精
- OLED_ShowChinese(0,2,6,16);//显示设
- OLED_ShowChinese(16,2,7,16);//显示定
- OLED_ShowString(32,0,":",16);//显示:
- OLED_ShowString(32,2,":",16);//显示:
- OLED_ShowString(88,2,"mg/ml",16);//显示mg/ml
- OLED_ShowString(88,0,"mg/ml",16);//显示mg/ml
- CLK = 0; //ADC0832初始化
- CS = 1;
- while(1)
- {
- AD = Get_AD_Result();
- vt = (500.0/256.0)*AD;//得到输出电压
- x=(vt-3)/2.778;//酒精浓度
- y=x/10;
- OLED_ShowNum(40,0,x,3,16);//显示整数
- OLED_ShowNum(72,0,y,1,16);//显示小数
- OLED_ShowString(64,0,".",16);//显示小数点
- OLED_ShowNum(40,2,boundaries,3,16);//显示设定值
- if(x>=boundaries)//酒精浓度大于等于设定,蜂鸣器响,红灯亮
- {
- Beep=0;
- LEDR=0;
- }
- else//酒精浓度小于设定值,蜂鸣器不响,红灯不亮
- {
- Beep=1;
- LEDR=1;
- }
-
- if(K1==0)//按下K1时,设定值减1
- {
- Delayms(15);//消抖
- if(K1==0)
- {
- boundaries--;
- }
- while(!K1);//判断K1是否弹起
- }
-
- if(K2==0)//按下K2时,设定值减+
- {
- Delayms(15);//消抖
- if(K2==0)
- {
- boundaries++;
- }
- while(!K2);//判断K2是否弹起
- }
- }
- }
- //------------------------------
- // 获取AD转换结果(0通道)
- //------------------------------
- uchar Get_AD_Result() //包含11个CLK下降沿
- {
- uchar i, dat;
- CS = 1; //ADC0832未工作时,CS端为高电平,此时芯片禁用
- _nop_; //对于延时很短的,要求在us级的,采用“_nop_”函数
- CLK =1;
- CS = 0;
- DIDO = 1; CLK = 0; _nop_; CLK = 1; _nop_; //SCLK第一个下降沿来到时,DI = 1启动ADC0832
- DIDO = 1; CLK = 0; _nop_; CLK = 1; _nop_; //SCLK第二个下降沿
- DIDO = 0; CLK = 0; _nop_; CLK = 1; _nop_; //SCLK第三个下降沿,发送1,0选择通道cho
- DIDO = 1; //释放总线
- for(i = 0; i < 8; i++) //第4个下降沿到第11个下降沿
- {
- CLK = 0; //clk处于下降沿,每一个下降沿DO端输入下一个
- _nop_; //对于延时很短的,要求在us级的,采用_nop_函数
- if(DIDO) dat |= 0x01; // dat = dat | 0x01,dat和0x01做“或”的运算,意思是最低位置1,其它位保持不变。
- CLK = 1; _nop_; //clk处于上升沿
- dat <<= 1; //数据左移
- }
- return (dat);
- CS = 1; //ADC0832停止工作
- }
复制代码
Keil代码与Proteus8.13版本的仿真(注意其他版本打不开的)下载:
51酒精报警.zip
(91.61 KB, 下载次数: 70)
|