控制/MCU
IO(Input/Output),即输入输出端口,就是单片机的IO口,STC89C52RC单片机具有4组IO口,P0~P3,每一组IO都有8个IO口,且8个IO口都可以单独读写,也就是说STC89C52RC单片机具备32个可以单独读写的IO口,这些端口可以通过程序来控制输出高低电平,高电平5V,低电平0V,也可以通过程序读取端口输入的电平状态,IO端口的操作有两种方式,一种是位带操作,这种操作是单独控制其中某一个IO端口,还有一种是总线式操作,就是可以同时给P0~P3这4组IO中的其中一组进行赋值,同时令8个IO口同时输出或者输入信号。
2.1 位带操作
2.1.1 原理图
2.1.2 数据的输出
第13行:利用sbit关键字定义一个端口名称,把P1.0端口定义成LED,之后的开发中,所有的端口定义都需要用到sbit关键字,这个格式需要牢记
第22行~第27行:延时函数,通过2级循环完成的延时功能,由于单片机外部时钟是12MHz,所以程序执行起来会非常快,如果没有延时函数,在这个实验中,就无法实现LED的闪烁功能(因为人眼并没有那么快)
第35行:控制P1.0输出低电平,即0V,由于硬件电路LED的正极通过一个电阻接到了5V上,根据二极管的单向导电性,当负极为0V时,LED就会发光,当负极为5V时,LED就会熄灭,电阻起到了限制电流的作用,防止电流过大烧毁LED
第36行:调用延时函数,设置延时500ms
第37行:控制P1.0输出高电平,即5V。
注:主循环里面的不停地将P1.0端口设置成0V和5V的过程就可以控制LED不停的亮灭,其中延时函数就是为了让人眼能够看到这个过程,如果没有延时函数,就会因为程序执行的过快导致无法看到闪烁的效果。
2.1.3 数据的输入
这段程序和上一段数据输出的程序差不多,重点看以下几个位置
第14行:利用关键字sbit定义端口P1.7在程序中的名称为KEY
第35行~第43行:检测按键是否按下的流程
(1)检测到P1.7端口为低电平,即0V,因为按键的一端接单片机P1.7端口,另一端接在了GND上,所以按下后端口被强制拉到0V,抬起后,单片机P1.7端口到恢复5V
(2)延时一段时间(延时去抖动):延时的原因是由于机械按键按下后不是严格的按下,而是会有一段电平不稳定的时间,所以需要用程序将这段时间的电平忽略掉
(3)经过10ms后再一次检测到P1.7位低电平,这时,才能够确定按键的确按下了,此时P1.0输出低电平点亮LED
第44行~第47行:按键没有按下时,P1.7是默认的高电平,此时控制P1.0输出高电平
2.2 总线操作
2.2.1 原理图
2.2.2 数据的输出
当控制这种多个LED的时候,位带操作就显得比较麻烦,因为光sbit定义就需要8个,所以此时可以直接控制P1寄存器来控制LED状态,通过直接将数据写入P1寄存器来控制LED状态。
第28行:定义P1寄存器数据,将8位二进制代码转换成16进制数据,由于LED接在了P1端口上,所以每个灯的状态如下表所示
LED0 | LED1 | LED2 | LED3 | LED4 | LED5 | LED6 | LED7 | 16进制数据 |
0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0xFE |
1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0xFD |
1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 0xFB |
1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0xF7 |
1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 0xEF |
1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0xDF |
1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0xBF |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0x7F |
其中LED7为数据最高位,所以数据应该是1111 1110,而不是0111 1111
第32行~第36行:利用for循环,循环8次将数据送入P1寄存器,P1寄存器的数据会直接映射在P1端口上。
2.2.3 数据的输入
数据输入这一部分代码明显少了很多,因为这里面不需要延时函数,所以直接删去了延时函数,在编程时,如果没有用到的函数可以直接注释掉或者删除,因为如果有函数没有调用,编译会报警告,但是并不影响程序执行结果,重点看17行的代码,将P3读取到的数据直接写入P1寄存器中,因为8个按键接在了P3端口上,LED接在了P1端口上,所以刚好可以通过按键来实现LED的控制。
全部0条评论
快来发表一下你的评论吧 !