1.震动传感器详解的记录
从主程序分析
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "exti.h"
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
led_init(); /* 初始化LED灯 */
exti_init(); /* 初始化EXTI */
while(1)
{
//如果检测到震动
if(vibrate_flag_get() == TRUE)
{
//那么就点亮LED1两秒,然后熄灭
led1_on();
delay_ms(2000);
led1_off();
vibrate_flag_set(FALSE);
}
}
}
2.
HAL_Init();
用到了stm32f1xx_hal.c
对hal 库经常用的还是要提前熟悉下的
HAL_StatusTypeDef HAL_Init(void)
{
/* Configure Flash prefetch */
#if (PREFETCH_ENABLE != 0)
#if defined(STM32F101x6) || defined(STM32F101xB) || defined(STM32F101xE) || defined(STM32F101xG) || \
defined(STM32F102x6) || defined(STM32F102xB) || \
defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || \
defined(STM32F105xC) || defined(STM32F107xC)
/* Prefetch buffer is not available on value line devices */
__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
#endif
#endif /* PREFETCH_ENABLE */
/* Set Interrupt Group Priority */
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);
/* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */
HAL_InitTick(TICK_INT_PRIORITY);
/* Init the low level hardware */
HAL_MspInit();
/* Return function status */
return HAL_OK;
}
2.1
stm32_clock_init(RCC_PLL_MUL9)
调用了 sys.c
分析的时候 最后.h 头文件也包含进来
sys.c
#include "sys.h"
/**
* @brief 系统时钟初始化函数
* @param plln: PLL倍频系数(PLL倍频), 取值范围: 2~16
* @retval 无
*/
void stm32_clock_init(uint32_t plln)
{
HAL_StatusTypeDef ret = HAL_ERROR;
RCC_OscInitTypeDef rcc_osc_init = {0};
RCC_ClkInitTypeDef rcc_clk_init = {0};
rcc_osc_init.OscillatorType = RCC_OSCILLATORTYPE_HSE; /* 选择要配置HSE */
rcc_osc_init.HSEState = RCC_HSE_ON; /* 打开HSE */
rcc_osc_init.HSEPredivValue = RCC_HSE_PREDIV_DIV1; /* HSE预分频系数 */
rcc_osc_init.PLL.PLLState = RCC_PLL_ON; /* 打开PLL */
rcc_osc_init.PLL.PLLSource = RCC_PLLSOURCE_HSE; /* PLL时钟源选择HSE */
rcc_osc_init.PLL.PLLMUL = plln; /* PLL倍频系数 */
ret = HAL_RCC_OscConfig(&rcc_osc_init); /* 初始化 */
if (ret != HAL_OK)
{
while (1); /* 时钟初始化失败,之后的程序将可能无法正常执行,可以在这里加入自己的处理 */
}
/* 选中PLL作为系统时钟源并且配置HCLK,PCLK1和PCLK2*/
rcc_clk_init.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
rcc_clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; /* 设置系统时钟来自PLL */
rcc_clk_init.AHBCLKDivider = RCC_SYSCLK_DIV1; /* AHB分频系数为1 */
rcc_clk_init.APB1CLKDivider = RCC_HCLK_DIV2; /* APB1分频系数为2 */
rcc_clk_init.APB2CLKDivider = RCC_HCLK_DIV1; /* APB2分频系数为1 */
ret = HAL_RCC_ClockConfig(&rcc_clk_init, FLASH_LATENCY_2); /* 同时设置FLASH延时周期为2WS,也就是3个CPU周期。 */
if (ret != HAL_OK)
{
while (1); /* 时钟初始化失败,之后的程序将可能无法正常执行,可以在这里加入自己的处理 */
}
}
sys.h
#ifndef __SYS_H__
#define __SYS_H__
#include "stm32f1xx.h"
void stm32_clock_init(uint32_t plln); /* 系统时钟初始化函数 */
#endif
2.2
led_init(); /* 初始化LED灯 */
调用了 led.c
#include "led.h"
#include "sys.h"
//初始化GPIO函数
void led_init(void)
{
GPIO_InitTypeDef gpio_initstruct;
//打开时钟
__HAL_RCC_GPIOB_CLK_ENABLE(); // 使能GPIOB时钟
//调用GPIO初始化函数
gpio_initstruct.Pin = GPIO_PIN_8 | GPIO_PIN_9; // 两个LED对应的引脚
gpio_initstruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出
gpio_initstruct.Pull = GPIO_PULLUP; // 上拉
gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH; // 高速
HAL_GPIO_Init(GPIOB, &gpio_initstruct);
//关闭LED
led1_off();
led2_off();
}
//点亮LED1的函数
void led1_on(void)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET); // 拉低LED1引脚,点亮LED1
}
//熄灭LED1的函数
void led1_off(void)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET); // 拉高LED1引脚,熄灭LED1
}
//翻转LED1状态的函数
void led1_toggle(void)
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);
}
//点亮LED2的函数
void led2_on(void)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET); // 拉低LED2引脚,点亮LED2
}
//熄灭LED2的函数
void led2_off(void)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET); // 拉高LED2引脚,熄灭LED2
}
//翻转LED2状态的函数
void led2_toggle(void)
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_9);
}
2.3
exti_init(); /* 初始化EXTI */
调用了 exti.c
void exti_init(void)
{
GPIO_InitTypeDef gpio_initstruct;
//打开时钟
__HAL_RCC_GPIOA_CLK_ENABLE(); // 使能GPIOA时钟
//调用GPIO初始化函数
gpio_initstruct.Pin = GPIO_PIN_4; // 震动传感器对应的引脚
gpio_initstruct.Mode = GPIO_MODE_IT_FALLING; // 下降沿触发
gpio_initstruct.Pull = GPIO_PULLUP; // 上拉
HAL_GPIO_Init(GPIOA, &gpio_initstruct);
HAL_NVIC_SetPriority(EXTI4_IRQn, 2, 0); // 设置EXTI0中断线的优先级
HAL_NVIC_EnableIRQ(EXTI4_IRQn); // 使能中断
}
2.4 其他的分析类似
delay_ms(2000);
延时函数
delay.h
#include "delay.h"
/**
* @brief 微秒级延时
* @param nus 延时时长,范围:0~233015
* @retval 无
*/
void delay_us(uint32_t nus)
{
uint32_t temp;
SysTick->LOAD = 72 * nus; /* 设置定时器重装值 */
SysTick->VAL = 0x00; /* 清空当前计数值 */
SysTick->CTRL |= 1 << 2; /* 设置分频系数为1分频 */
SysTick->CTRL |= 1 << 0; /* 启动定时器 */
do
{
temp = SysTick->CTRL;
} while ((temp & 0x01) && !(temp & (1 << 16))); /* 等待计数到0 */
SysTick->CTRL &= ~(1 << 0); /* 关闭定时器 */
}
/**
* @brief 毫秒级延时
* @param nms 延时时长,范围:0~4294967295
* @retval 无
*/
void delay_ms(uint32_t nms)
{
while(nms--)
delay_us(1000);
}
/**
* @brief 秒级延时
* @param ns 延时时长,范围:0~4294967295
* @retval 无
*/
void delay_s(uint32_t ns)
{
while(ns--)
delay_ms(1000);
}
/**
* @brief 重写HAL_Delay函数
* @param nms 延时时长,范围:0~4294967295
* @retval 无
*/
void HAL_Delay(uint32_t nms)
{
delay_ms(nms);
}
参考