这次的实验功能是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;
}
}
}