目录
2.RCC_APB2PeriphClockCmd函数详解如下:
[3.GPIO_LED.GPIO_Pin = GPIO_Pin_0; 之类的是一些赋值,可以跳过](#3.GPIO_LED.GPIO_Pin = GPIO_Pin_0; 之类的是一些赋值,可以跳过)
2.sys_stm32_clock_init(RCC_PLL_MUL9);
[4. delay_ms(500);](#4. delay_ms(500);)
经过上篇的STM32的输入输出,就可以看懂例子代码了.
一.LED初始化
cpp
#include "led.h"
//LED 初始化程序
void led_init(void)
{
GPIO_InitTypeDef GPIO_LED; //定义GPIO结构体变量
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_LED.GPIO_Pin = GPIO_Pin_0; //LED端口配置
GPIO_LED.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_LED.GPIO_Speed = GPIO_Speed_2MHz; //IO口速度为2MHz
GPIO_Init(GPIOB, &GPIO_LED); //根据设定参数初始化GPIOB0
GPIO_SetBits(GPIOB,GPIO_Pin_0); //GPIOB0输出高电平,初始化LED灭
}
1.GPIO_InitTypeDeff的定义如下
cpp
/**
* @brief GPIO Init structure definition
*/
typedef struct
{
uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured.
This parameter can be any value of @ref GPIO_pins_define */
GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins.
This parameter can be a value of @ref GPIOSpeed_TypeDef */
GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins.
This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;
2.RCC_APB2PeriphClockCmd函数详解如下:
用于启用或禁用位于APB2总线上的外设的时钟。APB2(Advanced Peripheral Bus 2)是一个高性能总线,通常用于连接需要更高时钟频率的外设。
以下是一些常见的位于APB2总线上的外设:
- USART1、USART2、USART3:串口通信外设。
- SPI1、SPI2:串行外设接口。
- TIM1、TIM8:高级定时器。
- GPIOA、GPIOB、GPIOC、GPIOD、GPIOE:通用输入输出引脚控制器。
3.GPIO_LED.GPIO_Pin = GPIO_Pin_0; 之类的是一些赋值,可以跳过
4.GPIO_Init
初始化一个或者多个IO口(同一组)的工作方式和速度。该函数主要是操作GPIO_CRL(CRH)寄存器,在上拉或者下拉的时候有设置BSRR或者BRR寄存器。
cpp
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
{
uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;
uint32_t tmpreg = 0x00, pinmask = 0x00;
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));
assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));
/*---------------------------- GPIO Mode Configuration -----------------------*/
currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F);
if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00)
{
/* Check the parameters */
assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));
/* Output mode */
currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;
}
/*---------------------------- GPIO CRL Configuration ------------------------*/
/* Configure the eight low port pins */
if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00)
{
tmpreg = GPIOx->CRL;
for (pinpos = 0x00; pinpos < 0x08; pinpos++)
{
pos = ((uint32_t)0x01) << pinpos;
/* Get the port pins position */
currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
if (currentpin == pos)
{
pos = pinpos << 2;
/* Clear the corresponding low control register bits */
pinmask = ((uint32_t)0x0F) << pos;
tmpreg &= ~pinmask;
/* Write the mode configuration in the corresponding bits */
tmpreg |= (currentmode << pos);
/* Reset the corresponding ODR bit */
if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
{
GPIOx->BRR = (((uint32_t)0x01) << pinpos);
}
else
{
/* Set the corresponding ODR bit */
if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
{
GPIOx->BSRR = (((uint32_t)0x01) << pinpos);
}
}
}
}
GPIOx->CRL = tmpreg;
}
/*---------------------------- GPIO CRH Configuration ------------------------*/
/* Configure the eight high port pins */
if (GPIO_InitStruct->GPIO_Pin > 0x00FF)
{
tmpreg = GPIOx->CRH;
for (pinpos = 0x00; pinpos < 0x08; pinpos++)
{
pos = (((uint32_t)0x01) << (pinpos + 0x08));
/* Get the port pins position */
currentpin = ((GPIO_InitStruct->GPIO_Pin) & pos);
if (currentpin == pos)
{
pos = pinpos << 2;
/* Clear the corresponding high control register bits */
pinmask = ((uint32_t)0x0F) << pos;
tmpreg &= ~pinmask;
/* Write the mode configuration in the corresponding bits */
tmpreg |= (currentmode << pos);
/* Reset the corresponding ODR bit */
if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
{
GPIOx->BRR = (((uint32_t)0x01) << (pinpos + 0x08));
}
/* Set the corresponding ODR bit */
if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
{
GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08));
}
}
}
GPIOx->CRH = tmpreg;
}
}
5.GPIO_SetBits
GPIO_SetBits对应的还有一个GPIO_ResetBits
- 实现功能:控制某个GPIO引脚的输出电平(拉高 / 拉低)
- GPIO_SetBits 拉高引脚输出电平
- GPIO_ResetBits 拉低引脚输出电平
二.Main函数
1.简易版.
cpp
#include "main.h"
int main(void)
{
led_init(); //LED初始化
while(1)
{
GPIO_ResetBits(GPIOB,GPIO_Pin_0); //点亮LED
}
}
2.延迟版
cpp
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
led_init(); /* LED初始化 */
while(1)
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET); /* PB5置1 */
delay_ms(500);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET); /* PB5置0 */
delay_ms(500);
}
}
1.HAL_Init
该函数用于初始化HAL库;这一定是第一次在主程序中执行的指令(在调用任何其他指令之前)
HAL_Init,其执行如下:
*配置Flash预取。
*配置SysTick每1毫秒产生一个中断,
由HSI计时(在这个阶段,时钟还没有配置,因此系统运行从内部HSI在16 MHz)。
*"NVIC组优先级"设置为"4"。
*调用HAL_MspInit()
2.sys_stm32_clock_init(RCC_PLL_MUL9);
设置时钟
cpp
void Stm32_Clock_Init(unsigned char PLL)
{
unsigned char temp = 0;
MYRCC_DeInit(); //复位一些RC寄存器与向量表
RCC->CR |= 0x00010000; //开启HSE(由于战舰是外接了8MHZ的晶振,所以要用)
while(!(RCC->CR >> 17)); //等待HSE完全开启
RCC->CFGR = 0x00000400; //PPRE1 /2 //APB1为2分频
PLL -= 2; //由于CFGR寄存器中000代表二倍频,所以111代表9倍频,即7,所以9要-2变成7,其实引用此函数时的9是要9倍频,达到SYSCLK为72Hz,
RCC->CFGR |= (unsigned int)PLL << 18; // PLL X 9//写入9倍频
RCC->CFGR |= 1 << 16; //打开SRC选择器,即选用HSE作为倍频
FLASH->ACR |= 0x32; //2个周期的延时,具体详见STM32F10xxx闪存编程手册,很详细,如果你不想看,就暂且将它想成这里是向FLASH的ACR寄存器中写入0x32,而这个延时是以后保证程序不跑飞用的。
RCC->CR |= 0x01000000; //打开PLL倍频器
while(!(RCC->CR >> 25)); //等待PLL倍频器打开
RCC->CFGR |= 0x00000002;//SYSCLK时钟来源为PLL
while(temp != 0x02)
{
temp = RCC->CFGR >> 2;
temp &= 0x03;
}由SWS寄存器看出是否成功切换SYSCLK源
}
3.delay_init(72);
延时初始化
cpp
void delay_init()
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8
fac_us=SystemCoreClock/8000000; //为系统时钟的1/8
fac_ms=(u16)fac_us*1000; //非OS下,代表每个ms需要的systick时钟数
}
4. delay_ms(500);
延迟500ms;
三.结束语
以上就是STM32点灯,用到的函数详解.自己直接用例子的时候,看这些都不理解,现在学习了32的输入输出模式,可以理解点了,