SAM4E单片机之旅——1、LED闪烁之空循环

来源:本站
导读:目前正在解读《SAM4E单片机之旅——1、LED闪烁之空循环》的相关信息,《SAM4E单片机之旅——1、LED闪烁之空循环》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《SAM4E单片机之旅——1、LED闪烁之空循环》的详细说明。
简介:第一个程序就是控制板子上一个LED灯的闪烁,下面一起来学习一下:

最近因为导师要写一本关于SAME4单片机的书籍,而我也作为一个嵌入式的初学者看了这本书。现在也让我写写几个小的程序,做做示例。既然写了文档之类的,就发到博客上来吧。

目前关于这芯片能参考的书籍大概就只有英文手册了。用的板子是SAM4E16E。IDE用的是AtmelStudio。既然是学习单片机,就没有使用asf框架,而是直接采用访问寄存器的方法了。

第一个程序就是控制板子上一个LED灯的闪烁了。

一、电路

SAM4E单片机之旅——1、LED闪烁之空循环

通过查看电路图,可以发现有一个蓝色的LED灯连接在PA0引脚上。我们可以通过改变PA0输出的电平实现LED灯的闪烁。

二、寄存器的访问和CMSIS

对单片机的操作需要通过对相关寄存器的访问来实现。比如,为调节PA0引脚上的电平,首先我们需要允许PIOA控制PA0引脚。通过查看寄存器说明可知,这只要向相应的PIO使能寄存器(PIO_PER)写入0x01就可以了。同时,也可以查到PIOA的PIO_PER被映射到地址0x400E0E00上了。所以通过如下代码就可以达到目的:

/*假设unsignedint长度为32位*/

unsignedint*PIOA_PER_p=(unsignedint*)0x400E0E00u;

(*PIOA_PER_p)=0x01;

这样做非常繁琐,而且我们也不能保证unsignedint总是32位长。而且当我们换一块开发板的时候,外设的寄存器地址可能会不同,导致移植起来十分困难。

所以CMSIS出现了。

ARM®Cortex™微控制器软件接口标准(CMSIS)是Cortex-M处理器系列的与供应商无关的硬件抽象层。CMSIS可实现与处理器和外设之间的一致且简单的软件接口,从而简化软件的重用,缩短微控制器开发人员新手的学习过程,并缩短新设备的上市时间。

软件的创建是嵌入式产品行业的一个主要成本因素。通过跨所有Cortex-M芯片供应商产品将软件接口标准化(尤其是在创建新项目或将现有软件迁移到新设备时),可以大大降低成本。

《CMSIS到底是什么》介绍了大概介绍了CMSIS。在这里,我们可以使用它提供的微控制器专用头文件(我们这使用的就是sam.h了),这里提供里外设寄存器的定义,中断号码等:

#include

PIOA->PIO_PER=(uint32_t)0x01;

我们在以后的程序代码中也将使用CMSIS。

三、实现思路

PIO的引脚是复用的,但在这里我们直接使用PIO控制器控制引脚的电平就可以了。可以通过向PIO_SODR、PIO_CODR写入特定的值来直接控制引脚的电平。

然后,通过让程序执行一个次数较长的空循环就可以实现延时功能。

四、代码

实现较为简单,直接看代码就可以了(需要运行Debug模式下产生的代码):

#include

intmain(void)

{

/*PIO控制器直接控制PA0引脚*/

PIOA->PIO_PER=(uint32_t)0x01;

/*PA0输出使能*/

PIOA->PIO_OER=(uint32_t)0x01;

/*PA0输出写使能*/

PIOA->PIO_OWER=(uint32_t)0x01;

while(1){

/*设置PA0引脚为高电平,灯灭*/

PIOA->PIO_SODR=(uint32_t)0x01;

/*延迟*/

for(inti=0;i<1024*1024*2;++i)

;

/*设置PA0引脚为高电平,灯亮*/

PIOA->PIO_CODR=(uint32_t)0x01;

for(inti=0;i<1024*1024*2;++i)

;

}

return0;

}

五、编译器优化的副作用

上面的示例代码中,通过空循环实现延迟的语句出现了两次。很自然的会想到要将这些语句提出成一个函数,甚至可以使用一个参数来大致控制延迟时间的长短:

voidDelay(intnum)

{

for(inti=0;i<1024*1024*num;++i);

}

然后试着通过这个函数来进行延迟。很遗憾,再运行程序时我们发现LED会一直亮着,而不会闪烁。即使是在Debug模式下,编译器也把这个函数调用给优化掉。类似的情况也会出现不少,这给我们对程序的调试造成一定的不便。原因是AtmelStudio默认的Debug配置中,使用了O1级别的优化,可以在项目属性中关闭它。

我们试着使用宏来实现这个“函数”:

#defineDelay(num)

do{

for(inti=0;i<1024*1024*(num);++i);

}while(0)

再运行一下,很好,LED又开始闪烁了。

程序发布的时候,我们一般会使用Release模式生成代码。AtmelStudio使用的gcc编译器果然“不负众望”,把这个空循环语句直接优化掉了。

我们可以使用如下语句阻止编译器的优化:

for(inti=0;i<1024*1024*num;++i)

asm("");

或者使用volatile关键字:

for(volatileinti=0;i<1024*1024*num;++i);

提醒:《SAM4E单片机之旅——1、LED闪烁之空循环》最后刷新时间 2024-03-14 00:53:43,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《SAM4E单片机之旅——1、LED闪烁之空循环》该内容的真实性请自行鉴别。