IIC总线和PCF8591应用


[TOC]

1. IIC总线

1.0 概述

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

IIC总线只有两根信号线:

  • SDA:数据线
  • SCL:时钟线

当总线空闲时,这两根数据线均处于高电平的状态,数据传输时由设备拉低总线。

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

蓝桥杯提供的驱动函数:

1
2
3
4
5
6
7
8
9
10
11
#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:当接受信号时,数据后面为非应答信号。
每发送或接受一个数据都需要经过这样的流程,那么利用官方函数代码就可以这样写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// ***********发送数据****************
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设备地址包括固定部分和可编程的部分,如图:
enter description here

2.3控制

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

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

2.4A/D转换流程

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

3.实例

在第十二届蓝桥杯省赛中考察了光敏电阻和电位器电压的采集
题目部分

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#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();
}

文章作者:
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 !
评论
  目录