定时器分类
定时器分类STM32F1系列中,除了互联型的产品,共有8个定时器,分为基本定时器,通用定时器和高级定时器。
- 基本定时器 TIM6/7 是一个16位的只能向上计数的定时器,只能定时,没有外部IO。
- 通用定时器 TIM2/3/4/5 是一个16位的可以向上/下计数的定时器,可以定时,可以输出比较,可以输入捕捉,每个定时器有四个外部IO。
- 高级定时器 TIM1/8 是一个16位可以向上/下计数的定时器,可以定时,可以输出比较,可以输入捕捉,还可以有三相电机互补输出信号,每个定时器有8个外部IO。
原理图:
所用开发板:ZET6
LED初始化;PB5,PE5,开发板上的两个LED灯!
1. #define LED0 GPIO_Pin_5 2. #define LED0_PORT GPIOB //PB5 3. #define LED1 GPIO_Pin_5 4. #define LED1_PORT GPIOE //PE5 5. 6. 7. void LED_Init(void) 8. { 9. //这里的时钟一定要开对呀!!!!!! 10. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); 11. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); 12. 13. GPIO_InitTypeDef GPIO_InitStructure; //初始化结构体 14. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 15. GPIO_InitStructure.GPIO_Pin = LED0; 16. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 17. GPIO_Init(LED0_PORT, &GPIO_InitStructure); 18. GPIO_SetBits(LED0_PORT, LED0); //置高电平,默认熄灭 19. 20. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 21. GPIO_InitStructure.GPIO_Pin = LED1; 22. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 23. GPIO_Init(LED1_PORT, &GPIO_InitStructure); 24. GPIO_SetBits(LED1_PORT, LED1); 25. }
定时器6初始化函数
基本定时器 TIM6/7 是一个16位的只能向上计数的定时器,只能定时,没有外部IO。
具体配置如下:
1. void TIM6_Config(uint16_t Period, uint16_t Prescaler) 2. { 3. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //挂载在APB1总线上 4. TIM_TimeBaseInitTypeDef TIM_InitStructure; 5. NVIC_InitTypeDef NVIC_InitStructure; 6. 7. TIM_InitStructure.TIM_Period = Period; 8. TIM_InitStructure.TIM_Prescaler = Prescaler; 9. TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1; 10. TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up; //基本定时器只支持向上计数 11. TIM_InitStructure.TIM_RepetitionCounter = DISABLE; //重复计数次数,基本定时器也不支持 12. TIM_TimeBaseInit(TIM6, &TIM_InitStructure); 13. 14. TIM_ClearITPendingBit (TIM6, TIM_IT_Update);//先清除中断标志位 15. TIM_ITConfig(TIM6, TIM_IT_Update | TIM_IT_Trigger, ENABLE); //使能 16. TIM_Cmd(TIM6, ENABLE); 17. 18. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); 19. NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn; 20. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; 21. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 22. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 23. NVIC_Init(&NVIC_InitStructure); 24. }
定时器6中断函数
1. void TIM6_IRQHandler(void)//500ms基准定时 2. { 3. static uint8_t LED_Count; 4. if (TIM_GetITStatus (TIM6, TIM_IT_Update) == SET ) 5. { 6. //如果读到0,给1,否则给0,实现500ms翻转电平 7. ( GPIO_ReadOutputDataBit(LED0_PORT, LED0) == RESET ) \ 8. ? GPIO_SetBits(LED0_PORT, LED0) \ 9. : GPIO_ResetBits(LED0_PORT, LED0); //三目运算符,更简洁 10. 11. LED_Count++; 12. if (LED_Count >= 2) //两次计数为1s 13. { 14. ( GPIO_ReadOutputDataBit(LED1_PORT, LED1) == RESET ) \ 15. ? GPIO_SetBits(LED1_PORT, LED1) \ 16. : GPIO_ResetBits(LED1_PORT, LED1); 17. LED_Count = 0; 18. } 19. TIM_ClearITPendingBit (TIM6, TIM_IT_Update); //清除中断标志位 20. } 21. }
用三目运算符写这个IO口电平反转的功能代码太长了,我用连接符给分开咯,更整齐一点……
三目运算符( *** ? ### : @@@ )
简化版的if else语句,如果***成立,就执行 ### 程序,否则就执行 @@@ 程序
在开发STM32时使用三目运算符会很方便!
这个定时器自定义时长,还以为是啥高端的东西呢!
没想到和51单片机里的定时器一样用~
在中断里定义几个静态局部变量 static uint8_t LED_Count;
定时器 有一个基准定时,这里设置500ms
每次进中断,这几个静态局部变量都++ LED_Count++;
然后if语句判断,根据想要定时的时间长短来计算LED_Count变量的值!
if语句里执行对应的操作,然后手动清零这个计数变量!
main.c
1. #include "stm32f10x.h" // Device header 2. #include "Delay.h" 3. #include "LED.h" 4. #include "Timer6.h" 5. 6. int main(void) 7. { 8. Delay_Init (72); 9. LED_Init(); 10. TIM6_Config (10000-1 , 3600-1); //500ms定时 11. /* 12. 3600分频,72000000/3600 = 20000, 1s计数两万 13. 500ms = 0.5s 0.5s*20000 = 10000 14. */ 15. while(1) 16. { } 17. } 18. 19. /***********************************END OF FILE***********************************/
最后抓个波形玩玩~
用逻辑分析仪抓取波形一定要和开发板共地哟!而且还有将开发板上电!
最重要的是连接对引脚,别问为啥了~_~



