蓝桥杯进阶——IIC总线和PCF8591应用

1. IIC总线

1.0 概述

 IIC总线全称:Inter-Integrated Circuit,是由飞利浦公司开发出来的一种串行总线协议,它是一种多主机的总线,当发生主机竞争时,有总线仲裁机制。

IIC总线只有两根信号线:
* SDA:数据线
* SCL:时钟线
当总线空闲时,这两根数据线均处于高电平的状态,数据传输时由设备拉低总线。

IIC的通信原理可以通过数据手册了解,想要写底层代码的时候对比着写就好,在蓝桥杯中提供了底层代码,因此我们只需要了解官方代码如何使用就好。

蓝桥杯提供的驱动函数:

#ifndef _IIC_H
#define _IIC_H

void IIC_Start(void); //起始信号
void IIC_Stop(void);  //停止信号
bit IIC_WaitAck(void);  //等待应答
void IIC_SendAck(bit ackbit); //产生应答
void IIC_SendByte(unsigned char byt); //发生数据
unsigned char IIC_RecByte(void); //接受数据

#endif

1.1 IIC数据传输过程

在没有硬件IIC外设的微处理器中,需要根据总线时序设计IIC接口的驱动程序。包括:起始信号、停止信号、产生应答、等待应答、发送数据和接收数据6个函数,如上.h文件当中的函数,那如何利用这些函数实现数据的传输
与接受?
流程

开始信号写入地址等待响应得到响应发送数据等待响应停止信号
S从机地址0A数据A/非AP

ps:当接受信号时,数据后面为非应答信号。
每发送或接受一个数据都需要经过这样的流程,那么利用官方函数代码就可以这样写:

// ***********发送数据****************
	IIC_Start();		//IIC总线起始信号							
	IIC_SendByte(0xxx); 	//设备地址		
	IIC_WaitAck();  	//等待从机应答		
	IIC_SendByte(0xxx); 	//写入数据
	IIC_WaitAck();  	//等待从机应答						
	IIC_Stop(); 		//IIC总线停止信号	
    
//**************接受数据**************	
	IIC_Start();		//IIC总线起始信号									
	IIC_SendByte(0xxx); 	//读设备地址		
	IIC_WaitAck(); 		//等待从机应答		
	dat = IIC_RecByte();	//读取数据 			
	IIC_Ack(0); 		//产生非应答信号				
	IIC_Stop(); 		//IIC总线停止信号
————————————————

2.PCF8591

2.1概述

PCF8591是具有IIC接口的8位A/D和D/A转换芯片,具有4路模拟输入、一路DAC输出和一个IIC总线接口。

原理图
在这里插入图片描述

2.2设备地址

PCF8591设备地址包括固定部分和可编程的部分,
如图:.
建议将图片保存下来直接上传(img-UvAgaIEG-1642666915940)(en-resource://database/671:1)]

在蓝桥杯板子上,A2~A0均已置于0,因此设备的读操作地址为:0x91写操作地址:0x90

2.3控制

PCF8591内部控制寄存器,当确定地址后,向该地址发送数据来控制器件的功能。

在这里插入图片描述

765 和4321 和0
固定值模拟输出控制模拟量输入方式选择固定值自动增量控制A/D通道选择

2.4A/D转换流程

  • 1–发送写设备地址,选择IIC总线上的PCF8591器件。
  • 2–发送控制字节,选择模拟量输入模式和通道。
  • 3–发送读设备地址,选择IIC总线上的PCF8591器件。
  • 4–读取PCF8591中目标通道的数据。

3.实例

在第十二届蓝桥杯省赛中考察了光敏电阻和电位器电压的采集
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pvDuX80e-1642666915942)(en-resource://database/667:1)]

在此对电位器的电压进行采样并在数码管进行显示。

#include "reg52.h"
#include "iic.h"
unsigned char Num[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char dat = 0;
void delay(unsigned char T){
	while(T--);
}

void select_74HC138(unsigned char num){
	switch(num){
		case 4: 
			 P2 = (P2 & 0x1f) |0x80;               //led
			break;
		case 5: 
			P2 = (P2 & 0x1f) |0xa0;                  //蜂鸣器
			break;
		case 6:	
			P2 = (P2 & 0x1f) |0xc0;				  //位置
			break;
		case 7:	
			P2 = (P2 & 0x1f) |0xe0; 				  //数据
			break;
		case 0:
			P2 = P2 & 0x1f ;
			break;
	}
}
// ******************关闭蜂鸣器和led*************
void system_Init(){
	select_74HC138(4);	
	P0 = 0xff;
	select_74HC138(5);	
	P0 = 0x00;	
	select_74HC138(0);	
}
//**************************************************


//************************数码管显示****************
void Desplay(unsigned char dat , unsigned  pos){
    P0 = 0xff;
	 select_74HC138(6);
	 P0 = 0x01 << pos;
	 select_74HC138(7);
	 P0 = dat;
}
void display_smg(){
	Desplay(Num[dat/100],5);
	delay(100);
	Desplay(Num[(dat%100)/10],6);
	delay(100);
	Desplay(Num[(dat%100)%10],7);
	delay(100);
}

void read_rb2(){
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x03);
	IIC_WaitAck();
	IIC_Stop();
	display_smg();

	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	dat = IIC_RecByte();
	IIC_SendAck(0);
	IIC_Stop();
	display_smg();
}

最后欢迎大家访问我的博客
希望大家都能坚持学习,一起进步!

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

おもいね

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值