/**********************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();
}