51单片机C语言程序100例分析(1)IO+C语言+头文件
\\\插播一条:文章末尾有惊喜哟~///
P1=0xfe;//P1=11111110B,即P1.0输出低电平}
分析:通过这短短的几行代码就能够让51单片机的P1.0引脚输出低电平,首先#include<>>这句代码是包含51单片机寄存器定义的头文件,51单片机是寄存器和IO统一编址的,所以你往相应的寄存器中写1就会在对应引脚输出高电平,写0就会输出低电平,我们知道51共32个引脚作为IO端使用,所以只须要四个寄存器(一个寄存器是8位,这取决于数据总线),翻开头文件就会发现P0和0X80这个地址绑定了,所以编程的实质就是往内存中写值,又由于单片机是数字器件,所以只能读懂二进制,为什么是二进制?由于0对应低电平0V,1对应高电平5V足够了,没有第三种明确的状态。注意加粗的地方,要细品。单片机是控制器件而不是驱动器件,由于输出电流很小,不足以驱动某些须要大电流的外设。
//实例2:用单片机控制一个灯闪烁:认识单片机的工作频次
#include //包含单片机寄存器的头文件
/****************************************
函数功能:延时一段时长
*****************************************/
void delay(void) //两个void意思分别为没需返回值,没有参数传递
{
unsigned int i; //定义没符号整数,最大取值范围65535
for(i=0;i/做20000次空循环
; //什么也不做,等待一个机器周期
}
/*******************************************************
函数功能:主函数(C语言规定必需有也只能有1个主函数)
********************************************************/
void main(void)
{
while(1) //没限循环
{
P1=0xfe; //P1=11111110B,P1.0输出低电平
delay(); //延时一段时长
P1=0xff; //P1=11111111B,P1.0输出高电平
delay(); //延时一段时长
}
}
分析:写程序是自下而上的过程,而读程序是自上而下的过程,所以编写程序和读程序的流程是不同的。从零初始编写程序一般要先构思,再走一步看一步,当然我更喜爱修改代码以完成目标,所以提前准备典型实例能够大大提高编程效率。对于读代码是很常见的,准备典型案例的时候就要读懂,毕竟读懂是修改的前提,事实证明有些代码读着都费力,自己是万万写不出来的,所以在不适宜的时长选择发挥主观能动性就是愚昧的表现,你花你个月的时长未必能到达写代码的那个人的水平,但我看懂加修改用不了多久,剩下的时长我又分析的大量的案例,51的功能也进一步把握,这难道不香吗?也不说不提倡创造,而是不提倡闭门造车,创造力应该用在人类没有突破的地方,独有更多的人到达那个阶段才更有希望。每个人的人生经历都不一样,所以每个人都是一种可能,别人做不到不代表你做不到,他可能就是少了一点必要的经历,但只有可能多了,总有一个人会成功推进。
读程序能够直接看主函数,看到未定义的函数和变量再往外找,事实上编程也能够这样,先做方案再找人。这个代码没什么好说的,还是在围绕着引脚玩。在我的上一篇文章中,我说编程就像做菜一样,没看过的能够先去看一下,这里的头文件就是菜库,4个IO端口只占了其中的4个菜种。
//实例3:将P1口状态分别送入P0、P2、P3口:认识I/O口的引脚功能
#include//包含单片机寄存器的头文件
/*******************************************************
函数功能:主函数(C语言规定必需有也只能有1个主函数)
********************************************************/
void main(void)
{
while(1) //没限循环
{
P1=0xff; //P1=11111111B,熄灭LED
P0=P1; // 将P1口状态送入P0口
P2=P1; // 将P1口状态送入P2口
P3=P1; // 将P1口状态送入P3口
}
}
分析:内存的值只有没有代码去变更就会保持。这里关于端口的四个菜都上齐了,IO端口当然能够输写也能够输出。
//实例4:使用P3口流水点亮8位LED
#include //包含单片机寄存器的头文件
/****************************************
函数功能:延时一段时长
*****************************************/
void delay(void)
{
unsigned char i,j;
for(i=0;i
for(j=0;j
;
}
/*******************************************************
函数功能:主函数
********************************************************/
void main(void)
{
while(1)
{
P3=0xfe;//第一个灯亮
delay();//调用延时函数
P3=0xfd;//第二个灯亮
delay();//调用延时函数
P3=0xfb;//第三个灯亮
delay();//调用延时函数
P3=0xf7;//第四个灯亮
delay();//调用延时函数
P3=0xef;//第五个灯亮
delay();//调用延时函数
P3=0xdf;//第六个灯亮
delay();//调用延时函数
P3=0xbf;//第七个灯亮
delay();//调用延时函数
P3=0x7f;//第八个灯亮
delay();//调用延时函数
}
}
分析:注意二进制和16进制的转换就好啦,另外这里的例子都没有波及到位操作,不要着急,下面会有的。
//实例5:通过对P3口地址的操作流水点亮8位LED
#include //包含单片机寄存器的头文件
sfr x=0xb0; //P3口在存储器中的地址是b0H,通过sfr可定义8051内核单片机
//的所有内部8位特殊功能寄存器,对地址x的操作也就是对P1口的操作
/****************************************
函数功能:延时一段时长
*****************************************/
void delay(void)
{
unsigned char i,j;
for(i=0;i
for(j=0;j
; //利用循环等待若干机器周期,从而延时一段时长
}
/*****************************************
函数功能:主函数
******************************************/
void main(void)
{
while(1)
{
x=0xfe; //第一个灯亮
delay(); //调用延时函数
x=0xfd; //第二个灯亮
delay(); //调用延时函数
x=0xfb; //第三个灯亮
delay(); //调用延时函数
x=0xf7; //第四个灯亮
delay(); //调用延时函数
x=0xef; //第五个灯亮
delay(); //调用延时函数
x=0xdf; //第六个灯亮
delay(); //调用延时函数
x=0xbf; //第七个灯亮
delay(); //调用延时函数
x=0x7f; //第八个灯亮
delay(); //调用延时函数
}
}
分析:sfr还能够在头文件之外使用哦,虽然意义不大,但是你又学到了一个操作不是吗?这里能够不用包含头文件。
//实例6:用不同数据类型控制灯闪烁时长
如何使用 KEIL下载 HEX文件?
熟悉 KEIL的人都知道,KEIL下载时使用 axf格式的文件,里面不仅有代码指令信息,也包含了调试信息,假如C代码和汇编代码之间的对应关系(这些信息不会下载到单片机中,不然单片机可能装不下,哈哈),地址信息等。
事实上,KEIL也能下载 HEX文件,同时也能保存数据为HEX文件。
很多道友可能会问,既然有 axf文件,为啥还要学 HEX文件下载呢?我们知道,公司为了保密或者其他一些理由,不会给你源代码编译后再下载,还有一种可能是单片机有两份程序,BOOT_LOADER程序可能是别人编写与维护的,只给你 HEX文件,假如说你掌握了 KEIL下载方式,那么就不须要找其他工具下载了,方便快速(还有一种情况,代码使用 GCC编译,文件格式为 elf)。
所以,掌握 KEIL下载 HEX文件的方法还是很重要的。
那么今天鱼鹰就教你如何使用 KEIL下载 HEX文件到单片机中。
首先,复制一个 STM32工程模板(假如没有,去鱼鹰的公众号后台回复关键字获取)。
翻动工程,看看有没有勾选 HEX文件生成功能:
勾选这个只是为了让工程生成一个 HEX文件,方便我们做测试,在实际 HEX文件下载过程中,不须要勾选这个。
最后生成的文件的文件名你会发现和axf文件名是一致的,只是后缀不同,变成了 hex:
所以你在工程目录下能够搜到 rtthread-stm32.hex文件,为了接下来更好的进行说明,鱼鹰将这个文件名修改为 rtthread.hex,这样就不会认为我们接下来下载的是 axf文件了。
下载 HEX文件最关键的两点来了:
最后选择适宜的调试器,配置好下载 axf文件时的相关参数(即能用调试器正常下载 axf文件即可)。
最后点击下载按钮即可完成下载。
是不是很简略?
假如说经常须要下载hex文件,每次要新建一个工程、翻动工程、然后再修改参数,还是挺麻烦的,为了方便起见,我们能够为常用工程添加一个下载的宗旨,即多宗旨工程,类似这种:
这样一来,只有事先设置好,切换宗旨后,即可快捷完成下载,方便快速。
什么,你还不知道怎么设置多宗旨工程?看这里:
《STM32工程模板建设之Simu宗旨》
《STM32工程模板建设之RAM宗旨》
好了,鱼鹰再说说怎么保存 FLASH或者 RAM数据的问题。
有些时候,FLASH或 RAM保存了很多参数或者代码,假如通过串口助手之类的工具打印出来再保存不免有些麻烦,事实上 KEIL有命令能够帮助你快捷将一块数据保存为 HEX文件,假如鱼鹰想保存从地址 0x0800 0000初始,大小为 0xC00的数据,那么只有在 KEIL命令行输写以下命令即可完成保存,方便快速,你值得拥有:
当然,你也能够在该命令后增加以下参数(后面加一个逗号再跟这个参数)以实现不同的访问方式,是不是很贴心啊。
假如命令执行正确的话(上图表示命令已执行正确,假如不正确会报错的),你应该就能在工程目录下找到你所需的 data.hex文件了,然后用 HEX文件查看工具即可轻松查看,再也不须要串口打印啦!
彩蛋:最近有同学跟我要单片机的资料,我特意花几个月时间,总结了我产品研发经验,资料包几乎覆盖了C语言、单片机、模电数电、原理图和PCB设计、单片机高级编程等等,非常适合初学者入门和进阶。除此以外,再含泪分享我压箱底的22个热门开源项目,包含源码+原理图+PCB+说明文档,不是市面上打包卖的那种课程,我认为教程多未必是好事,前我自学快,除了自身执行力以外,还有就是教程少。不要害羞做伸手党,等你一个小红点。后期我也会组建一些纯技术交流的小圈子,让大家能认识更多的大佬,有个好的圈子,你对行业的认知一定是最前沿的。