花了一个星期做的单片机结课作业,代码注释清晰,可读性高。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
代码:
- /******************************************************************
- * @file chengxu.c
- * @author 16自动化1班
- * @version 终结版
- * @date 2018年11月5号
- ******************************************************************
- * @instructions
- * 该程序实现的是对烟雾浓度的检测以百分制形式将采集到的值显示在数
- * 码管上,使用的是AT89系列单片机做处理器,模数转换芯片采用AD0809
- * 芯片。(该程序运用在大多模拟量采集转数字的传感器)
- ******************************************************************/
- #include <reg52.h> //头文件
- #define uchar unsigned char //宏定义无符号字符型
- #define uint unsigned int //宏定义无符号整型
- code uchar seg7code[10]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //显示段码 数码管字跟
- uchar wei[4]={0XEf,0XDf,0XBf,0X7f}; //位控制码
- sbit ST=P3^0; //A/D启动转换信号
- sbit OE=P3^1; //数据输出允许信号
- sbit EOC=P3^2; //A/D转换结束信号
- sbit CLK=P3^3; //时钟脉冲
- sbit Beep=P3^7; //蜂鸣器IO口
- uint z,x,c,v,AD0809, date; //定义数据类型(全局变量)
- /******************************************************************
- us延时函数,具体延时情况跟单片机选择的晶振有关
- ******************************************************************/
- void delayus(uint i)
- {
- while(i--);
- }
- /******************************************************************
- ms延时函数,具体延时情况跟单片机选择的晶振有关
- ******************************************************************/
- void delayms(uchar t)
- {
- uchar i,j;
- for(i=0;i<t;i++)
- {
- for(j=13;j>0;j--);
- { ;
- }
- }
- }
- /*************************************************************************
- 蜂鸣器报警函数
- **************************************************************************/
- void Subeep()
- {
- int i;
- for(i=0;i<10;i++)
- {
- Beep=~Beep; //蜂鸣器输出
- delayus(12); //如要改变发声改变延时即可
- }
- }
- /**********************************************************************
- 数码管动态扫描
- *********************************************************************/
- void xianshi() //显示函数
- {
- uint z,x,c,v;
- z=date/1000; //求百分数十位
- x=date%1000/100; //求百分数的个位
- c=date%100/10; //求百分数小数点后一位
- v=date%10; //求百分数小数点的后两位
- if(z>5) //如果烟雾浓度大于50%蜂鸣器发出报警声
- {
- Subeep(); //调用蜂鸣器报警函数
- }
-
- if(z==10) //判断z的值是否是10
- {
- z=9; //z赋值9
- x=9; //x赋值9
- c=9; //c赋值9
- v=9; //v赋值9
- }
- P2=0XFF; //P2IO初始化
- P0=seg7code[z]; //百分数十位赋值给数码管断码
- P2=wei[0]; //选择百分数十位显示
- delayms(3); //显示3ms
- P2=0XFF; //消影
- P0=seg7code[x]&0x7f; //百分数个位赋值给数码管断码和小数点断码
- P2=wei[1]; //选择百分数个位显示
- delayms(3); //显示3ms
- P2=0XFF; //消影
- P0=seg7code[c]; //百分数小数点后一位赋值给数码管断码
- P2=wei[2]; //选择百分数小数点后两位显示
- delayms(3); //显示3ms
- P2=0XFF; //消影
- P0=seg7code[v]; //百分数小数点后两位赋值给数码管断码
- P2=wei[3]; //选择百分数小数点后两位显示
- delayms(4); //显示3ms
- P2=0XFF; //消影
- }
- /*************************************************************************
- CLK振荡信号
- **************************************************************************/
- void timer0( ) interrupt 1 //定时器0工作方式1
- {
- TH0=(65536-2)/256; //重装计数初值
- TL0=(65536-2)%256; //重装计数初值
- CLK=!CLK; //取反
- }
- /*************************************************************************
- 主函数
- **************************************************************************/
- void main()
- {
- TMOD=0X01; //定时器中断0
- CLK=0; //脉冲信号初始值为0
- TH0=(65536-2)/256; //定时时间高八位初值
- TL0=(65536-2)%256; //定时时间低八位初值
- EA=1; //开CPU中断
- ET0=1; //开T/C0中断
- TR0=1;
- while(1) //无限循环
- {
- ST=0; //使采集信号为低
- ST=1; //开始数据转换
- ST=0; //停止数据转换
- while(!EOC); //等待数据转换完毕
- OE=1; //允许数据输出信号
- AD0809=P1; //读取数据
- OE=0; //关闭数据输出允许信号
- if(AD0809>=251) //电压显示不能超过5V
- AD0809=250;
- date=AD0809*40; //数码管显示的数据值,其中40为采集数据的毫安值
- xianshi(); //数码管显示函数
- }
- }
所有资料51hei提供下载: