試驗要求上的AD,DA調一調,用鍵盤輸入一個2V以下電壓比如1.2V,DA輸出1.2V,ADC采集如果大于1.2,讓DA減少,小于1.2讓DA增大,同時液晶上顯示設定值和實測值,
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineDelay4us(){_nop_();_nop_();_nop_();_nop_();}
sbitLCD_RS=P2^6;
sbitLCD_RW=P2^5;
sbitLCD_EN=P2^7;
sbitSCL=P2^0;//I2C時鐘引腳
sbitSDA=P2^1;//I2C數據輸入輸出引腳
ucharRecv_Buffer[4];//數據接收緩沖
uintVoltage[]={'0','0','0','0'};//數據分解為電壓x.xx
bitbdataIIC_ERROR;//I2C錯誤標志位
ucharLCD_Line_1[]={".V"};
//延時
voiddelay(intms)
{
uchari;
while(ms--)for(i=0;i<250;i++)Delay4us();
}
//LCD忙檢測
bitLCD_Busy_Check()
{
bitResult;
LCD_RS=0;LCD_RW=1;
LCD_EN=1;Delay4us();Result=(bit)(P0&0x80);
LCD_EN=0;
returnResult;
}
//寫指令
voidLCD_Write_Command(ucharcmd)
{
while(LCD_Busy_Check());
LCD_RS=0;LCD_RW=0;LCD_EN=0;_nop_();_nop_();
LCD_EN=1;Delay4us();LCD_EN=0;
P0=cmd;Delay4us();
}
//寫數據
voidLCD_Write_Data(uchardat)
{
while(LCD_Busy_Check());
LCD_RS=1;LCD_RW=0;LCD_EN=0;P0=dat;Delay4us();
LCD_EN=1;Delay4us();LCD_EN=0;
}
//初始化
voidLCD_Initialise()
{
LCD_Write_Command(0x38);delay(5);
LCD_Write_Command(0x0c);delay(5);
LCD_Write_Command(0x06);delay(5);
LCD_Write_Command(0x01);delay(5);
}
//設置顯示位置
voidLCD_Set_Position(ucharpos)
{
LCD_Write_Command(pos
0x80);
}
//顯示一行
voidLCD_Display_A_Line(ucharLine_Addr,uchars[])
{
uchari;
LCD_Set_Position(Line_Addr);
for(i=0;i<16;i++)LCD_Write_Data(s[i]);
}
//將模數轉換后得到的值分解存入緩存
voidConvert_To_Voltage(ucharval)
{
ucharTmp;//最大值為255,對應5V,255/5=51
Voltage[2]=val/51+'0';//整數部分
Tmp=val%51*10;//第一位小數
Voltage[1]=Tmp/51+'0';
Tmp=Tmp%51*10;
Voltage[0]=Tmp/51+'0';
}
//啟動I2C總線
voidIIC_Start()
{
SDA=1;SCL=1;Delay4us();SDA=0;Delay4us();SCL=0;
}
//停止I2C總線
voidIIC_Stop()
{
SDA=0;SCL=1;Delay4us();SDA=1;Delay4us();SCL=0;
}
//從機發送應答位
voidSlave_ACK()
{
SDA=0;SCL=1;Delay4us();SCL=0;SDA=1;
}
//從機發送非應答位
voidSlave_NOACK()
{
SDA=1;SCL=1;Delay4us();SCL=0;SDA=0;
}
//發送一字節
voidIIC_SendByte(ucharwd)
{
uchari;
for(i=0;i<8;i++)//循環移入8位
{
SDA=(bit)(wd&0x80);_nop_();_nop_();
SCL=1;Delay4us();SCL=0;wd<<=1;
}
Delay4us();
SDA=1;//釋放總線并準備讀取應答
SCL=1;
Delay4us();
IIC_ERROR=SDA;//IIC_ERROR=1表示無應答
SCL=0;
Delay4us();
}
//接收一字節
ucharIIC_ReceiveByte()
{
uchari,rd=0x00;
for(i=0;i<8;i++)
{
SCL=1;rd<<=1;rd
=SDA;Delay4us();SCL=0;Delay4us();
}
SCL=0;Delay4us();
returnrd;
}
//連續讀入4路通道的A/D轉換結果并保存到Recv_Buffer
voidADC_PCF8591(ucharCtrlByte)
{
uchari;
IIC_Start();
IIC_SendByte(0x90);//發送寫地址
if(IIC_ERROR==1)return;
//IIC_SendByte(CtrlByte);//發送控制字節
//if(IIC_ERROR==1)return;
IIC_Start();//重新發送開始命令
IIC_SendByte(0x91);//發送讀地址
if(IIC_ERROR==1)return;
IIC_ReceiveByte();//空讀一次,調整讀順序
Slave_ACK();//收到一字節后發送一個應答位
for(i=0;i<4;i++)
{
Recv_Buffer[i++]=IIC_ReceiveByte();
Slave_ACK();//收到一個字節后發送一個應答位
}
Slave_NOACK();
IIC_Stop();//收到一個字節后發送一個非應答位
}
//向PCF8591發送1字節進行AD轉換
//主程序
voidmain()
{
LCD_Initialise();
while(1)
{
ADC_PCF8591(0x04);
Convert_To_Voltage(Recv_Buffer[0]);
LCD_Line_1[2]=Voltage[2];
LCD_Line_1[4]=Voltage[1];
LCD_Line_1[5]=Voltage[0];
LCD_Display_A_Line(0x00,LCD_Line_1);
}
}
大功率電感廠家 |大電流電感工廠