炒冷饭系列-STM32F103之电容按键

淦,搞了好久,这逻辑我理解不了啊啊啊啊啊

#include "stm32f10x.h"
#include "LED.h"
#include "delay.h"
#include "tim.h"
#include "usart.h"
#include "icap.h"void tpadHandler(uint16_t prer,uint16_t value);
void tpadInitVal(void);
u16 TPAD_Get_Val(void);
void TPAD_Reset();
u16 TPAD_Get_MaxVal(u8 n);
//u8 TPAD_Scan();
u8 TPAD_Scan(u8 mode);u16 TPAD_ARR_MAX_VAL=0xFFFF;int main(void)
{	u8 t=0;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);delay_init();	    	 //延时函数初始化LED_Init();uart_init(115200);	 //串口初始化为115200tpadHandler(6-1,TPAD_ARR_MAX_VAL);tpadInitVal();while(1){if(TPAD_Scan(0)){LED0=~LED0;		//LED0取反}t++;if(t==15){t=0;LED1=~LED1;}delay_ms(10);}
}//定时器、捕获初始化
void tpadHandler(uint16_t prer,uint16_t value)
{GPIO_InitTypeDef GPIO_InitStruct;TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;TIM_ICInitTypeDef TIM_ICInitStruct;//1、时钟使能 TIM5时钟  GOIPA时钟		PA1->TIM5_CH2RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);//2、GPIOA1口的配置GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;// GPIO_Mode_IPD   GPIO_Mode_IN_FLOATINGGPIO_InitStruct.GPIO_Pin=GPIO_Pin_1;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);//3、TIM5配置TIM_TimeBaseInitStruct.TIM_Prescaler=prer;//给TIM时钟分频:范围0x0000~0xFFFF=0~65535,对应预分频寄存器:TIMx->PSCTIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;//计数模式:有5种,对应控制寄存器1:TIM_CR1_DIR位4 | TIM_CR1_CMS位[6:5]TIM_TimeBaseInitStruct.TIM_Period=value;//自动重装载值:0x0000 and 0xFFFF 对应自动重装载值寄存器:TIMx->ARRTIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;//TIM_CKD_DIV1//APB1时钟36MHz  分频72MHz    给APB1时钟分频:1,2,4 ,对应控制寄存器1:TIM_CR1_CKD位[9:8]TIM_TimeBaseInit(TIM5, &TIM_TimeBaseInitStruct);//4、TIM5输入比较参数配置TIM_ICInitStruct.TIM_Channel=TIM_Channel_2;//TIM5_CH2->PA1TIM_ICInitStruct.TIM_ICFilter= 0x03;//配置输入滤波器 8 个定时器时钟周期滤波TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Rising;//输 入 信 号 的 有 效 捕 获 极 性TIM_ICInitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1;//TIM_ICInitStruct.TIM_ICSelection=TIM_ICSelection_DirectTI;//配置 IC1 直接映射在 TI1 上TIM_ICInit(TIM5,&TIM_ICInitStruct);//6、更新中断、捕获中断//TIM_ITConfig(TIM5, TIM_IT_Update|TIM_IT_CC1,ENABLE);//7、使能TIM5定时器TIM_Cmd(TIM5,ENABLE);
}//原理:没有按下时充电所需要的时间  对比 按下时充电所需要的时间(时间长)//计算重启后(按键还没按下)充电所需要的时间(需要精确的获取到)
vu16 tpad_default_val=0;//计算重启后(按键还没按下)充电所需要的时间(需要精确的获取到)
void tpadInitVal(void)
{u16	buf[10];u16 temp=0;u8 k=0;int i=0;int j=0;int h=0;//不断的充放电来获取10次时间for(h=0;h<=10;h++){buf[h]=TPAD_Get_Val();delay_ms(10);}//将这10个值进行冒泡排序,为了去掉最大最小值for(i=0;i<10;i++){for( j=i+1;j<10;j++){if(buf[i]<buf[j]){u16 temp1=0;temp1=buf[i];buf[i]=buf[j];buf[j]=temp1;}}}for(k=2;k<8;k++)//取中间的六个值{temp+=buf[k];}tpad_default_val=temp/6;//精确计算重启后充电所需要的时间(全局变量) printf("tpad_default_val:%d\r\n",tpad_default_val);	//计算重启后充电所需要的时间    	    	
}//得到定时器捕获值
//如果超时,则直接返回定时器的计数值.u16 TPAD_Get_Val(void)
{	TPAD_Reset();while(TIM_GetFlagStatus(TIM5,TIM_IT_CC2 ))//等待充电完成,出现上升沿{if(TIM_GetCounter(TIM5)>=TPAD_ARR_MAX_VAL-500)//如果超时,就返回计数器(CNT)的值{return TIM_GetCounter(TIM5);}}return TIM_GetCapture2(TIM5);//返回捕获值
}//不断的放电和充电
void TPAD_Reset()
{GPIO_InitTypeDef GPIO_InitStruct;//1、时钟使能 TIM5时钟  GOIPA时钟		PA5->TIM5_CH2RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//2、GPIOA5口的配置GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;// 放电,推挽输出低电平GPIO_InitStruct.GPIO_Pin=GPIO_Pin_1;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);GPIO_ResetBits(GPIOA,GPIO_Pin_1);//输出低电平,电容放电delay_ms(10);//等待放电完成TIM_SetCounter(TIM5, 0);//设置定时器的值为 0,为计算充电时间做准备TIM_ClearITPendingBit(TIM5, TIM_IT_CC2|TIM_IT_Update); //清除中断标志GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;// 放电,浮空输入GPIO_Init(GPIOA,&GPIO_InitStruct);
}扫描触摸按键
返回值:0,没有按下;1,有按下;										  
//#define TPAD_GATE_VAL 	100	//触摸的门限值,也就是必须大于tpad_default_val+TPAD_GATE_VAL,才认为是有效触摸.
//u8 TPAD_Scan()
//{
//	u8 res=0;//没有按下时为0,按下为1;
//	
//	u8 max_val=TPAD_Get_MaxVal(5);
//	if(max_val>tpad_default_val+TPAD_GATE_VAL)
//	{
//		res=1;
//		return res;
//	}
//	
//	return res;
//}//扫描触摸按键
//mode:0,不支持连续触发(按下一次必须松开才能按下一次);1,支持连续触发(可以一直按下)
//返回值:0,没有按下;1,有按下;										  
#define TPAD_GATE_VAL 	100	//触摸的门限值,也就是必须大于tpad_default_val+TPAD_GATE_VAL,才认为是有效触摸.
u8 TPAD_Scan(u8 mode)
{static u8 keyen=0;	//0,可以开始检测;>0,还不能开始检测	 u8 res=0;u8 sample=3;		//默认采样次数为3次	 u16 rval;if(mode){sample=6;		//支持连按的时候,设置采样次数为6次keyen=0;		//支持连按	  }rval=TPAD_Get_MaxVal(sample); if(rval>(tpad_default_val+TPAD_GATE_VAL))//大于tpad_default_val+TPAD_GATE_VAL,有效{							 if(keyen==0)res=1;		//keyen==0,有效 //printf("r:%d\r\n",rval);		     	    					   keyen=3;				//至少要再过3次之后才能按键有效   } if(keyen)keyen--;		   							   		     	    					   return res;
}	//采样5次获取最大值
u16 TPAD_Get_MaxVal(u8 n)
{u16 temp=0;u16 res=0;while(n--){temp=TPAD_Get_Val();if(temp>res){res=temp;}}return res;
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部