基于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() {//設置INT0IT0=1;//跳變沿出發方式(下降沿)EX0=1;//打開INT0的中斷允許。 EA=1;//打開總中斷 } void Int1Init() {//設置INT1IT1=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; // 啟動T0oe=0; Int0Init();Int1Init(); // 設置外部中斷1LED=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; //發送數據最高位送到SDAb= 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仿真
總結
以上是生活随笔為你收集整理的基于51单片机的废气检测I2Cproteus仿真的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何成为巨量引擎Marketing AP
- 下一篇: mac怎么查node版本_Mac更新no