📄 subroutine.c
字号:
//============================头 文 件=================================
#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 + -