OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3377|回复: 1

tpad中keyen的作用及我认为的原子哥程序中的小瑕疵

[复制链接]

13

主题

48

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
431
金钱
431
注册时间
2017-9-24
在线时间
81 小时
发表于 2018-5-13 17:31:01 | 显示全部楼层 |阅读模式
TPAD实验
关于keyen的作用:
通过实验就可以发现keyen的值不一定是3,只要大于或者等于2就可以随便设什么样的值,只要不要溢出这个值的类型就可以。当你将原子哥的程序下载到板中是不知细心地你有没有发现,一直按下不松手灯是不会闪烁的,这个就是变量keyen的作用。分析原子哥的程序就会发现,只要一直按着不松手,keyen的值就会是3、2、3、2、3、2...一直循环下去。不会出现keyen的值为0,也就不会说检测到手指按下(实际上手指一直按着,只不过程序中又是另一个提现方式)。所以灯就并不会出现一直闪烁的现象。这个思想也可以用在按键中。当你松手后keyen的值就会递减,变成3、2、1、0然后返回值res=1就又可以发挥作用了。


在TPAD_Init()函数中我发现一点小瑕疵,原子哥标了注释说计数频率为1MHz,实际上的计频率比这个还要快十倍左右,不多说,上代码[mw_shl_code=c,true]        TIM5_CH2_Cap_Init(TPAD_ARR_MAX_VAL,psc-1);//以1Mhz的频率计数


  TPAD_Init(6);[/mw_shl_code]。TPAD_ARR_MAX_VAL=0xFFFF,为最大的值,加1的话就是0 即预装载寄存器中的值为0,所以更新中断就不会打开,72M/6就是1M的十倍左右嘛!!如果门限值为100的话及TPAD_GATE_Val的值为100的话基本上达不到,因为相对的话它扩大了十倍左右的时间,我是基本上照着原子哥的程序理解自己写了一个,发现下载进去根本就不会亮,tpad_default_val的值在串口助手上显示的话就是18us 如果扩大十倍的话正好就是180us 可以达到原子哥在视频中说的那样。
还有就是在放电的函数中,即Reset();中,清除CNT寄存器中的计数值我可以理解,清CC2的标志位我也可以理解,但是清除中断标志位我就不怎么理解了,因为ARR寄存器根本就没有打开,于是我去掉去除更新中断标志位这个命令,发现程序照常执行。[mw_shl_code=c,true]#include "TPAD.h"
#include "delay.h"
#include "usart.h"
#define TPAD_GATE_VAL 10
#define ARR_MAX_VAL 0xffff
u16 tpad_default_val=0;


void TIM5_CH2_CAP_Init(u16 arr,u16 psc)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
        TIM_ICInitTypeDef TIM_ICInitStructure;

       
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);
       
        GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING;
        GPIO_InitStructure.GPIO_Pin =GPIO_Pin_1;
        GPIO_Init(GPIOA,&GPIO_InitStructure);
       
       
        TIM_TimeBaseInitStructure.TIM_ClockDivision =0;
        TIM_TimeBaseInitStructure.TIM_CounterMode =TIM_CounterMode_Up;
        TIM_TimeBaseInitStructure.TIM_Period =arr;
        TIM_TimeBaseInitStructure.TIM_Prescaler =psc;
        TIM_TimeBaseInit(TIM5, & TIM_TimeBaseInitStructure);
       
       
        TIM_ICInitStructure.TIM_Channel =TIM_Channel_2;
        TIM_ICInitStructure.TIM_ICFilter =0x03;
        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_Cmd(TIM5,ENABLE);
       
}

void TPAD_Init(void)
{
        u16 buff[10],temp=0;
        u8 i=0,j=0;
        TIM5_CH2_CAP_Init(ARR_MAX_VAL,71);//
        for(i=0;i<10;i++)
        {
                buff=TPAD_Get_Val();
                delay_ms(10);
        }
       
        for(i=0;i<9;i++)
                for(j=i+1;j<10;j++)
                {
                        if(buff>buff[j])
                        {
                                temp=buff;
                                buff=buff[j];
                                buff[j]=temp;
                        }
                }
                temp=0;
        for(i=2;i<8;i++)temp+=buff;
                tpad_default_val=(temp/6);
                printf("tpad_default_val:%d us\r\n",tpad_default_val);
               
}


void TPAD_RESET()
{
       
        GPIO_InitTypeDef GPIO_InitStructure;
       
       
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE);


        GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Pin =GPIO_Pin_1;
        GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
        GPIO_Init(GPIOA,&GPIO_InitStructure);
        GPIO_ResetBits(GPIOA,GPIO_Pin_1);       
        delay_ms(5);
       
        TIM_SetCounter(TIM5,0);
        TIM_ClearITPendingBit(TIM5,  TIM_IT_CC2);
       
        GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING;
        GPIO_InitStructure.GPIO_Pin =GPIO_Pin_1;
        GPIO_Init(GPIOA,&GPIO_InitStructure);
//        printf("reset \r\n");       
       
}
u16 TPAD_Get_Val(void)
{
        TPAD_RESET();
        while(TIM_GetFlagStatus(TIM5, TIM_FLAG_CC2)==RESET)
        {
                if(TIM_GetCounter(TIM5)>(ARR_MAX_VAL-500))return TIM_GetCounter(TIM5);
        };
               
//        printf("tpad_get_val\r\n");
        return        TIM_GetCapture2(TIM5);
}


u16 TPAD_Get_MaxVal(u8 n)
{
        u16 res=0,temp=0;
                while(n--)
                {
                        temp=TPAD_Get_Val();
                        if(res<temp)res=temp;
                };
//                printf("tpad_get_max_val\r\n");
                return res;
}

u8 TPAD_Scan(u8 mode)
{
        u16 rval=0;
        u8 simple=3,res=0;
        static u8 keyen=0;
        if(mode)
        {
                simple=6;
                keyen=0;
        }
        rval=TPAD_Get_MaxVal(simple);

        if(rval>(tpad_default_val+TPAD_GATE_VAL))
        {
                if(keyen==0)res=1;
                printf("r:%d\r\n",rval);
                keyen=3;
        }
        if(keyen)keyen--;
        if(keyen==2)printf("keyen:%d\r\n",keyen);
       
        return res;
               
}

[/mw_shl_code]

以上是我的一点浅显的见解,如果有什么理解出错的地方,还希望各位能帮我指出来,因为我是刚接STM32一个月左右的小白。谢谢,欢迎!!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

10

主题

97

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
486
金钱
486
注册时间
2019-12-6
在线时间
151 小时
发表于 2023-9-7 14:08:15 | 显示全部楼层
灯一直闪证明你主函数用的tpad_scan(1)函数参数你给1,支持连按,支持连按和不支持连按的区别就是支持连按 手不松开一直返回有效值,不支持连按,手按下去就第一次返回有效值,直到你手松开,再次按下才能返回有效值
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-24 17:56

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表