在Linux下掌握arm和操作系统(3)--点亮LED
发布日期:2021-06-29 02:35:32 浏览次数:2 分类:技术文章

本文共 2772 字,大约阅读时间需要 9 分钟。

说了那么多,我们终于开始写代码了.毫不例外,我们从世界上最著名的程序"helloword"开始,硬件的"helloword"就是点亮一个LED.

硬件原理图:

从原理图看出,LED (D1)连接电源和地,上电就亮.  LED D2连接VCC和PC13,所以我们只要给PC13引脚一个低电平就可以点亮这个LED.

准备点灯

俗话说,让我点亮一个LED我就能上天.  看把你能的,LED 可不是那么好点的,要准备准备.

如果你学过51,你会告诉我点灯很容易.

如果你学过STM32,也许你会告诉我很容易.(为什么我说也许?因为我知道你心虚,你用的是别人的库吧?你有很多不明白的地方吧.哈哈哈)

今天我们就从头来,明明白白的点一回灯.

其实这个STM32点灯的却不是那么容易,因为在真实点灯之前有很多配置,往往这些配置是最让人头疼的.

这也是用库编程的问题所在:虽然你用了库点亮了LED灯,干了很多别的事情,但是有些事情还是模模糊糊不清楚.

扯远了,其实那些烦人的配置是用来配置时钟的,STM32这样设计也是有原因的:默认所有外设时钟关闭,使用的时候再开启,这样可以省电啊.有地方省,就有地方多付出,比如芯片设计人员和软件开发人员--我们.幸好STM32有默认内部时钟,虽然不咋地,但是能用,我们先凑合着用内部时钟点亮我们的LED.

点灯

先使能portC的时钟(我们要用PC13),然后将PC13设置为输出模式.

while(1)循环设置PC13高低电平,就可以看见LED灯一闪一闪的了

/* main.c */#define RCC_BASE 0x40021000#define RCC_CR (*(volatile unsigned long *)(RCC_BASE))#define RCC_APB2ENR (*(volatile unsigned long *)(RCC_BASE+0x18))#define GPIOC_BASE 0x40011000#define GPIOC_CRH   (*(volatile unsigned long *)(GPIOC_BASE+0x04))#define GPIOC_ODR   (*(volatile unsigned long *)(GPIOC_BASE+0x0c))int main(){  int i;  RCC_APB2ENR = 1<<4;  //portC 时钟使能  GPIOC_CRH = 3<<20;  // pin13 输出模式  GPIOC_ODR = 0;  while(1){    GPIOC_ODR  |= 1<<13;   //pin13 高电平    for(i=0;i<1000000;i++);    GPIOC_ODR &= ~(1<<13);  //pin13 低电平    for(i=0;i<1000000;i++);  }  return 0;}

好像本章应该结束了?可是想想还有很多疑问:为什么从mian()函数开始执行?怎么编译成APP.bin?

为什么从mian()函数开始执行?

很多写应用的人往往会忽略忽这点,因为平时的应用都是从main开始的所以就理所当然的认为STM32也认识main().

要回答这个问题,这就要说说cortexM3的启动流程(复位流程).

如上图,CPU一上电就从0x00000000地址处取一个值赋给MSP(R13)寄存器.然后从接下来的一个32bit对齐的地址0x00000004处读取第一条要执行的指令执行.

那么我们的程序怎么保证0x00000004处就是main()函数呢?

/* start.S */.text.globl _start _start:    .word 0x20000000+20480 /*sram form 0x20000000,size 20K*/    .word main /*跳转到main函数*/

从_start开始,第一个 .word 后面就是放入MSP中的值,因为.word占用4个字节所有.word main  就0x00000004处了.

这就保证了程序一上电就执行main()函数.

其实,入口也不一定非要是main()函数,你写exit()也是可以的,只要你愿意,main只是约定俗成.

怎么编译?

//将start.S编译为start.o  但是不链接arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -c start.S -o start.o//将main.c编译为main.o  但是不链接arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -c main.c -o main.o//将start.o 和start.o 链接成nuttx.  第一个字节放在0x00000000 //这样main就在0x00000004arm-none-eabi-ld -Ttext=0x00000000 start.o main.o -o nuttx//最后转换格式,确保CPU可以正常运行arm-none-eabi-objcopy -O binary -S nuttx nuttx.bin

上面解释的很详细了,就不再多说,可是每次编译都敲这么多命令也太麻烦了,干脆写一个脚本(针对make的Makefle)

 

# file :MakefileAll:	arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -c start.S -o start.o	arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -c main.c -o main.o	arm-none-eabi-ld -Ttext=0x08000000 start.o main.o -o nuttx	arm-none-eabi-objcopy -O binary -S nuttx nuttx.bin	arm-none-eabi-objdump -D -m arm  nuttx > nuttx.disclean:	-rm *.o nuttx*flash: 	sudo stm32flash -w nuttx.bin -v -g 0 /dev/ttyUSB0

这样创建led目录,创建3个文件

main.c  Makefile  start.S   内容如上文.

这样以后编译烧写就方便多了.

//编译PC#make//清除编译产生的文件PC#make clean//烧写到STM32PC#make flash

576648661@qq.com

  • 微信号:find_xiaohei
  • 名称:找小黑 

转载地址:https://blog.csdn.net/yyyyyyyyyywwwwwwwwww/article/details/85932437 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:在Linux下掌握arm和操作系统(2)--开发环境最小系统
下一篇:在Linux下掌握arm和操作系统(1)--stm32和arm

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年04月20日 11时36分56秒