这个网上资料比较少,用AWU测量的方式是stm8s系列的。翻遍了stm8L的手册才发现用BEEP可以测量,英文的看的头疼。
image.png手册上只有寥寥两语,大意是要设置BEEP的寄存器连接到TIM2 定时器的输入测量。那还得研究一下定时器测频率。
根据这个图,要先使能BEEP时钟,然后选择LSI。
image.png
再设置 BEEP_CSR1 MSR位。接下来是定时器捕获。
char measureFlag = 0;
long lsiFreq = 0;
char count = 0;
//校正LSI误差引起AWT不准的问题
long measureLSI()
{
//利用BEEP 蜂鸣器寄存器和time2 来测试LSI的频率
//1.打开蜂鸣器时钟,选择时钟为LSI
CLK_PCKENR1_bit.PCKEN16 = 1;
CLK_CBEEPR_bit.CLKBEEPSEL0 = 1;
CLK_CBEEPR_bit.CLKBEEPSEL1 = 0; //01 选择 LSI
//连接到TIM2, ICAP1 测量
BEEP_CSR1_bit.MSR = 1;
//初始化TIM2
CLK_PCKENR1_bit.PCKEN10 = 1; //使能时钟
TIM2_CR1_CEN = 0; //关闭
TIM2_CCER1_bit.CC1E = 0; //使不能捕获
TIM2_CR1_URS=1;//仅当计数器溢出时才发生中断请求, 为0时可能有其他情况
TIM2_CR1_UDIS=1;//禁止更新事件//计数器溢出属于更新事件
TIM2_CR1_DIR = 0; //加法计数器
TIM2_CR1_ARPE = 0; //不通过预装载寄存器
//设置捕获模式
TIM2_CCMR1_bit.CC1S = 1; // CC1 channel is configured as input, IC1 is mapped on TI1FP1
TIM2_CCER1_bit.CC1P = 0; //上升沿触发
TIM2_IER_bit.CC1IE = 1; //使能捕获中断
TIM2_SMCR_bit.TS = 5;
TIM2_SMCR_bit.SMS = 4;
TIM2_CCER1_bit.CC1E = 1; //使能捕获
TIM2_CR1_CEN = 1; //开启
//等待测量完成、关闭TIM2 BEEP
while(measureFlag == 0);
CLK_PCKENR1_bit.PCKEN10 = 0; //使能时钟
TIM2_CR1_CEN = 0;
TIM2_CCER1_bit.CC1E = 0;
BEEP_CSR1_bit.MSR = 0;
CLK_PCKENR1_bit.PCKEN16 = 0;
#ifdef DEBUG
printf("LSI_FREQ=%ld\n", lsiFreq);
#endif
return lsiFreq;
}
#pragma vector=TIM2_CAPCOM_CC1IF_vector
__interrupt void TIM2_CAPCOM_CC1IF_ISR (void)
{
if(TIM2_SR1_CC1IF == 1)
{
TIM2_SR1_CC1IF = 0;//清除中断标志位
unsigned int ccr1 = TIM2_CCR1H;
ccr1 <<= 8;
ccr1 += TIM2_CCR1L;
//ccr1得到的时间为整个周期的时间, 包括波峰、波谷
//主时钟数为16M 16M 除以 单个周期的时间 就是 测出来的频率
lsiFreq = HSI_FREQ / ccr1;
//关中断,否则程序跑不下去
count++;
if(count >= 10)
{
measureFlag = 1;
TIM2_IER_bit.CC1IE = 0;
}
}
}
多测几次会准一点。也可以多测几次取均值
网友评论