STM32F051 触摸按键功能

搞了几天STM32F051的触摸按键功能,最后发现其实很简单。最开始下载了官方的库,结果使用的时候发现程序居然会跑飞,后来还是自己写吧,写完了才发现原来很简单,这里把代码贴出来和大家分享。

// --------------------TSCtrl.h---------------------------
#pragma once

enum TSCStatus
{
TSC_RELEASE,
TSC_PRESSED
};


class TSCtrl
{
public:
    // 构造对象。
    static TSCtrl &Construction(void)
    {
        static TSCtrl ts_obj;
        return ts_obj;
    }


// 扫描端口。
void Scan(void);


// 获取状态。
TSCStatus GetPortStatus(int index);


~TSCtrl();
private:
TSCtrl();
};
#define tsc (TSCtrl::Construction())
//-----------------------TSCtrl.cpp-----------------------------
#include "TSCtrl.h"
#include "stm32f0xx_gpio.h"
#include "stm32f0xx_rcc.h"
#include <stdlib.h>




#define THRESHOLD 30       // 按下时刻的门槛,根据实际情况修改此值。




#define PORT_NR 3


struct PortStatus
{
short fixed_value;
short current_value;
TSCStatus status;
unsigned short enable_mask;
};
struct ScanTrace
{
PortStatus port[PORT_NR];
char port_index;
};


ScanTrace _trace =
{
935, 0, TSC_RELEASE, 1 << 12,     // 935根据你的板卡而定,它是指在没有触碰按钮时刻采集的数据,该值在IOGXCR寄存器中。
926, 0, TSC_RELEASE, 1 << 13,     // 1<<13这些数据也要根据实际情况修改,这里使用的是GP4_IO1, GP4_IO2,GP4_IO4。
1100, 0, TSC_RELEASE, 1 << 15,
0
};




#define CAP_PORT         GPIOA                        // 根据实际情况修改。
#define SAMPCAP_PIN      GPIO_Pin_11
#define CHANNEL0_PIN     GPIO_Pin_9
#define CHANNEL1_PIN     GPIO_Pin_10
#define CHANNEL2_PIN     GPIO_Pin_12


static void _init_hw(void)
{
// 打开时钟。
::RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

GPIO_InitTypeDef gpio_config;
gpio_config.GPIO_Mode = GPIO_Mode_AF;
gpio_config.GPIO_OType = GPIO_OType_OD;
gpio_config.GPIO_Speed = GPIO_Speed_2MHz;
gpio_config.GPIO_PuPd = GPIO_PuPd_NOPULL;
gpio_config.GPIO_Pin = SAMPCAP_PIN;
::GPIO_Init(CAP_PORT, &gpio_config);          // 初始化CAP引脚。


gpio_config.GPIO_OType = GPIO_OType_PP;
gpio_config.GPIO_Pin = CHANNEL0_PIN | CHANNEL1_PIN | CHANNEL2_PIN;
::GPIO_Init(CAP_PORT, &gpio_config);          // 初始化CHANNEL引脚。

// 重定义引脚的功能。
::GPIO_PinAFConfig(CAP_PORT, 9, GPIO_AF_3);
::GPIO_PinAFConfig(CAP_PORT, 10, GPIO_AF_3);
::GPIO_PinAFConfig(CAP_PORT, 11, GPIO_AF_3);
::GPIO_PinAFConfig(CAP_PORT, 12, GPIO_AF_3);

::RCC_AHBPeriphClockCmd(RCC_AHBPeriph_TS, ENABLE);


// CTPH = 1x tPGCLK, CTPL = 1x tPGCLK, PGPSC = 5(fHCLK/32), MCV = 6, TSCE = ENABLE
TSC->CR = (0 << 28) | (0 << 24) | (5 << 12) | (6 << 5) | (1 << 0);

// 关闭施密特出发。
unsigned tmp_value = 0xFFFFFFFF;
tmp_value &= (unsigned)~((unsigned)1 << 12);
tmp_value &= (unsigned)~((unsigned)1 << 13);
tmp_value &= (unsigned)~((unsigned)1 << 14);
tmp_value &= (unsigned)~((unsigned)1 << 15);
TSC->IOHCR &= tmp_value;


// Sampling enabled
tmp_value = 0;
tmp_value |= (unsigned)((unsigned)1 << 14);
TSC->IOSCR |= tmp_value;


// Channel enabled, G4_IO4 G4_IO2 G4_IO1
// TSC->IOCCR = (0x01 << 12);

// Enable group, G4
TSC->IOGCSR |= (1 << 3);
}


static int _wait_eoc(void)
{
    int ret = 0;


    if (TSC->ISR & 0x01)
    {
        // Check MCEF flag
        if (TSC->ISR & 0x02)
        {
            ret = 0;
        }
        else
        {
            ret = 1;
        }
    }


    return ret;
}


static void _scan_channel(int index)
{
TSC->IOCCR = _trace.port[index].enable_mask;
TSC->ICR |= 0x03;
TSC->CR |= 0x02;


int delay_cnt = 0;
while(_wait_eoc() == 0)
{
if(++delay_cnt > 10000)         // 避免死循环。
{
_trace.port[index].status = TSC_RELEASE;
return;
}
}
_trace.port[index].current_value = TSC->IOGXCR[3];
short diff = ::abs(_trace.port[index].current_value - _trace.port[index].fixed_value);
if(diff > THRESHOLD)
{
_trace.port[index].status = TSC_PRESSED;
}
else
{
_trace.port[index].status = TSC_RELEASE;
}
}


void TSCtrl::Scan(void)
{
_scan_channel(_trace.port_index++);
_trace.port_index = (_trace.port_index >= PORT_NR) ? 0 : _trace.port_index;
}


TSCStatus TSCtrl::GetPortStatus(int index)
{
return _trace.port[index].status;
}


TSCtrl::TSCtrl()
{
_init_hw();
}


TSCtrl::~TSCtrl()
{
}

使用代码如下:

int main(void)
{
TSCStatus t;
while(1)
{
tsc.Scan();
t = tsc.GetPortStatus(1);
t = tsc.GetPortStatus(2);
t = tsc.GetPortStatus(3);
        }
}




  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值