0%

单片机学习入门(一)

单片机学习本身是一个了解学习一个技术的过程,学习的过程中不应该拘泥于某一款,而是要了解学习的方法。

同时学习技术较快的方法是完成一个完整的项目,同时记录学习中遇到的问题整个培训下来会提供一个或者多个具体的例子供学习,也可自由发挥。

教程首先会简述单片机的学习方法,然后讲解具体的细节,然后讲解具体的项目来完成学习过程。

本教程会以 MSP430 单片机为主进行讲解,对于接触单片机的初学者,同时推荐阅读《Launchpad口袋实验平台 (指导书)》.


从零开始的MSP430单片机学习(一)

1.MSP430单片机开发介绍

1.1 前情提要

MSP430单片机是德州仪器( TI )出品的以超低功耗为主要特点的16位单片机系列产品,采用精简指令集( RISC ),其称为混合信号处理器,其单片集成了数字、模拟模块以及处理器。

TI 官方提供了一些板卡( launchpad ),作为仿真器和核心板在一块板的方式提供用来学习开发。

例如我们即将用到的 MSP-EXP430G2(-ET) 。

对于其他类型的单片机,市面上常见的8051系列产品(如STC、WCH等),ARM产品(如ST、NXP等),有的也有官方提供的核心板或者网上有卖家提供的产品。

1.2 G2 launchpad 介绍

  • 对于已有的资源,首先进行了解方便后续的学习

    1.2.1 从官方下载板卡资料。

    从官网可以找到 MSP-EXP430G2 的产品资料,对于 TI 的产品还有别的方法进行下载,将在后面开发环境章节进行介绍。

    找到 MSP-EXP430G2 Hardware Design Files ,其中包含了设计原理图(有助于在硬件连接的时候进行参考),设计PCB文件。

    在这个产品提供的硬件设计资源(原理图和PCB文件)为 Eagle 所制造,其文件可以用Eagle或者 Fusion 360 打开查看:

    image-20210405185841746 image-20210405185950827

    一般查看PDF文件即可。


    在PDF查看原理图的时候,可以看到电路分为三部分,其中包含了接口,仿真器和单片机最小系统(后面称之为核心板)。

    简单介绍一下 Launchpad 的组成:

    下载器通过单片机的SWD接口可以下载程序到单片机,同时可以访问单片机内部资源因此可以仿真,这个下载器是TI的专用下载器,在 MSP-EXP430G2 这块开发板上,使用的下载器限制较大,只能下载部分MSP430单片机,同时提供一个串口用来连接调试。在新版的 MSP430G2553 开发板 MSP-EXP430G2ET 上,以及其他430 launchpad 上,使用的下载器为硬件开源的 MSP430_ezFETLite ,具有更好的性能,可以下载几乎所有的MSP430系列单片机,同时提供串口。

1.2.2 从官方下载芯片数据和用户指南手册以及例程。

不同的单片机厂商都会在其产品主页提供用户手册和产品数据表供使用。对于 TI 的产品,可以直接在其官网搜索对应的产品型号并点击进入,或者在CCS中下载其产品支持包,这个方法在开发环境章节中讲解。顺便一提,如果使用Bing或者Google作为搜索引擎,直接搜索找数据表和手册是一件很容易的事情。

同时,对于单片机类产品,通常官方会提供例程供开发使用,因为单看手册就写有点麻烦。这里以MSP430G2553 为例,讲解一下如何在毫无了解的情况下进行入门:

进入产品主页之后,首先可以看到数据表(datasheet)和用户指南。这些肯定是要查看的。

同时,点击技术文档,可以看到 TI 提供的更多相关技术的文档 ,可以进行下载阅读。

比较重要的是,设计与开发,点击后,可以看到 TI 提供了指示,提示应该用什么方法进行开发,使用什么软件,最后一项:

提供了代码例程。

对于其他厂商的单片机同理,不过这里可以先不下载,因为有更方便的方法。

可以看到,设计与开发中,其指示了用于MSP的 集成开发环境。

这就是下一章节所需要讲解的。

1.2.3 硬件信息补充

针对 TI 的开发板,其只是一个核心板,因此如果需要扩展功能,可以引线出来,也可以通过外接拓展板,这个拓展板子TI为其提供了一个通用的格式,称之为 BoosterPack 插件,可以通过这个模板进行自己的开发。

1.3 集成开发环境介绍

要进行单片机开发,首先选择合适的集成开发环境( IDE ),并基于这个IDE进行开发。

首先,可以认为,官方所提供开发的集成开发环境通常是最方便的,因为能得到较好的技术支持,而且官方提供的 IDE 通常是免费的。

在上一章节中,在设计与开发内,TI 介绍了 Code Composer Studio (CCS) ,也介绍了IAR 嵌入式工作平台 Kickstart - 免费 8KB 版本.

其中,可以看到:

image-20210405194214472

CCS 作为官方IDE,内容是更多的。可以从官网获得更多技术支持。

在区别上,CCS内建的编译器和IAR的编译器存在一些不同,同时还有开源产品MSP430-GCC 也可以用来编译代码,所以在官方提供的例程中可以看到一些预编译的符号用来区分不同的编译器。

CCS 是基于 eclipse(开源的 IDE)开发,瑞萨的 E2studio ,意法半导体(ST)的 STM32CUBEIDE 都是基于 Eclipse 设计,所以基本用法类似,所以使用IDE的快捷键以及操作可以通过在搜索引擎上以 Eclipse 为关键词进行搜索。

同时 CCS 也是 TI 官方推荐使用的IDE , TI甚至提供了基于云端的CCS cloud 可以进行开发。加之CCS更具专业性,后面所讲的开发环境都会基于CCS讲解。


说到专业性,TI 也提供了一个不那么专业的 IDE –– Energia , 其实就是一个红色版本的 Arduino ,只不过可以使用 TI 自家的板卡。其使用了与 Arduino 相同的语法和库,所以开发板卡在某些应用上更快更简单,但是如果想要使用开源社区的库以及社区提供的更多的板卡支持,推荐使用基于 VS codeplatform IO 代替 Energia , 其具备更好的技术支持,同时VS code 的编辑功能也更加强大,由于非常简单且可以参考Arduino学习,这里只做简单介绍,后面不在赘述,可自行学习。

image-20210405195810787 image-20210405200009851

2.使用CCS开发自己的第一个单片机程序–Blink

单片机到手第一件事情–正如一门编程语言第一件事是输出hello word – 便是点亮一个LED ( 有的 MSP430 单片机可以通过调试台输出 Hello world,G2553 不行,因为资源不足 ) 。

这里如果更愿意查看视频,可以选择查看视频教程:新建工程 资源搜索器 调试功能使用

2.1学习使用CCS

2.1.1 新建工程与导入导出工程

首先是CCS 进行安装,这个需要注意安装包路径以及安装路径以及电脑用户名(因为使用了临时目录包含用户名)不要包含中文以及其他非ASCII码值的符号。

打开CCS后首先选择工作空间,即放置工程的文件夹。

然后新建一个CCS工程。

不同的版本可能有不同,但是整体上都是点击顶部菜单栏-File - new -project(CCS project),或者直接选择菜单栏上的Project - new CCS project.


如果需要导入外部工程,点击File -import -CCS project ,跳出弹窗 :

  1. select search directory 为选择工程所在的文件夹;
  2. select archive file 为选择打包的工程文件压缩包。

然后选择导入,最好选择Copy Projects into workspace.

同样,导出选择File export 选择archive file,实际上这个就是个压缩包功能。


新建工程的界面可以看到:

image-20210405211710941
  1. 其中 Target 可以直接搜索所使用的单片机,这里我们使用的单片机型号是MSP430G2553,所以进行选择。
  2. Connection 是连接单片机的方式,这里保持默认也就是使用板载仿真器。
  3. 然后命名你的工程 Project name , 推荐工程使用文件名加日期方便管理加信息(例如 demo_blink_20210401_ver1 )
  4. 其他Tool-chain选择保持默认,最下面提示的Resource Explorer 将在后面介绍。
  5. 在最下面的模板中,可选择空工程或者基本例程,这里点击基本例程 blink the LED, 对这个例程进行讲解。

补充:集成开发环境(IDE)的作用在于简化流程,这样不必使用命令行进行编译,不用使用make等工具来编辑编译参数,而是使用图形化的方式来进行配置,因此,每一个工程都有配置,一个源文件只有在工程内部才能进行正确的编译。

而工程的概念对于使用C语言的的初学者可能不是很明确,因为在以往的学习中通常编译单个文件较多,建议复习C语言部分或者通过其他方式加深学习C语言问题。

简言之,这是一个C语言的编译的问题。

例如,右键你的工程,最下面的properties,可以看到,

image-20210405215210503

这里可以进行配置编译选项,这里暂时不多说。

2.1.2使用资源浏览器(Resource Explorer )

在第一章节中提到,如何从官方获取资料,针对TI 的产品,可以点击CCS 顶部菜单栏 -View -Resource Explorer 点开之后,

例如现在学习的是G2553, 那么直接搜索,可以看到

image-20210405212620621
  1. 首先点击 install 进行安装 MSP430Ware ,

  2. 点击MSP-EXP430G2展开,它集成包含了我们现在所用的板卡的所有资源。

    image-20210405212820390

Demo中包含了一些应用例程,而Peripheral Examples(外设例程)选择MSP430G2553,可以看到Assembly –也就是汇编 ,和Register Level ( 寄存器级例程 ),也就是这里只有寄存器编程没有库函数编程。

下面的 xx.c 文件指示了不同外设的例程,例如需要使用IO,

image-20210405213926925

这些文件是下载后(也就是前面的install)存在本地的,路径与CCS安装路径相同,推荐安装软件 everything 搜索对应的文件名,可以直接点击到文件夹查看。

2.1.3使用调试功能(debug)

回到刚刚新建的例程Blink the LED。

  • 点击菜单栏上的锤子,也就是Build进行编译。

简单说一下,如果没有点击编译,点击Build会首先编译程序,但是如果程序编译后修改了再点击debug,会载入上一个程序,但是有一个技巧就是,再debug中如果修改了程序,点击编译,可以勾选自动载入新的程序,这样比停在再debug更快。


编译完成之后点击绿的虫子图标进行debug,所谓debug,在PC上进行程序debug时候可以进行单步运行或者查看变量,这里同样。

点击箭头即可开始运行,关于其他图标的作用,可以鼠标挪到图标上等待出现文字提示,其中有暂停,停止,单步运行,单步跳过,单步返回。

在程序中可以在代码前面行号上双击添加断点。其实这些是一些基本调试方法。

  • 在调试中可以查看变量的值或者寄存器的状态。

首先点击顶部菜单栏 View ,可以分别打开Expressions 、Registers

在Expressions 中可以查看想要的变量,手动填写或者在程序中选择要添加的变量,右键,然后:

image-20210405220511081

对于MSP430单片机,在程序中添加断点,当程序暂停才可以查看添加的变量当前的值。

同理,Register窗口可以查看所有寄存器的值。

image-20210405220652715

对于上述操作,可以查看调试功能使用 视频演示。

2.2 开始学习第一个程序

回到例程,在2.1章节中讲到,G2553官方只提供了寄存器级别的例程,因此这里开发也会基于寄存器。

往往通过例程会更简单,因此这里首先查看例程进行学习。

 #include <msp430.h>                    //首先包含头文件      
/**
* blink.c
*/
void main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
P1DIR |= 0x01; // configure P1.0 as output

volatile unsigned int i; // volatile to prevent optimization

while(1)
{
P1OUT ^= 0x01; // toggle P1.0
for(i=10000; i>0; i--); // delay
}
}

这个程序是例程Blink the LED ,回到第一章节中的原理图,可以看到在G2 launchpad上,P1.0引脚通过跳线帽连接了一个LED.

因此任务目标是使P1.0循环输出高低电平。

2.2.1 GPIO

所谓GPIO,就是通用输入输出的缩写,其作为数字IO,只能输出高电平或者低电平,由于MSP430G2553 使用3.3V供电(也可以更低)

,当前输出的高电平就是3.3V.

WDTCTL = WDTPW | WDTHOLD;        // stop watchdog timer
P1DIR |= 0x01; // configure P1.0 as output

在程序的主函数的开始,首先第一句要关闭看门狗,看门狗是放置单片机程序跑飞的一个外设,具体会在后面讲解,由于这里不需要这种功能,所以关闭,这里先不讨论其具体含义。

然后程序写了P1DIR = P1DIR | 0x01;

表示读取P1DIR寄存器并和0x01做或运算并写入P1DIR;

这里P1DIR就是一个寄存器,包含八个bit,控制着P1整个端口8个IO的输入输出方向的配置,其每一个bit控制着一个IO

回到单片机的用户指南,《MSP430G2553用户指南》,在数字IO部分(P327):

image-20210405221926400

可以看到,寄存器的功能在于配置引脚的方向。

在《MSP430G2553datasheet》中可以看到引脚结构:

初学者接触可能感觉比较混乱,可以先不管上面这张图。

while(1)
{
P1OUT ^= 0x01; // toggle P1.0
for(i=10000; i>0; i--); // delay
}

然后这里控制了P1OUT,并与0x01做异或运算。

也就是说,从P1OUT第0位到第7位,分别于0 0 0 0 0 0 0 1 做异或运算(同为0,异为1),那么,对于从第1位到第7位,值不会改变,只有最后一位随着每次运算都会翻转,这样通过一句代码完成P1.0的点亮和熄灭。

下一句的10000次的循环是一个简单的延时。

如果对于二进制的数值没有那么敏感,可以使用头文件包含的宏定义 BIT0-BIT7;

例如:

while(1)
{
P1OUT ^= BIT0; // toggle P1.0
for(i=10000; i>0; i--); // delay
}

在CCS中,按住Ctrl键,同时点击变量即可查看变量的定义位置,按住Ctrl点击BIT0, 可以看到其宏定义的内容:

image-20210405223334092

顺便一提,在CCS中代码自动补全的快捷键是Alt+/。

当然这些快捷键是可以自定义的。

2.2.2 继续点灯

对于launchpad板卡,可以观察到有2个LED灯,从原理图上可以看到,这两个LED分别连接于P1.0和P1.6 , 因此下一个任务是点亮两个LED。

这里应该完成练习然后查看下面答案。

while(1)
{
P1OUT ^= (BIT0|BIT6); //
for(i=10000; i>0; i--); // delay
}
while(1)
{
P1OUT ^= 0x41; //
for(i=10000; i>0; i--); // delay
}

或者

while(1)
{
P1OUT ^= 0x41; //
__delay_cycles(1000000); // delay
}

这里的不同在于调用了一个__delay_cycles(1000000);

这个__delay_cycles();是调用一段汇编,进行N次空操作,也就是一个延时,但是由于使用汇编语句,所以相比for或者while循环更为准确。其参数只能是一个定值。

同样,程序可以写成交替点亮两个LED.

至此,单片机入门的第一个Hello world完成了。

有了前面的基础,后面的学习将有效率。