TTP229
STM32F103C8T6程序
触摸按键
main.c文件
#include “bsp.h”
UsartData COM1;
u32 DogCount;
u32 machineCount=0;
int main()
{
u8 number=0xff;
init_STM32F103C8T6();
Delay_Timer_Init();
TouchKeyinit_TY();
printf(“程序开始进入循环!\n”);
while(1)
{
//喂狗
if(DogCount>50)
{
DogCount=0;
IWDG_ReloadCounter();
}
if(machineCount>500)
{
machineCount=0;
LEDTest=~LEDTest;
}
number=GetKeyNum_TY();
if(number!=0xff)
{
printf("您触摸的按键数值为:%d\n",number);
}
}
return 0;
}
bsp.c文件
/*******************************************************************
**功 能:硬件配置文件
**配置人:Tommy
**时 间:2019年9月14日
********************************************************************/
#include “bsp.h”
u16 PreKeyNum;
u16 NowKeyNum;
/***************************************************************************************
**功 能:初始化STM32的硬件设置
**参 数:无
**返回值:无
****************************************************************************************/
void init_STM32F103C8T6(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//配置系统时钟为72M
SystemInit();
USART1_Config(9600);
//初始化定时器
TIM2_NVIC_Configuration();
TIM2_Configuration();
IWDG_Configuration();
//看门计数复位
DogCount=0;
//心跳灯
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
/***************************************************************************************
**功 能:初始化串口1的硬件设置
**参 数:bound为波特率
**返回值:无
****************************************************************************************/
void USART1_Config(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
// 使能 USART1 时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
//USART1 使用IO端口配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA
// USART1 工作模式配置
USART_InitStructure.USART_BaudRate = bound; //波特率设置
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位数设置:8位
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位设置:1位
USART_InitStructure.USART_Parity = USART_Parity_No ; //是否奇偶校验:无
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制模式设置:没有使能
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //接收与发送都使能
USART_Init(USART1, &USART_InitStructure); //初始化USART1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启中断
USART_ClearFlag(USART1,USART_FLAG_TC);
//串口配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =2; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器、
USART_Cmd(USART1, ENABLE);// USART1使能
}
/************************************************************
**功 能:串口1中断服务程序
**返回值:无
***********************************************************/
void USART1_IRQHandler(void)
{
u8 temp=0;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
temp = USART_ReceiveData(USART1);
//将接受的数据存在缓存区
if((COM1.UsartTime>=5)&&(COM1.UsartFlag==0))
{
COM1.UsartFlag=1;
COM1.UsartTime=0;
COM1.UsartRX[0]=temp;
COM1.UsartLength=1;
}
else
{
COM1.UsartFlag=1;
COM1.UsartTime=0;
COM1.UsartRX[COM1.UsartLength++]=temp;
}
}
}
/************************************************************
**功 能:串口1发送数据
**参 数:要发送的字符
**返回值:无
*************************************************************/
void USART1_Send(u8 data)
{
USART_SendData(USART1, data);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
{
}
}
/************************************************************
**功 能:串口1连续发送数据
**参 数:*buffe要发送的数据指针,len为数据长度
**返回值:无
************************************************************/
void USART1_SendSome(u8 buffer,u16 len)
{
while(len--)
{
USART1_Send(*buffer++);
}
}
/***************************************************************************************
**功 能:重定向c库函数printf到USART1
**参 数:无
**返回值:无
****************************************************************************************/
int fputc(int ch, FILE f)
{
/ 将Printf内容发往串口 */
USART_SendData(USART1, (unsigned char) ch);
while (!(USART1->SR & USART_FLAG_TXE));
return (ch);
}
/***************************************************************************************
**功 能:初始化计时器TIM2
**参 数:无
**返回值:无
****************************************************************************************/
void TIM2_NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/***************************************************************************************
**功 能:定时器函数
**参 数:无
**返回值:无
***************************************************************************************/
void TIM2_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);
TIM_DeInit(TIM2);
TIM_TimeBaseStructure.TIM_Period=1000; //自动重装载寄存器周期的值(计数值)
/ 累计 TIM_Period个频率后产生一个更新或者中断 */
TIM_TimeBaseStructure.TIM_Prescaler= (72 - 1); //时钟预分频数 72M/72
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_ClearFlag(TIM2, TIM_FLAG_Update); // 清除溢出中断标志
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
TIM_Cmd(TIM2, ENABLE); // 开启时钟
}
/***************************************************************************************
**功 能:定时器中断函数,按照定时器设置的时间执行一次
**参 数:无
**返回值:无
****************************************************************************************/
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update);
DogCount++;
if(DogCount>100)
{
DogCount=0;
}
machineCount++;
if(machineCount>50000)
{
machineCount=0;
}
COM1.UsartTime++;
if(COM1.UsartTime>=50)
{
//COM1.UsartFlag=1;
COM1.UsartTime=10;
}
}
}
/*****************************************************
**功能:看门狗
**返回值:无
**参数:无
********************************************************/
void IWDG_Configuration(void)
{
//使能寄存器 写功能
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
//设置预分频 40K/64=0.625k 一个周期是 1.6ms
IWDG_SetPrescaler(IWDG_Prescaler_64);
//设置初值
IWDG_SetReload(800); //800*1.6ms=1.28S
//喂狗
IWDG_ReloadCounter();
//使能独立看门狗
IWDG_Enable();
}
void Delay_Timer_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct);
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Down;
TIM_TimeBaseInitStruct.TIM_Period = 100-1;
TIM_TimeBaseInitStruct.TIM_Prescaler = (84-1);
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);
while((TIM3->SR & TIM_FLAG_Update)!=SET)
{
}
TIM3->SR = (uint16_t)~TIM_FLAG_Update;
}
void delay_us(uint32_t us_cnt)
{
TIM3->CNT = us_cnt-1;
TIM3->CR1 |= TIM_CR1_CEN;
while((TIM3->SR & TIM_FLAG_Update)!=SET);
TIM3->SR = (uint16_t)~TIM_FLAG_Update;
TIM3->CR1 &= ~TIM_CR1_CEN;
}
void delay_ms(uint32_t us_cnt)
{
u32 i=0,j=us_cnt*10;
for(i=0;i<j;i++)
{
delay_us(100);
}
}
void TouchKeyinit_TY()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
KEY_SDA_OUT(); //SDO设置为输出
TT_SDO = 0;
TT_SCL = 0;
TouchKeyRead_TY();
}
u16 TouchKeyRead_TY()
{
u8 i;
u16 reval = 0;
KEY_SDA_OUT();
TT_SDO = 1;
delay_us(100);
TT_SDO = 0;
delay_us(20);
KEY_SDA_IN();
for (i = 0; i < 16; i++){
TT_SCL = 1;
delay_us(200);
TT_SCL = 0;
if (TT_SDI==1){
reval |= (1 << i);
}
delay_us(200);
}
delay_ms(2); //根据时序图延时2ms, 不然容易出现按键串扰现象
return reval;
}
u8 GetKeyNum_TY()
{
u8 key_num = 0xff;
NowKeyNum = TouchKeyRead_TY();
if((NowKeyNum & 0x0001)&& !(PreKeyNum & 0x0001)){
key_num=0;
}
if((NowKeyNum & 0x0002)&& !(PreKeyNum & 0x0002)){
key_num=1;
}
if((NowKeyNum & 0x0004)&& !(PreKeyNum & 0x0004)){
key_num=2;
}
if((NowKeyNum & 0x0008)&& !(PreKeyNum & 0x0008)){
key_num=3;
}
if((NowKeyNum & 0x0010)&& !(PreKeyNum & 0x0010)){
key_num=4;
}
if((NowKeyNum & 0x0020)&& !(PreKeyNum & 0x0020)){
key_num=5;
}
if((NowKeyNum & 0x0040)&& !(PreKeyNum & 0x0040)){
key_num=6;
}
if((NowKeyNum & 0x0080)&& !(PreKeyNum & 0x0080)){
key_num=7;
}
if((NowKeyNum & 0x0100)&& !(PreKeyNum & 0x0100)){
key_num=8;
}
if((NowKeyNum & 0x0200)&& !(PreKeyNum & 0x0200)){
key_num=9;
}
if((NowKeyNum & 0x0400)&& !(PreKeyNum & 0x0400)){
key_num=10;
}
if((NowKeyNum & 0x0800)&& !(PreKeyNum & 0x0800)){
key_num=11;
}
if((NowKeyNum & 0x1000)&& !(PreKeyNum & 0x1000)){
key_num=12;
}
if((NowKeyNum & 0x2000)&& !(PreKeyNum & 0x2000)){
key_num=13;
}
if((NowKeyNum & 0x4000)&& !(PreKeyNum & 0x4000)){
key_num=14;
}
if((NowKeyNum & 0x8000)&& !(PreKeyNum & 0x8000)){
key_num=15;
}
PreKeyNum = NowKeyNum;
return key_num;
}
//bsp.h文件
/*******************************************************************
**功 能:硬件配置文件
**配置人:Tommy
**时 间:2019年9月14日
********************************************************************/
#ifndef BSP
#define BSP
#include “stm32f10x_conf.h”
#include “stm32f10x_it.h”
#include <stdio.h>
typedef struct
{
uint8_t UsartRX[1048];
uint8_t UsartTX[1048];
uint16_t UsartLength;
uint16_t UsartTime;
uint8_t UsartFlag;
uint8_t UsartBit;
}UsartData;
//全局变量
extern UsartData COM1;
extern u32 DogCount;
extern u32 machineCount;
extern u16 PreKeyNum;
extern u16 NowKeyNum;
//变量
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
#define GPIOA_ODR_Addr (GPIOA_BASE+12)
#define GPIOB_ODR_Addr (GPIOB_BASE+12)
#define GPIOC_ODR_Addr (GPIOC_BASE+12)
#define GPIOD_ODR_Addr (GPIOD_BASE+12)
#define GPIOE_ODR_Addr (GPIOE_BASE+12)
#define GPIOF_ODR_Addr (GPIOF_BASE+12)
#define GPIOG_ODR_Addr (GPIOG_BASE+12)
#define GPIOA_IDR_Addr (GPIOA_BASE+8)
#define GPIOB_IDR_Addr (GPIOB_BASE+8)
#define GPIOC_IDR_Addr (GPIOC_BASE+8)
#define GPIOD_IDR_Addr (GPIOD_BASE+8)
#define GPIOE_IDR_Addr (GPIOE_BASE+8)
#define GPIOF_IDR_Addr (GPIOF_BASE+8)
#define GPIOG_IDR_Addr (GPIOG_BASE+8)
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n)
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n)
#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n)
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n)
#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n)
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n)
#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n)
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n)
#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n)
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n)
#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n)
#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n)
#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n)
#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n)
#define LEDTest PCout(13) //测试灯
//触摸按键
#define KEY_SDA_IN() {GPIOA->CRL&=0XFFFF0FFF;GPIOA->CRL|=0X00008000;GPIOA->ODR==0<<3;} //下拉输入
#define KEY_SDA_OUT() {GPIOA->CRL&=0XFFFF0FFF;GPIOA->CRL|=0X00003000;} //推挽输出,50Mhz
#define TT_SCL PAout(2) //SCL-PA2
#define TT_SDO PAout(3) //SDA-PA3
#define TT_SDI PAin(3)
//函数声明
void init_STM32F103C8T6(void);
//串口部分
//串口1
void USART1_Config(u32 bound);
void USART1_Send(u8 data);
void USART1_SendSome(u8* buffer,u16 len);
int fputc(int ch, FILE *f);
//GPIO初始化
void initGPIO(void);
void TIM2_NVIC_Configuration(void);
void TIM2_Configuration(void);
void IWDG_Configuration(void);
void delay_us(uint32_t us_cnt);
void Delay_Timer_Init();
void delay_ms(uint32_t us_cnt);
u16 TouchKeyRead_TY(void);
void TouchKeyinit_TY(void);
u8 GetKeyNum_TY(void);
测试结果如下图所示:

程序及资料链接
链接:https://pan.baidu.com/s/173rxoSk1Nem3vUNDxD-Yng
提取码:khdl
本文档展示了如何在STM32F103C8T6微控制器上实现TTP229触摸按键的初始化和读取操作。主要涉及了系统时钟、串口1配置、定时器中断、看门狗、延迟函数以及串口数据发送。程序中包含主函数main.c和硬件配置文件bsp.c,实现了按键的检测和通过串口发送按键状态。
225

被折叠的 条评论
为什么被折叠?



