IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 基于51单片机的废气检测I2Cproteus仿真 -> 正文阅读

[嵌入式]基于51单片机的废气检测I2Cproteus仿真

目录

文章目录

前言

二、设计步骤

1.proteus设计

2.keil5代码编程设计

总结


前言

前段时间高中同学让我帮忙给她做一个数电课设,反正也没事做就随便做了做,现在总结一下,话不多说直接上效果。


一、课设要求

二、设计步骤

1.proteus设计

最终效果如下:

2.keil5代码编程设计

代码如下:

main.c

//废气检测。
#include <reg52.h>
#include <intrins.h>
#include <I2C.h>
#define uchar unsigned char
#define uint unsigned int
#define _Nop( )  _nop_( ) 				//定义空操作,1μs
sbit oe=P1^3;  							//数码管段选、位选锁存器输出控制信号
sbit dula=P1^4;  						//数码管段选锁存器控制信号
sbit wela=P1^5;  						//数码管位选锁存器控制信号
sbit LED=P2^0;
sbit k3=P3^2;  //定义按键K3
sbit k4=P3^3;  //定义按键K4
uchar j=0;
int s,t,k,flag=1;
uchar code sled_bit[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};		//定义点亮数码管位选码
data uchar disp[8]={1,6,16,16,16,16,16,16};								// 8位数码管都不亮
uchar code table[18]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};	//共阴极数码管显示段码(0-F)
sbit P3_5=P3^5;


void delay(u16 i)
{
	while(i--);	
}
void Int0Init()
{
	//设置INT0
	IT0=1;//跳变沿出发方式(下降沿)
	EX0=1;//打开INT0的中断允许。	
	EA=1;//打开总中断	
}
void Int1Init()
{
	//设置INT1
	IT1=1;//跳变沿出发方式(下降沿)
	EX1=1;//打开INT1的中断允许。	
	EA=1;//打开总中断	
}
void main(void)
{   
		unsigned long d;
		P3_5=0;		
		TMOD=0x01;						// 设置定时器T0为方式1定时
    TH0=(65536-500)/256;			// 给T0装入初值
    TL0=(65536-500)%256;  			// 给T0装入初值
    ET0=1; 							// 允许T0中断
    EA=1;							// CPU开中断
    TR0=1;							// 启动T0
		oe=0;	
    Int0Init();
    Int1Init();  //	设置外部中断1
    LED=0;

sen:	erflags=0;
		Start( ); 							//发送起始信号
		SendByte(0x90); 					//发送写PCF8591的寻址字节(写)
		cAck( );							//检查应答
		if(erflags) goto sen;				//无应答,重来
		SendByte(0x00); 					//发送写入PCF8591的控制字,选择0通道
		cAck( );							//检查应答
		if(erflags) goto sen;				//无应答,重来

sen1:	Start( ); 							//发送起始信号
		SendByte(0x91); 					//发送写PCF8591的寻址字节(读)
		cAck( );							//检查应答
		if(erflags) goto sen1;				//无应答,重来
		d=RcvByte(  );						//第1次读的数据无效
		Ack(  );					 		//应答位函数,
    while(1)
   {	 	
		 d=RcvByte(  );
		 Ack(  );					 		//应答位函数,
		 d=(d*5*1000)/256;                  //电压值
         disp[0]=(int)d/1000;
		 disp[1]=(int)d%1000/100;
         s = (disp[0]*10+disp[1])*2+2;       
         if(s>=100)
             s=99;
         if(s<=50&&flag)
             LED=1;
         else if(s>50&&flag)
             LED=0;
         t = s/10;
         k = s%10;
   }

}

void  T0_int(void)  interrupt 1 
{   
	TH0=(65536-1000)/256;
    TL0=(65536-1000)%256;
	oe=1;							// 关闭2个573输出,防止在送数据时相互影响	
	switch(j)
    {
        case 0:P0 = table[0];break;
        case 1:P0 = 0xe6;break;
        case 2:P0 = table[5];break;
        case 3:P0 = table[0];break;
        case 4:P0 = table[2];break;
        case 5:P0 = 0x40;break;
        case 6:P0 = table[t];break;
        case 7:P0 = table[k];break;
    }
	dula=1;
	dula=0;							// 锁存段码
	
	P0=sled_bit[j];   				// 选择相应数码管位选 
	wela=1;
	wela=0;							// 锁存位码
	oe=0;							// 打开2个573三态门,输出段码和位码	
	j++;							// 为下一个显示做准备
	if(j>=8)j=0;		   
}
void Int0()	interrupt 0		//外部中断0的中断函数
{
	delay(1000);	 //延时消抖
	if(k3==0)
	{
		if(flag==1)
        {
            flag=0;
            LED=0;
        } 
        else if(flag==0)
            flag=1;
	}
}
void Int1()	interrupt 2		//外部中断1的中断函数
{
    int i;
	delay(1000);	 //延时消抖
	if(k4==0)
	{
		while(1)
        {
            for(i=0;i<8;i++)
            {
                oe=1;							// 关闭2个573输出,防止在送数据时相互影响	
                P0 = 0x40;
                dula=1;
                dula=0;							// 锁存段码
                
                P0=sled_bit[i];   				// 选择相应数码管位选 
                wela=1;
                wela=0;							// 锁存位码
                oe=0;							// 打开2个573三态门,输出段码和位码
                delay(500);
            }
        }
	}
}

?I2C.c

#include <reg52.h>
#include <intrins.h>
#include "I2C.h"
#define uchar unsigned char
#define uint unsigned int
#define _Nop( )  _nop_( ) 				//定义空操作,1μs
bdata uchar b;
sbit b_7=b^7;
sbit  SDA=P3^4; 						//模拟I2C数据传送位
sbit  SCL=P3^6; 						//模拟I2C时钟控制位

void Start(void)	  					//起始位函数
{  	
	  SDA=1;
    SCL=1;
    _Nop( ); _Nop( ); _Nop( ); _Nop( ); 	
   	SDA=0; 
   	_Nop( ); _Nop( ); _Nop( ); _Nop( );	
   	SCL=0; 			
}

void Stop(void)	 						//终止位函数,
{ 	SDA=0;
   	SCL=1;
   	_Nop( ); _Nop( ); _Nop( ); _Nop( ); 
   	SDA=1;
   	_Nop( ); _Nop( ); _Nop( ); _Nop( ); 
}

void Ack(void )					 		//应答位函数,
{ 	SDA=0;
  	_Nop( ); _Nop( ); _Nop( ); _Nop( );
	  SCL=1;
   	_Nop( ); _Nop( ); _Nop( ); _Nop( ); 
   	SCL=0;
   	SDA=1;
 }

void NoAck(void )						//非应答位函数		
{ 	SDA=1;
   	_Nop( ); _Nop( ); _Nop( ); _Nop( ); 
	  SCL=1;
   	_Nop( ); _Nop( ); _Nop( ); _Nop( );  
   	SCL=0;
 }

void cAck( void )   					//检查应答函数   
{  	
	uchar i=0;    
	SCL=1;    
	while((SDA==1)&&(i<255))  i++;    
	erflags=SDA;    
	SCL=0; 								     //函数结束,使SCL=0
} 	

void SendByte(uchar temp)		//写入1字节数据函数
{	
	uchar i;
  b=temp;
  for(i=0; i <8; i++)				 // 8位数据长度
 	{ 	
		SCL=0;
    SDA=b_7;						     //发送数据最高位送到SDA
    b= b<<1;						     //左移一位,准备下一发送位
    SCL=1;							     //SCL↑送入
    _Nop( ); _Nop( ); 
		_Nop( ); _Nop( );  
	}
  SCL=0;
  SDA=1; 							       //发送完后使SDA=1,等待应答
}

uchar RcvByte(void)					//读出1字节数据函数
 { 	uchar i,temp;
    SCL=0;
    SDA=1;								  //作输入先输出1	
    for(i=0; i <8; i++)			// 8位数据长度
   	{ 
			SCL=1;							  //SCL↑数据输入到SDA
    	_Nop( ); _Nop( ); 
		  _Nop( ); _Nop( ); 
    	temp<<=1; 						//接收数据变量左移一位,最低位腾空
     	if(SDA) temp|=0x01;		//读1位数据到最低位
     	SCL=0;                //SCL=0,为SCL↑作准备
		}						
   		return temp;          //返回接收数据 
 }					

I2C.h

#ifndef __I2C_H__
#define __I2C_H__

sbit  erflags=P3^7; 									//检查应答错误标志

extern void Start(void);	  							//起始位函数
extern void Stop(void);	 								//终止位函数,
extern void Ack(void );					 				//应答位函数
extern void NoAck(void);								//非应答位函数	
extern void cAck( void );   							//检查应答函数   
extern void SendByte(unsigned char temp);				 //写入1字节数据函数
extern unsigned char RcvByte(void);						//读出1字节数据函数

#endif

总结

本课设是涉及到了51的AD转换,数码管显示,I2C,中断等的综合实验,需要学习的同学呢麻烦点赞关注,然后在评论区留下邮箱有空我就会私发,当然工程下载链接等审核通过后我也会附上。

工程链接:基于51单片机的废气检测proteus仿真

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-04 11:22:45  更:2021-08-04 11:23:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/28 4:59:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码