|
PCF8591做AD转换,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延时函数(4.34us)
void delayNOP()
{
_nop_();
_nop_();
_nop_();
_nop_();
}
//ms延时函数
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) //写命令函数
{
Read_busy();
RS = 0; //0:写指令
RW = 0; //0:写操作
LCD_databus = value;
EN = 1; //EN下降沿锁存有效数据
_nop_();
_nop_();
_nop_();//空指令,短暂延时
EN = 0;
}
void write_LCD_data(uint8 value) //写数据函数
{
Read_busy();
RS = 1; //1:写数据
RW = 0; //写操作
LCD_databus = value;
EN = 1; //EN下降沿锁存有效数据
_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) //显示开关函数,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;
}
//发送1个字节
void IICSendByte(unsigned char indata)
{
unsigned char n=8;
while(n--)
{
SDA=(bit)(indata &0x80);
SCL=1;
delayNOP();
SCL=0;
indata=indata<<1;
}
}
//接收一个字节
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);
}
//发送数据子程序
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转换
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]);
}
}
}
|
|