单片机IO处理 电容触摸按键

单片机IO处理 电容触摸按键

单片机IO处理 电容触摸按键

单片机IO处理 电容触摸按键

单片机IO处理 电容触摸按键

原理说明:

  通过检测感应按键PAD的电容量变化来判断是否有触摸动作。当手指触摸PAD时,电容量增加,充放电时间变长。
  本方案中利用M48的20个双向IO口实现了20个触摸按键,而且所用原器件最少。其中R1~R20的10K电阻是消除干扰用的,如果采用软件算法,用数字滤波来消除干扰,这20个电阻也可以省略。这样就只需要10只1M的充放电电阻(R21~R30)就可以了。

  最基本的按键单元是两个PAD分别接M48的两个IO引脚,两个引脚之间用一个1M的电阻相连。如图:
  
  PB1(PAD1) O------/\/\/1M\/\/\------O (PAD2) PB2

  有3种方法检测PAD1的电容量变化:
  方法1:检测PAD1的充电时间
  (1)初始化PB1输出低电平,PB2输出高电平,这时PAD1上的电量被放掉,PB1为低电平;
  (2)设置PB1高阻输入,同时记时,使能PB1引脚电平变化中断。这时PB2输出的高电平通过1M的电阻对PAD1充电;
  (3)充电到PAD1电平到MOS高电平的最低值时,PB1引脚电平变化中断,在中断里记下充电时间。
  方法2:检测PAD1的放电时间
  (1)初始化PB1输出高电平,PB2输出低电平,这时PAD1充电,PB1为高电平;
  (2)设置PB1高阻输入,同时记时,使能PB1引脚电平变化中断。这时PAD1通过1M的电阻对PB2(地)放电;
  (3)放电到PAD1电平到MOS低电平的最高值时,PB1引脚电平变化中断,在中断里记下放电时间。
  方法3:检测PAD1的充放电时间
  (1)初始化PB1输出低电平,PB2输出高电平,这时PAD1上的电量被放掉,PB1为低电平;
  (2)设置PB1高阻输入,同时记时,使能PB1引脚电平变化中断。这时PB2输出的高电平通过1M的电阻对PAD1充电;
  (3)充电到PAD1电平到MOS高电平的最低值时,PB1引脚电平变化中断。在中断里设置PB2输出低电平,这时PAD1通过1M的电阻对PB2放电;
  (4)放电到PAD1电平到MOS低电平的最高值时,PB1引脚电平变化中断。在中断里记下充放电的总时间。

  多次测量取滑动平均值(可以去掉最大、最小值后取平均值)来消除干扰。
  定时检测PAD1的充放电时间t0,t1,t2......tk,tk+1,所有数据的平均值作为参考值,最近几次采样值的平均值作为当前值,用来判断充放电时间的增减。当充放电时间的增量超过一个设定的门限值时就认为有按键动作。修改这个门限值可以改变按键的灵敏度。
  一个按键的检测过程就是这样的。其它按键同理。
  检测到按键后,通过I2C接口发送按键码。测试视频里只用了一个LED来指示按键动作,有键按下灯亮,按键释放灯灭。

源程序:

//ICC-AVR application builder : 2011/12/1 20:30:09
// Target : m48
// Crystal: 8.0000Mhz

#include <iom48v.h>
#include <macros.h>

#define PSCL  PC5  //LED+
#define PSDA  PC4  //LED-

//   按键编号 引脚编号

#define P07   PB5  //  5  //SCK
#define P08   PB4  //  4  //MISO

#define P12   PB3  //  3  //MOSI

#define on    1
#define off   0

//引脚编号=K[按键编号]
unsigned ]={,,,,,,,,,,,,,,,,,,,,};

void led(unsigned char on_off)
{
    if(on_off)  PORTC &= ~BIT(PSDA);
    else        PORTC |= BIT(PSDA);
}

void key_tst_prep(unsigned char k)
{
    PORTB = 0xFF;
    DDRB  = 0x00;
    PORTC |= 0x6F;
    DDRC  = 0x30;
    PORTD = 0xFF;
    DDRD  = 0x00;

    PCMSK0 = 0x00; //pin change mask 0
    PCMSK1 = 0x00; //pin change mask 1
    PCMSK2 = 0x00; //pin change mask 2
    PCIFR = 0x07; //clear pin change flag2...0
    PCICR = 0x07; //pin change enable 

    )
    {
        PORTB &= ~(<<k);
        DDRB |= (<<k);
    }
    )
    {
        k-=;
        PORTC &= ~(<<k);
        DDRC |= (<<k);
    }
    )
    {
        k-=;
        PORTD &= ~(<<k);
        DDRD |= (<<k);
    }
}

void key_tst_start(unsigned char k)
{
    PCIFR = 0x07; //clear pin change flag2...0
    )
    {
        PCMSK0 = (<<k); //pin change mask 0
        DDRB &= ~(<<k);
    }
    )
    {
        k-=;
        PCMSK1 = (<<k); //pin change mask 1
        DDRC &= ~(<<k);
    }
    )
    {
        k-=;
        PCMSK2 = (<<k); //pin change mask 2
        DDRD &= ~(<<k);
    }
    TCNT0 = 0x00;
}
//4,7,8,12,14,17,19,20
unsigned ,KF[]={};//按键标记 1按下 0未按
//按键编号               1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
unsigned ]={,,,,,,,,,,,,,,,,,,,,};//门限值

#pragma interrupt_handler key_tst:iv_PCINT0
#pragma interrupt_handler key_tst:iv_PCINT1
#pragma interrupt_handler key_tst:iv_PCINT2
void key_tst(void)
{
    unsigned char i;
    if(TCNT0>D[KEYNUM]) KF[KEYNUM]=on;
    else KF[KEYNUM]=off;
    ;i<;i++)
    {
        ]=i; break;}
            ]=;
    }
    led(KF[]);
    ) KEYNUM = ;
}

//TIMER0 initialize - prescale:1
// WGM: Normal
// desired value: 0.125uSec
// actual value:  0.125uSec (0.0%)
void timer0_init(void)
{
    TCCR0B = 0x00; //stop
    TCNT0 = 0xFF; //set count
    TCCR0A = 0x00;
    TCCR0B = 0x02; //start timer
    TIMSK0 = 0x00; //timer 0 interrupt sources
}

//TIMER2 initialize - prescale:32
// WGM: Normal
// desired value: 1mSec
// actual value:  1.000mSec (0.0%)
void timer2_init(void)
{
    TCCR2B = 0x00; //stop
    ASSR  = 0x00; //set async mode
    TCNT2 = 0x00; //setup
    OCR2A = 0x83;
    TCCR2A = 0x00;
    TCCR2B = 0x02; //start
    TIMSK2 = 0x03; //timer 2 interrupt sources
}

#pragma interrupt_handler timer2_compa_isr:iv_TIM2_COMPA
void timer2_compa_isr(void)
{
    key_tst_start(K[KEYNUM]);
}

#pragma interrupt_handler timer2_ovf_isr:iv_TIM2_OVF
void timer2_ovf_isr(void)
{
    //TCNT2 = 0x06; //reload counter value
    key_tst_prep(K[KEYNUM]);
}

//TWI initialize
// bit rate:1
void twi_init(void)
{
    TWCR= 0X00; //disable twi
    TWBR= 0x01; //set bit rate
    TWSR= 0x01; //set prescale
    TWAR= 0x00; //set slave address
    TWCR= 0x44; //enable twi
}

//call this routine to initialize all peripherals
void init_devices(void)
{
    //stop errant interrupts until set up
    CLI(); //disable all interrupts
    key_tst_prep(K[KEYNUM]);
    timer0_init();
    timer2_init();
    //twi_init();

    MCUCR = 0x00;
    EICRA = 0x00; //extended ext ints
    EIMSK = 0x00;
    PRR = 0x0F; //power controller
    SEI(); //re-enable interrupts
    //all peripherals are now initialized
}

//
void main(void)
{
    init_devices();
}

有不明白的地方可以随时咨询我:

欢迎致电:15267845422

研发部经理:代品川

QQ350998385

地址:宁波北仑恒晶电子科技有限公司

电话:15267845422

传真:0574-55128828

企业网址:www.hengtaimcu.com

 

浙江宁波北仑恒晶电子科技有限公司专业为客人定制各种电容式触控液晶TN、HTN、LCD液晶屏、LCD液晶显示屏,LCD液晶显示器,笔段式液晶、IC邦定加工等业务,现有8台510邦定机,两条LCD前后段生产线;工厂在深圳、潮州、惠州、江西,工厂现在员人3000余人,占地面积45000平方米,LCD生产线能完成从前段的投料到后段切割、灌晶、电检、丝印、贴片、装脚等工艺操作。LCD交货周期: 客户提供详细LCD资料=>3天出图纸(客户确认)=>15天交样品(客户确认)=>20天出货(不装金属脚)/25天出货(装金属脚)

产品服务类型:1.产品主要技术参数

1)触控类型:电容式触控

1)外型尺寸:285×345mm以下;

2)导电玻璃厚度:0.4、0.55、0.7、1.1mm;

3)象素最小间隙:10um;

4)占空比:1/240duty以下;

5)连接方式:导电胶条、斑马纸、金属插脚、TAB、COG等。

2.产品型式

1)显示方式:正性、负性;

2)光学模式:反射型、透射型、半透半反型、全息型等;

3) LCD类别:TN型、HTN型、STN型、FSTN型、VATN型; 4)颜色模式:黄绿、灰、黑、白、蓝等模式。

 

 在本公司订购产品的客户均可以享受到我们的专业技术团队的配合,以帮助您更好的更快的吧我们的产品接口道你们的产品上。

上一篇:Docker:Dockerfile命令详解


下一篇:【安卓中的缓存策略系列】安卓缓存策略之综合应用ImageLoader实现照片墙的效果