找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2152|回复: 7
打印 上一主题 下一主题
收起左侧

单片机酒精测试仪的AD转换问题

[复制链接]
跳转到指定楼层
楼主
30黑币
在下刚接触单片机不久,小白一个,前几天让做一个酒精测试仪,一开始没要求使用stc15的芯片,后面要求改掉,并使用自带的ad转换,增加一个指示灯,要求指示未饮酒(20毫克/100毫升),饮酒(20-80毫克/100毫升),醉酒(80>毫克/100毫升),目前自己仅做出来这么一点点东西,求助各位大佬帮忙修改一下程序,指点一下,不胜感激!!!

不改好不让走,帮帮孩子吧,我想早点回家过年0.0

//程序头函数
#include <stc15.h>
#include <math.h>
//显示函数
#include <display.h>

#include <intrins.h>
#include "eeprom52.h"
//宏定义
#define uint unsigned int
#define uchar unsigned char
#define Data_ADC0809 P1

//管脚声明
sbit LED_R= P2^2; //红指示灯
sbit LED_G= P2^0; //绿色指示灯
sbit FENG = P2^5; //蜂鸣器
//ADC
sbit ST=P3^3;

//按键
sbit Key1=P2^6;        //设置按键
sbit Key2=P2^7; //加
sbit Key3=P3^7;        //减

bit bdata flag;//指示灯和蜂鸣器闪烁报警标志位
uchar set;          //设置标志位


//函数声明
extern uchar ADC0809();
extern void Key();

//酒精含量变量
int temp=0;
int ZERO=0;
char sec=3;          //开机初始化的时间


uchar WARNING=25; // 初始报警值

void delay(uint x)
{
        uint i,j;
        for(i=0;i<x;i++)
        for(j=0;j<121;j++);
}

/******************把数据保存到单片机内部eeprom中******************/
void write_eeprom()
{
        SectorErase(0x2000);
        byte_write(0x2000, WARNING);
        byte_write(0x2001, ZERO);
        byte_write(0x2060, a_a);        
}

/******************把数据从单片机内部eeprom中读出来*****************/
void read_eeprom()
{
        WARNING   = byte_read(0x2000);
        ZERO      = byte_read(0x2001);
        a_a       = byte_read(0x2060);
}

/**************开机自检eeprom初始化*****************/
void init_eeprom()
{
        read_eeprom();                //先读
        if(a_a != 1)                //新的单片机初始单片机内问eeprom
        {
                WARNING   = 25;
                ZERO=0;
                a_a = 1;
                write_eeprom();           //保存数据
        }        
}

//初始化函数
void init()         
{
        TMOD=0x01; //定时器0方式1
         TL0=0xb0;
         TH0=0x3c;  //赋初值
         EA=1;        //开总中断
        ET0=1;        //允许定时器0中断
         TR0=1;        //定时器0开
}
//主函数
void main()
{
        init();         //初始化函数

        Init1602_init();        //1602初始化
        while(sec+1)
        {
                write_com(0x80+0x40+13);
                write_data(sec/10+0x30);
                write_data(sec%10+0x30);
        }
        Init1602();        //1602初始化
        init_eeprom();  //开始初始化保存的数据
        
        while(1)//主循环
        {
                if(set==0) //如果没有按下设置(默认set是0,就是正常显示状态)
                {
                        temp=ADC0809();        //读取酒精值
                        Display_1602(temp-ZERO,WARNING);         //显示酒精值
                }
                if(temp-ZERO<WARNING&&set==0)        //如果实际的酒精值小于报警值且在正常显示状态下
                {
                        flag=0;         //执行下面flag=0的(主要就是绿灯闪,关蜂鸣器和继电器)
                }
                else if(temp-ZERO>WARNING&&set==0)  //如果实际的酒精值大于报警值且在正常显示状态下
                {
                        flag=1;        //执行下面flag=1的(主要就是红灯闪,开蜂鸣器和继电器)
                }
                Key();//按键扫描
        }
}
//ADC0809读取信息
uchar ADC0809()
{
        uchar temp_=0x00;
        //初始化高阻太

        OE=0;
        //转化初始化
        ST=0;
        //开始转换
        ST=1;
        ST=0;
        //外部中断等待AD转换结束
        while(EOC==0)
        //读取转换的AD值
        OE=1;
        temp_=Data_ADC0809;
        OE=0;
        return temp_;
}
//按键函数
void Key()
{
        if(Key1==0)        //如果设置按键按下
        {
                delay(20);
                if(Key1==0)
                {
                        FENG=0;        //蜂鸣器响
                        delay(100);
                        FENG=1;        //蜂鸣器关
                        set++;        //设置的变量加1
                        if(set==1)
                        {
                                flag=0;        //绿灯闪
                                TR0=0;        //关定时器0
                                write_com(0x0f);//打开显示 无光标 光标闪烁
                                write_com(0x80+0x40+13);//位置
                        }
                        else
                        {
                                set=0;
                                set=0;        //正常显示状态
                                write_com(0x0c);//打开显示 无光标 无光标闪烁
                                FENG=1;        //蜂鸣器关
                                flag=1;        //红灯闪
                                TR0=1;        //定时器0?
                        }
                        
                        while(Key1==0);//等待按键释放
                }
        }
        if(Key2==0&&set!=0)          //在设置的状态下按下加
        {
                delay(20);
                if(Key2==0&&set!=0)          //在设置的状态下按下加
                {
                        FENG=0;                //蜂鸣器响
                        delay(100);
                        FENG=1;         //蜂鸣器关
                        WARNING++;        //报警值加1
                        if(WARNING>=255)  //如果报警值大于等于255
                        WARNING=0;                 //报警值归零
                        write_com(0x80+0x40+11);
                        write_data('0'+WARNING/100);
                        write_data('0'+WARNING/10%10);
                        write_data('0'+WARNING%10);           //显示报警值
                        write_com(0x80+0x40+13);//调整位置
                        write_eeprom();                           //保存数据        
                        while(Key2==0);          //等待按键释放
                }
        }
        if(Key3==0&&set!=0)         //在设置的状态下按下减
        {
                delay(20);
                if(Key3==0&&set!=0)         //在设置的状态下按下减
                {
                        FENG=0;                 //蜂鸣器响
                        delay(100);
                        FENG=1;         //蜂鸣器关
                        WARNING--;         //报警值减1
                        if(WARNING<=0)        //如果报警值小于等于0
                        WARNING=255;        //那么报警值为255
                        write_com(0x80+0x40+11);
                        write_data('0'+WARNING/100);
                        write_data('0'+WARNING/10%10);
                        write_data('0'+WARNING%10);
                        write_com(0x80+0x40+13);//调整位置
                        write_eeprom();                           //保存数据        
                        while(Key3==0);         //等待按键释放        
                }
        }
        if(Key2==0&&Key3==0&&set==0)
        {
                delay(1000);
                if(Key2==0&&Key3==0&&set==0)
                {
                        FENG=0;                 //蜂鸣器响
                        delay(200);
                        FENG=1;         //蜂鸣器关
                        ZERO=temp;
                        while(Key2==0&&Key3==0);
                        write_eeprom();                           //保存数据
                }
        }
}

void  time1_int(void) interrupt 1 //定时器中断0
{
        uchar count;
        TL0=0xb0;
         TH0=0x3c;  //重赋初值50ms
          count++;  ///溢出值加1
        if(count==10)  //如果时间到半秒
        {
                if(flag==0)          //如果flag为0
                {
                        LED_G=0;  //绿灯亮
                        LED_R=1;  //红灯灭
                        FENG=1;          //蜂鸣器关
                }
                if(flag==1)           //如果flag为1
                {
                        LED_G=1;   //绿灯关
                        LED_R=0;   //红灯亮
                        FENG=0;           //蜂鸣器开
                }
        }

           if(count>=20)          //如果时间到1秒
           {
                count=0;          //溢出值清零
                if(flag==0)         //如果flag为0
                {
                        LED_G=1;        //绿灯关
                        LED_R=1;        //红灯灭
                        FENG=1;           //蜂鸣器关
                }
                if(flag==1)           //如果flag为1
                {
                        LED_G=1;   //绿灯关
                        LED_R=1;        //红灯灭
                        FENG=1;           //蜂鸣器关
                }
                if(sec>=0)
                sec--;
        }
}

酒精.7z

125.14 KB, 下载次数: 10

最佳答案

查看完整内容

LCD不显示是时序没有处理好,改了时序就可以了。实物正常不代表仿真也行。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:213173 发表于 2022-1-8 21:20 | 只看该作者
uhl0 发表于 2022-1-9 19:25
我导入仿真显示不了,是我仿真有问题吗?大佬麻烦再帮忙看看

LCD不显示是时序没有处理好,改了时序就可以了。实物正常不代表仿真也行。


程序构架.rar (26.91 KB, 下载次数: 13)

回复

使用道具 举报

板凳
ID:213173 发表于 2022-1-9 14:58 | 只看该作者
给你写了个程序构架,管脚配置、PH值计算、报警等细节部分你自己完善。
程序构架.rar (25.31 KB, 下载次数: 9)

回复

使用道具 举报

地板
ID:999060 发表于 2022-1-9 19:25 | 只看该作者
wulin 发表于 2022-1-9 14:58
给你写了个程序构架,管脚配置、PH值计算、报警等细节部分你自己完善。

我导入仿真显示不了,是我仿真有问题吗?大佬麻烦再帮忙看看
回复

使用道具 举报

5#
ID:213173 发表于 2022-1-9 21:49 | 只看该作者
uhl0 发表于 2022-1-9 19:25
我导入仿真显示不了,是我仿真有问题吗?大佬麻烦再帮忙看看

这个程序只是根据以往编程经验构建的一个基础构架,各功能模块相对独立,通过全局变量、标志位和定时器中断协调运行。虽然通过编译但既没有仿真也没有经实物验证。充其量只能算是一个编程思路。注释也还算比较详细,应该不难理解。
回复

使用道具 举报

6#
ID:57657 发表于 2022-1-10 17:29 | 只看该作者
uhl0 发表于 2022-1-9 19:25
我导入仿真显示不了,是我仿真有问题吗?大佬麻烦再帮忙看看

仿真模型不是完整的,有很多STC新增的寄存器、中断在仿真里面都是空白,只能实物验证,只适合仿真一些基本寄存器、算法类程序。
回复

使用道具 举报

7#
ID:999060 发表于 2022-1-10 17:37 | 只看该作者
wulin 发表于 2022-1-10 15:06
LCD不显示是时序没有处理好,改了时序就可以了。实物正常不代表仿真也行。

我使用其他的程序也试了下,使用proteus只能使用stc15w4k32s4,好像Proteus的STC15元件不能仿真AD,当然也可能是我自己仿真有错,感谢大佬耐心帮助,非常感谢
回复

使用道具 举报

8#
ID:999060 发表于 2022-1-11 11:39 | 只看该作者
wulin 发表于 2022-1-8 21:20
LCD不显示是时序没有处理好,改了时序就可以了。实物正常不代表仿真也行。

大佬stc的原理图有吗?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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