有一个小板子芯片是STM32L431CB,用的内部晶振,时钟频率2M。之前是要500us的间隔采样,倒也能调的到,就是间隔的参数要手工调,和理论对不上。下面是大概的代码:
//定时器初始化
htim1.Instance = TIM1;
htim1.Init.Prescaler = 1;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 242;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
//定时器中断回调函数
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim == (&htim1))
{
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);
HAL_TIM_OC_Stop_IT(htim, TIM_CHANNEL_1); /* ½ûÄÜCC1ÖÐ¶Ï */
/* ÏȹرÕÖжϣ¬ÔÙÖ´Ðлص÷º¯Êý¡£ÒòΪ»Øµ÷º¯Êý¿ÉÄÜÐèÒªÖØÆô¶¨Ê±Æ÷ */
s_TIM_CallBack1();
}
}
//开启定时器的函数
void StartOnceHardTimer(uint8_t _CC, uint32_t _uiTimeOut, void * _pCallBack)
{
uint32_t cnt_now;
uint32_t cnt_tar;
cnt_now = __HAL_TIM_GET_COUNTER(&htim1); /* ¶ÁÈ¡µ±Ç°µÄ¼ÆÊýÆ÷Öµ */
cnt_tar = cnt_now + _uiTimeOut; /* ¼ÆËã²¶»ñµÄ¼ÆÊýÆ÷Öµ */
if (_CC == 1)
{
s_TIM_CallBack1 = (void (*)(void))_pCallBack;
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, cnt_tar); /*
__HAL_TIM_CLEAR_IT(&htim1, TIM_IT_CC1);
HAL_TIM_OC_Start_IT(&htim1, TIM_CHANNEL_1); /*
}
}
//采样函数,定时器回调函数会调用这个函数
void Adc_Sample(void)
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_9);
StartOnceHardTimer(1, CAIYANG_JIANGE, Adc_Sample);
}
理论上我2048点采样,采样间隔是488,但是这里我要把采样间隔的宏设为288。。。
这次要4096采样,我把采样间隔的宏调小点,发现不管怎么调,示波器量到的时间间隔都是300多us,而我需要244us的间隔。
之后换了8M的晶振,然后对代码进行了调整,将采样直接放在定时器的回调函数中,像下面这样:
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim == (&htim1))
{
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_9);
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 5);
AdcSample_BaseStruct.value[AdcSample_BaseStruct.cnt * 2 + 1] = 0;
AdcSample_BaseStruct.value[AdcSample_BaseStruct.cnt * 2] = Adc_value;
if (++AdcSample_BaseStruct.cnt > ADC_SAMPLES_NUMBERS - 1)
{
AdcSample_BaseStruct.cnt = 0;
AdcSample_BaseStruct.flag = 1;
HAL_TIM_OC_Stop_IT(htim, TIM_CHANNEL_1); /* ½ûÄÜCC1ÖÐ¶Ï */
}
}
}
//定时器初始化部分
htim1.Instance = TIM1;
htim1.Init.Prescaler = 1;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 243;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
这时发现采样间隔就是244us。和理论计算完全一致。
为什么会这样呢?因为2M的时候本来指令就执行的慢,而且在回调函数内又加了好多的函数调来调去,一大段代码执行完就需要很长的时间了,所以采样间隔就对不上了。
记录一下,免的过半年忘了。