51单片机(时钟频率12MHz)控制PCF8591
PCF8591在开始后,第一个字节为地址和写,第二个字节为控制字节(转换通道),第三个字节为DAC寄存器数据。
PCF8591在开始后,第一个字节为地址和读,读操作(读取ADC寄存器数据)
关于IIC的函数(除了终止时序函数),都保证在函数结束后,SCL = 0;便于编程
执行完终止时序函数后,执行的下一个IIC有关的函数一定为开始时序函数,所以可以不用将SCL置零。因为执行完终止时序函数后,SDA = 1, SCL = 1,所以只需要将SDA = 0就可以实现开始时序功能
在程序中一般不需要释放总线。
SCL = 0一般不需要延时,除了SCL = 0后,直接接SCL = 1;。在SCL = 1后面,必有延时4us
IIC开始时序(void IIC_Start(void))(将此函数与终止函数类比看下)
将SDA置1
将SCL置1
延时4us
将SDA置0
延时4us
将SCL置0,便于后续程序编程
//此函数中没有将SDA释放,这是为什么。为什么要将SDA释放?因为,从机要传数据。但在从机传数据之前,要发送一个读指令,该读指令使在从机传数据之前SDA = 1;
IIC终止时序(void IIC_Stop(void))
将SDA置0
将SCL置1
延时4us
将SDA置1
//为什么不用将SCL = 0,已在上面说清楚
IIC发送应答(void IIC_SendAck(bit Ack))//Ack为0表示主机应答,1则不应答
SDA = Ack;
SCL = 1;
延时4us
SCL = 0;
IIC等待应答(bit IIC_Wait(void))//返回0
SCL = 1;
延时4us
将SDA的值赋给Ack
SCL = 0;
返回Ack//返回0表示从机应答,1表示不应答
IIC发送字节(void IIC_Wr(uchar dat))//IIC最先发送最高位
If(dat & 0x80) SDA = 1;
Else SDA = 0;//准备数据
SCL = 1;//送数据
延时4us
SCL = 0;//便于后面传输数据
Dat <<= 1;
IIC接受字节(uchar IIC_Re(void))
Dat <<= 1;
SCL = 1;
延时4us
Dat |= SDA;
SCL = 0;
返回dat
Delay_us(uint nus)
{
While(–nus);
}