12864显示ad采集压力值怎么压传感器都不变,估计是程序问题,自己怎么查也查不出错
#include <intrins.h>
#include <stdio.h>
#define MAIN_Fosc 11059200UL //宏定义主时钟HZ
#define PCF8591_ADDR 0x90 //PCF8591地址
/*====================================
自定义类型名
====================================*/
typedef unsigned char INT8U;
typedef unsigned char uchar;
typedef unsigned int INT16U;
typedef unsigned int uint;
/*====================================
硬件接口位声明
====================================*/
sbit SDA = P2^0; //I2C串行数据
sbit SCL = P2^1; //I2C串行时钟
sbit DU = P2^6; //数码管段选
sbit WE = P2^7; //数码管位选
sbit EN = P3^4; // 液晶使能控制
sbit RS = P3^5; //数据命令选择端
sbit RW = P3^6; //读写选择端
sbit LCD_PSB = P3^7;//串行选择端
uint AD_Value; //存储AD转换回的数字量
uchar i,temp,com;
uchar code dis1[]={"压力值:"};
uchar code dis2[]={"角度值:"};
/*====================================
函数:void Delay_Ms(INT16U ms)
参数:ms,毫秒延时形参
描述:12T 51单片机自适应主时钟毫秒级延时函数
====================================*/
void Delay_Ms(INT16U ms)
{
INT16U i;
do{
i = MAIN_Fosc / 96000;
while(--i); //96T per loop
}while(--ms);
}
/*====================================
函数:void Delay5us()
描述:12T 51单片机5微秒延时函数自适应时钟(11.0592M,12M,22.1184M)
====================================*/
void Delay5us()
{
#if MAIN_Fosc == 11059200
_nop_();
#elif MAIN_Fosc == 12000000
_nop_()
#elif MAIN_Fosc == 22118400
_nop_(); _nop_(); _nop_();
#endif
}
/*====================================
函数:I2C_init()
描述:I2C总线初始化
====================================*/
void I2C_init()
{
SDA = 1; //数据总线高
_nop_();
SCL = 1; //时钟总线高
_nop_();
}
/*====================================
函数:I2C_Start()
描述:I2C起始信号
====================================*/
void I2C_Start()
{
SCL = 1;
_nop_();
SDA = 1;
Delay5us();
SDA = 0;
Delay5us();
}
/*====================================
函数:I2C_Stop()
描述:I2C停止信号
====================================*/
void I2C_Stop()
{
SDA = 0;
_nop_();
SCL = 1;
Delay5us();
SDA = 1;
Delay5us();
}
/*====================================
函数:Master_ACK(bit i)
参数:i 为0时发送非应答 为1时发送应答
描述:I2C主机发送应答
====================================*/
void Master_ACK(bit i)
{
SCL = 0; // 拉低时钟总线允许SDA数据总线上的数据变化
_nop_(); // 让总线稳定
if (i) //如果i = 1 那么拉低数据总线 表示主机应答
{
SDA = 0;
}
else
{
SDA = 1; //发送非应答
}
_nop_();//让总线稳定
SCL = 1;//拉高时钟总线 让从机从SDA线上读走 主机的应答信号
_nop_();
SCL = 0;//拉低时钟总线, 占用总线继续通信
_nop_();
SDA = 1;//释放SDA数据总线。
_nop_();
}
/*====================================
函数:Test_ACK()
返回:0为非应答 1为应答
描述:I2C检测从机应答
====================================*/
bit Test_ACK() // 检测从机应答
{
SCL = 1;//时钟总线为高电平期间可以读取从机应答信号
Delay5us();
if (SDA)
{
SCL = 0;
I2C_Stop();
return(0);
}
else
{
SCL = 0;
return(1);
}
}
/*====================================
函数:I2C_send_byte(uchar byte)
参数:byte 要发送的字节
描述:I2C发送一个字节
====================================*/
void I2C_send_byte(uchar byte)
{
uchar i;
for(i = 0 ; i < 8 ; i++)
{
SCL = 0;
_nop_();
if (byte & 0x80) //
{
SDA = 1;
_nop_();
}
else
{
SDA = 0;
_nop_();
}
SCL = 1;
_nop_();
byte <<= 1;
}
SCL = 0;
_nop_();
SDA = 1;
_nop_();
}
/*====================================
函数:I2C_read_byte()
返回:读取的字节
描述:I2C读一个字节
====================================*/
uchar I2C_read_byte()
{
uchar i, dat;
SCL = 0 ;
_nop_();
SDA = 1;
_nop_();
for(i = 0 ; i < 8 ; i++)
{
SCL = 1;
_nop_();
dat <<= 1;
if (SDA)
{
dat |= 0x01;
}
_nop_();
SCL = 0;
_nop_();
}
return(dat);
}
/*读AD数据*/
bit ADC_Read(uchar CON)
{
I2C_Start();
I2C_send_byte(PCF8591_ADDR+0);
if (!Test_ACK())
{
return(0);
}
I2C_send_byte(CON);
Master_ACK(0);
I2C_Start();
I2C_send_byte(PCF8591_ADDR+1);
if (!Test_ACK())
{
return(0);
}
AD_Value = I2C_read_byte();
Master_ACK(0);
I2C_Stop();
return(1);
}
/*void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
} */
/*====================================
函数:LCD_status()
描述:判断忙
====================================*/
bit lcd_status()
{
bit status;
RS = 0;
RW = 1;
Delay_Ms(5);
EN = 1;
status = P0&0x80;
EN = 0;
return(status);
}
/*====================================
函数:write_cmd()
描述:写指令到LCD
====================================*/
void write_cmd( uchar cmd)
{
while(lcd_status());
RS = 0;
RW = 0;
EN = 0;
P0 = cmd;
Delay_Ms(5);
EN= 1;
Delay_Ms(5);
EN = 0;
}
/*====================================
函数:write_dat()
描述:写数据到LCD
====================================*/
void write_dat( uchar dat)
{
while(lcd_status());
RS = 1;
RW = 0;
EN = 0;
P0 = dat;
Delay_Ms(5);
EN= 1;
Delay_Ms(5);
EN = 0;
}
/*====================================
函数:write_dat()
描述:设定显示位置
====================================*/
void lcd_pos(uchar X,uchar Y)
{
uchar pos;
switch(X)
{
case 0: X = 0x80;break;
case 1: X = 0x90;break;
case 2: X = 0x88;break;
case 3: X = 0x98;break;
}
pos = X+Y;
write_cmd(pos);
}
/*
/*====================================
函数:lcd_init()
描述:lcd初始化
====================================*/
void lcd_init()
{
LCD_PSB = 1;
write_cmd(0x30);
Delay_Ms(5);
write_cmd(0x0c);
Delay_Ms(5);
write_cmd(0x01);
Delay_Ms(5);
}
/* void ad_display(uint i)
{
uint t1,t2,t3,t4,t5;
if( 10000 < i <100000)
{
t1 = i/10000 +0x30;
t2 = i/10000%1000+0x30 ;
t3 = i%1000/100 +0x30;
t4 = i%100/10 +0x30;
t5 = i%10+0x30;
write_dat(t1);
write_dat(t2);
write_dat(t3);
write_dat('.');
write_dat(t4);
write_dat(t5);
}
else if(1000<i<10000)
{
t1 = i/1000+0x30;
t2 = i/1000%100+0x30;
t3 = i%100/10 +0x30;
t4 = i%10 +0x30;
write_dat(t1);
write_dat(t2);
write_dat('.');
write_dat(t3);
write_dat(t4);
}
else if(10<i<1000)
{
t1 = i/100+0x30;
t2 = i/100%10+0x30;
t3 = i%10+0x30;
write_dat(t1);
write_dat('.');
write_dat(t2);
write_dat(t3);
}
}
*/
void display(uint i)
{
uchar count,tmp;
uchar datas[] = {0, 0, 0, 0, 0,0};
datas[0] = tmp / 10000;
datas[1] = tmp % 10000 / 1000;
datas[2] = tmp % 1000 / 100;
datas[3] = tmp % 100 / 10;
datas[4] = tmp % 10;
lcd_pos(0,4);
for(count = 1; count != 6; count++)
{
write_dat('0'+datas[count]);
if(count == 3)
{
write_dat('.');
}
}
}
void main()
{
uchar a,b;
WE= 0;
DU = 0;
I2C_init();
lcd_init();
while(1)
{
lcd_pos(0,0);
a = 0;
while(dis1[a]!='\0')
{
write_dat(dis1[a]);
a++;
}
lcd_pos(0,7);
write_dat('N');
ADC_Read(0x03);
com = (uint)(AD_Value*1.17*100 );
display(com);
lcd_pos(2,0);
b = 0;
while(dis2!='\0')
{
write_dat(dis2);
b++;
}
}
}
试试看这里吧,形参是i,函数中对tmp做计算,并没有对i做计算
void display(uint i)
{
uchar count,tmp;
uchar datas[] = {0, 0, 0, 0, 0,0};
datas[0] = tmp / 10000;
datas[1] = tmp % 10000 / 1000;
datas[2] = tmp % 1000 / 100;
刚改了,可是显示数值变乱了,初始值也不是零,一会变大一会变小,我的显示函数是不是写的有问题啊
你可以随意给定一些数值来显示,判断是否显示程序有问题,如果显示程序没问题,那就是传感器部分的问题了
建议把
for(count = 1; count != 6; count++)
{
write_dat('0'+datas[count]);
if(count == 3)
{
write_dat('.');
}
}
改成
write_dat(t1);
write_dat(t2);
write_dat(t3);
write_dat('.');
write_dat(t4);
write_dat(t5);这种方式,不做循环,每次显示一个数值,另外做了datas[0] = tmp / 10000;,但是却不显示
刚刚又改了,随便另AD-Value取了几个值放进去,发现显示的还是不对。
void display(uint tmp)
{
uint datas[6];
datas[0] = tmp / 10000;
datas[1] = tmp /10000%1000 ;
datas[2] = tmp % 1000 / 100;
datas[4] = tmp % 100 / 10;
datas[5] = tmp % 10;
lcd_pos(0,4);
write_dat('0'+datas[0]);
write_dat('0'+datas[1]);
write_dat('0'+datas[2]);
write_dat('.');
write_dat('0'+datas[4]);
write_dat('0'+datas[5]);
}