⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 subroutine.c

📁 TI公司MSP430单片机实现方形触摸按键的C语言源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:

//============================头 文 件=================================
#include"subroutine.h"
#include"msp430x41x.h"
//=====================================================================

//=============================子程序定义==============================   

//=====================================================================
//函数名称:void Delay(unsigned int time)
//型参类型:无符号整形
//返回类型:空
//函数功能:根据time的值延时相应的时间
//=====================================================================
void Delay(unsigned int time)
{
  unsigned int i;
  for(i=0;i<time;i++)
  {
    _NOP();
  }
}
//=====================================================================
//函数名称:void Init_Mcu(void)
//型参类型:空
//返回类型:空
//函数功能:完成Mcu的各寄存器的初始化工作
//=====================================================================
void Init_Mcu(void)
{
  unsigned int i;
  WDTCTL=WDTPW+WDTHOLD;                                                // 停止看门狗
  
  FLL_CTL0 |=  XCAP18PF;                                               // 振荡滤波电容为 ~10pf
  SCFI0 |= FN_2;                                                       // 选择振荡频率范围为 fDCOCLK =   1.4-12MHz
  SCFQCTL = 121;                                                       // N=121, DCO输出频率为4MHz
  
  for(i=0;i<20000;i++);                                                // 等待时钟稳定
  
  P1OUT=0;                                                             // 端口一输出低电平,关中断使能,上升沿触发
  P1DIR=0XFF;
  P1IE=0;
  P1IES=0;
  P1IFG=0;
  P2OUT=0;                                                             // 端口二输出低电平,关中断使能,上升沿触发
  P2DIR=0XFF;
  P2IE=0;
  P2IES=0;
  P2IFG=0;    
  P6OUT=0X00;                                                          // 端口六初始化,输出低电平
  P6DIR=0XFF;
  
  LCDCTL = LCDON+LCD4MUX+LCDSG0_1;                                     // LCD ON+(4 MUX+LCD SEG ON)+S0~S15
  BTCTL  = BT_fLCD_DIV64;                                              // 扫描频率率 32768/64=512 桢率 64  
  P5SEL = 0xFC;                                                        //端口五,选用复用功能
   
   TACTL = TASSEL_2 + MC_2;                                              //开TAR ,时钟选择SMCLK, 计数方式选择为连续计数
  _EINT();
}

//=====================================================================
//函数名称:void Init_key(key_data_t *key,const key_config_t *key_config)
//型参类型:空
//返回类型:空
//函数功能:把所有的按键都置低
//=====================================================================
void Init_Key(key_data_t *key,const key_config_data_t *key_config)
{
  //unsigned char i;
  //for(i=0;i<NUM_KEYS;i++)
  //{
    
  //}
  key->base_capacitance = 0;                                            // 清基本电容量为0
  key->filtered = 0;                                                      // 清当前电容差值为0
  key->adapt = 0;                                                       // 清自适应记数为0
  if(key_config->port==1)                                               // 如果是端口一
  {
    P1OUT &= ~key_config->port_bit;                                     // 当前位输出低电平,形成地 
    P1DIR |=  key_config->port_bit;                                      // 方向输出
    P1IES |=  key_config->port_bit;                                      //触发沿设置为下降沿
    P1IE  &= ~key_config->port_bit;
    P1IFG &= ~key_config->port_bit;
  }
  else
  {
    P2OUT &= ~key_config->port_bit;
    P2DIR |=  key_config->port_bit;
    P2IES |=  key_config->port_bit;
    P2IE  &= ~key_config->port_bit;
    P2IFG &= ~key_config->port_bit;
  }
}

//=====================================================================
//函数名称:unsigned int Measure_Key_Capacitance(unsigned int keyno)
//型参类型:空
//返回类型:空
//函数功能:先测触摸式按键的放电时间,再测触模式按键的充电时间,最后两个时间相加除以2
//=====================================================================
unsigned int Measure_Key_Capacitance(unsigned int keyno)
{
  unsigned char active_key;                                             //定义当前活动按键寄存器
  const key_config_data_t *keyp;                                        //定义当前按键结构指针
  const key_config_data_t *partner;                                     //定义配对按键结构指针 
  keyp = &key_config[keyno];                                            //赋予当前按键结构指针相应的数值
  partner = &key_config[keyno^1];                                       //赋予配对按键结构指针相应的数值
  active_key = keyp->port_bit;                                          //赋予当前活动按键相应的数值 
    
  if(keyp->port == 1)                                                   //如果是端口一,端口一相应的为输出高电平
  {
    P1OUT |= active_key;
  }
  else                                                                  //如果是端口一,端口一相应的为输出高电平
  {
    P2OUT |= active_key;
  }
                                        
  _NOP();                                                               //给予短暂的时间余量,保证当前活动按键充电到高电平
  _NOP();
  _NOP();
  _NOP();
  Delay(100);
  if(keyp->port == 1)                                                   //如果是端口一,设置相应位为下降沿触发,开相应位中断使能,设为输入
  {
    P1IES |=  active_key;
    P1IE  |=  active_key;
    P1DIR &= ~active_key;
  }
  else                                                                  //如果是端口二,设置相应位为下降沿触发,开相应位中断使能,设为输入
  {
    P2IES |=  active_key;
    P2IE  |=  active_key;
    P2DIR &= ~active_key;
  }
  
  cnt_time=TAR;                                                         //读取当前定时器的数值
  LPM0;                                                                 //进入低功耗0,等待低电平触发
  _NOP();
  
  if(keyp->port == 1)                                                   //如果是端口一,关相应位中断使能,设为设置为输出低电平,把剩余的电势放光
  {
    P1IE  &= ~active_key;
    P1OUT &= ~active_key;
    P1DIR |=  active_key;
  }
  else                                                                  //如果是端口二,关相应位中断使能,设为设置为输出低电平,把剩余的电势放光
  {
    P2IE  &= ~active_key;
    P2OUT &= ~active_key;
    P2DIR |=  active_key;
  }  
  sum = cnt_time;                                                       //读取放电时间,存入寄存器 SUM
  _NOP();
  _NOP();  
  if(partner->port == 1)                                                //如果配对位是端口一,则端口一相应的位输出高电平
  {
    P1OUT |=  partner->port_bit;
  }
  else
  {
    P2OUT |=  partner->port_bit;
  }
  _NOP();
  _NOP();
  _NOP();
  _NOP();
  _NOP();
  _NOP();
  if(keyp->port == 1)                                                   //如果活动口为端口一,则置端口一相应的位为上升沿触发,开相应的中断,设为输入
  {
    P1IES &= ~active_key;
    P1IE  |=  active_key;
    P1DIR &= ~active_key;
  }
  else                                                                  //如果活动口为端口二,则置端口二相应的位为上升沿触发,开相应的中断,设为输入
  {
    P2IES &= ~active_key;
    P2IE  |=  active_key;
    P2DIR &= ~active_key;
  }
  
  cnt_time=TAR;                                                         //读取当前定时器的数值
  LPM0;                                                                 //进入低功耗0,等待低电平触发
  _NOP();
  
  if(keyp->port == 1)                                                   //如果是端口一,关相应位中断使能,设为设置为输出低电平,把剩余的电势放光 
  {
    P1IE  &= ~active_key;
    P1OUT &= ~active_key;
    P1DIR |=  active_key;
  }
  else                                                                  //如果是端口二,关相应位中断使能,设为设置为输出低电平,把剩余的电势放光
  {
    P2IE  &= ~active_key;
    P2OUT &= ~active_key;
    P2DIR |=  active_key;
  }
  _NOP();
  _NOP();
  _NOP();
  _NOP();
  _NOP();
  _NOP();
  if(partner->port == 1)                                                //如果配对位属于端口一,则端口一相应位输出低电平
  {
    P1OUT &= ~partner->port_bit;
  }
  else
  {
    P2OUT &= ~partner->port_bit;                                        //如果配对位属于端口二,则端口二相应位输出低电平
  }
  sum +=cnt_time;                                                       //把充电时间和放电时间相加,送给寄存器SUM
  return sum;                                                           //寄存器除以2,作为返回值
}
  
//=====================================================================
//函数名称:void Scan_Key(void)
//参数类型;空
//函数类型:空
//函数功能:扫描案件电容量的变化
//=====================================================================
void Scan_Key(void)
{
  int i;
  int margin;
  for(i=0;i<NUM_KEYS;i++)
  {
    margin = Measure_Key_Capacitance(i)-key[i].base_capacitance;
    key[i].filtered += (margin-(key[i].filtered>>4));
  }
}

//=====================================================================
//函数名称:unsigned char Key_Position(void)
//参数类型:空
//函数类型: 无符号字符型
//函数功能: 获取单个按键的位置
//=====================================================================

int Key_Position(void)
{
  unsigned char i;
  int max_position;                                           //最大电容量的位置
  int min;                                                              //最小电容量
  int max;                                                              //最大电容量
  int key_threshold;                                                    //电容量筏值 


  key_threshold=500;

  
  min =  32767;
  max = -32768;
  max_position= 0;
  
  for(i = 0;i < NUM_KEYS;i++)                                           //获取最大或最小电容变化量的值和最大电容变化量的位置
  {
    if(key[i].filtered < min)
      min = key[i].filtered;
    if(key[i].filtered > max)
    {
      max = key[i].filtered;
      max_position=i+1;
    }
  }
  
  if(max < key_threshold)                                              //如果最大电容变化量小于电容量变化阀值则LCD显示空白
  {
     return -1;
  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -