制作數(shù)字電壓表(2學(xué)時(shí)) 一、實(shí)驗(yàn)?zāi)康模?/p> 1. 了解I2C串行總線工作原理及通信協(xié)議 2. 了解ADC0804、DAC0832、PCF8591與AT89S51的接口設(shè)計(jì) 3. 掌握ADC0804、DAC0832、PCF8591的編程方法 4. 能夠熟練運(yùn)用數(shù)模轉(zhuǎn)換模塊 二、實(shí)驗(yàn)要求: 1. 數(shù)字電壓表:在AT89C52系統(tǒng)中采用PCF8591芯片,測(cè)量0-5V范圍內(nèi)的直流電壓,并在2位數(shù)碼管上顯示電壓值。 三、實(shí)驗(yàn)設(shè)備:(PROTEUS元件表)
四、實(shí)驗(yàn)報(bào)告: 1.描述實(shí)驗(yàn)過(guò)程(重要步驟用屏幕截圖表示)。 2.給出在PROTEUS中設(shè)計(jì)的單片機(jī)系統(tǒng)電路圖 3.畫(huà)出程序流程圖 4.給出在KEIL中編寫(xiě)的源程序。 5.描述在proteus中仿真運(yùn)行程序的實(shí)驗(yàn)現(xiàn)象 五、實(shí)驗(yàn)總結(jié) 


單片機(jī)源程序如下:
- /**********************BST-M51實(shí)驗(yàn)開(kāi)發(fā)板例程************************
- * 平臺(tái):BST-M51 + Keil U4 + STC89C52
- * 名稱:AD串口讀取實(shí)驗(yàn)
- * 公司:深圳市亞博軟件開(kāi)發(fā)有限公司
- * 日期:2015-6
- * 晶振:11.0592MHZ
- ******************************************************************/
- #include<reg52.h> //包含單片機(jī)寄存器的頭文件
- #include <intrins.h>
-
- #define AddWr 0x90 //PCF8591 地址
-
- // 變量定義
- unsigned char AD_CHANNEL=0;
- unsigned char D[32];
- unsigned char code table[10]={0xC0,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //共陽(yáng)極數(shù)碼管0~9顯示的數(shù)值表
- unsigned int data dis[3]={0x00,0x00,0x00}; //用以計(jì)算存儲(chǔ)輸出電壓的3元素?cái)?shù)組
-
- sbit scl=P2^0; //I2C 時(shí)鐘
- sbit sda=P2^1; //I2C 數(shù)據(jù)
- bit ack; /*應(yīng)答標(biāo)志位*/
- sbit C1=P2^6;//數(shù)碼管位選
- sbit C2=P2^7;//數(shù)碼管位選
- sbit Dp=P2^5;//小數(shù)點(diǎn)
-
- unsigned char date;
-
- /*******************************************************************
- 起動(dòng)總線函數(shù)
- 函數(shù)原型: void Start_I2c();
- 功能: 啟動(dòng)I2C總線,即發(fā)送I2C起始條件.
- ********************************************************************/
- void Start_I2c()
- {
- sda=1; /*發(fā)送起始條件的數(shù)據(jù)信號(hào)*/
- _nop_();
- scl=1;
- _nop_(); /*起始條件建立時(shí)間大于4.7us,延時(shí)*/
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- sda=0; /*發(fā)送起始信號(hào)*/
- _nop_(); /* 起始條件鎖定時(shí)間大于4μs*/
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- scl=0; /*鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù) */
- _nop_();
- _nop_();
- }
-
- /*******************************************************************
- 結(jié)束總線函數(shù)
- 函數(shù)原型: void Stop_I2c();
- 功能: 結(jié)束I2C總線,即發(fā)送I2C結(jié)束條件.
- ********************************************************************/
- void Stop_I2c()
- {
- sda=0; /*發(fā)送結(jié)束條件的數(shù)據(jù)信號(hào)*/
- _nop_(); /*發(fā)送結(jié)束條件的時(shí)鐘信號(hào)*/
- scl=1; /*結(jié)束條件建立時(shí)間大于4μs*/
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- sda=1; /*發(fā)送I2C總線結(jié)束信號(hào)*/
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
-
- /*******************************************************************
- 字節(jié)數(shù)據(jù)發(fā)送函數(shù)
- 函數(shù)原型: void I2C_SendByte(UCHAR c);
- 功能: 將數(shù)據(jù)c發(fā)送出去,可以是地址,也可以是數(shù)據(jù),發(fā)完后等待應(yīng)答,并對(duì)
- 此狀態(tài)位進(jìn)行操作.(不應(yīng)答或非應(yīng)答都使ack=0)
- 發(fā)送數(shù)據(jù)正常,ack=1; ack=0表示被控器無(wú)應(yīng)答或損壞。
- ********************************************************************/
- void I2C_SendByte(unsigned char c)
- {
- unsigned char i;
-
- for(i=0;i<8;i++) /*要傳送的數(shù)據(jù)長(zhǎng)度為8位*/
- {
- if((c<<i)&0x80)sda=1; /*判斷發(fā)送位*/
- else sda=0;
- _nop_();
- scl=1; /*置時(shí)鐘線為高,通知被控器開(kāi)始接收數(shù)據(jù)位*/
- _nop_();
- _nop_(); /*保證時(shí)鐘高電平周期大于4μs*/
- _nop_();
- _nop_();
- _nop_();
- scl=0;
- }
-
- _nop_();
- _nop_();
- sda=1; /*8位發(fā)送完后釋放數(shù)據(jù)線,準(zhǔn)備接收應(yīng)答位*/
- _nop_();
- _nop_();
- scl=1;
- _nop_();
- _nop_();
- _nop_();
- if(sda==1)ack=0;
- else ack=1; /*判斷是否接收到應(yīng)答信號(hào)*/
- scl=0;
- _nop_();
- _nop_();
- }
-
- /*******************************************************************
- 字節(jié)數(shù)據(jù)接收函數(shù)
- 函數(shù)原型: UCHAR I2C_RcvByte();
- 功能: 用來(lái)接收從器件傳來(lái)的數(shù)據(jù),并判斷總線錯(cuò)誤(不發(fā)應(yīng)答信號(hào)),
- 發(fā)完后請(qǐng)用應(yīng)答函數(shù)應(yīng)答從機(jī)。
- ********************************************************************/
- unsigned char I2C_RcvByte()
- {
- unsigned char retc=0,i;
- sda=1; /*置數(shù)據(jù)線為輸入方式*/
- for(i=0;i<8;i++)
- {
- _nop_();
- scl=0; /*置時(shí)鐘線為低,準(zhǔn)備接收數(shù)據(jù)位*/
- _nop_();
- _nop_(); /*時(shí)鐘低電平周期大于4.7μs*/
- _nop_();
- _nop_();
- _nop_();
- scl=1; /*置時(shí)鐘線為高使數(shù)據(jù)線上數(shù)據(jù)有效*/
- _nop_();
- _nop_();
- retc=retc<<1;
- if(sda==1)retc=retc+1; /*讀數(shù)據(jù)位,接收的數(shù)據(jù)位放入retc中 */
- _nop_();
- _nop_();
- }
- scl=0;
- _nop_();
- _nop_();
- return(retc);
- }
-
- /********************************************************************
- 應(yīng)答子函數(shù)
- 函數(shù)原型: void Ack_I2c(bit a);
- 功能: 主控器進(jìn)行應(yīng)答信號(hào)(可以是應(yīng)答或非應(yīng)答信號(hào),由位參數(shù)a決定)
- ********************************************************************/
- void Ack_I2c(bit a)
- {
- if(a==0)sda=0; /*在此發(fā)出應(yīng)答或非應(yīng)答信號(hào) */
- else sda=1; /*0為發(fā)出應(yīng)答,1為非應(yīng)答信號(hào) */
- _nop_();
- _nop_();
- _nop_();
- scl=1;
- _nop_();
- _nop_(); /*時(shí)鐘低電平周期大于4μs*/
- _nop_();
- _nop_();
- _nop_();
- scl=0; /*清時(shí)鐘線,住I2C總線以便繼續(xù)接收*/
- _nop_();
- _nop_();
- }
-
- /************************************************************
- * 函數(shù)名 : Pcf8591_DaConversion
- * 函數(shù)功能 : PCF8591的輸出端輸出模擬量
- * 輸入 : addr(器件地址),channel(轉(zhuǎn)換通道),value(轉(zhuǎn)換的數(shù)值)
- * 輸出 : 無(wú)
- ******************* *****************************************/
- bit Pcf8591_DaConversion(unsigned char addr,unsigned char channel, unsigned char Val)
- {
- Start_I2c(); //啟動(dòng)總線
- I2C_SendByte(addr); //發(fā)送器件地址
- if(ack==0)return(0);
- I2C_SendByte(0x40|channel); //發(fā)送控制字節(jié)
- if(ack==0)return(0);
- I2C_SendByte(Val); //發(fā)送DAC的數(shù)值
- if(ack==0)return(0);
- Stop_I2c(); //結(jié)束總線
- return(1);
- }
-
- /************************************************************
- * 函數(shù)名 : Pcf8591_SendByte
- * 函數(shù)功能 : 寫(xiě)入一個(gè)控制命令
- * 輸入 : addr(器件地址),channel(轉(zhuǎn)換通道)
- * 輸出 : 無(wú)
- ************************************************************/
- bit PCF8591_SendByte(unsigned char addr,unsigned char channel)
- {
- Start_I2c(); //啟動(dòng)總線
- I2C_SendByte(addr); //發(fā)送器件地址
- if(ack==0)return(0);
- I2C_SendByte(0x40|channel); //發(fā)送控制字節(jié)
- if(ack==0)return(0);
- Stop_I2c(); //結(jié)束總線
- return(1);
- }
-
- /************************************************************
- * 函數(shù)名 : PCF8591_RcvByte
- * 函數(shù)功能 : 讀取一個(gè)轉(zhuǎn)換值
- * 輸入 :
- * 輸出 : dat
- ************************************************************/
- unsigned char PCF8591_RcvByte(unsigned char addr)
- {
- unsigned char dat;
-
- Start_I2c(); //啟動(dòng)總線
- I2C_SendByte(addr+1); //發(fā)送器件地址
- if(ack==0)return(0);
- dat=I2C_RcvByte(); //讀取數(shù)據(jù)0
-
- Ack_I2c(1); //發(fā)送非應(yīng)答信號(hào)
- Stop_I2c(); //結(jié)束總線
- return(dat);
- }
- /*------------------------------------------------
- 串口初始化函數(shù)
- ------------------------------------------------*/
- void init_com(void)
- {
- EA=1; //開(kāi)總中斷
- ES=1; //允許串口中斷
- ET1=1; //允許定時(shí)器T1的中斷
- TMOD=0x20; //定時(shí)器T1,在方式2中斷產(chǎn)生波特率
- PCON=0x00; //SMOD=0
- SCON=0x50; // 方式1 由定時(shí)器控制
- TH1=0xfd; //波特率設(shè)置為9600
- TL1=0xfd;
- TR1=1; //開(kāi)定時(shí)器T1運(yùn)行控制位
-
- }
- /*------------------------------------------------
- 延時(shí)函數(shù)
- ------------------------------------------------*/
- void delay(unsigned char i)
- {
- unsigned char j,k;
- for(j=i;j>0;j--)
- for(k=125;k>0;k--);
- }
- /*------------------------------------------------
- 把讀取值轉(zhuǎn)換成一個(gè)一個(gè)的字符,給串口顯示
- ------------------------------------------------*/
- void To_ascii(unsigned char num)
- {
- SBUF=num/100+'0';
- delay(200);
- SBUF=num/10%10+'0';
- delay(200);
- SBUF=num%10+'0';
- delay(200);
- }
- /*------------------------------------------------
- 主函數(shù)
- ------------------------------------------------*/
- main()
- {
-
- init_com();
- while(1)
- {
- /********以下AD-DA處理*************/
- PCF8591_SendByte(AddWr,0); //啟動(dòng)轉(zhuǎn)換
- D[0]=PCF8591_RcvByte(AddWr); //讀轉(zhuǎn)換完的數(shù)字信號(hào),ADC0 模數(shù)轉(zhuǎn)換1 光敏電阻
- /********以下將AD的值通過(guò)串口發(fā)送出去*************/
- dis[1]=D[0]/51; //每刻度值為5/256V,所以電壓值為輸出的8位數(shù)字值*5/256V,計(jì)算輸出電壓的整數(shù)值
- dis[2]=D[0]%51; //dis[2]位中間暫存數(shù)據(jù)位
- dis[2]=dis[2]*10;
- dis[0]=dis[2]/51; //計(jì)算輸出電壓的小數(shù)值
-
- C1=0; //關(guān)閉第二位數(shù)碼管
- C2=1; //打開(kāi)第一位數(shù)碼管
- Dp=1; //打開(kāi)小數(shù)點(diǎn)
- P1=table[dis[0]]; //顯示整數(shù)部分及小數(shù)點(diǎn)
- delay(10); //延時(shí)一定時(shí)間
-
- C2=0; //關(guān)閉第一位數(shù)碼管
- C1=1; //打開(kāi)第二位數(shù)碼管
- Dp=0; //關(guān)閉小數(shù)點(diǎn)
- P1=table[dis[1]]; //顯示小數(shù)部分
-
- /*delay(200);
- To_ascii(D[0]);
- SBUF='\n';
- delay(200);
- if(RI)
- {
- date=SBUF; //單片機(jī)接受
- SBUF=date; //單片機(jī)發(fā)送
- RI=0;
- }*/
- }
- }
復(fù)制代碼
0.png (41.56 KB, 下載次數(shù): 31)
下載附件
2019-1-3 17:10 上傳
所有資料51hei提供下載:
實(shí)驗(yàn)九制作數(shù)字電壓表.rar
(419.46 KB, 下載次數(shù): 209)
2019-1-3 14:50 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|