基于stm32f031c6t6的按键扫描,带超时重发机制与校验。

首先能你需要自己做一块最小系统,因为计时精度不需要太高,所以为了节省成本可以省去晶振,直接使用芯片内部的时钟。这是我的原理图采用的是stm32f031c6t6某宝2.5块钱,

硬件部分

 

 然后你可根据你的按键的模具画一块孔位匹配大小相等的pcb,并选用按键,我这边使用的是薄膜按键,当然你也可以使用机械按键或者更好的。最终得到pcb


软件部分

使用stm32cubemx进行辅助开发首先先勾选 “debug serial wire”(这非常重要不然生成的工程烧录后就会出现烧写一次后无法烧写)

 然后正常的设置gpio口的模式因为这边我使用的是5x4所以需要使用9个io口,且使用4个io口为输出,5个引脚为输入检测。io口配置为下图

 然后在配置串口1实现串口1的收发模式找到串口1 mode选择asynchronous。

 并配置相关的串口参数,一般就是改改波特率这是我的串口配置

 如何选择clock configuration 进行时钟配置如下图

 如何配置定时器进行超时判定,这里使用的是定时器2,这里呢涉及预分频和重装值,通过对时钟进行分频获得我们想要的频率,就是多少秒计一个数,以及什么时候触发计数,什么时候触发重装,触发定时器中断执行我们想要的程序。其中prescaler为预防频值这里是4799,把48mhz进行分频,48000000(48m)/(4799+1)=10000(10khz)根据频率公式:f=1/T ,t=1/f=0.1ms意思是每0.1ms电平变化一次,而我这边选择的模式为上升沿计数,便是下方的counter mode 选择为up。而重装值则为你需要的时间:T / t(计数的时间)-1,如我这边需要300ms 所以得到的period(重装值)就为2999.

 配置完后就可以进行代码的生成了选择 project manager,选择你想要的文件夹,和代码编译器

我这里选择的是keil 5 然后点击右上角的 GENERATE CODE 进行生成

 然后就可以开始写逻辑功能了

串口配置

首先可以先写个把C语言的printf给放到我们的串口中,不用也可以,然后在stm32f0xx.hal.c中加入下面的代码,串口发送定义到回串口1

#include <stdio.h>
extern UART_HandleTypeDef huart1;   //声明串口
int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}
 
/**
  * 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fgetc(FILE *f)
{
  uint8_t ch = 0;
  HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
  return ch;

且在主函数的文件中添加宏定义,好定义一个数组

#define RXBUFFERSIZE  256
char RxBuffer[RXBUFFERSIZE];

并在编译出来的main函数中,添加定时器中断函数。便可进行测试,定时器,与串口发送是否正常

主函数中的while(1)死循环中添加

HAL_TIM_Base_Start_IT(&htim2);//开启定时器2

在main.c文件的末尾添加以下定时器中断函数。

/*******************定时器中断*******/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	 if(htim->Instance==TIM2)
	{
        printf("test,test\n");
   __HAL_TIM_CLEAR_FLAG(&htim2,TIM_SR_UIF);//清除tim2的中断标志位

	}
	 
}

烧录到芯片后,便会定时发送 test ,我这便为300ms发送一次,倘若因为串口发送太快,亦可使用吧重装值preiod 调到29999,使其3s发送一次,便可大概知道代码是否正常。

代码段在以下此段中断period的值

 当成功后便可开始写

                                             按键键测

按键扫描有许多种写法,如比较老实的使用 :if else if 或者使用 获取io寄存器的值进行取值与swich判断便可(当然你要明白他代表的意义)

要写逻辑,首先呢便要搞清楚你需要的逻辑,按键矩阵按键扫描方式我这里有两种,(当然会有其他我没想到的方式)我这 写的有 :

方法一,很简单通过单独对每一行进行输出,并进行io口的扫描,得到你输出的行数,与扫描列得的列数可知道几行几列。并赋值(简单)当然你也可以通过寄存器简化,代码就不用写这么多,这就是为什么说寄存器运行比(不管是标准库还是hal库,不接受反驳)库函数快的原因。

                                                                 实现代码为

char KeyPad_Scan()
{
	
		u16 readvalue = 0;
	 
	   
	    char data1=0;
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, GPIO_PIN_RESET);//
		HAL_Delay(2);
		readvalue =GPIOA->IDR;	//读取gpioA所有的引脚
		readvalue &= 0x01f0;				//保留低8位的高5位的值
		if(readvalue != 0x01f0) 				//高5位引脚有一个被按下
		{
				HAL_Delay(5);
				readvalue =GPIOA->IDR;	//读取gpioA所有的引脚
				readvalue &= 0x01f0;				//保留低8位的值
				if(readvalue != 0x01f0) 				//高5位引脚有一个被按下
				{
                         
						HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, GPIO_PIN_SET);//
						HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
						HAL_Delay(2);
	
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值