我做的一个关于51单片机的电压表,用pcf8591和1602做的。用protues做的仿真没问题,一下到实物就没用。首先是显示的数字一直在跳,然后也无法测量电压。下面是我的程序
#include<reg52.h> //????????????
#include<intrins.h>
#define ulong unsigned long
#define uchar unsigned char
#define uint unsigned int
#define LCD1602_PORT P0 //?LED1602_PORT??P0????
#define PCF8591 0x90 //PCF8591 ??
#define NOP() _nop_() /* ????? */
#define _Nop() _nop_() /*?????*/
// ???
sbit SCL=P1^0; //I2C ??
sbit SDA=P1^1; //I2C ??
sbit LCD1602_RS = P2^3; //??1602????????/?????,??/??(H/L)
sbit LCD1602_RW = P2^4; //??1602???????/????,?/?(H/L)
sbit LCD1602_EN = P2^5; //??1602?????????
bit ack; /*?????*/
// ????
uchar AD_CHANNEL;
ulong xdata LedOut[8]; //????????
ulong v,a,ss;
uchar date;
// ????
extern bit ack; //??????
extern void Start_I2c(); //??????
extern void Stop_I2c(); //?????
extern void Ack_I2c(bit a); //????????
extern void SendByte(uchar c); //?????????????
extern bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no) ; //?????????????
extern bit ISendStrExt(uchar sla,uchar *s,uchar no); //???????????
extern uchar RcvByte();
void LCD1602_delay_ms(uint n);
void LCD1602_write_com(uchar com);
void LCD1602_write_data(ulong dat);
void LCD1602_write_word(uchar *s);
void Init_LCD1602();
uchar str[4];
bit ISendByte(uchar sla,uchar c);
uchar IRcvByte(uchar sla);
//MS????(12M?????)
void delay_ms(uint n)
{
unsigned int i,j;
for(i=0;i<n;i++)
for(j=0;j<123;j++);
}
//???
void LCD1602_write_com(uchar com)
{
LCD1602_RS = 0; //1602????????/??????0,??/??(H/L),?????????
delay_ms(1);
LCD1602_EN = 1; //??,????????????????
LCD1602_PORT = com; //?????P2?
delay_ms(1);
LCD1602_EN = 0;
}
//???
void LCD1602_write_data(ulong dat)
{
LCD1602_RS = 1; //1602????????/??????0,??/??(H/L),?????????
delay_ms(1);
LCD1602_PORT = dat; //?????P2?
LCD1602_EN = 1;
delay_ms(1);
LCD1602_EN = 0;
}
//?????
void LCD1602_write_word(uchar *s)
{
while(*s>0)
{
LCD1602_write_data(*s);
s++;
}
}
//1602?????
void Init_LCD1602()
{
LCD1602_EN = 0;
LCD1602_RW = 0; //??????
LCD1602_write_com(0x38); //??????
LCD1602_write_com(0x0c); //??????????????????
LCD1602_write_com(0x06); //??????????
LCD1602_write_com(0x01); //????
}
/*******************************************************************
??????
????: void Start_I2c();
??: ??I2C??,???I2C????.
********************************************************************/
void Start_I2c()
{
SDA=1; /*???????????*/
_Nop();
SCL=1;
_Nop(); /*??????????4.7us,??*/
_Nop();
_Nop();
_Nop();
_Nop();
SDA=0; /*??????*/
_Nop(); /* ??????????4μs*/
_Nop();
_Nop();
_Nop();
_Nop();
SCL=0; /*??I2C??,????????? */
_Nop();
_Nop();
}
/*******************************************************************
??????
????: void Stop_I2c();
??: ??I2C??,???I2C????.
********************************************************************/
void Stop_I2c()
{
SDA=0; /*???????????*/
_Nop(); /*???????????*/
SCL=1; /*??????????4μs*/
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SDA=1; /*??I2C??????*/
_Nop();
_Nop();
_Nop();
_Nop();
}
/*******************************************************************
????????
????: void SendByte(UCHAR c);
??: ???c????,?????,??????,???????,??
????????.(?????????ack=0)
??????,ack=1; ack=0????????????
********************************************************************/
void SendByte(uchar c)
{
uchar BitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++) /*?????????8?*/
{
if((c<<BitCnt)&0x80)SDA=1; /*?????*/
else SDA=0;
_Nop();
SCL=1; /*??????,????????????*/
_Nop();
_Nop(); /*???????????4μs*/
_Nop();
_Nop();
_Nop();
SCL=0;
}
_Nop();
_Nop();
SDA=1; /*8??????????,???????*/
_Nop();
_Nop();
SCL=1;
_Nop();
_Nop();
_Nop();
if(SDA==1)ack=0;
else ack=1; /*???????????*/
SCL=0;
_Nop();
_Nop();
}
/*******************************************************************
????????
????: UCHAR RcvByte();
??: ????????????,???????(??????),
??????????????
********************************************************************/
uchar RcvByte()
{
uchar retc;
uchar BitCnt;
retc=0;
SDA=1; /*?????????*/
for(BitCnt=0;BitCnt<8;BitCnt++)
{
_Nop();
SCL=0; /*??????,???????*/
_Nop();
_Nop(); /*?????????4.7μs*/
_Nop();
_Nop();
_Nop();
SCL=1; /*???????????????*/
_Nop();
_Nop();
retc=retc<<1;
if(SDA==1)retc=retc+1; /*????,????????retc? */
_Nop();
_Nop();
}
SCL=0;
_Nop();
_Nop();
return(retc);
}
/********************************************************************
?????
????: void Ack_I2c(bit a);
??: ?????????(???????????,????a??)
********************************************************************/
void Ack_I2c(bit a)
{
if(a==0)SDA=0; /*???????????? */
else SDA=1;
_Nop();
_Nop();
_Nop();
SCL=1;
_Nop();
_Nop(); /*?????????4μs*/
_Nop();
_Nop();
_Nop();
SCL=0; /*????,??I2C????????*/
_Nop();
_Nop();
}
/*******************************************************************
ADC????[??]????
*******************************************************************/
bit ISendByte(uchar sla,uchar c)
{
Start_I2c(); //????
SendByte(sla); //??????
if(ack==0)return(0);
SendByte(c); //????
if(ack==0)return(0);
Stop_I2c(); //????
return(1);
}
/*******************************************************************
ADC???????
*******************************************************************/
uchar IRcvByte(uchar sla)
{
uchar c;
Start_I2c(); //????
SendByte(sla+1); //??????
if(ack==0)return(0);
c=RcvByte(); //????0
Ack_I2c(1); //??????
Stop_I2c(); //????
return(c);
}
// ??????
void Display()
{
LCD1602_write_com(0x80); //????,??1602????????
LCD1602_write_word("Voltage: ");
LCD1602_write_com(0x80+0x0e); //????,??1602????????
LCD1602_write_word(" V");
}
//????????
void Display_Voltage()
{
LCD1602_write_com(0x80+0x09); //1602???????,?????????????7?
LCD1602_write_data(str[0]+ 0x30);
LCD1602_write_data(str[1] + 0x30);
LCD1602_write_data('.');
LCD1602_write_data(str[2] + 0x30);
LCD1602_write_data(str[3] + 0x30);
/* ss=(v*a);
ss=((ss*8)/100);
LCD1602_write_com(0x80+0x09); //1602???????,?????????????7?
LCD1602_write_data(ss%10000000/1000000 + 0x30);
LCD1602_write_data(ss%1000000/100000 + 0x30);
LCD1602_write_data('.');
LCD1602_write_data(ss%100000/10000 + 0x30);
LCD1602_write_data(ss%10000/1000 + 0x30); */
}
main()
{
Init_LCD1602(); //???LCD1602
Display();
a=50000000/255*2.5;
while(1)
{
ISendByte(PCF8591,0x41);
v=IRcvByte(PCF8591);
ss=(v*a);
ss=((ss*8)/100);
str[0]=ss%10000000/1000000 ;
str[1]=ss%1000000/100000;
str[2]=ss%100000/10000;
str[3]=ss%10000/1000;
Display_Voltage(); //????
}
}
|