IIC总线
IIC总线是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。IIC通信多用于板内通信。
PCF8591与A/D转换
PCF8591是具有IIC接口的8位A/D和D/A转换芯片,具有4路模拟输入、一路DAC输出和一个IIC总线接口。其主要的功能特性如下:
- 单电源供电,典型值为5V。
- 通过3个硬件地址引脚编址。
- 8位逐次逼近式A/D转换。
- 片上跟踪与保持电路,采样速率取决与IIC总线速度。
- 4路模拟输入可编程为单端输入或查分输入。
- 自动增量通道选择。
- 带一个模拟输出的乘法DAC。
蓝桥杯单片机设计与开发赛项使用的CT107D单片机开发平台中,PCF8591的三个硬件引脚地址均接地,两路模拟信号均为单端输入,分别是:
- 光敏传感器接到AIN1,通道1;控制寄存器应写入:0x01。
- 电位器Rb2接到AIN3,通道3;控制寄存器应写入:0x03。
A/D转换应用开发流程:一个A/D转换的周期的开始,总是在发送有效的读设备地址给PCF8591之后,A/D转换在应答时钟脉冲的后沿被触发。PCF8591的A/D转换程序设计流程,可以分为四个步骤:
- 1–发送写设备地址,选择IIC总线上的PCF8591器件。
- 2–发送控制字节,选择模拟量输入模式和通道。
- 3–发送读设备地址,选择IIC总线上的PCF8591器件。
- 4–读取PCF8591中目标通道的数据。
编程实现PCF8591读取通道1和通道3的电压值。
#include <STC15F2K60S2.H>
#include <SMG_SHOW.H>
#include <IIC.H>
void write_adc(unsigned char add);
unsigned char read_adc(unsigned char add);
unsigned char adc; //存放光敏电阻值
float v;//存放转换后的电压值
void main()
{
selectHC(5);P0=0x00;P2&=0x1f;
write_adc(0x03); //读取通道1的电压 //读取通道3的电压write_adc(0x03);
while(1)
{
adc=read_adc(0x03);
v=adc/255.0f*5;
show(0,table[adc/100]);
show(1,table[adc/10%10]);
show(2,table[adc%10]);
show(5,table2[(unsigned char)v]); //或上0x80,显示小数点
show(6,table[(unsigned char)v/10%10]); //float类型强制转换为unsigned char类型
show(7,table[(unsigned char)v%10]);
}
}
//PCF8591写ADC函数
void write_adc(unsigned char add)
{
IIC_Start(); //总线启动
IIC_SendByte(0x90);//通过I2C总线发送数据
IIC_WaitAck(); //应答位控制
IIC_SendByte(add); //通过I2C总线发送数据
IIC_WaitAck(); //等待应答
IIC_Stop(); //总线停止
}
//PCF8591读ADC函数
unsigned char read_adc(unsigned char add)
{
unsigned char temp;
IIC_Start(); //总线启动
IIC_SendByte(0x90);//通过I2C总线发送数据
IIC_WaitAck(); //应答位控制
IIC_SendByte(add); //通过I2C总线发送数据
IIC_WaitAck(); //等待应答
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
temp=IIC_RecByte();//从I2C总线上接收数据
IIC_WaitAck();
IIC_Stop(); //总线停止
return temp;
}
24C02存储器
- 24C02是一个2K Bit的串行EEPROM存储器,内部含有256个字节。
- 在24C02里面有一个8字节的页写缓冲器。
- 该设备的工作电压为1.8V到6.0V,芯片的第7引脚WP为写保护引脚,将该引脚接地允许正常的读写。
编程实现AT24C02的读写,让0X55单元的数值每次上电自加1。
#include <STC15F2K60S2.H>
#include <SMG_SHOW.H>
#include <IIC.H>
void write_24c02(unsigned char add,unsigned char data1);
unsigned char read_24c02(unsigned char add);
unsigned char open_num;//0X55单元的数值
unsigned char voit; //每次上电加1
void main()
{
selectHC(5);P0=0x00;P2&=0x1f;
open_num=read_24c02(0x55);
write_24c02(0x55,++open_num);//每次上电加1
while(1)
{
show(6,table[open_num/10]);
show(7,table[open_num%10]);
}
}
//AT24C02写函数
void write_24c02(unsigned char add,unsigned char data1)
{
IIC_Start(); //总线启动
IIC_SendByte(0xa0);//通过I2C总线发送数据
IIC_WaitAck(); //应答位控制
IIC_SendByte(add);
IIC_WaitAck();
IIC_SendByte(data1);
IIC_WaitAck();
IIC_Stop(); //总线停止
}
//AT24C02读函数
unsigned char read_24c02(unsigned char add)
{
unsigned char temp;
IIC_Start(); //总线启动
IIC_SendByte(0xa0);//通过I2C总线发送数据
IIC_WaitAck(); //应答位控制
IIC_SendByte(add);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
temp=IIC_RecByte();//从I2C总线上接收数据
IIC_WaitAck();
IIC_Stop(); //总线停止
return temp;
}
IIC驱动代码
/*
程序说明: IIC总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台 8051,12MHz
日 期: 2011-8-9
*/
#include "reg52.h"
#include "intrins.h"
#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();}
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
//总线启动条件
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
somenop;
SDA = 0;
somenop;
SCL = 0;
}
//总线停止条件
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
somenop;
SDA = 1;
}
//应答位控制
void IIC_Ack(bit ackbit)
{
if(ackbit)
{
SDA = 0;
}
else
{
SDA = 1;
}
somenop;
SCL = 1;
somenop;
SCL = 0;
SDA = 1;
somenop;
}
//等待应答
bit IIC_WaitAck(void)
{
SDA = 1;
somenop;
SCL = 1;
somenop;
if(SDA)
{
SCL = 0;
IIC_Stop();
return 0;
}
else
{
SCL = 0;
return 1;
}
}
//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(byt&0x80)
{
SDA = 1;
}
else
{
SDA = 0;
}
somenop;
SCL = 1;
byt <<= 1;
somenop;
SCL = 0;
}
}
//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++)
{
SCL = 1;
somenop;
da <<= 1;
if(SDA)
da |= 0x01;
SCL = 0;
somenop;
}
return da;
}
#ifndef _IIC_H
#define _IIC_H
//函数声明
void IIC_Start(void);
void IIC_Stop(void);
void IIC_Ack(bit ackbit);
void IIC_SendByte(unsigned char byt);
bit IIC_WaitAck(void);
unsigned char IIC_RecByte(void);
#endif
```