按键和定时器学习
按键问题最主要就是抖动问题,因此最重要的事情就是消抖。
按键的原理
- 检测按键是否按下
- 延时一定时间
- 再次检测按键是否按下
- 若按下则执行相应动作
消除抖动:软件消抖、硬件消抖
引脚的浮动输入代表没有确定的输入电平。
高内聚,低耦合
通过标志位来改变程序的状态,可以降低耦合度。
在按键中根据是否有while循环等待的语句分为支持连续按和不支持连续按。
定时器学习
STM32最多有8个定时器。在F103系列中,定时器时钟源均为72MHz。
(摘自海创电子的PPT)
计数器类型:
- 向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件
- 向下计数模式:计数器从自动加载值(TIMx_ARR)开始向下计数到0,然后重从自动加载值(TIMx_ARR)重新开始,并产生一个计数器向下溢出事件
- 中央对齐模式:计数器从0计数到自动加载值(TIMx_ARR-1),并产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件
注意:如果计数器分辨率为16位的话,自动加载值的最大值为216。
F103C8T6只有四个定时器。
定时器的定时功能:在一定的时钟频率下,从零递增到一定的值或者从一定值递减到零,标志位改变或发生中断。
相关寄存器
控制寄存器1(TIMx_CR1)
DMA/中断使能寄存器(TIMx_DIER)
状态寄存器(TIMx_SR)
TIM_GetITStatus()里面是存在判断状态寄存器的第0位来确定是否更新
预分频器(TIMx_PSC)
预分频的值也是(0~216-1)。
溢出时间(1s)
一个周期的时间 = (psc+1)/fck //晶振振一次的时间
一个周期的时间 * (arr+1) = 溢出时间 //晶振振一次的时间*振动次数 = 定时时间
溢出时间 = (psc+1)(arr+1)/fck
自动重装载寄存器(TIMx_ARR)
最大值为216-1。
库函数配置
- 使能定时器时钟
RCC_APB1PeriphClockCmd();
- 初始化定时器
TIM_TimeBaseInit();
- 定时器中断配置
void TIM_ITConfig();
- 使能定时器
TIM_Cmd();
- 编写中断服务函数
TIMx_IRQHandler();
还有NVIC的配置!
相关代码编写
void TIM3_Init(u16 arr,u16 psc){
TIM_TimeBaseInitTypeDef TIM_BaseStructure;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
TIM_BaseStructure.TIM_Period = arr; //重装载值
TIM_BaseStructure.TIM_Prescaler = psc; //预分频系数
TIM_BaseStructure.TIM_ClockDivision = 0; //时钟分割,用不到
TIM_BaseStructure.TIM_CounterMode = TIM_CounterMode_up; //计数模式
NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn; //选择的中断源
NVIC_InitStruct.NVIC_IRQChannelPreemtionPriority = 2; //组优先级(抢占优先级)
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2; //响应优先级
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //用于确定是否使能
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
NVIC_Init(&NVIC_InitStruct);
TIM_Cmd(TIM3,ENABLE);
}
void TIM3_IRQHandler(void){
static u8 i =0 ;
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{
switch (i){
case 0:GPIO_ResetBits(LED_GPIO_PORT, LED_GPIO_PIN);i++;break;
case 1:GPIO_SetBits(LED_GPIO_PORT, LED_GPIO_PIN);i=0;break;
}
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除TIMx的中断待处理位:TIM 中断源
}
}
//main.c
int main(void){
TIM3_Init(9999,7199);
while(1){}
}
怎么查看数据手册
先观看视频,然后查看相关手册。用的时候多查看,熟能生巧。