查看: 5912|回复: 11

[原创] 【YL-KL26Z开发】+ TSI电容触摸按键测试

[复制链接]

该用户从未签到

42

主题

340

帖子

0

高级会员

Rank: 4

积分
722
最后登录
2016-1-9
发表于 2015-7-31 18:13:17 | 显示全部楼层 |阅读模式
接上次的实验:https://www.nxpic.org.cn/module/forum/thread-600350-1-1.html

本次所测试模块为TSI的电容触摸按键,关于这里的TSI,里面涉及到了许多模拟电路的知识,我不是非常清楚,所以帖子里有错误的地方也请指出。

首先来看程序:

主函数:
int  main (void)
{
    INT16U Vout = 0;
  SIM_SCGC5 |= (SIM_SCGC5_PORTA_MASK
                  | SIM_SCGC5_PORTB_MASK
                  | SIM_SCGC5_PORTC_MASK
                  | SIM_SCGC5_PORTD_MASK
                  | SIM_SCGC5_PORTE_MASK
                  | SIM_SCGC5_TSI_MASK);

    SystemCoreClockUpdate();

    PORT_ENABLE_CLK(MKL_PORTB);                                         /* 使能PORT时钟                 */
    PORT_ENABLE_CLK(MKL_PORTD);
   
    IO_FUN_SEL(MKL_PORTB,18,1);                                         /* IO功能选择                   */
    IO_FUN_SEL(MKL_PORTB,19,1);
    IO_FUN_SEL(MKL_PORTD,1,1);   
     
    GPIO_DDR_OUTPUT(MKL_PORTB,18);                                      /* IO设置为输出模式             */
    GPIO_DDR_OUTPUT(MKL_PORTB,19);
    GPIO_DDR_OUTPUT(MKL_PORTD,1);   
   
    GPIO_CLR(MKL_PORTB,18);                                             /* IO设置为高电平,LED熄灭      */
    GPIO_SET(MKL_PORTB,19);
    GPIO_SET(MKL_PORTD,1);
    TSI_Init();

  NVIC_EnableIRQ(TSI0_IRQn);
  NVIC_SetPriority(TSI0_IRQn,3);   /**< TSI0 interrupt */
while (1){
  TSI_Slider_LED();
  }      
}


主函数中关于这个模块我们主要关心的就是上面红色的部分:TSI的初始化, TSI控制LED。

TSI初始化:

SIM_SCGC5 |= SIM_SCGC5_TSI_MASK;  // Enable clock gating for TSI
  
  /* Enable proper GPIO as TSI channels */
  PORTB_PCR16 = PORT_PCR_MUX(0);   // PTB16 as TSI channel 9
  PORTB_PCR17 =  PORT_PCR_MUX(0);   // PTB17 as TSI channel 10
  PORTC_PCR0 =  PORT_PCR_MUX(0);   // PTB17 as TSI channel 13
  NVIC_DisableIRQ((IRQn_Type)TSI0_IRQn);
  
  
  TSI0_GENCS |= (TSI_GENCS_ESOR_MASK                  //允许扫描结束中断
                   | TSI_GENCS_MODE(0)                            //配置为电容传感模式
                   | TSI_GENCS_REFCHRG(4)                       //参考振荡器充放电电流值
                   | TSI_GENCS_DVOLT(0)                           //振荡器电压下限
                   | TSI_GENCS_EXTCHRG(7)                       //电极振荡器充放电电流值
                   | TSI_GENCS_PS(4)                                 //电极振荡器分频数
                   | TSI_GENCS_NSCN(11)                           //电极采样次数
                   | TSI_GENCS_TSIIEN_MASK                     //TSI中断使能
                   | TSI_GENCS_STPE_MASK                        //开启低功耗模式正常工作
                   );
  
  TSI0_GENCS |= TSI_GENCS_TSIEN_MASK;                 //使能TSI
  
  TSI_SelfCalibration();                                                //TSI校准
}


在TSI配置里面提到了两个振荡器(暂且这么翻译),他们的区别如下:
QQ截图20150731174613.png
电极振荡器是通过电量的变化值来控制TSI中断,从而达到触摸控制的目的。
QQ截图20150731174544.png
参考振荡器是用来代替外部电容,给电极振荡器充电的。

TSI校准:

void TSI_SelfCalibration(void)
{
  unsigned char cnt;
  unsigned char trigger_backup;
  
  
  TSI0_GENCS |= TSI_GENCS_EOSF_MASK;      // Clear End of Scan Flag
  TSI0_GENCS &= ~TSI_GENCS_TSIEN_MASK;    // Disable TSI module
  
  if(TSI0_GENCS & TSI_GENCS_STM_MASK)     // Back-up TSI Trigger mode from Application
       trigger_backup = TRUE;
  else
       trigger_backup = FALSE;
  
  TSI0_GENCS &= ~TSI_GENCS_STM_MASK;      // Use SW trigger
  TSI0_GENCS &= ~TSI_GENCS_TSIIEN_MASK;    // Enable TSI interrupts
  
  TSI0_GENCS |= TSI_GENCS_TSIEN_MASK;     // Enable TSI module
  
  for(cnt=0; cnt < total_electrode; cnt++)  // Get Counts when Electrode not pressed
  {
    TSI0_DATA = ((elec_array[cnt] << TSI_DATA_TSICH_SHIFT) );
    TSI0_DATA |= TSI_DATA_SWTS_MASK;
    while(!(TSI0_GENCS & TSI_GENCS_EOSF_MASK));
    TSI0_GENCS |= TSI_GENCS_EOSF_MASK;
    gu16Baseline[cnt] = (TSI0_DATA & TSI_DATA_TSICNT_MASK);
  }
  
  TSI0_GENCS &= ~TSI_GENCS_TSIEN_MASK;    // Disable TSI module
  TSI0_GENCS |= TSI_GENCS_TSIIEN_MASK;     // Enale TSI interrupt
  if(trigger_backup)                      // Restore trigger mode
    TSI0_GENCS |= TSI_GENCS_STM_MASK;
  else
    TSI0_GENCS &= ~TSI_GENCS_STM_MASK;
  
  TSI0_GENCS |= TSI_GENCS_TSIEN_MASK;     // Enable TSI module
  
   TSI0_DATA = ((elec_array[0]<<TSI_DATA_TSICH_SHIFT) );    //选择TSI通道0
   TSI0_DATA |= TSI_DATA_SWTS_MASK;
  
}


程序看似复杂,实则实现的是:在未触摸电容按键时,读取当前的电流值来作为参考值。
只是在程序中的时序以及关闭和打开TSI的时机即可。

中断服务函数:

void TSI0_IRQHandler(void)
{
  end_flag = TRUE;
  TSI0_GENCS |= TSI_GENCS_EOSF_MASK; // Clear End of Scan Flag
  change_electrode();
}

这就不多说了,置LED判断标志位,清采样完成标志位。

电极变化判断(change_electrode):

void change_electrode(void)
{
    int16_t u16temp_delta;
   
    gu16TSICount[ongoing_elec] = (TSI0_DATA & TSI_DATA_TSICNT_MASK);          // Save Counts for current electrode
    u16temp_delta = gu16TSICount[ongoing_elec] - gu16Baseline[ongoing_elec];  // Obtains Counts Delta from callibration reference
    if( u16temp_delta < 0)
            gu16Delta[ongoing_elec] = 0;
    else
            gu16Delta[ongoing_elec] = u16temp_delta;
   
    if(total_electrode > 1)  //Change Electrode to Scan
    {
            if((total_electrode-1) > ongoing_elec) ongoing_elec++;
            else   ongoing_elec = 0;
            
            TSI0_DATA = ((elec_array[ongoing_elec]<<TSI_DATA_TSICH_SHIFT) );    //选择接下来的通道
            TSI0_DATA |= TSI_DATA_SWTS_MASK;
    }
}

程序的要点是获取当前通道的转换值,并于参考值比较,得出变化值。

判断并选择LED状态:


void TSI_Slider_LED(void )
{
     if(end_flag)
      {   
        end_flag = FALSE;

        if((gu16Delta[0] > gu16Threshold[0])||(gu16Delta[1] > gu16Threshold[1])||(gu16Delta[2] > gu16Threshold[2]))
         {
           if((gu16Delta[0] > gu16Threshold[0]))
           {
                 GPIO_SET(MKL_PORTB,18);                                               

                 GPIO_SET(MKL_PORTB,19);
                 GPIO_CLR(MKL_PORTD,1);                                                
           }
           if((gu16Delta[1] > gu16Threshold[1]))
           {
                 GPIO_SET(MKL_PORTB,18);                                                         

                 GPIO_CLR(MKL_PORTB,19);
                 GPIO_SET(MKL_PORTD,1);
                       
           }
             if((gu16Delta[2] > gu16Threshold[2]))
           {
                 GPIO_CLR(MKL_PORTB,18);                                         

                 GPIO_SET(MKL_PORTB,19);
                 GPIO_SET(MKL_PORTD,1);              
           }
         
         }else
         {
            SliderPercentegePosition[0] = NO_TOUCH;  
            SliderPercentegePosition[1] = NO_TOUCH;
            SliderPercentegePosition[2] = NO_TOUCH;
            SliderDistancePosition[0] = NO_TOUCH;
            SliderDistancePosition[1] = NO_TOUCH;
            SliderDistancePosition[2] = NO_TOUCH;
            AbsolutePercentegePosition = NO_TOUCH;
            AbsoluteDistancePosition = NO_TOUCH;
         }
      }
}     



将预先设定的值与变换量比较,大于说明按键被按下,执行LED显示函数。


下面是视频:


源工程: Touch.zip (1.05 MB, 下载次数: 13)

评分

参与人数 1NXP金币 +35 收起 理由
小七 + 35 赞一个!

查看全部评分

回复

使用道具 举报

  • TA的每日心情
    开心
    2018-7-23 21:04
  • 签到天数: 103 天

    连续签到: 1 天

    [LV.6]常住居民II

    228

    主题

    5379

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    16706
    最后登录
    1970-1-1
    发表于 2015-8-1 00:03:58 | 显示全部楼层
    多谢分享,学习了
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2020-11-5 18:45
  • 签到天数: 158 天

    连续签到: 1 天

    [LV.7]常住居民III

    26

    主题

    669

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1724
    最后登录
    2020-11-5
    发表于 2015-10-11 21:55:17 | 显示全部楼层
    谢谢分享!

    futu.png
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-6-15 16:35
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    50

    主题

    159

    帖子

    0

    高级会员

    Rank: 4

    积分
    549
    最后登录
    2023-3-11
    发表于 2015-10-11 22:25:48 | 显示全部楼层
    谢谢分享
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2017-2-9 14:16
  • 签到天数: 17 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    25

    主题

    1785

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    2250
    最后登录
    2024-6-11
    发表于 2015-10-12 12:37:38 | 显示全部楼层
    谢谢分享   
    freescaleic.org.png
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-7-4 07:07
  • 签到天数: 24 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    22

    主题

    513

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    2043
    最后登录
    2018-8-15
    发表于 2015-10-12 15:05:01 | 显示全部楼层
    这个比较有用
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2019-10-17 08:07
  • 签到天数: 273 天

    连续签到: 1 天

    [LV.8]以坛为家I

    74

    主题

    2338

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    7508
    最后登录
    2021-8-30
    发表于 2015-10-13 10:56:24 | 显示全部楼层
    看到这么好的帖子,我都不敢发帖了
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2017-3-2 08:55
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    23

    主题

    193

    帖子

    0

    高级会员

    Rank: 4

    积分
    500
    最后登录
    2017-11-3
    发表于 2015-10-13 16:35:56 | 显示全部楼层
    不错,支持楼主
    logo.png
    天气好
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2017-3-2 08:55
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    23

    主题

    193

    帖子

    0

    高级会员

    Rank: 4

    积分
    500
    最后登录
    2017-11-3
    发表于 2015-10-14 12:29:23 | 显示全部楼层
    多谢分享!      
    1.png
    天气好
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    24

    帖子

    0

    注册会员

    Rank: 2

    积分
    59
    最后登录
    1970-1-1
    发表于 2015-10-22 11:33:35 | 显示全部楼层
    感谢分享,学习中,谢谢
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-23 14:26 , Processed in 0.123713 second(s), 30 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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