开发板LED截图如下:
开发板厂商的例程是1~4个LED形成流水灯,我自己闪灭LED1即可,以期熟悉stm32 的GPIO的几个固件库函数。
为了养成稍微好一点的习惯,于是开始练习一个功能一个函数,下面是led初始化代码,先是<led.h>
1 #ifndef _LED_H 2 #define _LED_H 3 4 void led_init(void); 5 #endif
然后是<led.c>
1 #include <stm32f10x.h> 2 #include "led.h" 3 4 GPIO_InitTypeDef GPIO_InitStructure; 5 void led_init(void) 6 { 7 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);//Enable APB2 clock 8 9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //select GPIO pin 10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //I/O Mode 11 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //I/O speed 12 GPIO_Init(GPIOD,&GPIO_InitStructure); //GPIO init 13 14 GPIO_ResetBits(GPIOD, GPIO_Pin_2); //pin 2 init value 15 }
ps: 4行:GPIO_InitTypeDef 结构体在官方库里展示如下:
1 typedef struct 2 { 3 uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. 4 This parameter can be any value of @ref GPIO_pins_define */ 5 6 GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins. 7 This parameter can be a value of @ref GPIOSpeed_TypeDef */ 8 9 GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins. 10 This parameter can be a value of @ref GPIOMode_TypeDef */ 11 }GPIO_InitTypeDef;
于是,<led.c>文件中的9、10、11即是对这个结构体的填充而已,当然是在熟悉硬件的前提下;
<led.c>文件中的12行是对前面已经填充好的结构体进行初始化---专业说法是对某GPIO端口进行初始化。
<led.c>文件中的14行是对我所用的PD2 端口付初值--初始值为0;按照电路图的意思,也就是灯起始为熄灭状态。
下面是对led.c的测试文件,<test.c>:
1 #include <stm32f10x.h> 2 #include "Hardware/led.h" 3 4 void delay(unsigned long nCount) 5 { 6 for(;nCount != 0;nCount--); 7 } 8 9 void loop(void) 10 { 11 GPIO_ResetBits(GPIOD, GPIO_Pin_2); 12 delay(1000000); 13 GPIO_SetBits(GPIOD, GPIO_Pin_2); 14 delay(1000000); 15 } 16 17 int main() 18 { 19 SystemInit(); 20 led_init(); 21 22 while(1) { 23 loop(); 24 } 25 }
ps:第2行头文件的包含情况是这样的:在test.c的同级目录下我创建了一个Hardware文件夹,然后在Hardware文件夹下创建了led.h和led.c这两个文件,所以,在led.c中用的是#include "led.h";而在test.c中使用的是#include "Hardware/led.h"。
test.c中就是一个延时函数,一个调用led灯的函数,main函数里面起循环条件---循环调用led灯函数loop();
鼓捣了一个月的stm32,终于开始写代码了。想想其感觉,就像水帘洞的那些猴子,左跳右跳,总是不敢进洞---一直对stm32的库感觉很陌生,不知道该如何调用。其实也很简单,就是将官方库拷贝进自己的工程目录下,然后在自己的代码中调用这些函数即可--当然,别忘记了包括相应的库的头文件。
还有就是,keill软件,在设置Target的时候,也一定要注意,不然程序是无法下载到自己的板子里面去的。好了,后续还有stm32 的时钟和中断,一点一点的记下来吧,争取早点涨工资啊!哈哈~~
------------------------------------------------------
以上部分代码格式需要修正下,代码结果本身没错,但在执行过程中并不是最优的。
原因是这样:一个函数里的循环体所需要的开销,同循环调用一个函数所需要的开销相比,觉得还是前面一种开销小些--因为函数的调用,将涉及到上下文的切换和保护,这期间空间和时间的花费远比一个循环体花费的大<在一定的条件下>。循环调用一个函数,不是在必须的情况下,个人觉得尽量避免这样使用。
修改的方法是,将led.c里面使用循环体,而main函数的调用就去掉循环体,结果如下:
1 #include <stm32f10x.h> 2 #include "Hardware/led.h" 3 4 void delay(unsigned long nCount) 5 { 6 for(;nCount != 0;nCount--); 7 } 8 void loop(void) 9 {10 while(1){ 11 GPIO_ResetBits(GPIOD, GPIO_Pin_2); 12 delay(1000000); 13 GPIO_SetBits(GPIOD, GPIO_Pin_2); 14 delay(1000000); 15 } 16 } 17 int main() 18 { 19 SystemInit(); 20 led_init(); 21 loop(); 22 } 232425