|
- #include<reg52.h>
- #include<stdio.h>
- #include <intrins.h>
- #include "PCF8591.H"
- #define uchar unsigned char
- #define uint unsigned int
- #define PCF8591 0x90 //寫數(shù)據(jù)地址,PCF8591 地址 ,把PCF8591定義成0x90
- //第二PCF8591程序
- #define AddWr 0x92 //PCF8591 地址
- #define Data P0 //數(shù)據(jù)端口
- bit ack; /*應(yīng)答標(biāo)志位*/
- sbit RS = P3^0;//Pin4
- sbit RW = P3^1; //Pin5
- sbit E = P3^2;//Pin6
- unsigned char TempData[8];
- unsigned char FirstLine[16]="Voltage: ";
- unsigned char SecondLine[16] ="Current: ";
- unsigned char AD_CHANNEL1; // 定義函數(shù)中間變量
- unsigned char ADtemp; //定義中間變量
- bit P2CF8591_SendByte(unsigned char addr,unsigned char channel);
- unsigned char P2CF8591_RcvByte(unsigned char addr);
- void disp(void);
- void InitLcd();
- void mDelay();
- sbit scl=P1^1; //I2C 時(shí)鐘
- sbit sda=P1^0; //I2C 數(shù)據(jù)
- sbit ENTER = P3^3; //手動(dòng)與自動(dòng)切換
- sbit UP = P3^4; //上
- sbit DOWN = P3^5; //下
- sbit LEFT = P3^6; //左
- sbit RIGHT = P3^7; //右
- sbit LED1 = P1^2;
- sbit LED2 = P1^3;
- uchar Motor_Up[4]={0x08,0x04,0x02,0x01};
- uchar Motor_Down[4]={0x01,0x02,0x04,0x08};
- uchar Motor_Left[4]={0x10,0x20,0x40,0x80};
- uchar Motor_Right[4]={0x80,0x40,0x20,0x10};
- unsigned char AD_CHANNEL; //定義中間變量
- //延時(shí)函數(shù)
- void Delay_ms(uint jj)
- {
- uint ii;
- while(jj--)
- for(ii=0;ii<125;ii++);
- }
- void UART_Init(void)
- {
- TMOD = 0x20; //定時(shí)器模式選擇
- PCON = 0x00;
- SCON = 0x50;
- TH1 = 0xFd; //設(shè)置波特率 9600
- TL1 = 0xFd;
- TR1 = 1; //啟動(dòng)定時(shí)器1
- ES = 1; //開(kāi)串口中斷
- EA = 1; //開(kāi)總中斷
- }
- /********************************************************************
- * 名稱 : PSend_Hex()
- * 功能 : 發(fā)送字符串函數(shù),可控制發(fā)送長(zhǎng)度
- * 變量 : 無(wú)
- * 返回值 : 無(wú)
- ********************************************************************/
- void Send_Hex(unsigned char *p,unsigned char num)
- {
- while(num--) //剩余發(fā)送的字符數(shù)
- {
- SBUF = *p; //將要發(fā)送的數(shù)據(jù)賦給串口緩沖寄存器
- while(!TI);//等待發(fā)送結(jié)束
- TI = 0; //軟件清零
- p++; //指針加一
- }
- }
- void main() //函數(shù)功能:主函數(shù)
- {
- // unsigned char ADtemp; //定義中間變量
- uchar AD_Up,AD_Down,AD_Left,AD_Right;
- uchar i,j,k;
- uchar Table[6];
- Delay_ms(2000);
- UART_Init(); //定時(shí)中斷函數(shù)
- InitLcd(); //1602初始化
- while(1)
- {
- disp();
- if(!ENTER) //手動(dòng)與自動(dòng)切換
- {
- Delay_ms(20);
- while(!ENTER);
- k++;
- }
- if(k%2 == 0) //如果按鍵被按下
- {
- LED1 = 1;
- LED2 = 0;
- for(i=0;i<8;i++)
- {
- switch(AD_CHANNEL)
- {
- case 0: PCF8591_ISendByte(PCF8591,0x41);
- AD_Up=PCF8591_IRcvByte(PCF8591)*2; //ADC0 模數(shù)轉(zhuǎn)換1
- break;
-
- case 1: PCF8591_ISendByte(PCF8591,0x42);
- AD_Down=PCF8591_IRcvByte(PCF8591)*2; //ADC1 模數(shù)轉(zhuǎn)換2
- break;
- case 2: PCF8591_ISendByte(PCF8591,0x43);
- AD_Left=PCF8591_IRcvByte(PCF8591)*2; //ADC2 模數(shù)轉(zhuǎn)換3
- break;
-
- case 3: PCF8591_ISendByte(PCF8591,0x40);
- AD_Right=PCF8591_IRcvByte(PCF8591)*2; //ADC3 模數(shù)轉(zhuǎn)換4
- break;
- }
- Send_Hex(Table,4);
- if(++AD_CHANNEL>3)
- {
- AD_CHANNEL=0;
- Table[0] = AD_Up;
- Table[1] = AD_Down;
- Table[2] = AD_Left;
- Table[3] = AD_Right;
- }
- }
- }
- if(AD_CHANNEL1=0) //第二PCF8591程序
- {
- P2CF8591_SendByte(AddWr,1);
- ADtemp = P2CF8591_RcvByte(AddWr); //ADC0 模數(shù)轉(zhuǎn)換1
- TempData[0]=(ADtemp*10/51)/10; //處理0通道電壓顯示
- TempData[1]=(ADtemp*10/51)%100; //處理0通道電壓顯示
- TempData[2]=((ADtemp*10)%51)/5;
- TempData[3]=((ADtemp*10)%51)%5;
- }
- else //(AD_CHANNEL1=1)
- {
- P2CF8591_SendByte(AddWr,0);
- ADtemp=P2CF8591_RcvByte(AddWr); //ADC1 模數(shù)轉(zhuǎn)換2
- TempData[4]=ADtemp/51;//處理1通道電壓顯示
- TempData[6]=(ADtemp%51)/5;
- }
- if(++AD_CHANNEL1>2) AD_CHANNEL1=0;
- disp();
-
- if(k%2 == 1) //如果按鍵沒(méi)有被按下
- {
- LED1 = 0;
- LED2 = 1;
- AD_Up = 0; //上
- AD_Down = 0;//下
- AD_Left = 0;//左
- AD_Right = 0;//右
- }
- ///////根據(jù)光敏電阻A/D采樣結(jié)果,進(jìn)行兩兩比較//////////
-
- if(((AD_Up<AD_Down)&&(AD_Down-AD_Up>10))||(!UP))//上轉(zhuǎn)
- {
- for(i=0;i<10;i++)
- {
- for(j=0;j<4;j++)
- {
- P2=Motor_Up[j];
- Delay_ms(10);
- }
- }
- }
- //////////////////上下光敏電阻A/D值比較////////////////////
- if(((AD_Up>AD_Down)&&(AD_Up-AD_Down>10))||(!DOWN))//下轉(zhuǎn)
- {
- for(i=0;i<10;i++)
- {
- for(j=0;j<4;j++)
- {
- P2=Motor_Down[j];
- Delay_ms(10);
- }
- }
- }
- //////////////左右光敏電阻A/D值比較///////////////
- if(((AD_Left<AD_Right)&&(AD_Right-AD_Left>10))||(!LEFT))//左轉(zhuǎn)
- {
- for(i=0;i<10;i++)
- {
- for(j=0;j<4;j++)
- {
- P2=Motor_Left[j];
- Delay_ms(10);
- }
- }
-
- }
- ////////////////////左右光敏電阻A/D值比較//////////////////
- if(((AD_Left>AD_Right)&&(AD_Left-AD_Right>10))||(!RIGHT))//右轉(zhuǎn)
- {
- for(i=0;i<10;i++)
- {
- for(j=0;j<4;j++)
- {
- P2=Motor_Right[j];
- Delay_ms(10);
- }
- }
- }
- ////////////////////////////////////
- Delay_ms(100);//延時(shí),可適當(dāng)修改
- }
- /* switch(AD_CHANNEL1) //第二PCF8591程序
- {
- case 0: P2CF8591_SendByte(AddWr,1);
- ADtemp = P2CF8591_RcvByte(AddWr); //ADC0 模數(shù)轉(zhuǎn)換1
- TempData[0]=(ADtemp*10/51)/10; //處理0通道電壓顯示
- TempData[1]=(ADtemp*10/51)%100; //處理0通道電壓顯示
- TempData[2]=((ADtemp*10)%51)/5;
- TempData[3]=((ADtemp*10)%51)%5;
-
- break;
-
- case 1: P2CF8591_SendByte(AddWr,0);
- ADtemp=P2CF8591_RcvByte(AddWr); //ADC1 模數(shù)轉(zhuǎn)換2
- TempData[4]=ADtemp/51;//處理1通道電壓顯示
- TempData[6]=(ADtemp%51)/5;
- break;
-
-
- }
- if(++AD_CHANNEL1>2) AD_CHANNEL1=0;
- disp(); */
- }
- //第二個(gè)模塊程序
- /*******************************************************************
- 起動(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;
- _nop_();
- _nop_();
- _nop_();
- scl=1;
- _nop_();
- _nop_(); /*時(shí)鐘低電平周期大于4μs*/
- _nop_();
- _nop_();
- _nop_();
- scl=0; /*清時(shí)鐘線,住I2C總線以便繼續(xù)接收*/
- _nop_();
- _nop_();
- sda=1;
- _nop_();
- _nop_();
- } /*在此發(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_();
- sda=0;
- _nop_();
- _nop_();
- }
- }
- /************************************************************
- * 函數(shù)名 : Pcf8591_SendByte
- * 函數(shù)功能 : 寫入一個(gè)控制命令
- * 輸入 : addr(器件地址),channel(轉(zhuǎn)換通道)
- * 輸出 : 無(wú)
- ************************************************************/
- bit P2CF8591_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 P2CF8591_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);
- }
- /******************************************************************/
- /* 1602液晶屏相關(guān)函數(shù) */
- /******************************************************************/
- 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));//循環(huán)顯示16個(gè)字符
- }
- /*********************************************************************/
- void InitLcd()
- {
- DelayMs(15);
- WriteCommand(0x38); //display mode
- WriteCommand(0x38); //display mode
- WriteCommand(0x38); //display mode
- WriteCommand(0x06); //顯示光標(biāo)移動(dòng)位置
- WriteCommand(0x0c); //顯示開(kāi)及光標(biāo)設(shè)置
- 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);
- }
- /*------------------------------------------------
- 延時(shí)程序
- ------------------------------------------------*/
- void mDelay(unsigned char j)
- {
- unsigned int i;
- for(;j>0;j--)
- {
- for(i=0;i<125;i++)
- {;}
- }
- }
復(fù)制代碼 |
-
-
程序修改.rar
2019-4-19 12:19 上傳
點(diǎn)擊文件名下載附件
124.98 KB, 下載次數(shù): 37
仿真
|