开启两个定时器FPGA 使用
 
要求是
 
一、定时器可以在任何时刻关闭,就算计数不满也要停
 
二、定时器在再次开启时可以从 0 计数
 
三、定时器可以在启动过程中停止,然后更改定时周期再开始从 0 计数
 
 
主要的几个函数
 
//tim_num=0 对应 定时器 2,TIm_num=1 对应 定时器 3;TIm_us:定时器 uS 数
 
void stm32_TImer_start(uint16_t TIm_num,uint16_t tim_us)
 
{
 
PCLK1=36MHz
 
TIM CLK = 72 MHz, Prescaler = 72, 72M/72=1M,即计数 1000000 为 1S,即计数加 1 为 1uS
 
/* Time base configuration */
 
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
 
stm32_timer_stop(tim_num);
 
TIM_TimeBaseStructure.TIM_Period = tim_us; // 设置在下一个更新事件装入活动的自动重装载寄存器周期的值计数到 5000 为 500ms
 
TIM_TimeBaseStructure.TIM_Prescaler =(72-1); // 设置用来作为 TIMx 时钟频率除数的预分频值 10Khz 的计数频率
 
TIM_TimeBaseStructure.TIM_ClockDivision = 0; // 设置时钟分割:TDTS = Tck_tim
 
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM 向上计数模式
 
if(tim_num == 0){
 
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // 根据 TIM_TimeBaseInitStruct 中指定的参数初始化 TIMx 的时间基数单位
 
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 清除 TIMx 的中断待处理位:TIM 中断源
 
TIM_SelectOnePulseMode(TIM2, TIM_OPMode_Single); // 定时器单次模式
 
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); // 使能中断
 
TIM_Cmd(TIM2, ENABLE); // 使能 TIMx 外设
 
}
 
else if(tim_num == 1){
 
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // 根据 TIM_TimeBaseInitStruct 中指定的参数初始化 TIMx 的时间基数单位
 
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); // 清除 TIMx 的中断待处理位:TIM 中断源
 
TIM_SelectOnePulseMode(TIM3, TIM_OPMode_Single);// 定时器单次模式
 
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); // 使能中断
 
TIM_Cmd(TIM3, ENABLE); // 使能 TIMx 外设
 
}
 
}
 
// 停止定时器
 
void stm32_timer_stop(uint16_t tim_num)
 
{
 
if(tim_num == 0)
 
{
 
TIM_ITConfig(TIM2, TIM_IT_Update, DISABLE); // 关中断
 
TIM_Cmd(TIM2, DISABLE); // 关闭 TIMx 外设
 
}
 
else if(tim_num == 1)
 
{
 
TIM_ITConfig(TIM3, TIM_IT_Update, DISABLE); // 关中断
 
TIM_Cmd(TIM3, DISABLE); // 关闭 TIMx 外设
 
}
 
}
 
void TIM2_IRQHandler(void)
 
{
 
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET){ // 检查指定的 TIM 中断发生与否:TIM 中断源
 
TIM_ClearITPendingBit(TIM2, TIM_IT_Update ); // 清除 TIMx 的中断待处理位:TIM 中断源
 
time_handlers[0]();// 中断处理函数
 
}
 
}
 
void TIM3_IRQHandler(void)
 
{
 
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET){ // 检查指定的 TIM 中断发生与否:TIM 中断源
 
TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); // 清除 TIMx 的中断待处理位:TIM 中断源
 
time_handlers[1]();// 中断处理函数
 
}
 
}
 
不管在第一次启动定时器还是在停止之后再打开定时器,都调用 stm32_timer_start 函数
 
这样可以保证定时器停止后再开启从 0 计数,在重新设置了计数值后,定时器会马上按照新的定时值计数,哪怕不去调用 stop 函数
 
stm32_timer_start 里面的
 
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // 根据 TIM_TimeBaseInitStruct 中指定的参数初始化 TIMx 的时间基数单位
 
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); // 清除 TIMx 的中断待处理位:TIM 中断源
 
这两个函数不能对调,不然就会出现不管定时器定时多长,一启动就会产生定时中断的现象
 
这个时间大概是 120uS
 
对于 ADC
 
调试 STM32 采集板的电压分压测试,使用 ADC 采集数据,发现会有偏差,大概偏差 5%
 
后来测量硬件电路,发现基准电压 VDDA 和 VREF+是 3V,后来调到 3.3V,AD 采样就不存在偏差了。