qq_39427311
real王不二
采纳率0%
2021-03-07 21:33

pcf8591 AD光敏电阻转换数码管只显示255

pcf8591 AD光敏电阻转换数码管只显示255  跟着视频写的 没有什么错误的地方呀  但是数码管就只是显示255

 

以下是代码段


#include <reg52.h>
#include <intrins.h>
#include <stdio.h>

#define uint unsigned int
#define uchar unsigned char
#define PCF8591ADDR 0x90
#define I2cWrite 0
#define I2cRead 1

sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选
sbit SCL = P2^1;
sbit SDA = P2^0;
uchar num;//数码管显示的值
bit AckFlag;

//共阴数码管段选表0-9
uchar code SMGduan[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};
//数码管位选码
uchar code SMGwei[] = {0xfe, 0xfd, 0xfb};

//三位共阴数码管动态显示
void display(uchar i)
{
	static uchar wei; 		
	P0 = 0XFF;//清除断码
	WE = 1;//打开位选锁存器
	P0 = SMGwei[wei];
	WE = 0;//锁存位选数据
	switch(wei)
	{
		case 0: DU = 1; P0 = SMGduan[i / 100]; DU = 0; break;
		case 1: DU = 1; P0 = SMGduan[i % 100 / 10]; DU = 0; break;	
		case 2: DU = 1; P0 = SMGduan[i % 10]; DU = 0; break;		
	}
	wei++;
	if(wei == 3)
		wei = 0;
}
//定时器0初始化
void timer0Init()
{
	EA = 1;	//打开总中断
	ET0 = 1;//打开定时器0中断
	TR0 = 1;	 //启动定时器0
	TMOD |= 0X01; //定时器工作模式1,16位定时模式
	TH0 = 0xED;
	TL0 = 0xFF; //定时5ms
}

void delay(int z)
{
	int x,y;

	for (x = 114; x; x--)
	{
		for (y = z; y; y--);
	}
}
/****************************************************
IIC通信代码
****************************************************/
void delay5us()
{
	_nop_();
}
//I2c起始信号程序
void I2cStart()
{
	SCL = 1;
	SDA = 1;
	delay5us();
	SDA = 0;
	delay5us();
}
//I2c终止信号程序
void I2cStop()
{
	SCL = 0;
	SDA = 0;
	SCL = 1;
	delay5us();
	SDA = 1;
	delay5us();
}
//I2c主机读从机应答
bit ReadACK()
{
	SCL = 1;
	delay5us();
	if(SDA){ //NOACK
		SCL = 0;
		return(1);
	}else{   //ACK
		SCL = 0;
		return(0);
	}
}
//I2c主机发送应答
void SendACK(bit i )
{
	SCL = 0;
	if(i)  SDA = 1;
	else   SDA = 0;
	SCL = 1;
	delay5us();
	SCL = 0;  //拉低时钟总线
	SDA = 1;  //释放数据总线
}

void I2cSendByte(uchar DAT)
{
		uchar i;
	for(i=0;i<8;i++){
		SCL = 0;
		if(DAT & 0x80)
			SDA = 1;
	    else
			SDA = 0;
		SCL = 1;
		DAT <<=1;
	}
	SCL = 0; //拉低时钟总线
	SDA = 1; //释放数据总线 
}

uchar I2cReadByte(){
	uchar i,DAT;
	for(i=0;i<8;i++){
		DAT <<=1;
		SCL = 0;
		SCL = 1;
		if(SDA)
			DAT |= 0x01;
	}
	return (DAT);
}


uchar PCF8591Read(uchar ctrl)
{
	uchar DAT;
	I2cStart();
    I2cSendByte(PCF8591ADDR + I2cWrite);  //I2c发送一个字节
    if(ReadACK())
   		AckFlag = 1;  //NOACK
	else
	    AckFlag = 0;  //ACK
	I2cSendByte(ctrl);  //I2c发送一个字节
	ReadACK();
	I2cStart();
	I2cSendByte(PCF8591ADDR + I2cRead);  //I2c发送一个字节
	if(ReadACK())
   		AckFlag = 1;  //NOACK
	else
	    AckFlag = 0;  //ACK
	DAT = I2cReadByte();  //读一字节
	SendACK(1);
	I2cStop();
	return (DAT);
}




//void AT24c02Write(uchar ADDR,DAT)
//{
//    I2cStart();
//    I2cSendByte(PCF8591ADDR + I2cWrite);  //I2c发送一个字节
//    if(ReadACK())
//   		AckFlag = 1;  //NOACK
//	else
//	    AckFlag = 0;  //ACK
//	I2cSendByte(ADDR);  //I2c发送一个字节
//	if(ReadACK())
//   		AckFlag = 1;  //NOACK
//	else
//	    AckFlag = 0;  //ACK
//	I2cSendByte(DAT);  //I2c发送一个字节
//	if(ReadACK())
//   		AckFlag = 1;  //NOACK
//	else
//	    AckFlag = 0;  //ACK
//	I2cStop();					 
//} 

void main()//main函数自身会循环
{	
	timer0Init();//定时器0初始化
	while (1)
	{
		EA = 0;		 //屏蔽中断
		num = PCF8591Read(0);
		EA = 1;		 //开中断
		delay(5);
	}
	
} 

//定时器0中断函数
void timer0() interrupt 1
{
	TH0 = 0xED;
	TL0 = 0xFF; //定时5ms
	display(num); //数码管显示函数	
}
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

1条回答

  • Neptune_skr Neptune_skr 11天前

    num这个值是ad值要通过转换才能得到实际的电压值    基准电压*(num测得值/255 ) 

    点赞 评论 复制链接分享