单片机代码解析
知识点的问题解决了,但是这还远远不够,代码怎么办?
直接背,这是不可能的,一不小心就会背错一个数字或者字母,直接没分,而且,代码好难背啊。
要是理解了会不会好背一点呢?
带着帮助同学们的心情,我抽了几个课本上的源码给大家解析一下。1
话不多说,直接上代码。
基础准备
代码大题基本上都涉及到了中断的使用,在知识点复习过程中,包含有关中断部分的介绍,在这里结合代码复习一遍。
如下图所示,当我们需要使用中断时,需要打开相应的开关,在代码中就是将相应的中断允许位置1。
使用外部中断时,需要额外设置中断触发条件,下降沿触发或高电平触发。代码中就是IT0/IT1 置1或置0,或设置TCON寄存器。
使用定时器中断时,需要设置定时器的工作方式。即设置TMOD寄存器。
中断允许位置1,可以单独设置,也可以通过IE寄存器统一设置。
对于多个中断的项目工程中,可能需要设置中断触发优先级。代码中即为设置IP寄存器。但是题意中不需要设置中断优先级时,IP寄存器可不设置。
实例1
有一包装流水线,产品每计数12瓶时发出一个包装控制信号。试编写程序完成这一计数任务。用T0完成计数,用P3.7发出控制信号。
分析:
在本题中,涉及到定时/计数器的使用。首先应该想到对定时器的一系列初始化。
“ 用T0完成计数 ” 的隐含意义就是:总中断要打开,定时器要打开,定时/计数器设置为计数模式。
“ 计数12瓶 ” 隐含意义:计数内容不大,使用方式设置,初值计算。
解题过程:
第一步 分析:
在答题卡上写出答题过程,寄存器数值的由来,初值的由来。(不分析直接写也可以,但是保险起见,还是写上稳妥。)
由上图可知,我们要将EA、ET0置1,结果就是IE=1000 0010 → IE=0x82;
由上图可知,我们要将定时/计数器0的工作方式设置一下,GATE标志位为0,C/T标志位为1,C/T标志位为1时,定时计数器为计数模式。M1M0设置为8位自动重装载模式,M1M0为10。结果就是TMOD=0000 0110 →TMOD=0x06;
在定时/计数器的方式2工作方式下,初值的计算为X=2^8-N;即初值=256-12=244=0xf4。将0xf4送入TH0、TL0→TH0=0XF4;TL0=0XF4;
第二步 写代码:
1、程序框架
#include<reg51.h>
#define uchar unsigned char //宏定义,将unsigned char 重命名为 uchar
#define uint unsigned int //相当于是把尼古拉斯凯奇·德玛西·凯金更名为李狗蛋
void main(void)
{
while(1);
}
2、中断初始化
上面的分析和框架写好后,再一步一步添加内容,可以先将代码写在演草纸上,最后写在答题纸上。
将初始化的内容写上:
IE=0x82;
TMOD=0x06;
TH0=0XF4;
TL0=0XF4;
TR0=0; //打开定时/计数器,开始工作
这里可以使用函数。具有c语言基础的小伙伴可以跳过这部分,看第三代点。
#include<reg51.h>
#define uchar unsigned char //宏定义,将unsigned char 重命名为 uchar
#define uint unsigned int //相当于是把尼古拉斯凯奇·德玛西·凯金更名为李狗蛋
void init()
{
IE=0x82;
TMOD=0x06;
TH0=0XF4;
TL0=0XF4;
TR0=0; //打开定时/计数器,开始工作
}
void main(void)
{
init();
while(1);
}
3、数码管
题目中未明确要求使用数码管可将本部分省略。
在书本上我们看到一个code的标识符,作用是,将常量数组存储在ROM中。片内资源有限,所以将一些不会变的,不经常调用的,占用内存较大的数据存储在ROM中。
uchar code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF,0XC6};
//这里是共阳极数码管,如果题目中使用共阴极数码管,将上述数码管数组中的值展开成二进制,在取反即可。例如:0的值是0xC0,展开就是1100 0000,取反后就是0011 1111,转换为16进制就是0x3F。剩下同理。
一个数码管就要占用8个I/O口,当出现多个数码管时,会占用大量I/O口,但是单片机本身自带I/O口数量又不是很多,所以在出现多个数码管时,往往会使用3-8译码器,在这里先不过多讲解了。
4、主函数
本题中,主函数中的程序不算多,主要就是控制包装机。
while(1)
{
if(flag==1)
{
flag=0;
P3^7=0;//P3^7引脚是直接调用单片机I/O口,也可以先对P3^7口进行定义再调用
P0=tab[Conter];
Delay(20);
P3^7=1;
}
}
5、中断服务程序
void C0Isr() interrupt 1 //返回值类型为void 函数名为C0Isr 中断号为1
//函数名随意,只要自己好区分即可
//后面的中断号一定不要错了,这里使用的是定时/计数器0,中断号为1
{
Flag = 1; //用户自定义变量,主要作用类似于开关
Counter++; //用户自定义变量,主要作用计数
if(Counter==13)Counter=0;
}
其他实例
其他实例内容暂时为空,大家对教材上的代码有不理解的,可以将代码粘贴在评论区,作者会及时进行更新。
——————————————————————————————————————
本文纯原创,如有侵权请联系删除,如有错误,敬请批评指正,谢谢大家。
当然了,解析的有问题或者不太清楚可以私信或者在下面评论,我看到会及时更改。 ↩︎