題目:多路數據采集顯示器設計
用的芯片是:STC90C516RD+,PCF8591
一、基本要求:
1、用DA轉換器輸出一正弦信號,頻率150Hz
2、用AD轉換器周期測量此正弦信號的頻率,在數碼管或LCD上將頻率值顯示出來,精確到0.1Hz
3、同時用IO口輸出一500Hz的方波信號,用另一IO測量,顯示信號參數,
4、設置一功能鍵,切換兩種信號的顯示參數
5、通過鍵盤,可修改方波的頻率。每按一次鍵,頻率步進或后退一定值,頻率范圍100Hz~1500Hz
二、發揮部分:
1、通過鍵盤,可修改正弦波的頻率。每按一次鍵,頻率步進或后退一定值,頻率范圍10Hz~1000Hz
2、顯示器能同步反應參數的變化
3、按鍵時,蜂鳴器發出提示音,表示按鍵有效
顯示格式:
使用LCD1602,參數必須能顯示,并通過按鍵更改顯示不同參數內容
三、protuse仿真運行圖(方波和正玄波)
仿真圖2.png (86.05 KB, 下載次數: 83)
下載附件
2019-9-6 00:45 上傳
仿真圖.png (86.31 KB, 下載次數: 62)
下載附件
2019-9-6 00:45 上傳
四、源代碼見附件
單片機源程序如下:
- /*-----------------------------------------------
- 名稱:LCD1602
- 編寫:shifang
- 日期:2019-9-3
- 修改:無
- 內容:通過標準程序動態顯示字符
- 引腳定義如下:1-VSS 2-VDD 3-V0 4-RS 5-R/W 6-E 7-14 DB0-DB7 15-BLA 16-BLK
- ------------------------------------------------*/
- #include<reg52.h> //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
- #include<intrins.h>
- #define _Nop() _nop_() //定義空指令
- bit ack; //應答標志位
- bit flag_dis=0;
- sbit SDA=P2^1;
- sbit SCL=P2^0;
- #define AddWr 0x90 //寫數據地址
- #define AddRd 0x91 //讀數據地址
- unsigned char ReadADC(unsigned char Chl);
- bit WriteDAC(unsigned char dat);
- //--定義全局變量--//
- unsigned char code table[] ={"Welcome use: 000 "};
- unsigned char code table1[]={"SIN:0000.0Hz FAG "};
- unsigned int dis,deg; //{"D:0 Voltage:0.00"};
- sbit RS = P2^4; //定義端口
- sbit RW = P2^5;
- sbit EN = P2^6;
- sbit out = P2^7;
- sbit k1 = P3^5;
- sbit k2 = P3^6;
- sbit k3 = P3^7;
- sbit out2 =P1^7;
- sbit buz = P1^2;
- unsigned int fh=150,fh2=100; //初始頻率為150Hz
- unsigned int t_10us=0,pinlv,t100us,t100us2;
- #define RS_CLR RS=0
- #define RS_SET RS=1
- #define RW_CLR RW=0
- #define RW_SET RW=1
- #define EN_CLR EN=0
- #define EN_SET EN=1
- #define DataPort P0
- unsigned char code table2[256] ={
- 0x80, 0x83, 0x86, 0x89, 0x8c, 0x8f, 0x92, 0x95, 0x98, 0x9c, 0x9f,
- 0xa2, 0xa5, 0xa8, 0xab, 0xae, 0xb0, 0xb3, 0xb6, 0xb9, 0xbc, 0xbf,
- 0xc1, 0xc4, 0xc7, 0xc9, 0xcc, 0xce, 0xd1, 0xd3, 0xd5, 0xd8, 0xda,
- 0xdc, 0xde, 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xed, 0xef,
- 0xf0, 0xf2, 0xf3, 0xf4, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc,
- 0xfc, 0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfd, 0xfc, 0xfc, 0xfb, 0xfa,
- 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf3, 0xf2, 0xf0, 0xef, 0xed, 0xec,
- 0xea, 0xe8, 0xe6, 0xe4, 0xe3, 0xe1, 0xde, 0xdc, 0xda, 0xd8, 0xd6,
- 0xd3, 0xd1, 0xce, 0xcc, 0xc9, 0xc7, 0xc4, 0xc1, 0xbf, 0xbc, 0xb9,
- 0xb6, 0xb4, 0xb1, 0xae, 0xab, 0xa8, 0xa5, 0xa2, 0x9f, 0x9c, 0x99,
- 0x96, 0x92, 0x8f, 0x8c, 0x89, 0x86, 0x83, 0x80, 0x7d, 0x79, 0x76,
- 0x73, 0x70, 0x6d, 0x6a, 0x67, 0x64, 0x61, 0x5e, 0x5b, 0x58, 0x55,
- 0x52, 0x4f, 0x4c, 0x49, 0x46, 0x43, 0x41, 0x3e, 0x3b, 0x39, 0x36,
- 0x33, 0x31, 0x2e, 0x2c, 0x2a, 0x27, 0x25, 0x23, 0x21, 0x1f, 0x1d,
- 0x1b, 0x19, 0x17, 0x15, 0x14, 0x12, 0x10, 0x0f, 0x0d, 0x0c, 0x0b,
- 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x01, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
- 0x0a, 0x0c, 0x0d, 0x0e, 0x10, 0x12, 0x13, 0x15, 0x17, 0x18, 0x1a,
- 0x1c, 0x1e, 0x20, 0x23, 0x25, 0x27, 0x29, 0x2c, 0x2e, 0x30, 0x33,
- 0x35, 0x38, 0x3b, 0x3d, 0x40, 0x43, 0x46, 0x48, 0x4b, 0x4e, 0x51,
- 0x54, 0x57, 0x5a, 0x5d, 0x60, 0x63, 0x66, 0x69, 0x6c, 0x6f, 0x73,
- 0x76, 0x79, 0x7c,
- };
- /*------------------------------------------------
- uS延時函數,含有輸入參數 unsigned char t,無返回值
- unsigned char 是定義無符號字符變量,其值的范圍是
- 0~255 這里使用晶振12M,精確延時請使用匯編,大致延時
- 長度如下 T=tx2+5 uS
- ------------------------------------------------*/
- void DelayUs2x(unsigned int t)
- {
- while(--t);
- }
- /*------------------------------------------------
- mS延時函數,含有輸入參數 unsigned char t,無返回值
- unsigned char 是定義無符號字符變量,其值的范圍是
- 0~255 這里使用晶振12M,精確延時請使用匯編
- ------------------------------------------------*/
- void DelayMs(unsigned int t)
- {
-
- while(t--)
- {
- //大致延時1mS
- DelayUs2x(245);
- DelayUs2x(245);
- }
- }
- /*------------------------------------------------
- 啟動總線
- ------------------------------------------------*/
- void Start_I2c()
- {
- SDA=1; //發送起始條件的數據信號
- _Nop();
- SCL=1;
- _Nop(); //起始條件建立時間大于4.7us,延時
- _Nop();
- _Nop();
- _Nop();
- SDA=0; //發送起始信號
- _Nop(); //起始條件鎖定時間大于4μ
- _Nop();
- _Nop();
- _Nop();
- SCL=0; //鉗住I2C總線,準備發送或接收數據
- _Nop();
- _Nop();
- }
- /*------------------------------------------------
- 結束總線
- ------------------------------------------------*/
- void Stop_I2c()
- {
- SDA=0; //發送結束條件的數據信號
- _Nop(); //發送結束條件的時鐘信號
- SCL=1; //結束條件建立時間大于4μ
- /* _Nop();
- _Nop();
- _Nop();
- _Nop();*/
- DelayUs2x(1);
- SDA=1; //發送I2C總線結束信號
- /* _Nop();
- _Nop();
- _Nop();*/
- }
- /*----------------------------------------------------------------
- 字節數據傳送函數
- 函數原型: void SendByte(unsigned char c);
- 功能: 將數據c發送出去,可以是地址,也可以是數據,發完后等待應答,并對
- 此狀態位進行操作.(不應答或非應答都使ack=0 假)
- 發送數據正常,ack=1; ack=0表示被控器無應答或損壞。
- ------------------------------------------------------------------*/
- void SendByte(unsigned char c)
- {
- unsigned char BitCnt;
-
- for(BitCnt=0;BitCnt<8;BitCnt++) //要傳送的數據長度為8位
- {
- if((c<<BitCnt)&0x80)SDA=1; //判斷發送位
- else SDA=0;
- _Nop();
- SCL=1; //置時鐘線為高,通知被控器開始接收數據位
- DelayUs2x(2);
- /* _Nop(); //保證時鐘高電平周期大于4μ
- _Nop();
- _Nop();
- _Nop(); */
- SCL=0;
- }
-
- // _Nop();
- _Nop();
- SDA=1; //8位發送完后釋放數據線,準備接收應答位
- // _Nop();
- _Nop();
- SCL=1;
- DelayUs2x(1);
- /* _Nop();
- _Nop();
- _Nop();
- if(SDA==1)ack=0;
- else ack=1; */ //判斷是否接收到應答信號
- SCL=0;
- // _Nop();
- }
- /*----------------------------------------------------------------
- 字節數據傳送函數
- 函數原型: unsigned char RcvByte();
- 功能: 用來接收從器件傳來的數據,并判斷總線錯誤(不發應答信號),
- 發完后請用應答函數。
- ------------------------------------------------------------------*/
- unsigned char RcvByte()
- {
- unsigned char retc;
- unsigned char BitCnt;
-
- retc=0;
- SDA=1; //置數據線為輸入方式
- for(BitCnt=0;BitCnt<8;BitCnt++)
- {
- _Nop();
- SCL=0; //置時鐘線為低,準備接收數據位
- DelayUs2x(2);
- /* _Nop();
- _Nop(); //時鐘低電平周期大于4.7us
- _Nop();
- _Nop();
- _Nop();*/
- SCL=1; //置時鐘線為高使數據線上數據有效
- // _Nop();
- // _Nop();
- retc=retc<<1;
- if(SDA==1)retc=retc+1; //讀數據位,接收的數據位放入retc中
- // _Nop();
- // _Nop();
- }
- SCL=0;
- return(retc);
- }
- /*----------------------------------------------------------------
- 非應答子函數
- 原型: void NoAck_I2c(void);
-
- ----------------------------------------------------------------*/
- void NoAck_I2c(void)
- {
-
- SDA=1;
- DelayUs2x(1);
- /* _Nop();
- _Nop();
- _Nop(); */
- SCL=1;
- /*_Nop();
- _Nop(); //時鐘低電平周期大于4μ
- _Nop();
- _Nop(); */
- DelayUs2x(1);
- SCL=0; //清時鐘線,鉗住I2C總線以便繼續接收
- // _Nop();
- //_Nop();
- }
- /*------------------------------------------------
- 寫入命令函數
- ------------------------------------------------*/
- void LCD_Write_Com(unsigned char com)
- {
- // while(LCD_Check_Busy()); //忙則等待
- DelayMs(5);
- RS_CLR;
- RW_CLR;
- EN_SET;
- DataPort= com;
- _nop_();
- EN_CLR;
- }
- /*------------------------------------------------
- 寫入數據函數
- ------------------------------------------------*/
- void LCD_Write_Data(unsigned char Data)
- {
- //while(LCD_Check_Busy()); //忙則等待
- DelayMs(5);
- RS_SET;
- RW_CLR;
- EN_SET;
- DataPort= Data;
- _nop_();
- EN_CLR;
- }
- /*------------------------------------------------
- 清屏函數
- ------------------------------------------------*/
- void LCD_Clear(void)
- {
- LCD_Write_Com(0x01);
- DelayMs(5);
- }
- /*------------------------------------------------
- 初始化函數
- ------------------------------------------------*/
- void LCD_Init(void)
- {
- // LCD_Write_Com(0x38); /*顯示模式設置*/
- // DelayMs(5);
- // LCD_Write_Com(0x38);
- // DelayMs(5);
- LCD_Write_Com(0x38);
- DelayMs(5);
- LCD_Write_Com(0x38);
- LCD_Write_Com(0x08); /*顯示關閉*/
- LCD_Write_Com(0x01); /*顯示清屏*/
- LCD_Write_Com(0x06); /*顯示光標移動設置*/
- DelayMs(5);
- LCD_Write_Com(0x0C); /*顯示開及光標設置*/
- }
- /*------------------------------------------------
- 讀AD轉值程序
- 輸入參數 Chl 表示需要轉換的通道,范圍從0-3
- 返回值范圍0-255
- ------------------------------------------------*/
- /*unsigned char ReadADC(unsigned char Chl)
- {
- unsigned char Val;
- Start_I2c(); //啟動總線
- SendByte(AddWr); //發送器件地址
- if(ack==0)return(0);
- SendByte(0x40|Chl); //發送器件子地址
- if(ack==0)return(0);
- Start_I2c();
- SendByte(AddWr+1);
- if(ack==0)return(0);
- Val=RcvByte();
- NoAck_I2c(); //發送非應位
- Stop_I2c(); //結束總線
- t_10us=100;
- return(Val);
- }*/
- /*------------------------------------------------
- 寫入DA轉換數值
- 輸入參數:dat 表示需要轉換的DA數值,范圍是0-255
- ------------------------------------------------*/
- /*bit WriteDAC(unsigned char dat)
- {
- Start_I2c(); //啟動總線
- SendByte(AddWr); //發送器件地址
- if(ack==0)return(0);
- SendByte(0x40); //發送器件子地址
- if(ack==0)return(0);
- SendByte(dat); //發送數據
- if(ack==0)return(0);
- Stop_I2c();
- }*/
- bit WriteDAC2()
- {
- unsigned int numm;
- Start_I2c(); //啟動總線
- SendByte(AddWr); //發送器件地址
- // if(ack==0)return(0);
- SendByte(0x40); //發送器件子地址
- // if(ack==0)return(0);
-
- for(numm=0;numm<256;numm++)
- {
- SendByte(table2[numm]); //發送數據
- DelayUs2x((unsigned int)(1000/fh*3.9)-4); //150-1000Hz
- }
-
- // if(ack==0)return(0);
- // Stop_I2c();
- }
- /*void InitTimer0(void)
- {
- TMOD = 0x01;
- TH0 = 0x0FF;
- TL0 = 0x0F6;
- EA = 1;
- ET0 = 1;
- TR0 = 0;
- }
- void Timer0Interrupt(void) interrupt 1
- {
- TH0 = 0x0FF;
- TL0 = 0x0F6;
- t_10us++;
- if(t_10us>10000)t_10us=0;
- }*/
- void InitTimer1(void)
- {
- TMOD |= 0x10;
- TH1 = 0xFF;
- TL1 = 0xF6;
- EA = 1;
- ET1 = 1;
- TR1 = 0;
- }
- void Timer1Interrupt(void) interrupt 3
- {
- TH1 = 0xFF;
- TL1 = 0xF6;
- t100us++;
- t100us2++;
- if(t100us2<10)out2=0;
- else if(t100us2<20)out2=1;
- else t100us2=0;
-
- // if(t100us>10000)
- // t100us=0;
- if(t100us<(500*5/fh2))out=1;
- else if(t100us<(500*8/fh2))out=0;
- else t100us=0;
- // keyscan();
- }
- void display()
- {
- unsigned int shi,ge,bai,qian,wan;
-
- LCD_Write_Com(0x80+0x40);
- if(flag_dis==1)
- {
- LCD_Write_Data(table1[13]);
- LCD_Write_Data(table1[14]);
- LCD_Write_Data(table1[15]);
- pinlv=fh2;
- }
- if(flag_dis==0)
- {
- LCD_Write_Data(table1[0]);
- LCD_Write_Data(table1[1]);
- LCD_Write_Data(table1[2]);
- pinlv=fh;
- }
- pinlv*=10.0;
- wan=pinlv/10000;
- qian=pinlv%10000/1000;
- bai=pinlv%1000/100;
- // shi=pinlv%100/10;
- // ge=pinlv%10;
-
- LCD_Write_Com(0x8d);
- if(flag_dis==1)
- LCD_Write_Data(0x35);
- else LCD_Write_Data(0x30);
-
- LCD_Write_Com(0x80+0x44);
- LCD_Write_Data(0x30+wan);
- LCD_Write_Data(0x30+qian);
- LCD_Write_Data(0x30+bai);
- // LCD_Write_Data(0x30+shi);
- // LCD_Write_Com(0x80+0x49);
- // LCD_Write_Data(0x30+ge);
- }
- void keyscan()
- {
- TR1 = 0;
- if(k1==0)
- {TR1 = 0;
- DelayMs(10);
- if(k1==0)
- {
- if(flag_dis==0)
- flag_dis=1;
- else flag_dis=0;
- while(!k1){buz=!buz;DelayUs2x(250);}
- }
- display();
- }
- if(k2==0)
- {TR1 = 0;
- DelayMs(10);
- if(k2==0)
- {
- if(flag_dis==0)
- if(fh==10)fh=0;
- if(fh<1000)
- fh+=50;
- if(flag_dis==1)
- if(fh2<1500)
- fh2+=100;
- while(!k2){buz=!buz;DelayUs2x(250);}
- }
- display();
- }
- if(k3==0)
- {TR1 = 0;
- DelayMs(10);
- if(k3==0)
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
0.png (10.94 KB, 下載次數: 76)
下載附件
2019-9-6 16:37 上傳
所有資料51hei提供下載:
仿真程序.7z
(309.04 KB, 下載次數: 90)
2021-11-14 04:40 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|