最近由于导师要写一本关于SAME4单片机的书本,而我也作为一个嵌入式的初学者看了这本书。现在也让我写写几个小的程序,做做示例。已然写了文档之类的,就发到博客上来吧。
现在关于这芯片能参阅的书本大约就只有英文手册了。用的板子是SAM4E16E。IDE用的是Atmel Studio。已然是学习单片机,就没有运用asf结构,而是直接选用拜访寄存器的办法了。
第一个程序便是操控板子上一个LED灯的闪耀了。
一、电路
经过检查电路图,能够发现有一个蓝色的LED灯连接在PA0引脚上。咱们能够经过改动PA0输出的电平完成LED灯的闪耀。
二、寄存器的拜访和CMSIS
对单片机的操作需求经过对相关寄存器的拜访来完成。比方,为调理PA0引脚上的电平,首要咱们需求答应PIOA操控PA0引脚。经过检查寄存器阐明可知,这只要向相应的PIO使能寄存器(PIO_PER)写入0x01就能够了。一起,也能够查到PIOA的PIO_PER被映射到地址0x400E0E00上了。所以经过如下代码就能够到达意图:
/* 假定 unsigned int长度为32位 */
unsigned int* PIOA_PER_p = (unsigned int*)0x400E0E00u;
(*PIOA_PER_p) = 0x01;
这样做十分繁琐,并且咱们也不能确保unsigned int总是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
int main(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 (int i=0; i<1024*1024*2; ++i)
;
/* 设置PA0引脚为高电平,灯亮 */
PIOA->PIO_CODR = (uint32_t)0x01;
for (int i=0; i<1024*1024*2; ++i)
;
}
return 0;
}
五、编译器优化的副作用
上面的示例代码中,经过空循环完成推迟的句子呈现了两次。很天然的会想到要将这些句子提出成一个函数,乃至能够运用一个参数来大致操控推迟时刻的长短:
void Delay(int num)
{
for (int i = 0; i < 1024 * 1024 * num; ++i );
}
然后试着经过这个函数来进行推迟。很惋惜,再运转程序时咱们发现LED会一向亮着,而不会闪耀。即使是在Debug形式下,编译器也把这个函数调用给优化掉。相似的状况也会呈现不少,这给咱们对程序的调试形成必定的不方便。 原因是Atmel Studio默许的Debug装备中,运用了O1级其他优化,能够在项目特点中封闭它。
咱们试着运用宏来完成这个“函数”:
#define Delay(num) \
do{ \
for (int i = 0; i < 1024 * 1024 * (num); ++i ); \
}while(0)
再运转一下,很好,LED又开端闪耀了。
程序发布的时分,咱们一般会运用Release形式生成代码。Atmel Studio运用的gcc编译器公然“不负众望”,把这个空循环句子直接优化掉了。
咱们能够运用如下句子阻挠编译器的优化:
for (int i = 0; i < 1024 * 1024 * num; ++i )
asm ("");
或许运用volatile关键字:
for (volatile int i = 0; i < 1024 * 1024 * num; ++i ) ;