zoukankan      html  css  js  c++  java
  • STM32F103RCt6 -->输入捕获

    //加入以下代码,支持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
    ",temp);    //打印总的高点平时间
                 TIM2CH1_CAPTURE_STA=0;            //开启下一次捕获
             }
        }
        
    return 0;
    }

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

  • 相关阅读:
    jsp获取一个对象和list对象
    request属性 request.getAttribute()
    Ajax注册表单用户名实时验证
    codeigniter 操作mysql的PHP代码--更新
    linux后台server开发环境的部署配置和验证(nginx+apache+php-fpm+FASTCGI(C/C++))
    Android
    Jquery Jqprint—随着Jquery Jqprint实现网页打印
    SQL于DML(数据库操作语言)采用
    远程数据client交换器
    如何选择项目?
  • 原文地址:https://www.cnblogs.com/Loving-Q/p/12900985.html
Copyright © 2011-2022 走看看