51_PCF8591

 /**********************51单片机学习例程************************
*  平台:Keil U4 + STC89C52
*  名称: PCF8591 控制LED 
*  编写:Tony
*  日期:2022-2-2
*   QQ : 674749794
*  晶体:12MHZ
*	 变更记录:无
******************************************************************/
#define uchar unsigned char
#define INCRE 1		//数据递增
#define REDUCE 0	//数据递减
bit direc_flag;		//数据变化方向变量
uchar vol_num;      //存储电压对应的8进制数
void num_direct_update(void);
extern void PCF8591_DAC_OUT(uchar DAT);
 /***************************************************
*								数据更新子函数 
*							数据更新,方向更新
****************************************************/
void num_direct_updata(void)
{
   if(direc_flag==INCRE)
        vol_num++;
	else 
	    vol_num--;
   if(vol_num==0xFF)
        direc_flag=	REDUCE;
   if(vol_num==0x57)	//二极管需要1.7v电压点亮
        direc_flag=	INCRE;				    
}

void main()

{
	unsigned int i;
	vol_num=0x57;
	direc_flag = INCRE;
	while(1)
	{
	   	PCF8591_DAC_OUT(vol_num);
		num_direct_updata();
		for(i=0;i<5000;i++);
	}

}

  

 

#include <reg52.h>
#include <intrins.h> 					//包含空指令函数_nop_();
#define uchar unsigned char
#define delay_6us {_nop_();_nop_();_nop_();\
					_nop_();_nop_();_nop_();}		//延时6个机器周期,PCF8591 iic  100Khz
#define PCF_ADDR	0x90				//定义PCF8591的地址

sbit SCL = P3^6;      					//定义总线连接端口
sbit SDA = P3^7;
void IIC_start(void);					//函数声明
void IIC_stop(void);
bit ack_check(void);
bit send_byte(uchar DAT);
void PCF8591_DAC_OUT(uchar DAT);
/***************************************************
*								IIC总线开始信号
****************************************************/
void IIC_start(void)
{
	SDA=1;
	SCL=1;			//置一两条线
	delay_6us ;		//延时6个机器周期
	SDA=0;			//拉低数据线
	delay_6us ;		
//	SCL=0;			//拉低时钟线
}
/***************************************************
*								IIC总线停止信号
****************************************************/
void IIC_stop(void)
{
	SDA=0;			//拉低数据线
	SCL=1;			//置一时钟线
	delay_6us ;		
	SDA=1;			//置一数据线
	delay_6us ;		
 }
/***************************************************
*								检测IIC总线应答信号
****************************************************/
bit ack_check(void)
{
	bit ack_bit;		//位定义应答信号存储单元
	SDA=1;				//释放数据线,勾引从设备发送应答信号
	delay_6us ;			
	SCL=1;				//置一时钟线
	delay_6us ;		
	ack_bit = SDA;		//采样此时的数据线信号
	SCL=0;				//拉低时钟线
	return ack_bit;		//返回采样到的应答信号
}
/***************************************************
*							向从设备发送一个字节,
*							同时检测应答信号
****************************************************/
bit send_byte(uchar DAT)
{
	uchar i;
	uchar temp;					//缓存寄存器
	bit ack;					//定义位变量,反馈应答信号
	temp = DAT;					//待发送字节存入缓冲寄存器
	for(i = 0;i < 8;i++)		//循环发送8位数据
	{
		SCL = 0;				//拉低时钟线
		if((temp&0x80)==0x80)	//判断temp的高位是0还是1
			SDA=1;							
		else
			SDA=0;				//送出相应数据
		delay_6us ;			
		SCL = 1;				//拉高时钟线
		temp <<=1;		//待发送数据左移一位
		delay_6us ;			
	}
	SCL = 0;					//拉低时钟线
	ack = ack_check();			//调用应答信号检测子函数
	return ack;					//返回检测到的应答信号
}
/***************************************************
*								DA转换子函数 
*								控制DA输出电压
****************************************************/
void PCF8591_DAC_OUT(uchar DAT)
{
  IIC_start();
  if(send_byte(PCF_ADDR)==1)
    {
	   	IIC_stop();
		return;
	}
   send_byte(0x40);
   send_byte(DAT);
   IIC_stop();
}

 

 

 

posted @ 2022-02-12 17:49  xiaoberber  阅读(31)  评论(0编辑  收藏  举报