测量频率在 1k-2k之间,要求精度0.01%,也就是2kHZ, 0.2HZ。在做的过程中,发现最大跳动在0.8HZ,不知道代码哪有问题,之后就用avr做了一个,能满足要求,但我还是想用STM8,希望高人指点,谢谢!
代码如下:
#include "
tiM1_Capture.h"#include "includes.h"#include "delay.h"
//u16 tab[200];
INT_CHARS ICValue1,ICValue2;u8 cnt;u8 TIM1_OVF_Num;bool flag;
void TIM1_Init(void){ GPIOC->DDR &= ~(1<<1); // 配置PC1为输入 GPIOC->CR1 |= 1<<1; GPIOC->CR2 &= ~(1<<1); // 开启TIM1时钟 CLK->CKENR1 |= 0X80; TIM1->CNTRH = 0X00; TIM1->CNTRL = 0X00; TIM1->ARRH = 0Xff; TIM1->ARRL = 0Xff; TIM1->CR1 = 0X80; // 自动重装 TIM1->CCMR1 = 0X00; TIM1->CCER1 = 0X00; TIM1->CCMR1 |= 0X01; TIM1->CCER1 &= 0XFD; // 上升沿捕获
TIM1->IER |= 0X03; // 允许TIM1捕获中断,更新中断 TIM1->SR1 = 0x00; TIM1->SR2 = 0x00; TIM1->CR1 |= 0X01; // 使能TIM1 TIM1->CCER1 = 0X01; // 使能捕获}
u16 ComputeFreq(void){ u16 temp; u32 sum;
flag = FALSE; cnt = 0; TIM1_Init(); while(!flag); // 等待100次捕获结束 sum = TIM1_OVF_Num; sum *= 65536; sum += ICValue2.x; sum -= ICValue1.x; sum /= 10; temp = 1600000000/sum; return temp;}
#pragma vector=0x0E__interrupt void TIM1_CAP_COM_IRQHandler(void){ disableInterrupts(); if(cnt==5) { ICValue1.FJ[0] = TIM1->CCR1H; ICValue1.FJ[1] = TIM1->CCR1L; flag = FALSE; TIM1_OVF_Num = 0; } else if(cnt==105) // 100次捕获结束 { ICValue2.FJ[0] = TIM1->CCR1H; ICValue2.FJ[1] = TIM1->CCR1L; flag = TRUE; TIM1->CR1 &= 0XFE; // 失能TIM1 TIM1->CCER1 = 0X00; } TIM1->SR1 &= 0xFD;// TIM1->SR2 = 0x00; cnt++;
enableInterrupts();}
#pragma vector=0x0D__interrupt void TIM1_OVF_IRQHandler(void){ disableInterrupts(); TIM1_OVF_Num++; TIM1->SR1 &= 0xFE;// TIM1->SR2 = 0x00;
enableInterrupts();}
0