今天做了一个小实验,使用STM32的嘀嗒定时器做一个LED闪烁(一秒亮,一秒灭),可是调试了好一阵子,没能达到目的。其实很简单,只不过我忽视了中断文件的存在;其次我的低级错误导致了调试时间过长,LED闪烁的方法写错了。
1、不加Systick中断,先保证LED灯闪烁可用。
2、保证配置Systick的代码是正确的。
3、一定要#include "stm32f10x_it.h"头文件,工程中也要引入该文件。
下面是测试的主函数代码
#ifndef __STM32F10X_H
#define __STM32F10X_H
#include "stm32f10x.h"
#endif
#ifndef __Z_HARDWARE_LED_H
#define __Z_HARDWARE_LED_H
#include "z_hardware_led.h"
#endif
#ifndef __Z_UTIL_TIME_H
#define __Z_UTIL_TIME_H
#include "z_util_time.h"
#endif
int main(void)
{
init_led();
systick_configuration();
for(;;)
{
if(systick_timestamp_ms %1000 == 0)
{
func_led1_toggle();
}
}
}
其次是LED灯的代码
#ifndef __Z_HARDWARE_LED_H
#define __Z_HARDWARE_LED_H
#include "z_hardware_led.h"
#endif
void init_led()
{
GPIO_InitTypeDef GPIO_InitStructure_A;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
GPIO_InitStructure_A.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure_A.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure_A.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure_A);
}
void func_led1_on()
{
GPIO_SetBits(GPIOA, GPIO_Pin_8);
}
void func_led1_off()
{
GPIO_ResetBits(GPIOA, GPIO_Pin_8);
}
void func_led1_toggle()
{
if(GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_8) == Bit_SET)
{
GPIO_ResetBits(GPIOA, GPIO_Pin_8);
}
else
{
GPIO_SetBits(GPIOA, GPIO_Pin_8);
}
}
void func_led2_on()
{
GPIO_SetBits(GPIOA, GPIO_Pin_9);
}
void func_led2_off()
{
GPIO_ResetBits(GPIOA, GPIO_Pin_9);
}
LED的头文件
#ifndef __STM32F10X_H
#define __STM32F10X_H
#include "stm32f10x.h"
#endif
void init_led(void);
void func_led1_on(void);
void func_led1_off(void);
void func_led1_toggle(void);
void func_led2_on(void);
void func_led2_off(void);
重点是配置Systick的C代码
#ifndef __Z_UTIL_TIME_H
#define __Z_UTIL_TIME_H
#include "z_util_time.h"
#endif
u32 systick_timestamp_ms;
void systick_configuration(void)
{
while (SysTick_Config(SystemCoreClock/1000)){}
/* Configure the SysTick handler priority */
NVIC_SetPriority(SysTick_IRQn, 0x0);
}
void SysTick_Handler(void)
{
systick_timestamp_ms ++;
}
void delay_us(uint32_t time_us)
{
SysTick->LOAD = AHB_INPUT * time_us;
SysTick->VAL = 0x00;
SysTick->CTRL = 0x00000005;
for(;!(SysTick->CTRL & 0x00010000););
SysTick->CTRL = 0x00000004;
}
void delay_ms(uint32_t time_ms)
{
for(;time_ms-- > 0;)
{
delay_us(1000);
}
}
配置Systick的头文件
#ifndef __STM32F10X_H
#define __STM32F10X_H
#include "stm32f10x.h"
#endif
#include "stm32f10x_it.h"
#define AHB_INPUT 72
extern u32 systick_timestamp_ms;
void systick_configuration(void);
void delay_us(uint32_t time_us);
void delay_ms(uint32_t time_ms);
注意,配置Systick的头文件中,一定要包含#include "stm32f10x_it.h",不引入中断,进不到
void SysTick_Handler(void)
{
systick_timestamp_ms ++;
}
这个方法中。
还有,stm32f10x_it.c文件中,把SysTick_Handler注释掉。
以上,即可以实现实验要达到的目的,走过的坑,不想再走了。