基于51单片机的废气检测I2Cproteus仿真
生活随笔
收集整理的這篇文章主要介紹了
基于51单片机的废气检测I2Cproteus仿真
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
目錄
文章目錄
前言
二、設(shè)計(jì)步驟
1.proteus設(shè)計(jì)
2.keil5代碼編程設(shè)計(jì)
總結(jié)
前言
前段時(shí)間高中同學(xué)讓我?guī)兔o她做一個(gè)數(shù)電課設(shè),反正也沒(méi)事做就隨便做了做,現(xiàn)在總結(jié)一下,話(huà)不多說(shuō)直接上效果。
一、課設(shè)要求
二、設(shè)計(jì)步驟
1.proteus設(shè)計(jì)
最終效果如下:
2.keil5代碼編程設(shè)計(jì)
代碼如下:
main.c
//廢氣檢測(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; //數(shù)碼管段選、位選鎖存器輸出控制信號(hào) sbit dula=P1^4; //數(shù)碼管段選鎖存器控制信號(hào) sbit wela=P1^5; //數(shù)碼管位選鎖存器控制信號(hào) 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}; //定義點(diǎn)亮數(shù)碼管位選碼 data uchar disp[8]={1,6,16,16,16,16,16,16}; // 8位數(shù)碼管都不亮 uchar code table[18]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; //共陰極數(shù)碼管顯示段碼(0-F) sbit P3_5=P3^5;void delay(u16 i) {while(i--); } void Int0Init() {//設(shè)置INT0IT0=1;//跳變沿出發(fā)方式(下降沿)EX0=1;//打開(kāi)INT0的中斷允許。 EA=1;//打開(kāi)總中斷 } void Int1Init() {//設(shè)置INT1IT1=1;//跳變沿出發(fā)方式(下降沿)EX1=1;//打開(kāi)INT1的中斷允許。 EA=1;//打開(kāi)總中斷 } void main(void) { unsigned long d;P3_5=0; TMOD=0x01; // 設(shè)置定時(shí)器T0為方式1定時(shí)TH0=(65536-500)/256; // 給T0裝入初值TL0=(65536-500)%256; // 給T0裝入初值ET0=1; // 允許T0中斷EA=1; // CPU開(kāi)中斷TR0=1; // 啟動(dòng)T0oe=0; Int0Init();Int1Init(); // 設(shè)置外部中斷1LED=0;sen: erflags=0;Start( ); //發(fā)送起始信號(hào)SendByte(0x90); //發(fā)送寫(xiě)PCF8591的尋址字節(jié)(寫(xiě))cAck( ); //檢查應(yīng)答if(erflags) goto sen; //無(wú)應(yīng)答,重來(lái)SendByte(0x00); //發(fā)送寫(xiě)入PCF8591的控制字,選擇0通道cAck( ); //檢查應(yīng)答if(erflags) goto sen; //無(wú)應(yīng)答,重來(lái)sen1: Start( ); //發(fā)送起始信號(hào)SendByte(0x91); //發(fā)送寫(xiě)PCF8591的尋址字節(jié)(讀)cAck( ); //檢查應(yīng)答if(erflags) goto sen1; //無(wú)應(yīng)答,重來(lái)d=RcvByte( ); //第1次讀的數(shù)據(jù)無(wú)效Ack( ); //應(yīng)答位函數(shù),while(1){ d=RcvByte( );Ack( ); //應(yīng)答位函數(shù),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; // 關(guān)閉2個(gè)573輸出,防止在送數(shù)據(jù)時(shí)相互影響 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]; // 選擇相應(yīng)數(shù)碼管位選 wela=1;wela=0; // 鎖存位碼oe=0; // 打開(kāi)2個(gè)573三態(tài)門(mén),輸出段碼和位碼 j++; // 為下一個(gè)顯示做準(zhǔn)備if(j>=8)j=0; } void Int0() interrupt 0 //外部中斷0的中斷函數(shù) {delay(1000); //延時(shí)消抖if(k3==0){if(flag==1){flag=0;LED=0;} else if(flag==0)flag=1;} } void Int1() interrupt 2 //外部中斷1的中斷函數(shù) {int i;delay(1000); //延時(shí)消抖if(k4==0){while(1){for(i=0;i<8;i++){oe=1; // 關(guān)閉2個(gè)573輸出,防止在送數(shù)據(jù)時(shí)相互影響 P0 = 0x40;dula=1;dula=0; // 鎖存段碼P0=sled_bit[i]; // 選擇相應(yīng)數(shù)碼管位選 wela=1;wela=0; // 鎖存位碼oe=0; // 打開(kāi)2個(gè)573三態(tài)門(mén),輸出段碼和位碼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數(shù)據(jù)傳送位 sbit SCL=P3^6; //模擬I2C時(shí)鐘控制位void Start(void) //起始位函數(shù) { SDA=1;SCL=1;_Nop( ); _Nop( ); _Nop( ); _Nop( ); SDA=0; _Nop( ); _Nop( ); _Nop( ); _Nop( ); SCL=0; }void Stop(void) //終止位函數(shù), { SDA=0;SCL=1;_Nop( ); _Nop( ); _Nop( ); _Nop( ); SDA=1;_Nop( ); _Nop( ); _Nop( ); _Nop( ); }void Ack(void ) //應(yīng)答位函數(shù), { SDA=0;_Nop( ); _Nop( ); _Nop( ); _Nop( );SCL=1;_Nop( ); _Nop( ); _Nop( ); _Nop( ); SCL=0;SDA=1;}void NoAck(void ) //非應(yīng)答位函數(shù) { SDA=1;_Nop( ); _Nop( ); _Nop( ); _Nop( ); SCL=1;_Nop( ); _Nop( ); _Nop( ); _Nop( ); SCL=0;}void cAck( void ) //檢查應(yīng)答函數(shù) { uchar i=0; SCL=1; while((SDA==1)&&(i<255)) i++; erflags=SDA; SCL=0; //函數(shù)結(jié)束,使SCL=0 } void SendByte(uchar temp) //寫(xiě)入1字節(jié)數(shù)據(jù)函數(shù) { uchar i;b=temp;for(i=0; i <8; i++) // 8位數(shù)據(jù)長(zhǎng)度{ SCL=0;SDA=b_7; //發(fā)送數(shù)據(jù)最高位送到SDAb= b<<1; //左移一位,準(zhǔn)備下一發(fā)送位SCL=1; //SCL↑送入_Nop( ); _Nop( ); _Nop( ); _Nop( ); }SCL=0;SDA=1; //發(fā)送完后使SDA=1,等待應(yīng)答 }uchar RcvByte(void) //讀出1字節(jié)數(shù)據(jù)函數(shù){ uchar i,temp;SCL=0;SDA=1; //作輸入先輸出1 for(i=0; i <8; i++) // 8位數(shù)據(jù)長(zhǎng)度{ SCL=1; //SCL↑數(shù)據(jù)輸入到SDA_Nop( ); _Nop( ); _Nop( ); _Nop( ); temp<<=1; //接收數(shù)據(jù)變量左移一位,最低位騰空if(SDA) temp|=0x01; //讀1位數(shù)據(jù)到最低位SCL=0; //SCL=0,為SCL↑作準(zhǔn)備} return temp; //返回接收數(shù)據(jù) }I2C.h
#ifndef __I2C_H__ #define __I2C_H__sbit erflags=P3^7; //檢查應(yīng)答錯(cuò)誤標(biāo)志extern void Start(void); //起始位函數(shù) extern void Stop(void); //終止位函數(shù), extern void Ack(void ); //應(yīng)答位函數(shù) extern void NoAck(void); //非應(yīng)答位函數(shù) extern void cAck( void ); //檢查應(yīng)答函數(shù) extern void SendByte(unsigned char temp); //寫(xiě)入1字節(jié)數(shù)據(jù)函數(shù) extern unsigned char RcvByte(void); //讀出1字節(jié)數(shù)據(jù)函數(shù)#endif總結(jié)
本課設(shè)是涉及到了51的AD轉(zhuǎn)換,數(shù)碼管顯示,I2C,中斷等的綜合實(shí)驗(yàn),需要學(xué)習(xí)的同學(xué)呢麻煩點(diǎn)贊關(guān)注,然后在評(píng)論區(qū)留下郵箱有空我就會(huì)私發(fā),當(dāng)然工程下載鏈接等審核通過(guò)后我也會(huì)附上。
工程鏈接:基于51單片機(jī)的廢氣檢測(cè)proteus仿真
總結(jié)
以上是生活随笔為你收集整理的基于51单片机的废气检测I2Cproteus仿真的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 如何成为巨量引擎Marketing AP
- 下一篇: mac怎么查node版本_Mac更新no