|
仿真 使用Proteus +keil4 使用51單片機(jī)進(jìn)行仿真, 用dac0832模擬不同的電壓 模仿不同的空氣流量
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.png (26 KB, 下載次數(shù): 57)
下載附件
2019-12-19 16:22 上傳
單片機(jī)源程序如下:
- #include"XPT2046.h"
-
- #include<intrins.h> //包含_nop_()函數(shù)定義的頭文件
- #include<reg52.h>
- #include"lcd.h"
- #include"temp.h"
- typedef unsigned int u16; //???????????
- typedef unsigned char u8;
- u8 disp[5];
- u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
- //--定義使用的IO口--//
- sbit PWM=P2^1;
- bit DIR;
- sbit k1=P3^1; //定義P31口是k1
- sbit k2=P3^2; //定義P31口是k1
- sbit led=P2^0; //定義P20口是led
- //ADC0832端口引腳定義
- //sbit CS=P3^5; //將CS位定義為P3.4引腳
- //sbit CLK=P3^6; //將CLK位定義為P1.0引腳
- sbit DIO=P3^4; //將DIO位定義為P1.1引腳
- //液晶端口定義
- sbit RS=P2^6; //寄存器選擇位,將RS位定義為P2.0引腳
- sbit RW=P2^5; //讀寫選擇位,將RW位定義為P2.1引腳
- sbit E=P2^7; //使能信號(hào)位,將E位定義為P2.2引腳
- sbit BF=P0^7; //忙碌標(biāo)志位,,將BF位定義為P0.7引腳
- //全局變量聲明
- unsigned char code digit[10]={"0123456789"}; //定義字符數(shù)組顯示數(shù)字
- unsigned char code Str[]={"Volt="}; //說明顯示的是電壓
- //--定義一個(gè)全局變量--//
- u16 count,timer1;
- void LcdDisplay(int);
- void UsartConfiguration();
- void datapros();
- /*******************************************************************************
- * 函 數(shù) 名 : delay
- * 函數(shù)功能 : 延時(shí)函數(shù),i=1時(shí),大約延時(shí)10us
- *******************************************************************************/
- void delay(u16 i)
- {
- while(i--);
- }
- /*****************************************************
- 函數(shù)功能:延時(shí)1ms
- (3j+2)*i=(3×33+2)×10=1010(微秒),可以認(rèn)為是1毫秒
- ***************************************************/
- void delay1ms()
- {
- unsigned char i,j;
- for(i=0;i<10;i++)
- for(j=0;j<33;j++)
- ;
- }
- /*****************************************************
- 函數(shù)功能:延時(shí)若干毫秒
- 入口參數(shù):n
- ***************************************************/
- void delaynms(unsigned char n)
- {
- unsigned char i;
- for(i=0;i<n;i++)
- delay1ms();
- }
- /*****************************************************
- 函數(shù)功能:判斷液晶模塊的忙碌狀態(tài)
- 返回值:result。result=1,忙碌;result=0,不忙
- ***************************************************/
- bit BusyTest(void)
- {
- bit result;
- RS=0; //根據(jù)規(guī)定,RS為低電平,RW為高電平時(shí),可以讀狀態(tài)
- RW=1;
- E=1; //E=1,才允許讀寫
- _nop_(); //空操作
- _nop_();
- _nop_();
- _nop_(); //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
- result=BF; //將忙碌標(biāo)志電平賦給result
- E=0; //將E恢復(fù)低電平
- return result;
- }
- /*****************************************************
- 函數(shù)功能:將模式設(shè)置指令或顯示地址寫入液晶模塊
- 入口參數(shù):dictate
- ***************************************************/
- void WriteInstruction (unsigned char dictate)
- {
- while(BusyTest()==1); //如果忙就等待
- RS=0; //根據(jù)規(guī)定,RS和R/W同時(shí)為低電平時(shí),可以寫入指令
- RW=0;
- E=0; //E置低電平(根據(jù)表8-6,寫指令時(shí),E為高脈沖,
- // 就是讓E從0到1發(fā)生正跳變,所以應(yīng)先置"0"
- _nop_();
- _nop_(); //空操作兩個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
- P0=dictate; //將數(shù)據(jù)送入P0口,即寫入指令或地址
- _nop_();
- _nop_();
- _nop_();
- _nop_(); //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
- E=1; //E置高電平
- _nop_();
- _nop_();
- _nop_();
- _nop_(); //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
- E=0; //當(dāng)E由高電平跳變成低電平時(shí),液晶模塊開始執(zhí)行命令
- }
- /*****************************************************
- 函數(shù)功能:指定字符顯示的實(shí)際地址
- 入口參數(shù):x
- ***************************************************/
- void WriteAddress(unsigned char x)
- {
- WriteInstruction(x|0x80); //顯示位置的確定方法規(guī)定為"80H+地址碼x"
- }
- /*****************************************************
- 函數(shù)功能:將數(shù)據(jù)(字符的標(biāo)準(zhǔn)ASCII碼)寫入液晶模塊
- 入口參數(shù):y(為字符常量)
- ***************************************************/
- void WriteData(unsigned char y)
- {
- while(BusyTest()==1);
- RS=1; //RS為高電平,RW為低電平時(shí),可以寫入數(shù)據(jù)
- RW=0;
- E=0; //E置低電平(根據(jù)表8-6,寫指令時(shí),E為高脈沖,
- // 就是讓E從0到1發(fā)生正跳變,所以應(yīng)先置"0"
- P0=y; //將數(shù)據(jù)送入P0口,即將數(shù)據(jù)寫入液晶模塊
- _nop_();
- _nop_();
- _nop_();
- _nop_(); //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
- E=1; //E置高電平
- _nop_();
- _nop_();
- _nop_();
- _nop_(); //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
- E=0; //當(dāng)E由高電平跳變成低電平時(shí),液晶模塊開始執(zhí)行命令
- }
- /*****************************************************
- 函數(shù)功能:對(duì)LCD的顯示模式進(jìn)行初始化設(shè)置
- ***************************************************/
- void LcdInitiate(void)
- {
- delaynms(15); //延時(shí)15ms,首次寫指令時(shí)應(yīng)給LCD一段較長(zhǎng)的反應(yīng)時(shí)間
- WriteInstruction(0x38); //顯示模式設(shè)置:16×2顯示,5×7點(diǎn)陣,8位數(shù)據(jù)接口
- delaynms(5); //延時(shí)5ms ,給硬件一點(diǎn)反應(yīng)時(shí)間
- WriteInstruction(0x38);
- delaynms(5); //延時(shí)5ms ,給硬件一點(diǎn)反應(yīng)時(shí)間
- WriteInstruction(0x38); //連續(xù)三次,確保初始化成功
- delaynms(5); //延時(shí)5ms ,給硬件一點(diǎn)反應(yīng)時(shí)間
- WriteInstruction(0x0c); //顯示模式設(shè)置:顯示開,無光標(biāo),光標(biāo)不閃爍
- delaynms(5); //延時(shí)5ms ,給硬件一點(diǎn)反應(yīng)時(shí)間
- WriteInstruction(0x06); //顯示模式設(shè)置:光標(biāo)右移,字符不移
- delaynms(5); //延時(shí)5ms ,給硬件一點(diǎn)反應(yīng)時(shí)間
- WriteInstruction(0x01); //清屏幕指令,將以前的顯示內(nèi)容清除
- delaynms(5); //延時(shí)5ms ,給硬件一點(diǎn)反應(yīng)時(shí)間
- }
- /*****************************************************
- 函數(shù)功能:顯示電壓符號(hào)
- ***************************************************/
- void display_volt(void)
- {
- unsigned char i;
- WriteAddress(0x03); //寫顯示地址,將在第2行第1列開始顯示
- i = 0; //從第一個(gè)字符開始顯示
- while(Str[i] != '\0') //只要沒有寫到結(jié)束標(biāo)志,就繼續(xù)寫
- {
- WriteData(Str[i]); //將字符常量寫入LCD
- i++; //指向下一個(gè)字符
- }
- }
- /*****************************************************
- 函數(shù)功能:顯示電壓的小數(shù)點(diǎn)
- ***************************************************/
- void display_dot(void)
- {
- WriteAddress(0x09); //寫顯示地址,將在第1行第10列開始顯示
- WriteData('.'); //將小數(shù)點(diǎn)的字符常量寫入LCD
- }
- /*****************************************************
- 函數(shù)功能:顯示電壓的單位(V)
- ***************************************************/
- void display_V(void)
- {
- WriteAddress(0x0c); //寫顯示地址,將在第2行第13列開始顯示
- WriteData('V'); //將字符常量寫入LCD
-
- }
- /*****************************************************
- 函數(shù)功能:顯示電壓的整數(shù)部分
- 入口參數(shù):x
- ***************************************************/
- void display1(unsigned char x)
- {
- WriteAddress(0x08); //寫顯示地址,將在第2行第7列開始顯示
- WriteData(digit[x]); //將百位數(shù)字的字符常量寫入LCD
- }
- /*****************************************************
- 函數(shù)功能:顯示電壓的小數(shù)數(shù)部分
- 入口參數(shù):x
- ***************************************************/
- void display2(unsigned char x)
- {
- unsigned char i,j;
- i=x/10; //取十位(小數(shù)點(diǎn)后第一位)
- j=x%10; //取個(gè)位(小數(shù)點(diǎn)后第二位)
- WriteAddress(0x0a); //寫顯示地址,將在第1行第11列開始顯示
- WriteData(digit[i]); //將小數(shù)部分的第一位數(shù)字字符常量寫入LCD
- WriteData(digit[j]); //將小數(shù)部分的第一位數(shù)字字符常量寫入LCD
- }
- /*****************************************************
- 函數(shù)功能:將模擬信號(hào)轉(zhuǎn)換成數(shù)字信號(hào)
- ***************************************************/
- unsigned char A_D()
- {
- unsigned char i,dat;
- CS=1; //一個(gè)轉(zhuǎn)換周期開始
- CLK=0; //為第一個(gè)脈沖作準(zhǔn)備
- CS=0; //CS置0,片選有效
- DIO=1; //DIO置1,規(guī)定的起始信號(hào)
- CLK=1; //第一個(gè)脈沖
- CLK=0; //第一個(gè)脈沖的下降沿,此前DIO必須是高電平
- DIO=1; //DIO置1, 通道選擇信號(hào)
- CLK=1; //第二個(gè)脈沖,第2、3個(gè)脈沖下沉之前,DI必須跟別輸入兩位數(shù)據(jù)用于選擇通道,這里選通道CH0
- CLK=0; //第二個(gè)脈沖下降沿
-
- DIO=0; //DI置0,選擇通道0
- CLK=1; //第三個(gè)脈沖
- CLK=0; //第三個(gè)脈沖下降沿
- DIO=1; //第三個(gè)脈沖下沉之后,輸入端DIO失去作用,應(yīng)置1
- CLK=1; //第四個(gè)脈沖
- for(i=0;i<8;i++) //高位在前
- {
- CLK=1; //第四個(gè)脈沖
- CLK=0;
- dat<<=1; //將下面儲(chǔ)存的低位數(shù)據(jù)向右移
- dat|=(unsigned char)DIO; //將輸出數(shù)據(jù)DIO通過或運(yùn)算儲(chǔ)存在dat最低位
- }
- CS=1; //片選無效
- return dat; //將讀書的數(shù)據(jù)返回
- }
- /*******************************************************************************
- * 函 數(shù) 名 : keypros
- * 函數(shù)功能 : 按鍵處理函數(shù),判斷按鍵K1是否按下
- *******************************************************************************/
- void keypros()
- {
- }
- //keypros(); //按鍵處理函數(shù)
- /*******************************************************************************
- * 函 數(shù) 名 : Timer1Init
- * 函數(shù)功能 : 定時(shí)器1初始化
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- void Timer1Init()
- {
- TMOD|=0X10;//選擇為定時(shí)器1模式,工作方式1,僅用TR1打開啟動(dòng)。
- TH1 = 0xFF;
- TL1 = 0xff; //1us
-
- ET1=1;//打開定時(shí)器1中斷允許
- EA=1;//打開總中斷
- TR1=1;//打開定時(shí)器
- }
- /*******************************************************************************
- * 函數(shù)名 : main
- * 函數(shù)功能 : 主函數(shù)
- * 輸入 : 無
- * 輸出 : 無
- *******************************************************************************/
- void main()
- { u16 value=0 ,a=0,b=0 ;
- unsigned int AD_val; //儲(chǔ)存A/D轉(zhuǎn)換后的值
- unsigned char Int,Dec; //分別儲(chǔ)存轉(zhuǎn)換后的整數(shù)部分與小數(shù)部分
- LcdInitiate(); //將液晶初始化
- delaynms(5); //延時(shí)5ms給硬件一點(diǎn)反應(yīng)時(shí)間
- display_volt(); //顯示溫度說明
- display_dot(); //顯示溫度的小數(shù)點(diǎn)
- display_V(); //顯示溫度的單位
- Timer1Init(); //定時(shí)器1初始化
- LcdInit(); //初始化LCD1602
- LcdWriteCom(0x88); //寫地址 80表示初始地址
-
- led=0;
- while(1)
- {
-
- AD_val= A_D(); //進(jìn)行A/D轉(zhuǎn)換
- Int=(AD_val)/51; //計(jì)算整數(shù)部分
- if(Int>4){led=1;
- LcdWriteCom(0xc2); //寫地址 80表示初始地址
- LcdWriteData(' '); //顯示小數(shù)點(diǎn)
- LcdWriteCom(0xc3); //寫地址 80表示初始地址
- LcdWriteData('E'); //顯示小數(shù)點(diǎn)
-
- LcdWriteCom(0xc4); //寫地址 80表示初始地址
- LcdWriteData('R'); //顯示小數(shù)點(diǎn)
- LcdWriteCom(0xc5); //寫地址 80表示初始地址
- LcdWriteData('R'); //顯示小數(shù)點(diǎn)
- LcdWriteCom(0xc6); //寫地址 80表示初始地址
- LcdWriteData('O');; //顯示小數(shù)點(diǎn)
-
- LcdWriteCom(0xc7); //寫地址 80表示初始地址
- LcdWriteData('R');; //顯示小數(shù)點(diǎn)
-
- LcdWriteCom(0xc8); //寫地址 80表示初始地址
- LcdWriteData('!');; //顯示小數(shù)點(diǎn)
-
- } //超過4報(bào)警
- else{
-
-
- led=0;
- LcdWriteCom(0xc2); //寫地址 80表示初始地址
- LcdWriteData('N'); //顯示小數(shù)點(diǎn)
- SBUF = ' ';//將接收到的數(shù)據(jù)放入到發(fā)送寄存器
- while (!TI); //等待發(fā)送數(shù)據(jù)完成
- TI = 0;
- LcdWriteCom(0xc3); //寫地址 80表示初始地址
- LcdWriteData('O'); //顯示小數(shù)點(diǎn)
-
- TI = 0;
- LcdWriteCom(0xc4); //寫地址 80表示初始地址
- LcdWriteData('R'); //顯示小數(shù)點(diǎn)
-
- TI = 0;
- LcdWriteCom(0xc5); //寫地址 80表示初始地址
- LcdWriteData('M'); //顯示小數(shù)點(diǎn)
-
- TI = 0;
- LcdWriteCom(0xc6); //寫地址 80表示初始地址
- LcdWriteData('A');; //顯示小數(shù)點(diǎn)
- TI = 0;
- LcdWriteCom(0xc7); //寫地址 80表示初始地址
- LcdWriteData('L');; //顯示小數(shù)點(diǎn)
- TI = 0;
- LcdWriteCom(0xc8); //寫地址 80表示初始地址
- LcdWriteData('!');; //顯示小數(shù)點(diǎn)
-
- TI = 0;
- }
-
- Dec=(AD_val%51)*100/51; //計(jì)算小數(shù)部分
- WriteAddress(0x08); //寫顯示地址,將在第2行第7列開始顯示
- display1(Int); //將百位數(shù)字的字符常量寫入LCD
- display2(Dec); //顯示小數(shù)部分
- display_dot(); //顯示溫度的小數(shù)點(diǎn)
- display_V(); //顯示溫度的單位
-
-
-
- }
- }
- /*******************************************************************************
- * 函 數(shù) 名 : Time1
- * 函數(shù)功能 : 定時(shí)器1的中斷函數(shù)
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- void Time1(void) interrupt 3 //3 為定時(shí)器1的中斷號(hào) 1 定時(shí)器0的中斷號(hào) 0 外部中斷1 2 外部中斷2 4 串口中斷
- {
- TH1 = 0xFF;
- TL1 = 0xff; //1us
- timer1++;
-
- }
- /*******************************************************************************
- * 函 數(shù) 名 :UsartConfiguration()
- * 函數(shù)功能 :設(shè)置串口
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- void UsartConfiguration()
- {
- SCON=0X50; //設(shè)置為工作方式1
- TMOD=0X20; //設(shè)置計(jì)數(shù)器工作方式2
- PCON=0X80; //波特率加倍
- TH1=0XF3; //計(jì)數(shù)器初始值設(shè)置,注意波特率是4800的
- TL1=0XF3;
- // ES=1; //打開接收中斷
- // EA=1; //打開總中斷
- TR1=1; //打開計(jì)數(shù)器
- }
復(fù)制代碼
所有資料51hei提供下載:
F流量計(jì)空氣.zip
(143.97 KB, 下載次數(shù): 20)
2019-12-19 16:05 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
(管理提醒:程序測(cè)試不成功 請(qǐng)謹(jǐn)慎下載)
|
|