|
//********************************
//說明:調用VR2時,ADC0832將模擬電壓轉換為數字電壓并顯示在LCD1602上
//********************************
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define delay4us(){_nop_();_nop_();_nop_();_nop_();}
//********************************
//ADC引腳定義
//********************************
sbit CS=P3^0;
sbit CLK=P3^1;
sbit DIO=P3^2;
//********************************
//LCD端口定義
//********************************
sbit RS=P3^7;
sbit RW=P3^6;
sbit E=P3^5;
//********************************
//一位整數、兩位小數的數字電壓顯示緩沖
//********************************
uchar Display_Buffer[]="00.000V";
//********************************
//LCD第一行顯示信息
//********************************
uchar code Line[]="TEST OK DC ";
//********************************
//延時子程序
//********************************
void DelayMS(uint x)
{
uchar t;
while(x--)for(t=0;t<120;t++);
}
//********************************
//LCD忙狀態檢測
//********************************
bit LCD_BUSY_CHECK()
{
bit result;
RS=0;
RW=1;
E=1;
delay4us();
result=(bit)(P2&0x80);
E=0;
return result;
}
//********************************
//寫LCD命令
//********************************
void LCD_Write_Command(uchar cmd)
{
while(LCD_BUSY_CHECK()); //判斷LCD是否忙碌
RS=0;
RW=0;
E=0;
_nop_();
P2=cmd;
delay4us();
E=1;
delay4us();
E=0;
}
//********************************
//設置LCD顯示位置
//********************************
void Set_Disp_Pos(uchar pos)
{
LCD_Write_Command(pos|0x80);
}
//********************************
//寫LCD數據
//********************************
void LCD_Write_Data(uchar dat)
{
while(LCD_BUSY_CHECK()); //判斷LCD是否忙碌
RS=1;
RW=0;
E=0;
P2=dat;
delay4us();
E=1;
delay4us();
E=0;
}
//********************************
//LCD初始化
//********************************
void LCD_Initialise()
{
LCD_Write_Command(0x38);DelayMS(1);
LCD_Write_Command(0x0C);DelayMS(1);
LCD_Write_Command(0x06);DelayMS(1);
LCD_Write_Command(0x01);DelayMS(1);
}
//********************************
//獲取AD轉換結果(0通道)
//********************************
uchar GET_AD_RESULT()
{
uchar i;
uchar dat1=0;
uchar dat2=0;
//起始控制位
CS=0;
CLK=0;
DIO=1;_nop_(); _nop_();
CLK=1;_nop_(); _nop_();
//第一個下降沿之前,設DI=1/0
//選擇單端/差分(SGL\DIF)模式中的單端輸入模式
CLK=0;
DIO=1;
_nop_();
_nop_();
CLK=1;
_nop_();
_nop_();
//第二個下降沿之前,設DI=0/1,選擇CH0\CH1
CLK=0;
DIO=0;
_nop_();
_nop_();
CLK=1;
DIO=1;
_nop_();
_nop_(); //第三個下降沿之前,設DI=1
CLK=0;
DIO=1;
_nop_();
_nop_();
//第四個至第十一個,共八個下降沿讀數據(MSB_LSB)
for(i=0;i<8;i++)
{
CLK=1;
_nop_();
_nop_();
CLK=0;
_nop_();
_nop_();
dat1=dat1<<1|DIO;
}
//第十一個至第十八個,共八個下降沿讀數據(LSB_MSB)
for(i=0;i<8;i++)
{
dat2=dat2|((uchar)(DIO)<<i);
CLK=1;
_nop_();
_nop_();
CLK=0;
_nop_();
_nop_();
}
CS=1;
//如果MSB_LSB和LSB_MSB讀取的結果相同,則返回讀取的結果,否則返回0
return(dat1==dat2)?dat2:0;
}
//***************************
//主函數
//***************************
void main()
{
uchar i;
uint d;
LCD_Initialise();
DelayMS(10);
while(1)
{
//獲取AD轉換值,最大值為255對應于最高電壓5.00V //本例中設計為三個顯示數位,故用500
d=GET_AD_RESULT()/(255.0/5)*200; //將AD轉換后的數據分解為3個數位
Display_Buffer[0]=d/1000+'0';
Display_Buffer[1]=d%1000/100+'0';
Display_Buffer[3]=d%100/10+'0';
Display_Buffer[4]=d%10+'0';
Set_Disp_Pos(0x00);
i=0;
while(Line[i]!='\0')
LCD_Write_Data(Line[i++]);
Set_Disp_Pos(0x46);
i=0;
while(Display_Buffer[i]!='\0')
LCD_Write_Data(Display_Buffer[i++]);
}
}
程序附上
|
|