<备战蓝桥杯之嵌入式>——输入捕获

来源:互联网 发布:大数据相关论坛 编辑:程序博客网 时间:2024/05/22 04:30

这次的实验功能是LCD显示按键按下的时间(高电平持续时间)。

 

一开始出了个小问题,怎么也进不了“go to the definition of  ”,后来编译了一下就可以了。

Error:expression is notassignable ;意思是不可以给改函数赋值,例如TIM_GetCapture1(TIM5)=0;

 

 

 

输入捕获配置:

1:GPIO和TIM5的时钟使能;

2:配置GPIO;

关于上下拉输入和浮空输入的区别:

如果上拉输入,意思是说,内部有个上拉电阻,确保IO口是高电平状态,当有低电平输入时,处理器可以稳定识别。下拉输入以此类推。浮空输入,言外之意就是说,引脚电平不确定,外部输入信号不一定管用,这样就会出现不稳定现象,一般用浮空输入的设备,内部是有上拉或者下拉电阻的。

而根据《STM32中文参考手册》,定时器TIM5_CH1输入捕获通道对应的GPIO应当设置为“浮空输入”,我也尝试配置成浮空输入,实验现象是打印出来的高电平时常极其不稳定,而正点原子的程序将其设置成下拉输入。因为设置成下拉输入是方便采集电平,否则如果用浮空输入的话,需要外加下拉电阻!!

并且使用GPIO_Reset();来拉低。

3:配置TIM初始化;

4:输入捕获初始化;

5:中断初始化;

6:使能定时器的两个中断和自动预装载;

7:定时器使能;

8:中断函数;

贴出来:

void IC_Init(u16 arr,u16 psc)

{

         GPIO_InitTypeDefGPIO_InitStructure;

         TIM_TimeBaseInitTypeDefTIM_TimeBaseInitStructure;

         TIM_ICInitTypeDefTIM_ICInitStructure;

         NVIC_InitTypeDefNVIC_InitStructure;

        

         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);

        

         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;

         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;

         GPIO_Init(GPIOA,&GPIO_InitStructure);

         GPIO_ResetBits(GPIOA,GPIO_Pin_0);

        

         TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;

         TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;

         TIM_TimeBaseInitStructure.TIM_Period=arr;

         TIM_TimeBaseInitStructure.TIM_Prescaler=psc;

         TIM_TimeBaseInit(TIM5,&TIM_TimeBaseInitStructure);

        

         TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE);

        

         TIM_ICInitStructure.TIM_Channel=TIM_Channel_1;

         TIM_ICInitStructure.TIM_ICFilter=0;

         TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;

         TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;

         TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;

         TIM_ICInit(TIM5,&TIM_ICInitStructure);

        

         TIM_ITConfig(TIM5,TIM_IT_CC1,ENABLE);

        

         NVIC_InitStructure.NVIC_IRQChannel=TIM5_IRQn;

         NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;

         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;

         NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;

         NVIC_Init(&NVIC_InitStructure);

        

         TIM_Cmd(TIM5,ENABLE);

}

u8 IN_CAPTURE_STA=0X00;

u16 IN_CAPTURE_VAL=0X0000;

 

void TIM5_IRQHandler(void)

{

         if(IN_CAPTURE_STA&0X40)

         {

                   if(TIM_GetITStatus(TIM5,TIM_IT_Update)==SET)

                   {

                            if(IN_CAPTURE_STA==0X7F)

                            {

                                     IN_CAPTURE_STA|=0X80;

                                     IN_CAPTURE_VAL=0XFFFF;

                            }

                            else  IN_CAPTURE_STA++;

                   }

         }       

         if((IN_CAPTURE_STA&0X40)==0)

         {

                   if(TIM_GetITStatus(TIM5,TIM_IT_CC1)==SET)

                   {

                            IN_CAPTURE_STA=0X00;

                            IN_CAPTURE_VAL=0X0000;

                            IN_CAPTURE_STA|=0X40;

                            TIM_SetCounter(TIM5,0);

                            TIM_OC1PolarityConfig(TIM5,TIM_OCPolarity_Low);

                   }

         }

         else

         {

                   if(TIM_GetITStatus(TIM5,TIM_IT_CC1)==SET)

                   {

                            IN_CAPTURE_STA|=0X80;

                            IN_CAPTURE_VAL=TIM_GetCapture1(TIM5);

                            TIM_OC1PolarityConfig(TIM5,TIM_OCPolarity_High);

                   }

         }       

         TIM_ClearITPendingBit(TIM5,TIM_IT_Update|TIM_IT_CC1);

}

 

主函数没什么好讲的,直接贴:

#include "delay.h"

#include "sys.h"

#include "usart.h"

#include "lcd.h"

#include "led.h"

#include "timer.h"

extern u8 IN_CAPTURE_STA;

extern u16 IN_CAPTURE_VAL;

int main(void)

{

         u32temp;

         u8lcd_id[12];                     //存放LCD ID字符串    

         delay_init();                    //延时函数初始化         

         uart_init(9600);               //串口初始化为9600

         LCD_Init();

         POINT_COLOR=RED;

         sprintf((char*)lcd_id,"LCDID:%04X",lcddev.id);//将LCD ID打印到lcd_id数组。      

         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);       

         IC_Init(0XFFFF,71);

         PWM_Init(899,0);

         POINT_COLOR=RED;         

         LCD_ShowString(30,40,200,24,24,"MiniSTM32 ^_^");

         LCD_ShowString(30,70,200,16,16,"ICTEST");

         LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");

         LCD_ShowString(30,110,200,16,16,lcd_id);             //显示LCD ID                                                   

         LCD_ShowString(30,130,200,12,12,"2014/3/7");                                                    

         while(1)

         {

                   delay_ms(10);

                   TIM_SetCompare1(TIM1,TIM_GetCapture1(TIM1)+1);

                   TIM_SetCompare1(TIM3,TIM_GetCapture1(TIM3)-1);

                   if(TIM_GetCapture1(TIM1)>300)    TIM_SetCompare1(TIM1,0);

                   if(TIM_GetCapture1(TIM3)==0)      TIM_SetCompare1(TIM3,300);

                   if(IN_CAPTURE_STA&0X80)

                   {

                            temp=(IN_CAPTURE_STA&0X3F);

                            temp*=65536;

                            temp+=IN_CAPTURE_VAL;

                            printf("HIGH:%dus\r\n",temp);

                            LCD_ShowNum(30,162,temp,10,16);     

                            IN_CAPTURE_STA=0;

                   }

         }

}

1 0
原创粉丝点击