一、引言
我写这篇博客的主要是介绍一下,自己在嵌入式的学习路线,在每一个阶段自己干了什么?学习了什么?遇到了什么问题?如何解决?在该阶段结束之后学会了什么?一是,通过我的经历帮助到那些零基础小白想走嵌入式方向,且不愿意报培训机构的人。二是,记录自己的成果,使自己的学习可视化,同时也方便后面自己回顾。
二、基础知识准备
首先,C语言的学习,对于想嵌入式方向是非常重要的。在我学习51单片机阶段,用的最多有define、typedef、for、while、switch-case、static、extern、函数等,网上有很多讲C的up主,我最推荐的是比特鹏哥,我在大一时经常看他的课程。本次我简单介绍一些用的比较少的,如typedef、static这些。上面的都是重点,大家自行学习。
2.1 typedef 关键字介绍
typedef——是 C/C++ 中的一个关键字🔍,作用是根据作者需要为现有的数据类型(int、char、float、double等)自定义一个新的名字,目的是为了方便代码的阅读、理解和使用。
2.1.1 typedef 的基本用法:
typedef 原类型名 新类型名;typedef 创建的符号与 #define 不同只受,之受限于类型,不能用于值的定义。
2.1.2 typedef 在C51中的使用
//定义 typedef unsigned char u8; //无符号字符型,占1byte(8bit) typedef unsigned int u16; //无符号整型,在单片机占2byte(16bit) //使用 u8 i = 0; u16 j = 0;typedef 在结构体比较常用,但我在学习51单片机阶段,还未使用过,所以就不做过多的赘述,如果你想学习可以看专门介绍该关键词的博客,我主要介绍在单片机学习过程中比较重要的,希望通过的介绍,可以让大家少走弯路。个人觉得用的时候再去学习记忆会更好。
2.2 static 关键词介绍
static——是C语言的一个关键词,根据写的位置不同有三种作用:
1.在函数内部,称为静态局部变量;
2.在函数外面,称为静态全局变量;
3.在函数前面,成为静态函数。
而在51单片机学习阶段,主要用到了静态局部变量和全局变量。我会对这两个部分进行简单的介绍,如果大家想进行更加细致的学习,可以去通过哔站或其他博客进行学习。
2.2.1 static 作为静态局部变量
#include <stdio.h> void function(); //对自定义函数的声明 int main() { for (int i = 0; i < 8; i++) { function(); //循环调用函数 } return 0; } /**************************************** *函数名称:function *函数功能:静态打印num *输入参数:无 *输出参数:无 ****************************************/ void function() { static int num = 0; printf("num = %d\n", num); num++; }上述代码运行结果为:
num = 0
num = 1
num = 2
num = 3
num = 4
num = 5
num = 6
num = 7
如果去掉关键词 static ,则输出的结果全为0。在学习单片机的时候我们会通过调用函数统计循环次数,如果不使用关键词 static 则每次都是同样的结果,static 就能很好的解决函数调用时重新初始化这个问题。
2.2.2 static 作为静态全局变量
#include <stdio.h> static int num = 0; //静态全局变量 /**************************************** *函数名称:function1 *函数功能:静态打印num *输入参数:无 *输出参数:无 ****************************************/ void function1() { printf("num = %d\n", num); num++; } /**************************************** *函数名称:function2 *函数功能:静态打印num *输入参数:无 *输出参数:无 ****************************************/ void function2() { printf("num = %d\n", num); num++; } int main() { for (int i = 0; i < 4; i++) { function1(); //循环调用函数 function2(); } return 0; }上述代码的运行结果,与前面的静态局部变量的一样。在函数外定义,所有函数都可以对其在原来值的基础上进行修改;而在函数定义,仅能在定义函数中使用和修改。
二、板子的准备
本人,是计算机专业的,机缘巧合下对嵌入式产生了浓厚的兴趣,首先是买了一个“普中科技51单片机”,当时我没有经验,总想一次买全,花了很多冤枉钱,很多部件还在吃灰,我买的版本是“A4套件6,价格是166元,包含开发板+舵机控制风扇+浇水套件+超声波模块+步进电机+WIFI模块+8266模块”,在我整个51学习的阶段这些额外的模块基本没用过,强烈建议大家买最基础的版本,不要图懒省事,想一次性买全,我就是太追求完美了。其他模块如果想学可以单独买或者在stm32上学习。等我后续学完stm32我会给大家分享。
嵌入式的学习,不是一门一门循循渐进的,需要你尽量早点上手操作,在学习的过程中发现问题、解决问题,查漏补缺。我是没有数电模电的基础,遇到哪些不会的,就去补那一块,这样更有针对性,对我来说记得也更牢。
我有一定的C语言的基础,在研零的开始准备学习嵌入式,我用了大概3个月的时间,到研一开学9月底才把51单片机学完。其实我是有点拖沓的,按理说不该花这么长时间。其中,踩了很多坑,我把普中的所有网课都看了,其中有很多没用的。建议大家把“LED、数码管、独立按键、中断、时钟、串口通信、IIC”重点学习。
三、Keil 5环境搭建
注意Keil 5有两种,一个是Keil uvision5 MDK版本的,这个是用来编译stm32的;另一个是Keil uvision5 C51,这个才是我们学习51单片机所需要环境。给大家推荐个公众号“火耳软件安装”,这里面有很多常用的软件,以及对应的安装教程,不过需要有相应的网盘会员。我把Keil uvision5 C51 v9.61的安装渠道放在下面:
- 下载渠道①迅雷云盘下载链接:https://pan.xunlei.com/s/VOtqy_lmnSD8-NtcbQnLfi2IA1?pwd=epts#
- 下载渠道②夸克网盘下载链接:https://pan.quark.cn/s/8e8a51bb4d8f
- 下载渠道③百度网盘下载链接:https://pan.baidu.com/s/1dQe8T-mo2qJ_a344sWUbAA?pwd=hrrj
3.1 Keil如何调整字符大小
通过下面的步骤可以根据自己的情况,调整代码的大小,便于更好的阅读。
四、常用的函数或功能
4.1 函数说明的格式
这是一个比较好的习惯,我们要从日常养成,只有每次都这样写,才能更加熟练运用。这种书写格式,不仅有利于自己的阅读,也能帮助后面调用的时候不迷茫。
/************************************************** *函数名称: *函数功能: *输入函数: *输出函数: **************************************************/4.2 延迟函数
在51单片机学习过程中,延迟函数需要经常用到。如在流水灯实验中,使用延迟函数,为了让人眼能够辨别闪烁,如果延迟过低(低于0.5ms),人眼无法辨别,即使灯在闪烁,而人眼看到的却是常亮。下面是两个常用的延迟函数,一个是微秒级的,一个是毫秒级的。
typedef unsigned char u8; //无符号字符型,在Keil C51中,占1字节(8bit) typedef unsigned int u16; //无符号整型,在Keil C51中,占2字节(16bit) /********************************************************************* *函数名称:delay_10us *函数功能:每传一个数,就延迟约10us *函数输入:无符号整型 *函数输出:无 *********************************************************************/ void delay_10us(u16 ten_us) { while (ten_us--); } /********************************************************************* *函数名称:delay_ms *函数功能:每传一个数,就延迟约1ms *函数输入:无符号整型 *函数输出:无 *********************************************************************/ void delay_ms(u16 ms) { u16 i, j; for (i = ms; i > 0; i--) for (j = 110; j > 0; j--); }4.3 传输数据
将num按二进制一位一位的取出并传输。
//方法一: for (i = 0; i < 8; i++) { receive = num >> 7; //将num的最高位赋给receive,先将num右移7位,左边补7个0 num <<= 1; //将num的次高位移到高位上,即num左移一位 } //方法二: for (i = 0; i < 8; i++) { receive = num >> (7 - i) & 1; //将num右移7-i位,然后和1进行与运算,即可取出num中的每一位 }五、总结
通过这一阶段,我对Keil的使用更为清晰,如中断是如何触发的、串口通信、在I2C协议中学会了如何创建一个完整的工程和串行数据线与串行时钟线的使用、在时钟这一章节学会了BCD码转十进制、以及通过时序图来编写相应的函数及对应功能……我第一次了解到一个比较完整的项目,以及项目的结构和框架。以上就是我对这一阶段的小总结,希望自己可以一直坚持下去,做的越来越好。也请各位给我一点建议,谢谢!
我清晰的知道以现在的自己对于找工作还存在着很大的问题,在下一阶段我会认真学习开发板stm32F103VET6,主要是标准库与HAL库的学习。希望自己能够找到一个满意的嵌入式工作。