打印
[STM32F1]

使用stm32 tim的ert检测频率成功,串口数据发送错误

[复制链接]
2976|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
小猫薄薄|  楼主 | 2014-5-3 16:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 小猫薄薄 于 2014-5-3 21:19 编辑

现在可以用stm32 tim_ert实现对脉冲的计数功能,如何才能实现对脉冲的频率计算呢?  对于高频脉冲(MhZ)的频率计算可以通过f=n/t实现,t取值10ms,如何才能实现对脉冲计数的精确定时呢?10ms定时已经解决,串口数据发送错误不知怎么回事? 如果把tim2的中断取消,就不会产生错误。

tim3计数代码粘贴如下,请问如何实现10ms 的精确定时
# include "Tim3.h"

void Tim3_Config(void){
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;
        
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
        
        /*PD2作为频率输入端口*/
        GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOD, &GPIO_InitStructure);
        

        
        
        TIM_DeInit(TIM3);
  TIM_TimeBaseStructure.TIM_Period =0xFFFF;//当计数器从0记到FFF为一个周期,自动装载寄存器ARR中的值
  TIM_TimeBaseStructure.TIM_Prescaler = 0X00;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;//设置时钟系数 不分频
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // Time base configuration
        
        
        
        
  /* ------------------------------------------------------------------------------------------
        * TIM_ExtTRGPSC_OFF  tim ETRP 预分频0
        * TIM_ExtTRGPolarity_Inverted 外部触发极性非翻转:高电平或上升沿有效
        *0 外部触发滤波器  再0x0-0xf之间  经过多少个周期认为脉冲稳定
        -------------------------------------------------------------------------------------------*/
        TIM_ITRxExternalClockConfig(TIM3,TIM_TS_ETRF);
  TIM_ETRClockMode2Config(TIM3, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_Inverted, 0);
  TIM_SetCounter(TIM3, 0);  //设置计数器为0
  TIM_Cmd(TIM3, ENABLE);
        //TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);

}

/*void NVIC_Config(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

  /* Enable the TIM3 global Interrupt
  NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}
*/

tim2 和中断函数配置如下
void Tim2_Config(){
        TIM_TimeBaseInitTypeDef   TIM2_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
        
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
        
        TIM_DeInit(TIM2);
  TIM2_TimeBaseStructure.TIM_Period =10000;
  TIM2_TimeBaseStructure.TIM_Prescaler = 71;
  TIM2_TimeBaseStructure.TIM_ClockDivision = 0x0;//ÉèÖÃʱÖÓϵÊý ²»·ÖƵ
  TIM2_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//ÏòÉϼÆÊýģʽ
  TIM_TimeBaseInit(TIM2, &TIM2_TimeBaseStructure); // Time base configuration
        TIM_ClearFlag(TIM2,TIM_FLAG_Update);//Çå³þ¸üбê־λ
        TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE );
        
        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
        
        TIM_Cmd(TIM2, ENABLE);               
}

void TIM2_IRQHandler(void)   
{
        if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
        {
                TIM_ClearITPendingBit(TIM2, TIM_IT_Update );
                Frequency_value = TIM_GetCounter(TIM3);
        }
}


串口收到的数据如下,前两个字节就是计数值Frequency_value,中间红色部分确是有数据发送错误是怎么回事?、
A0 5B 00 00 0D 0A
53 76 00 00 0D 0A
06 91 00 00 0D 0A
B9 AC 00 00 0D 0A
6C C7 00 00 0D 0A
1F E2 00 00 0D 0A
D2 FD 00 00 0D 0A
86 18 00 00 0D 0A
39 33 00 00 0D 0A
EC 4E 00 00 0D 0A
9F 69 00 00 0D 0A
52 84 00 00 0D 0A
05 9F 00 00 0D 0A
B8 BA 00 00 0D 0A
6B D5 00 00 0D 0A
1E F0 00 00 0D 0A
D2 0B 00 00 0D 0A
85 26 00 00 0D 0A
38 41 00 00 0D 0A
EB 5C 00 FF FF 6E
9E F9 FF FF FF 6C
00 F9 FF FF FF 69
00 F9 FF FF FF 67
00 F9 FF FF FF 65
00 F9 FF FF FF 62
28 87 00 00 0D 0A
DB A2 00 00 0D 0A
8E BD 00 00 0D 0A
41 D8 00 00 0D 0A
F4 F3 00 00 0D 0A
A8 0E 00 00 0D 0A
5B 29 00 00 0D 0A
0E 45 00 00 0D 0A
C1 60 00 00 0D 0A
串口配置如下
#include "uart.h"


void uart_Init(void){
        GPIO_InitTypeDef  GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;              
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE );

  /*
  *  USART1_TX -> PA9 , USART1_RX ->PA10
   */                                
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;                 
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);        

  USART_InitStructure.USART_BaudRate = 115200;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  USART_Init(USART1, &USART_InitStructure);

  USART_Cmd(USART1, ENABLE);
}

int fputc(int ch, FILE *f){
        USART_SendData(USART1, (unsigned char) ch);   
        //while (!(USART1->SR & USART_FLAG_TXE));   
        while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);      
        return (ch);   
}

void UART_send_byte(uint8_t byte)
{
while(!((USART1->SR)&(1<<7)));
USART1->DR=byte;       
}               

void UART_Send(uint8_t *Buffer, uint32_t Length)
{
        while(Length != 0)
        {
                while(!((USART1->SR)&(1<<7)));//µÈ´ý·¢ËÍÍê
                USART1->DR= *Buffer;
                Buffer++;
                Length--;
        }
}


uint8_t UART_Recive(void)
{       
        while(!(USART1->SR & (1<<5)));
        return(USART1->DR);                       
}



代码已经测试可以对脉冲进行计数,计数到达65535以后清零重新计数,如何实现10ms精确定时?
沙发
小猫薄薄|  楼主 | 2014-5-3 17:19 | 只看该作者
顶一下,有大神可以帮忙看下么

使用特权

评论回复
板凳
小猫薄薄|  楼主 | 2014-5-3 18:43 | 只看该作者
再顶,我使用tim2进行定时,10ms产生中断,但是发现串口传来的数据有问题。而且没38次传输以后就会有四次乱码传输,接着回归正常,还未找到原因

使用特权

评论回复
地板
小猫薄薄|  楼主 | 2014-5-3 19:34 | 只看该作者
再顶,求大神指点一下

使用特权

评论回复
5
小猫薄薄|  楼主 | 2014-5-3 21:34 | 只看该作者
@香水城   香主,帮帮忙吧

使用特权

评论回复
6
小猫薄薄|  楼主 | 2014-5-3 22:30 | 只看该作者
直到我现在搞定了 还是没有一个人

使用特权

评论回复
7
mmuuss586| | 2014-5-3 23:02 | 只看该作者
小猫薄薄 发表于 2014-5-3 22:30
直到我现在搞定了 还是没有一个人

搞定了就好,我没看出来哪问题。

使用特权

评论回复
8
香水城| | 2014-5-4 10:13 | 只看该作者
小猫薄薄 发表于 2014-5-3 22:30
直到我现在搞定了 还是没有一个人

五一大假期间,看来大家都出去玩了哦。

如果你自己搞定了,不妨把心得和解决办法和大家一起分享一下。论坛嘛,就是个大家互相交流互相学习的地方。

使用特权

评论回复
9
小猫薄薄|  楼主 | 2014-5-5 13:02 | 只看该作者
香水城 发表于 2014-5-4 10:13
五一大假期间,看来大家都出去玩了哦。

如果你自己搞定了,不妨把心得和解决办法和大家一起分享一下。论 ...

问题就是出在中断上,因为10ms的一次中断太过频繁,导致串口在发送过程中总是被打断,只要在串口发送之前添加中断失能代码然后在发送结束后打开中断就可以了。串口修改代码如下

void UART_Send(uint8_t *Buffer, uint32_t Length)
{
             TIM_ITConfig(TIM2,TIM_IT_Update,DISABLE );
        while(Length != 0)
        {
                while(!((USART1->SR)&(1<<7)));//µÈ´ý·¢ËÍÍê
                USART1->DR= *Buffer;
                Buffer++;
                Length--;
        }
             TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE );
}
希望对碰到类似问题的朋友有帮助

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

21

帖子

0

粉丝