OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 7893|回复: 5

STM8S003 TIM1输入捕获问题请教

[复制链接]

15

主题

46

帖子

0

精华

初级会员

Rank: 2

积分
151
金钱
151
注册时间
2014-9-29
在线时间
10 小时
发表于 2016-6-8 21:45:02 | 显示全部楼层 |阅读模式
5金钱
先谢谢各位。
1.芯片型号是STM8S003F3P6
2.测量方波的频率。
3.测试1khz的标准方波,测到的频率不正确。在计数分频为1分频和2分频时测到的数据分别是5658hz和5672hz,在计数分频为3~16分频时测到的数据是1001或者1002hz.
  在计数器分频为3分频时测79KHZ的方波时只有2647hz。其它频率的方波还没测试过。下面是我的代码,麻烦高手看看,问题在哪里,谢谢。
[mw_shl_code=applescript,true]void main(void)
{
        u8 i;
       
  CLK_CKDIVR = 0x00;
       
       
        GPIO_Init1();
       
       
        TIM1_Input_Capture();        /* 初始化TIM1输入捕获通道 */
       
  enableInterrupts();
        Get_FrequencyArray(Frequency_Array,GetPulseNum);
        AverageFrequency=Get_AverageFrequency(Frequency_Array,GetPulseNum);
        CLKNUM =((u32)16000000/3)*1/AverageFrequency;
        CLKNUM =0;

        while (1){



}       
}

/* 全局变量定义 */
static void Sort(u16 array[],u8 n);

/*******************************************************************************
* 名称: TIM1_Input_Capture
* 功能: TIM1输入捕捉初始化操作
* 形参: 无
* 返回: 无
* 说明: 无
******************************************************************************/
void TIM1_Input_Capture(void)
{
          /* 初始化TIM1输入捕捉通道1 */
                //TIM1_ICInit(TIM1_CHANNEL_1, TIM1_ICPOLARITY_RISING, TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV1, 0x0f);
        TIM1_ICInit(TIM1_CHANNEL_1, TIM1_ICPOLARITY_FALLING, TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV1, 0x00);
        TIM1_CNTRH = 0x00;//清零计数器高8位
        TIM1_CNTRL = 0x00;//清零计数器低8位
        TIM1_PSCRH = 0x00;//计数器时钟分频高8位
        TIM1_PSCRL = 0x02;//计数器时钟分频低8位16分频

        TIM1_ClearFlag(TIM1_FLAG_CC1);
        TIM1_CCxCmd(TIM1_CHANNEL_1, ENABLE);        /* 使能输入捕获通道1 */
        TIM1_Cmd(ENABLE);        /* 使能定时器 */
}



/*******************************************************************************
* 名称: Get_IC_Frequency
* 功能: 得到输入捕捉计数值
* 形参: 无
* 返回: 无
* 说明: 无
******************************************************************************/
u16 Get_IC_Frequency(void)
{
        u16 Period;
        u16 ICValue1,ICValue2;
       
        TIM1->CCR1H=0;
        TIM1->CCR1L=0;        /* 清空输入捕捉值 */
        while(!TIM1_GetFlagStatus(TIM1_FLAG_CC1));
        ICValue1=TIM1_GetCapture1();        /* 得到第一次捕捉计数值 */
       
        TIM1_ClearFlag(TIM1_FLAG_CC1);        /* 清空标志位 */
       
        while(!TIM1_GetFlagStatus(TIM1_FLAG_CC1));
        ICValue2=TIM1_GetCapture1();        /* 得到第二次捕捉计数值 */
        TIM1_ClearFlag(TIM1_FLAG_CC1);        /* 清空标志位 */
       
        if(ICValue2 > ICValue1)
                  Period = ICValue2-ICValue1;
        else if(ICValue2<ICValue1)
                  Period = 0xffff + ICValue2-ICValue1;
       
        return Period;
}


/*******************************************************************************
* 名称: Get_IC_Frequency
* 功能: 将计数值存入数组
* 形参: 无
* 返回: 无
* 说明: 无
******************************************************************************/
void Get_FrequencyArray(u16 FrequencyArray[], u8 times)
{
        u8 i;
        for(i = 0; i < times; i++)
                FrequencyArray=Get_IC_Frequency();
}

/*******************************************************************************
* 名称: Sort
* 功能: 对计数值进行排序
* 形参: 无
* 返回: 无
* 说明: 无
******************************************************************************/
static void Sort(u16 array[],u8 n)
{
        u8 i,j,k;
        u16 t;
        for(i=0;i<n-1;i++)
        {
                k=i;
                for(j=i+1;j<n;j++)
                        if(array[j]<array[k])
                                k=j;
               
                t=array[k];
                array[k]=array;
                array=t;
        }
}
/*******************************************************************************
* 名称: Get_AverageFrequency
* 功能: 对计数值进行滤波
* 形参: 无
* 返回: 无
* 说明: 无
******************************************************************************/
u16 Get_AverageFrequency(u16 GetFrequency[],u8 n)
{
        u8 i;
        u16 temp=0;
       
        Sort(GetFrequency,n);
       
        for(i=5;i<n-5;i++)
                temp+=GetFrequency;
       
        temp/=(n-10);
       
        return temp;
}



[/mw_shl_code]

最佳答案

查看完整内容[请看2#楼]

我用中断的方式去实现,可以测到五十多K,刚好够项目的使用,没继续研究了
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

15

主题

46

帖子

0

精华

初级会员

Rank: 2

积分
151
金钱
151
注册时间
2014-9-29
在线时间
10 小时
 楼主| 发表于 2016-6-8 21:45:03 | 显示全部楼层
我用中断的方式去实现,可以测到五十多K,刚好够项目的使用,没继续研究了
回复

使用道具 举报

558

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
164897
金钱
164897
注册时间
2010-12-1
在线时间
2100 小时
发表于 2016-6-8 22:46:47 | 显示全部楼层
帮顶
回复

使用道具 举报

2

主题

5

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2016-6-17
在线时间
0 小时
发表于 2016-6-25 09:13:34 | 显示全部楼层
CLKNUM =((u32)16000000/3)*1/AverageFrequency;
以上这句是有问题的吧
1.16000000*3才对
2.AverageFrequency应该是捕获1次和2次相减的值
回复

使用道具 举报

3

主题

24

帖子

0

精华

新手上路

积分
42
金钱
42
注册时间
2016-1-18
在线时间
10 小时
发表于 2017-2-3 15:01:34 | 显示全部楼层
为什么不用中断的方式?
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
6
金钱
6
注册时间
2019-11-13
在线时间
1 小时
发表于 2020-9-11 10:59:32 | 显示全部楼层
aleelau 发表于 2016-6-8 21:45
我用中断的方式去实现,可以测到五十多K,刚好够项目的使用,没继续研究了

你好,采用的什么外部中断,然后中断函数里读取定时器计数值吗?能具体说一下吗?谢谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-5-29 07:33

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表