I/O控制对于单片机而言是最基础最核心的东西,其实单片机除了模/数转换之外的事情。其他大部分的事情I/O口都能做的到。I/O控制简单却能千变万化。
单片机在大部分应用中做的事情,莫过于 输入高低电平 ,输出高低电平。就是通过这简单的控制电平来实现大多数的应用控制。
1. 什么是 I/O 口?
I 表示 IN(输入),O 表示 OUT(输出),所以 I/O = 输入/输出
2. I/O 具体能做什么呢?
如果你是刚刚步入电子的新手,那你最好要知道一下I/O口具体能做什么。感性的认识对你的学习是很有帮助的。I/O口输出一个高(低)电平可以用来点亮一个LED灯,可以接通过一个继电器来开启电机,来开启音响。开启许多的东西,也可以用于通信等等。输入一个高(低)电平 可以用来检测按键,检测红外线输入 ,检测信号等等。
3. I/O口和单片机内部寄存器之间的对应关系
首先看下一个芯片的原理图。 注意 RA0~RA5 这些口
RA端口的方向控制寄存器:TRISA(三态,tristate)
TRISA 寄存器占用一个字节(8位),每位代表一个引脚的方向:0表示输出模式(Out),1表示输入模式(In)
U-0 | U-0 | R/W-1/1 | R/W-1/1 | R-1/1 | R-1/1 | R-1/1 | R-1/1 |
- | - | TRISA5 | TRISA4 | TRISA3 | TRISA2 | TRISA1 | TRISA0 |
Bit 7 | Bit 0 |
RA3 默认位 1,无法修改
该表格摘自数据手册,不同的芯片略有不同,具体参见所使用芯片的数据手册
RA端口的数据控制寄存器:PORTA
U-0 | U-0 | R/W-x/x | R/W-x/x | R-x/x | R/W-x/x | R/W-x/x | R/W-x/x |
- | - | RA5 | RA4 | RA3 | RA2 | RA1 | RA0 |
Bit 7 | Bit 0 |
该表格摘自数据手册,不同的芯片略有不同,具体参见所使用芯片的数据手册
RA端口的模/数控制寄存器:ANSELA
ANSELA 寄存器占用一个字节(8位),每位代表一个引脚的模/数:0 = 数字I/O口,1 = 模拟输入口
U-0 | U-0 | U-0 | R/W-1/1 | U-0 | R/W-1/1 | R/W-1/1 | R/W-1/1 |
- | - | - | ANSA4 | - | ANSA2 | ANSA1 | ANSA0 |
Bit 7 | Bit 0 |
该表格摘自数据手册,不同的芯片略有不同,具体参见所使用芯片的数据手册
U-0 表示未实现位,读数为0;-n/n 表示POR 和BOR时的值/所有其他复位时的值
当将某个引脚设置为模拟输入时,必须将相应的 TRIS 位设置为输入模式,以允许从外部控制引脚电压。
通过上面的原理图和三个表格,可以很容易看出原理图中的 第2脚( ".../RA5")相关的寄存器:TRISA:TRISA5 和 PORTA:RA5,同时该脚不具备模拟输入功能
4. 如何控制I/O口?
其实控制单片机,就是控制寄存器上的各个位,设置成高(1)或者低(0)。
TRISA 寄存器是方向控制寄存器。就是控制 I/O 脚输入还是输出。比如 TRISA:TRISA5 位设置为 0,那么RA5口是输出,反之则为输入。(为了方便记忆,可以把 0 看成 Output, 1 看出 Input);
将RA5口设置成 输入 的几种方式(C语言):
第一种:TRISAbits.TRISA5=1; // 简单明了,只影响一个位 设置单个I/O比较方便
第二种:TRISA |= 0x20; // 0x20 = 0b0010 0000,不够明了,只影响一个位
第三种:TRISA = 0x20; // 0x20 = 0b0010 0000,不够明了,影响到其他位,设置多个I/O用比较方便
将RA5口设置成 输出 的几种方式(C语言):
第一种:TRISAbits.TRISA5=0;
第二种:TRISA &= ~0x20;
第三种:TRISA = 0x00;
PORTA 寄存器是数据控制寄存器。
如果是输出状态:PORTA:RA5 为 0,则 RA5引脚 输出低电平;PORTA:RA5 为 1,则 RA5引脚 输出高电平。
如果是输入状态:PORTA:RA5 为 0,则 RA5引脚 当前为低电平,PORTA:RA5 为 1,则 RA5引脚 当前为高电平。
5. 实例程序
如果在RA5口上连接着一个LED灯。我们将如何点亮他呢?
// 头文件
#include<pic.h>
// 单片机配置字
__CONFIG(FOSC_INTOSC&WDTE_OFF&PWRTE_ON&MCLRE_OFF&CP_ON&CPD_OFF&BOREN_ON&CLKOUTEN_OFF&IESO_ON&FCMEN_ON);
__CONFIG(PLLEN_OFF&LVP_OFF) ;
// 主程序
int main(int argc, char** argv) {
ANSELA = 0; // 将RA口全部设置成数字口,
TRISAbits.TRISA5 = 0; // 设置RA5为输出
PORTAbits.RA5 = 1; // 设置输出高电平点亮LED
while(1);//程序在此无限循环
}
头文件:程序中只要有了 #include<pic.h> 编译器就会去自动找到相应型号的头文件,头文件中定义好了每个寄存器的地址,位的地址等。
配置位:这是十分重要即使程序没有任何错误 配置位没配置好程序一样不能用。
模拟数字口:在使用I/O口的时候要确保对应的I/O口是被设置成数字口的。