基于51單片機的PCF8591模數轉換LCD顯示,自帶protues仿真.
0.png (29.34 KB, 下載次數: 70)
下載附件
2017-7-28 22:11 上傳
0.png (36.96 KB, 下載次數: 58)
下載附件
2017-7-28 22:11 上傳
單片機源程序如下:
- /****************************************************************
- 在1602液晶屏上顯示各通道的電壓值
- ******************************************************************/
- #include<reg52.h> //包含單片機寄存器的頭文件
- #include <intrins.h>
- #define AddWr 0x90 //PCF8591 地址
- #define Data P0 //數據端口
- // 變量定義
- unsigned char AD_CHANNEL;
- sbit scl=P2^6; //I2C 時鐘
- sbit sda=P2^7; //I2C 數據
- bit ack; /*應答標志位*/
- sbit RS = P2^0;//Pin4
- sbit RW = P2^1; //Pin5
- sbit E = P2^2;//Pin6
- unsigned char TempData[8];
- unsigned char FirstLine[16]="Voltage: ";
- unsigned char SecondLine[16] ="Current: ";
- /*******************************************************************
- 起動總線函數
- 函數原型: void Start_I2c();
- 功能: 啟動I2C總線,即發送I2C起始條件.
- ********************************************************************/
- void Start_I2c()
- {
- sda=1; /*發送起始條件的數據信號*/
- _nop_();
- scl=1;
- _nop_(); /*起始條件建立時間大于4.7us,延時*/
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- sda=0; /*發送起始信號*/
- _nop_(); /* 起始條件鎖定時間大于4μs*/
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- scl=0; /*鉗住I2C總線,準備發送或接收數據 */
- _nop_();
- _nop_();
- }
- /*******************************************************************
- 結束總線函數
- 函數原型: void Stop_I2c();
- 功能: 結束I2C總線,即發送I2C結束條件.
- ********************************************************************/
- void Stop_I2c()
- {
- sda=0; /*發送結束條件的數據信號*/
- _nop_(); /*發送結束條件的時鐘信號*/
- scl=1; /*結束條件建立時間大于4μs*/
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- sda=1; /*發送I2C總線結束信號*/
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- /*******************************************************************
- 字節數據發送函數
- 函數原型: void I2C_SendByte(UCHAR c);
- 功能: 將數據c發送出去,可以是地址,也可以是數據,發完后等待應答,并對
- 此狀態位進行操作.(不應答或非應答都使ack=0)
- 發送數據正常,ack=1; ack=0表示被控器無應答或損壞。
- ********************************************************************/
- void I2C_SendByte(unsigned char c)
- {
- unsigned char i;
-
- for(i=0;i<8;i++) /*要傳送的數據長度為8位*/
- {
- if((c<<i)&0x80)sda=1; /*判斷發送位*/
- else sda=0;
- _nop_();
- scl=1; /*置時鐘線為高,通知被控器開始接收數據位*/
- _nop_();
- _nop_(); /*保證時鐘高電平周期大于4μs*/
- _nop_();
- _nop_();
- _nop_();
- scl=0;
- }
-
- _nop_();
- _nop_();
- sda=1; /*8位發送完后釋放數據線,準備接收應答位*/
- _nop_();
- _nop_();
- scl=1;
- _nop_();
- _nop_();
- _nop_();
- if(sda==1)ack=0;
- else ack=1; /*判斷是否接收到應答信號*/
- scl=0;
- _nop_();
- _nop_();
- }
- /*******************************************************************
- 字節數據接收函數
- 函數原型: UCHAR I2C_RcvByte();
- 功能: 用來接收從器件傳來的數據,并判斷總線錯誤(不發應答信號),
- 發完后請用應答函數應答從機。
- ********************************************************************/
- unsigned char I2C_RcvByte()
- {
- unsigned char retc=0,i;
- sda=1; /*置數據線為輸入方式*/
- for(i=0;i<8;i++)
- {
- _nop_();
- scl=0; /*置時鐘線為低,準備接收數據位*/
- _nop_();
- _nop_(); /*時鐘低電平周期大于4.7μs*/
- _nop_();
- _nop_();
- _nop_();
- scl=1; /*置時鐘線為高使數據線上數據有效*/
- _nop_();
- _nop_();
- retc=retc<<1;
- if(sda==1)retc=retc+1; /*讀數據位,接收的數據位放入retc中 */
- _nop_();
- _nop_();
- }
- scl=0;
- _nop_();
- _nop_();
- return(retc);
- }
- /********************************************************************
- 應答子函數
- 函數原型: void Ack_I2c(bit a);
- 功能: 主控器進行應答信號(可以是應答或非應答信號,由位參數a決定)
- ********************************************************************/
- void Ack_I2c(bit a)
- {
- if(a==0)
- {
- sda=0;
- _nop_();
- _nop_();
- _nop_();
- scl=1;
- _nop_();
- _nop_(); /*時鐘低電平周期大于4μs*/
- _nop_();
- _nop_();
- _nop_();
- scl=0; /*清時鐘線,住I2C總線以便繼續接收*/
- _nop_();
- _nop_();
- sda=1;
- _nop_();
- _nop_();
- } /*在此發出應答或非應答信號 */
- else
- { sda=1; /*0為發出應答,1為非應答信號 */
- _nop_();
- _nop_();
- _nop_();
- scl=1;
- _nop_();
- _nop_(); /*時鐘低電平周期大于4μs*/
- _nop_();
- _nop_();
- _nop_();
- scl=0; /*清時鐘線,住I2C總線以便繼續接收*/
- _nop_();
- _nop_();
- sda=0;
- _nop_();
- _nop_();
- }
- }
- /************************************************************
- * 函數名 : Pcf8591_SendByte
- * 函數功能 : 寫入一個控制命令
- * 輸入 : addr(器件地址),channel(轉換通道)
- * 輸出 : 無
- ************************************************************/
- bit PCF8591_SendByte(unsigned char addr,unsigned char channel)
- {
- Start_I2c(); //啟動總線
- I2C_SendByte(addr); //發送器件地址
- if(ack==0)return(0);
- I2C_SendByte(0x40|channel); //發送控制字節
- if(ack==0)return(0);
- Stop_I2c(); //結束總線
- return(1);
- }
- /************************************************************
- * 函數名 : PCF8591_RcvByte
- * 函數功能 : 讀取一個轉換值
- * 輸入 :
- * 輸出 : dat
- ************************************************************/
- unsigned char PCF8591_RcvByte(unsigned char addr)
- {
- unsigned char dat;
- Start_I2c(); //啟動總線
- I2C_SendByte(addr+1); //發送器件地址
- if(ack==0)return(0);
- dat=I2C_RcvByte(); //讀取數據0
- Ack_I2c(1); //發送非應答信號
- Stop_I2c(); //結束總線
- return(dat);
- }
- /******************************************************************/
- /* 1602液晶屏相關函數 */
- /******************************************************************/
- void DelayUs(unsigned char us)//delay us
- {
- unsigned char uscnt;
- uscnt=us>>1;/* Crystal frequency in 12MHz*/
- while(--uscnt);
- }
- /******************************************************************/
- void DelayMs(unsigned char ms)//delay Ms
- {
- while(--ms)
- {
- DelayUs(250);
- DelayUs(250);
- DelayUs(250);
- DelayUs(250);
- }
- }
- void WriteCommand(unsigned char c)
- {
- DelayMs(5);//short delay before operation
- E=0;
- RS=0;
- RW=0;
- _nop_();
- E=1;
- Data=c;
- E=0;
- }
- /****************************************************************/
- void WriteData(unsigned char c)
- {
- DelayMs(5); //short delay before operation
- E=0;
- RS=1;
- RW=0;
- _nop_();
- E=1;
- Data=c;
- E=0;
- RS=0;
- }
- /*********************************************************************/
- void ShowChar(unsigned char pos,unsigned char c)
- {
- unsigned char p;
- if (pos>=0x10)
- p=pos+0xb0; //是第二行則命令代碼高4位為0xc
- else
- p=pos+0x80; //是第二行則命令代碼高4位為0x8
- WriteCommand (p);//write command
- WriteData (c); //write data
- }
- /*************************************************************************/
- void ShowString (unsigned char line,char *ptr)
- {
- unsigned char l,i;
- l=line<<4;
- for (i=0;i<16;i++)
- ShowChar (l++,*(ptr+i));//循環顯示16個字符
- }
- /*********************************************************************/
- void InitLcd()
- {
- DelayMs(15);
- WriteCommand(0x38); //display mode
- WriteCommand(0x38); //display mode
- WriteCommand(0x38); //display mode
- WriteCommand(0x06); //顯示光標移動位置
- WriteCommand(0x0c); //顯示開及光標設置
- WriteCommand(0x01); //顯示清屏
- }
- /////////////////////////////////////////////////////////////////
- void disp(void)
- {
- unsigned char i=0;
- while(FirstLine[i]!=' ')
- {
- ShowString(0,FirstLine);
- i++;
- }
-
- FirstLine[8]= '0'+TempData[0];
- FirstLine[9]= '0'+TempData[1];
- FirstLine[10]='.';
- FirstLine[11]='0'+TempData[2];
- FirstLine[12]='0'+TempData[3];
- FirstLine[14]='V';
- ShowString(0,FirstLine);
- while(SecondLine[i]!=' ')
- {
- ShowString(1,SecondLine);
- i++;
- }
- SecondLine[8]='0'+TempData[4];
- SecondLine[11]='0'+TempData[6];
- SecondLine[10]='.';
- SecondLine[14]='V';
- ShowString(1,SecondLine);
- }
- /*------------------------------------------------
- 延時程序
- ------------------------------------------------*/
- void mDelay(unsigned char j)
- {
- unsigned int i;
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
AD-PCF8591.zip
(70.71 KB, 下載次數: 210)
2017-7-28 21:03 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|