【蓝桥杯12】——IIC协议_PCF8591与A/D转换_24C02存储器

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存储器

  1. 24C02是一个2K Bit的串行EEPROM存储器,内部含有256个字节。
  2. 在24C02里面有一个8字节的页写缓冲器。
  3. 该设备的工作电压为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
```

猜你喜欢

转载自blog.csdn.net/z3447643805/article/details/113933194