码迷,mamicode.com
首页 > 其他好文 > 详细

STM32F103RCt6 -->输入捕获

时间:2020-05-16 16:55:36      阅读:57      评论:0      收藏:0      [点我收藏+]

标签:lse   eem   ann   color   接收   需要   ima   流控制   定时   

//加入以下代码,支持printf函数,而不需要选择use MicroLIB      
#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{ 
    int handle; 

}; 

FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ 
    x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{      
    while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
    USART1->DR = (u8) ch;      
    return ch;
}
#endif 

 
 
#if EN_USART1_RX   //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误       
u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15,    接收完成标志
//bit14,    接收到0x0d
//bit13~0,    接收到的有效字节数目
u16 USART_RX_STA=0;       //接收状态标记      
  
void uart_init(u32 bound){
  //GPIO端口设置
  GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
     
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);    //使能USART1,GPIOA时钟
  
    //USART1_TX   GPIOA.9
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用推挽输出
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
   
  //USART1_RX      GPIOA.10初始化
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

  //Usart1 NVIC 配置
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        //子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化VIC寄存器
  
   //USART 初始化设置

    USART_InitStructure.USART_BaudRate = bound;//串口波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
    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); //初始化串口1
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
  USART_Cmd(USART1, ENABLE);                    //使能串口1 

}

void WK_UP_Init()
{
    GPIO_InitTypeDef GPIO_InitStruct;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPD;
    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStruct);    
}




void TIM2_Cap_Init(u16 arr,u16 psc)
{
    
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_ICInitTypeDef TIM_ICInitStruct;
    NVIC_InitTypeDef NVIC_InitStruct;
    
    
    //开启TIM2的时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
    
    //初始化定时器2 TIM2     
    TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值 
    TIM_TimeBaseStructure.TIM_Prescaler =psc;     //预分频器   
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
    
    
    //初始化输入捕获
    TIM_ICInitStruct.TIM_Channel=TIM_Channel_1;
    TIM_ICInitStruct.TIM_ICFilter=0x00;
    TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Rising;
    TIM_ICInitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1;
    TIM_ICInitStruct.TIM_ICSelection=TIM_ICSelection_DirectTI;
    TIM_ICInit(TIM2,&TIM_ICInitStruct);
    
    //中断优先级分组
    NVIC_InitStruct.NVIC_IRQChannel=TIM2_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority=0;
    NVIC_Init(&NVIC_InitStruct);
    
    TIM_ITConfig(TIM2,TIM_IT_Update|TIM_IT_CC1,ENABLE);
    
    TIM_Cmd(TIM2,ENABLE );     //使能定时器2
        
}




u8  TIM2CH1_CAPTURE_STA=0;    //输入捕获状态                            
u16    TIM2CH1_CAPTURE_VAL;    //输入捕获值
 
//定时器5中断服务程序     
void TIM2_IRQHandler(void)
{ 

     if((TIM2CH1_CAPTURE_STA&0X80)==0)//还未成功捕获    
    {      
        if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
         
        {        
            if(TIM2CH1_CAPTURE_STA&0X40)//已经捕获到高电平了
            {
                if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
                {
                    TIM2CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次
                    TIM2CH1_CAPTURE_VAL=0XFFFF;
                }else TIM2CH1_CAPTURE_STA++;
            }     
        }
    if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)//捕获1发生捕获事件
        {    
            if(TIM2CH1_CAPTURE_STA&0X40)        //捕获到一个下降沿         
            {                  
                TIM2CH1_CAPTURE_STA|=0X80;        //标记成功捕获到一次上升沿
                TIM2CH1_CAPTURE_VAL=TIM_GetCapture1(TIM2);
                   TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获
            }else                                  //还未开始,第一次捕获上升沿
            {
                TIM2CH1_CAPTURE_STA=0;            //清空
                TIM2CH1_CAPTURE_VAL=0;
                 TIM_SetCounter(TIM2,0);
                TIM2CH1_CAPTURE_STA|=0X40;        //标记捕获到了上升沿
                   TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling);        //CC1P=1 设置为下降沿捕获
            }            
        }                                                
     }
 
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位
 
}




extern u8  TIM2CH1_CAPTURE_STA;        //输入捕获状态                            
extern u16    TIM2CH1_CAPTURE_VAL;    //输入捕获值

int main()
{
    
    u32 temp=0; 
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
    delay_init();             //延时函数初始化    
    WK_UP_Init();
    uart_init(9600);                 //9600    
    
    TIM2_Cap_Init(0XFFFF,72-1);        //以1Mhz的频率计数 
    
    while(1)
    {
         delay_ms(10);
        TIM_SetCompare1(TIM1,TIM_GetCapture1(TIM1)+1);
        if(TIM_GetCapture1(TIM1)==300)TIM_SetCompare1(TIM1,0);         
        if(TIM2CH1_CAPTURE_STA&0X80)//成功捕获到了一次高电平
        {
            temp=TIM2CH1_CAPTURE_STA&0X3F;
            temp*=65536/8;                    //溢出时间总和
            temp+=TIM2CH1_CAPTURE_VAL;        //得到总的高电平时间
            printf("高电平时间:%d us\r\n",temp);    //打印总的高点平时间
             TIM2CH1_CAPTURE_STA=0;            //开启下一次捕获
         }
    }
    
return 0;
}

先放之前的代码,然后写下主要的函数解析,中断就别瞎改了,你写的没人家的好

技术图片

STM32F103RCt6 -->输入捕获

标签:lse   eem   ann   color   接收   需要   ima   流控制   定时   

原文地址:https://www.cnblogs.com/Loving-Q/p/12900985.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!