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

文章目录

  • 1. IIC总线
    • 1.0 概述
    • 1.1 IIC数据传输过程
  • 2.PCF8591
    • 2.1概述
    • 2.2设备地址
    • 2.3控制
    • 2.4A/D转换流程
  • 3.实例

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 从机地址 0 A 数据 A/非A P

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总线接口。

原理图
蓝桥杯进阶——IIC总线和PCF8591应用_第1张图片

2.2设备地址

PCF8591设备地址包括固定部分和可编程的部分,
如图:.
蓝桥杯进阶——IIC总线和PCF8591应用_第2张图片

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

2.3控制

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

蓝桥杯进阶——IIC总线和PCF8591应用_第3张图片

7 6 5 和4 3 2 1 和0
固定值 模拟输出控制 模拟量输入方式选择 固定值 自动增量控制 A/D通道选择

2.4A/D转换流程

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

3.实例

在第十二届蓝桥杯省赛中考察了光敏电阻和电位器电压的采集
蓝桥杯进阶——IIC总线和PCF8591应用_第4张图片

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

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

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

你可能感兴趣的:(单片机,蓝桥杯,蓝桥杯,单片机,stm32)