PCF8591做AD轉(zhuǎn)換,ACS712做電流傳感器,LCD12864做顯示屏,顯示出來的是亂碼,想知道怎么解決,程序和仿真如下所示:
#include<reg51.h>
#include<intrins.h>
#define PCF8591_WRITE 0x90
#define PCF8591_READ 0x91
sbit SDA=P2^0;
sbit SCL=P2^1;
unsigned char code dis1[]="0-0.00V 1-0.00V";
unsigned int data dis[4];
unsigned char data receivebuf[4];
#define uint8 unsigned char
#define uint16 unsigned int
#define LCD_databus P0
sbit RS = P1^4;
sbit RW = P1^3;
sbit EN = P1^5;
sbit CS1 = P1^0;//片選1.低電平有效,控制左半屏
sbit CS2 = P1^1;//片選2,低電平有效,控制右半屏
void Read_busy();
void write_LCD_command(uint8);
void write_LCD_data(uint8);
void Set_page(uint8);
void Set_line(uint8);
void Set_column(uint8);
void SetOnOff(uint8);
void SelectScreen(uint8);
void ClearScreen(uint8);
void InitLCD();
void show_ch(uint8,uint8,uint8,uint8 *);
void show_im(uint8,uint8,uint8,uint8 *);
void show_value(unsigned char ad_data);
//us延時函數(shù)(4.34us)
void delayNOP()
{
_nop_();
_nop_();
_nop_();
_nop_();
}
//ms延時函數(shù)
void delayms(unsigned int ms)
{
unsigned char i;
while (ms--)
{
for(i=0;i<114;i++)
;
}
}
void show_value(unsigned char ad_data)
{
dis[2]=ad_data/51;
dis[2]=dis[2]+0x30;
dis[3]=ad_data%51;
dis[3]=dis[3]*10;
dis[1]=dis[3]/51;
dis[1]=dis[1]+0x30;
dis[3]=ad_data%51;
dis[3]=dis[3]*10;
dis[0]=dis[3]/51;
dis[0]=dis[0]+0x30;
}
void Read_busy()
{
P0 = 0X00;
RS = 0;
RW = 1;
EN = 1;
while(P0 & 0x80)
{;}
EN = 0;
}
void write_LCD_command(uint8 value) //寫命令函數(shù)
{
Read_busy();
RS = 0; //0:寫指令
RW = 0; //0:寫操作
LCD_databus = value;
EN = 1; //EN下降沿鎖存有效數(shù)據(jù)
_nop_();
_nop_();
_nop_();//空指令,短暫延時
EN = 0;
}
void write_LCD_data(uint8 value) //寫數(shù)據(jù)函數(shù)
{
Read_busy();
RS = 1; //1:寫數(shù)據(jù)
RW = 0; //寫操作
LCD_databus = value;
EN = 1; //EN下降沿鎖存有效數(shù)據(jù)
_nop_();
_nop_();
_nop_();//空指令,短暫延時
EN = 0;
}void Set_page(uint8 page) //設置顯示起始頁
{
page = 0xB8 | page; //頁的首地址為0xB8
write_LCD_command(page);
}
void Set_line(uint8 startline) //設置顯示起始行
{
startline = 0xC0 | startline;
write_LCD_command(startline);
}
void Set_column(uint8 column) //設置顯示的列
{
column = column & 0x3F; //列的最大值為64
column = column | 0x40; //列的首地址為0x40
write_LCD_command(column);
}
void SetOnOff(uint8 onoff) //顯示開關函數(shù),0x3E:關 0x3F:開
{
onoff = 0x3E | onoff; //onoff為0時關顯示,為1時開顯示
write_LCD_command(onoff);
}
void SelectScreen(uint8 screen) //選擇屏幕
{
switch(screen)
{
case 0:CS1 = 0;CS2 = 0;break;//全屏
case 1:CS1 = 0;CS2 = 1;break;//左半屏
case 2:CS1 = 1;CS2 = 0;break;//右半屏
default:break;
}
}
void ClearScreen(uint8 screen) //清屏
{
uint8 i,j;
SelectScreen(screen);
for(i=0;i<8;i++)
{
Set_page(i);
Set_column(0);
for(j=0;j<64;j++)
{
write_LCD_data(0x00); //寫入0,地址指針自動加1
}
}
}
void InitLCD()
{
Read_busy();
SelectScreen(0);
SetOnOff(0);
SelectScreen(0);
SetOnOff(1);
SelectScreen(0);
ClearScreen(0);
Set_line(0);
}
//啟動i2c
void iic_start(void)
{
SDA=1;
SCL=1;
delayNOP();
SDA=0;
delayNOP();
SCL=0;
}
//停止i2c
void iic_stop(void)
{
SDA=0;
SCL=1;
delayNOP();
SDA=1;
delayNOP();
SCL=0;
}
//初始化i2c
void iicInit(void)
{
SCL=0;
iic_stop();
}
//應答子程序
void slave_ACK(void)
{
SDA=0;
SCL=1;
delayNOP();
SCL=0;
SDA=1;
}
//非應答子程序
void slave_NOACK(void)
{
SDA=1;
SCL=1;
delayNOP();
SDA=0;
SCL=0;
SDA=0;
}
//檢查應答子程序
void check_ACK(void)
{
SDA=1;
SCL=1;
F0=0;
delayNOP();
if(SDA==1)
F0=1;
SCL=0;
}
//發(fā)送1個字節(jié)
void IICSendByte(unsigned char indata)
{
unsigned char n=8;
while(n--)
{
SDA=(bit)(indata &0x80);
SCL=1;
delayNOP();
SCL=0;
indata=indata<<1;
}
}
//接收一個字節(jié)
unsigned char IICreceiveByte(void)
{
unsigned char n=8;
unsigned char tdata=0;
while(n--)
{
SDA=1;
SCL=1;
tdata=tdata<<1;
if(SDA==1)
tdata=tdata|0x01;
else
tdata=tdata&0xfe;
SCL=0;
}
return(tdata);
}
//發(fā)送數(shù)據(jù)子程序
void DAC_PCF8591(unsigned char controlbyte,unsigned char w_data)
{
iic_start();
delayNOP();
IICSendByte(PCF8591_WRITE);
check_ACK();
IICSendByte(controlbyte&0x77);
check_ACK();
IICSendByte(w_data);
check_ACK();
iic_stop();
delayNOP();
delayNOP();
}
//A/D轉(zhuǎn)換
void ADC_PCF8591(unsigned char controlbyte)
{
unsigned char i=0;
iic_start();
IICSendByte(PCF8591_WRITE);
check_ACK();
IICSendByte(controlbyte);
check_ACK();
iic_start();
IICSendByte(PCF8591_READ);
check_ACK();
IICreceiveByte();
slave_ACK();
while(i<3)
{
receivebuf[i++]=IICreceiveByte();
slave_ACK();
}
receivebuf[3]=IICreceiveByte();
slave_NOACK();
iic_stop();
}
void main()
{
unsigned char i;
delayms(10);
InitLCD();
SelectScreen(1);
Set_page(1);
Set_column(0*16);
for(i=0;i<16;i++)
write_LCD_data(dis1);
ClearScreen(0);
Set_line(0);
while(1)
{
iicInit();
ADC_PCF8591(0x04);
while(F0)
{iicInit();
ADC_PCF8591(0x04);
}
show_value(receivebuf[0]);
SelectScreen(1);
Set_page(1);
Set_column(0*16);
write_LCD_data(dis[2]);
SelectScreen(1);
Set_page(1);
Set_column(2*16);
write_LCD_data(dis[1]);
write_LCD_data(dis[0]);
iicInit();
DAC_PCF8591(0x40,receivebuf[0]);
while(F0)
{
iicInit();
DAC_PCF8591(0x40,receivebuf[0]);
}
}
}
|