先主要学习二进制与十六进制的转换。
2-1 点亮一个LED
首先我先讲一下怎么在Keil5上写程序,并将Keil5上的程序下载到stc这个程序上,使单片机运行程序。
打开Keil5之后,点击左上角的project,再点击New uvision Project,之后在弹出的此电脑的桌面上新建一个文件夹,命名为KevilProject.之后在KevilProject这个文件夹里再新建文件夹以保存我们当前工程的文件夹。文件名起名为project即可,点击保存。在弹出的对话框输入AT89C52寻找单片机类型,在接下来弹出的对话框中选择否即可。之后点击Target 1左边的加号即会有Source Group1,选择Source Group1,右键点击添加新的文件到这个组里来,之后选择添加c语言的文件,在name里面起一个名字叫main,点击add.在KevilProject中输入点亮一个LED的c语言程序代码:
其中头文件需要我们在主函数的前面右键点击insert。因为我们的编译器不认识P2,而insert 这个文件中有P2。
下一步就是把这个代码下载到这个单片机里面:点击build之后,再点击output勾选项Create HEX File,点击OK即可保存代码。注意:保存为hex文件后需要点击build才能在stc中找到这个hex文件。打开stc这个软件,选择STC89C52RC这个单片机型号,点击打开程序文件,找到这节的文件夹,点击objects里面的Project.hex.,点击打开。点击下载,打开单片机的开关即可看到第一个LED灯闪亮。
2-2 LED闪烁
再新建一个工程,在KevilProject再新建一个2-2LED闪烁的文件夹,按第一次的操作进行即可。
LED闪烁的代码如下:
单片机运行这个程序时的闪烁速度特别快,人眼分辨不出。这时需要借助stc这个软件里面的工具:软件延迟计算器。在定时长度中选择我们要的延迟时间,指令集选择STC-Y1,点击复制代码,之后再在这个主函数上面Ctrl+V.由于我们的单片机不认识nop函数,所以还需添加#include <INTRINS.H>这个头文件。之后在主函数中调用这个Delay函数。代码如下:
将这个代码下载到stc上即可看到LED闪烁。
2-3 LED流水灯
LED流水灯的代码如下:
下面给出一个可以灵活改变延迟时间的代码:
这个代码与前面的区别就是在Delay中引入了函数参数,借助函数参数的代入改变延迟的时间。
3-1 独立按键控制LED亮灭
轻触按键:相当于是一种电子开关,按下时开关接通,松开时开关断开,实现原理是通过轻触按键内部的金属弹片受力弹动来实现接通和断开
以下是LED的六盏灯的接口
以下是四个独立按键的接口:
注意:K1为P31,K2为P30;
K1接口控制LED1亮灭的程序如下:
C51数据类型 |
类别 |
运算符 |
意义 |
类别 |
运算符 |
意义 |
算术 |
+ |
加 |
逻辑 |
&& |
逻辑与 |
- |
减 |
|| |
逻辑或 |
||
* |
乘 |
! |
逻辑非 |
||
/ |
除 |
位运算 |
<< |
按位左移 |
|
% |
求余 |
>> |
按位右移 |
||
= |
赋值 |
& |
按位与 |
||
判断 |
> |
大于 |
| |
按位或 |
|
>= |
大于等于 |
^ |
按位异或 |
||
< |
小于 |
~ |
按位取反 |
||
<= |
小于等于 |
||||
== |
等于 |
||||
!= |
不等于 |
||||
3-23
3-2独立按键控制LED状态
- 对于机械开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开,所以在开关闭合及断开的瞬间会伴随一连串的抖动。
下面是51单片机按键消抖的程序。
3-3独立按键控制LED显示二进制
话不多说,上代码:
注意:1、变量取反给P2的过程中变量的值不会变。
2、局部变量被定义时一定要附一个初始值,而全局变量被定义时默认是0。
3-4独立按键控制LED移位
这里需要注意是对0x01进行操作,跟之前左移右移没关系,不是在原来基础上又左移了。
看似是左移,其实是右移的个数变少了。
4-1 静态数码管显示
上面这张图是共阴极连接。
若要使数码管显示6这个数字,就需要给LED 10111110的段码,3、8号接口接地。
上面这张图是共阳极连接。
若要使数码管显示6这个数字,就需要把3、8号接口接在VCC,给01000001的段码。
要使数码管在第三位显示1,则需:
负极接高电平,可以保证LED灯不会亮。
138译码器的作用是减少单片机的io口。
P2口选中LED灯,P0口给段码数据。
子函数:将完成某一种功能的程序代码单独抽取出来形成一个模块,在其它函数中可随时调用此模块,以达到代码的复用和优化程序结构的目的
void Function(unsigned char x,y)
{
}
返回值 函数名(形参)
{
函数体
}
void Fun()
{
};
这个函数没有返回值,也没有参数。
a=Fun(8);用来接收Fun函数的返回值。
下面是静态数码管显示的代码,其中位选端是用 switch-case函数,段选端是用数组。
以下是数码管的段码表:
0 1 2 3 4 5 6 7 8 9 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,
A B C D E F 空
0x77,0x7C,0x39,0x5E,0x79,0x71,0x00,
4-2动态数码管显示
动态数码管显示的关键是要进行消影,因为在上一个段选之后,下一个位选开始,而下一个的段选还没有开始的时候,下一个还会沿用上一个的位选,造成串位,所有在进行下一个的位选之前,需要对上一个的段选清零。即:
其中延迟1毫秒是为了让显示的数字比较亮。P0=0x00即是对上一个的段码清零。
数码管的两种驱动方式:
1、单片机直接扫描:硬件设备简单,但会耗费大量的单片机CPU时间
2、专用驱动芯片:内部自带显存、扫描电路,单片机只需告诉它显示什么即可