找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1353|回复: 0
收起左侧

基于51单片机ADC0832转换MQ3酒精传感器OLED显示程序与Proteus仿真

[复制链接]
ID:1037634 发表于 2022-11-12 17:30 | 显示全部楼层 |阅读模式
如果仿真打不开,把Proteus升级到8.13版本。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
批注 2022-11-12 172932.png

单片机源程序如下:
  1. #include<reg51.h>
  2. #include<intrins.h>
  3. #include<oled.h>
  4. #define uchar unsigned char
  5. #define uint  unsigned int
  6. uchar Get_AD_Result();   //模数转换结果
  7. uint boundaries=80;//初始酒精报警设定为80
  8. uint vt;
  9. uchar AD;
  10. uint x,y;

  11. //ADC0832引脚定义
  12. sbit CS   = P1^0;
  13. sbit CLK  = P1^2;
  14. sbit DIDO = P1^1;
  15. sbit K1 = P2^2;
  16. sbit K2 = P2^3;
  17. sbit LEDR=P0^0;
  18. sbit Beep=P2^7;

  19. void Delayms(unsigned int n)//延时函数
  20. {
  21. unsigned int i,j;
  22. for(j=n;j>0;j--)
  23. for(i=112;i>0;i--);
  24. }

  25. void main()                        
  26. {         
  27.    OLED_Init();//初始化OLED
  28.          OLED_ColorTurn(0);//0正常显示,1 反色显示
  29.    OLED_DisplayTurn(1);//0正常显示 1 屏幕翻转显示
  30.         
  31.          OLED_ShowChinese(0,0,0,16);
  32.          OLED_ShowChinese(16,0,1,16);
  33.          OLED_ShowChinese(32,0,2,16);
  34.          OLED_ShowChinese(48,0,3,16);
  35.          OLED_ShowChinese(64,0,4,16);
  36.          OLED_ShowChinese(80,0,5,16);//显示酒精浓度测试
  37.          Delayms(2000);
  38.          OLED_Clear();
  39.          OLED_ShowChinese(0,0,0,16);//显示酒
  40.          OLED_ShowChinese(16,0,1,16);//显示精
  41.          OLED_ShowChinese(0,2,6,16);//显示设
  42.          OLED_ShowChinese(16,2,7,16);//显示定
  43.          OLED_ShowString(32,0,":",16);//显示:
  44.          OLED_ShowString(32,2,":",16);//显示:
  45.          OLED_ShowString(88,2,"mg/ml",16);//显示mg/ml
  46.          OLED_ShowString(88,0,"mg/ml",16);//显示mg/ml

  47.    CLK = 0;      //ADC0832初始化
  48.    CS   = 1;   
  49.    while(1)
  50.          {
  51.           AD = Get_AD_Result();
  52.     vt = (500.0/256.0)*AD;//得到输出电压
  53.           x=(vt-3)/2.778;//酒精浓度
  54.           y=x/10;
  55.           OLED_ShowNum(40,0,x,3,16);//显示整数
  56.           OLED_ShowNum(72,0,y,1,16);//显示小数
  57.           OLED_ShowString(64,0,".",16);//显示小数点
  58.           OLED_ShowNum(40,2,boundaries,3,16);//显示设定值
  59.                 if(x>=boundaries)//酒精浓度大于等于设定,蜂鸣器响,红灯亮
  60.                 {
  61.                         Beep=0;
  62.                         LEDR=0;
  63.                 }
  64.                 else//酒精浓度小于设定值,蜂鸣器不响,红灯不亮
  65.                 {
  66.           Beep=1;
  67.                 LEDR=1;
  68.                 }
  69.                
  70.                 if(K1==0)//按下K1时,设定值减1
  71.                 {
  72.                         Delayms(15);//消抖
  73.                         if(K1==0)
  74.                         {
  75.                          boundaries--;
  76.                         }
  77.                  while(!K1);//判断K1是否弹起
  78.                 }
  79.                  
  80.                 if(K2==0)//按下K2时,设定值减+
  81.                 {
  82.                         Delayms(15);//消抖
  83.                         if(K2==0)
  84.                         {
  85.                                 boundaries++;
  86.                         }
  87.                  while(!K2);//判断K2是否弹起
  88.                 }
  89.          }
  90. }





  91. //------------------------------
  92. //     获取AD转换结果(0通道)
  93. //------------------------------
  94. uchar Get_AD_Result()         //包含11个CLK下降沿      
  95. {
  96.     uchar i, dat;
  97.     CS = 1;              //ADC0832未工作时,CS端为高电平,此时芯片禁用
  98.     _nop_;               //对于延时很短的,要求在us级的,采用“_nop_”函数      
  99.     CLK =1;                  
  100.     CS = 0;
  101.     DIDO = 1; CLK = 0; _nop_; CLK = 1; _nop_; //SCLK第一个下降沿来到时,DI = 1启动ADC0832
  102.     DIDO = 1; CLK = 0; _nop_; CLK = 1; _nop_; //SCLK第二个下降沿
  103.     DIDO = 0; CLK = 0; _nop_; CLK = 1; _nop_; //SCLK第三个下降沿,发送1,0选择通道cho
  104.     DIDO = 1;                                //释放总线
  105.     for(i = 0; i < 8; i++)                  //第4个下降沿到第11个下降沿
  106.     {
  107.         CLK = 0;                           //clk处于下降沿,每一个下降沿DO端输入下一个
  108.         _nop_;                              //对于延时很短的,要求在us级的,采用_nop_函数      
  109.         if(DIDO) dat |= 0x01;              // dat = dat | 0x01,dat和0x01做“或”的运算,意思是最低位置1,其它位保持不变。
  110.         CLK = 1; _nop_;                      //clk处于上升沿
  111.         dat <<= 1;                          //数据左移
  112.     }
  113.     return (dat);
  114.     CS = 1;                                  //ADC0832停止工作
  115. }
复制代码

Keil代码与Proteus8.13版本的仿真(注意其他版本打不开的)下载:
51酒精报警.zip (91.61 KB, 下载次数: 66)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表