通过控制LED灯,熟悉STM32的存储器结构、地址映射、时钟树、库文件、利用库的方法及开发工程的步骤,建立STM32的开发思想。
这是我建立的第一个工程,由于涉及面较广,知识点分散,在此做一个总结。
1)为控制LED灯,知道要使用GPIO外设。
GPIO(General-Purpose I/O):I/O引脚可以被软件设置成各种不同的功能,如输入或输出。控制LED灯,即控制STM32芯片的I/O引脚电平的高低来实现。
2)了解GPIO外设有什么功能,要如何使用。
GPIO引脚又被分为GPIOA、GPIOB、...、GPIOG不同的组,每组端口分为0~15共16个不同的引脚,对于不同型号的芯片,端口的组和引脚的数量不同。
功能查看参考手册
3)获知GPIO的地址映射,知道它所挂载的总线APB2。
4)了解ST官方库对寄存器的封装。
5)了解时钟树,查看GPIOC的时钟来源,即PCLK2。
6)在stm32f10x_conf.h文件中包含用到的头文件stm32f10x_gpio.h、stm32f10x_rcc.h。
7)在工程模板的基础上添加led.c、led.h用户文件。
8)编写驱动初始化函数LED_GPIO_Config()。
9)开启外设GPIOC时钟,分析由SystemInit()函数配置的默认的Sysclk=71MHz的时钟频率是否符合工程要求。
10)根据控制要求,定义并填充初始化结构体GPIO_InitStructure,向相应的结构体成员写入适当的参数。
11)调用初始化函数GPIO_Init()初始化GPIOC。
12)编写相应的led.h头文件。
13)编写main应用程序。
14)调试程序、完成。
我建的工程:
/*led.h*/
#ifndef __LED_H
#define __LED_H
#include "stm32f10x.h"
#define ON 0
#define OFF 1
#define LED1(a) if(a) \
GPIO_SetBits(GPIOD,GPIO_Pin_3);\
else \
GPIO_ResetBits(GPIOD,GPIO_Pin_3)
#define LED2(a) if(a) \
GPIO_SetBits(GPIOD,GPIO_Pin_6);\
else \
GPIO_ResetBits(GPIOD,GPIO_Pin_6)
#define LED3(a) if(a) \
GPIO_SetBits(GPIOB,GPIO_Pin_5);\
else \
GPIO_ResetBits(GPIOB,GPIO_Pin_5)
void LED_GPIO_Config(void);
#endif /*__LED_H*/
/*led.c*/
#include "led.h"
/*配置LED用到的I/O口*/
void LED_GPIO_Config(void)
{
/*定义一个GPIO_InitTypeDef类型的结构体*/
GPIO_InitTypeDef GPIO_InitStructure;
/*开启GPIOC的外设时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);
/*选择要控制的GPIO引脚*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_6 | GPIO_Pin_5;
/*设置引脚模式为通用推挽输出*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
/*设置引脚速率为50MHz*/
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/*调用库函数,初始化GPIOB、GPIOD*/
GPIO_Init(GPIOB,&GPIO_InitStructure);
GPIO_Init(GPIOD,&GPIO_InitStructure);
/*关闭所有LED灯*/
GPIO_SetBits(GPIOB,GPIO_Pin_5);//3、6、5引脚输出高电平,关闭三盏LED灯
GPIO_SetBits(GPIOD,GPIO_Pin_3|GPIO_Pin_6);
}
/*main.c*/
#include "stm32f10x.h"
#include "led.h"
void Delay(__IO u32 nCount);
int main (void)
{
SystemInit() ;//设置系统时钟SYSCLK
LED_GPIO_Config();
while(1)
{
LED1(ON); //亮
Delay(0x0FFFEF);
LED1(OFF);
LED2(ON);
Delay(0x0FFFEF);
LED2(OFF);
LED3(ON);
Delay(0x0FFFEF);
LED3(OFF);
}
以上代码在奋斗STM32上课运行,以下是推荐范例,用来对比找出自己的不足。
/*范例*/
#include"stm32f10x.h"
#define ON 1
#define OFF 0
#define DELAY_TIME 0x3FFFFF
enum
{
LED1 = 0,
LED2,
LED3,
MAX_LED,
};
typedef struct led_gpio_s
{
int num; /* LED编号 */
GPIO_TypeDef *group; /* LED使用的GPIO在哪一组: GPIOB or GPIOD */
uint16_t pin; /* LED使用的GPIO组中的那一个pin: GPIO_Pin_x */
} led_gpio_t;
led_gpio_t leds_gpio[MAX_LED] =
{
{LED1, GPIOB, GPIO_Pin_5}, /* LED1 用的GPB5 */
{LED2, GPIOD, GPIO_Pin_6}, /* LED2 用的GPD6 */
{LED3, GPIOD, GPIO_Pin_3}, /* LED3 用的GPD3 */
};
void init_led_gpio(void)
{
int i;
GPIO_InitTypeDef GPIO_InitStructure;
/* 使能PB和PD组 GPIO的时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD , ENABLE);
/*设置 PB5(LED1), PD6(LED2), PD3(LED3)为 GPIO 输出推免模式,口线翻转速度为50MHz */
for(i=0; i { /*设置 PB5(LED1)为 GPIO 输出推免模式,口线翻转速度为50MHz */ GPIO_InitStructure.GPIO_Pin = leds_gpio[i].pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(leds_gpio[i].group, &GPIO_InitStructure); } } void turn_led(int which, int cmd) { if(which<0 || which> MAX_LED ) return; if(OFF == cmd) GPIO_ResetBits(leds_gpio[which].group, leds_gpio[which].pin); else GPIO_SetBits(leds_gpio[which].group, leds_gpio[which].pin); } void Delay(__IO uint32_t nCount) { for(; nCount != 0; nCount--) ; } int main(void) { /* 初始化系统时钟 */ SystemInit(); /* 初始化各个LED的GPIO管脚 */ init_led_gpio(); while(1) { /* 把LED1点亮, LED2和LED3灭掉 */ turn_led(LED1, ON); turn_led(LED2, OFF); turn_led(LED3, OFF); Delay(DELAY_TIME); /* 把LED2点亮, LED1和LED3灭掉 */ turn_led(LED2, ON); turn_led(LED1, OFF); turn_led(LED3, OFF); Delay(DELAY_TIME); /* 把LED3点亮, LED1和LED2灭掉 */ turn_led(LED3, ON); turn_led(LED2, OFF); turn_led(LED1, OFF); Delay(DELAY_TIME); } }
上一篇:STM32F103C8T6-LED点亮程序
下一篇:stm32f407的串口使用集合(USART1,USART2,USART3,USART6)
推荐阅读最新更新时间:2024-03-16 16:14