QQ截圖20190531154519.png (55.59 KB, 下載次數(shù): 35)
下載附件
2019-5-31 15:45 上傳
QQ圖片20190531155944.jpg (1.07 MB, 下載次數(shù): 40)
下載附件
2019-5-31 16:00 上傳
程序在下面,仿真可以通過。就是接硬件的時候,不論輸入電壓怎么變,LCD一直顯示2.5v。 單片機(jī)源程序如下:
- #include <reg52.h>
- #include <intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- #define WRITEADDR 0x90 //寫地址
- #define READADDR 0x91 //讀地址
- #define somenop() _nop_(),_nop_(),_nop_(),_nop_(),_nop_(),_nop_()
- sbit SCL=P2^1;
- sbit SDA=P2^0;
- sbit RS=P2^2;
- sbit RW=P2^3;
- sbit E=P2^4;
- sbit V= P2^6;
- uchar dat[6];
- void delay_ms(uint xms)
- {
- uint i,j;
- for(i=xms;i>0;i--)
- for(j=110;j>0;j--) ;
- }
- void I2C_Start() //起始
- {
- SDA=1;
- somenop();
- SCL=1;
- somenop();
- SDA=0;
- somenop();
- }
- void I2C_Stop() //終止
- {
- SDA=0;
- somenop();
- SCL=1;
- somenop();
- SDA=1;
- somenop();
- }
- void I2C_SendByte(uchar dat, uchar ack) //發(fā)送一個字節(jié)
- {
- uchar i,j,b=0;
- for(i=0;i<8;i++)
- {
- SCL=0;
- somenop();
- SDA=(bit)(dat&0x80); //每次取最高位進(jìn)行發(fā)送
- dat<<=1;
- SCL=1; //上升沿時發(fā)送數(shù)據(jù)
- somenop();
- }
- SCL=0;
- somenop();
- SDA=1;
- somenop();
- SCL=1;
- _nop_();
- while((SDA==1)&&(j<250)) j++; //等待應(yīng)答
- SCL=0;
- _nop_();
- }
- uchar I2C_ReadByte() //讀一個字節(jié)
- {
- uchar i,dat=0;
- SCL=0; //此處也可以不置低
- somenop();
- SDA=1; //拉高準(zhǔn)備數(shù)據(jù)讀取
- _nop_();
- for(i=0;i<8;i++) //讀取8位數(shù)據(jù)
- {
- SCL=1;
- somenop();
- dat<<=1;
- if(SDA==1)
- dat=dat|0x01;
- somenop();
- SCL=0; //下降沿時讀取數(shù)據(jù)
- somenop();
- }
- return dat;
- }
- uchar Lcd1602_ReadBusy() //判斷忙的狀態(tài)
- {
- uchar temp;
- RS=0;
- RW=1;
- _nop_();
- P0=0xff; //讀某IO口數(shù)據(jù)前,先將該口置為1
- _nop_();
- E=1;
- _nop_();
- temp=P0; //讀取此時lcd1602的狀態(tài)字
- _nop_();
- E=0;
- return (temp&0x80); //如果忙
- /*temp&0x80得1表示忙,得0表示不忙*/
- }
- void Lcd1602_WriteCom(uchar com) //寫命令
- {
- while(Lcd1602_ReadBusy()); //判忙
- RS=0; //命令
- RW=0; //寫
- _nop_();
- P0=com; //準(zhǔn)備發(fā)送命令
- _nop_();
- E=1; //時序圖
- _nop_();
- _nop_();
- E=0; //時序圖
- _nop_();
- _nop_();
- }
- void Lcd1602_WriteData(uchar dat) //寫數(shù)據(jù)
- {
- while(Lcd1602_ReadBusy()); //判忙
- RS=1; //數(shù)據(jù)
- RW=0; //寫
- _nop_();
- P0=dat;
- _nop_();
- E=1;
- _nop_();
- _nop_();
- E=0;
- _nop_();
- _nop_();
- }
- void Lcd1602_init() //初始化函數(shù)
- {
- delay_ms(15);
- Lcd1602_WriteCom(0x38); //顯示模式設(shè)置
- delay_ms(5);
- Lcd1602_WriteCom(0x38);
- delay_ms(5);
- Lcd1602_WriteCom(0x38);
- Lcd1602_WriteCom(0x0c); //顯示開
- Lcd1602_WriteCom(0x01); //顯示清屏
- Lcd1602_WriteCom(0x06); //顯示光標(biāo)
- Lcd1602_WriteData('P');
- }
- void Pcf8591SendByte(uchar channel)
- {
- I2C_Start();
- I2C_SendByte(WRITEADDR); //發(fā)送寫器件地址
- I2C_SendByte(0x40|channel); //發(fā)送控制寄存器
- I2C_Stop();
- }
- uchar Pcf8591ReadByte()
- {
- uchar num;
- I2C_Start();
- I2C_SendByte(READADDR); //發(fā)送讀器件地址
- num=I2C_ReadByte(); //讀取數(shù)據(jù)
- I2C_Stop(); //結(jié)束總線
- return num;
- }
- void main()
- {
- uint adNum,i;
- float value;
- Lcd1602_init();
- while(1)
- {
- if(V==1)
- {
- Pcf8591SendByte(0); //使用通道0
- /*adNum一定是0到255之間的一個數(shù),因?yàn)閜cf8591是8位的AD/DA芯片,所以輸出的范圍為00000000到11111111,即0到255*/
- adNum=Pcf8591ReadByte(); //讀出數(shù)值
- /*將adNum轉(zhuǎn)換成電壓值,單片機(jī)的電壓為5V,則電位器的電壓為0到5V,用0到255表示0到5V,則每一個1代表5/255V,即0.01953V*/
- value=adNum*0.01953; //轉(zhuǎn)為電壓值
- adNum=value*100; //保留兩位小數(shù),以便顯示出來
- dat[0]=adNum/1000+'0'; //加上'0'是表示數(shù)字轉(zhuǎn)換成字符,1602只能顯示字符
- dat[1]=adNum%1000/100+'0';
- dat[2]='.';
- dat[3]=adNum%100/10+'0';
- dat[4]=adNum%10+'0';
- dat[5]='v';
- Lcd1602_WriteCom(0x80);
- for(i=0;i<6;i++)
- {
- Lcd1602_WriteData(dat[i]);
- }
- }
- }
- }
復(fù)制代碼 全部資料51hei下載地址:
電壓表.zip
(156.24 KB, 下載次數(shù): 33)
2019-5-31 15:56 上傳
點(diǎn)擊文件名下載附件
|