stm32f103c8t6与stm32f103zet6 基于SX1276串口通信-----发送端(二)

矩阵按键控制代码

源码链接

使用4*4矩阵,主控芯片为STM32F103C8T6,串口发送配置在下面这篇文章里面

串口发送端配置博文

/************************************************************
正面朝上黑引脚为行,白引脚为列 
A、B 、C 、D  分别返回 10 11 12 13
*为 14
#为 15
0为 16
无按键按下返回0
*************************************************************/

#include "key.h"
#include "delay.h"
//矩阵键盘引脚初始化    
//软件消抖
void delayMs(u8 t)
{
	while(t--)
	{
		delay_ms(20);
	}
}
//按键初始化 PA0-PA3 为输入   PA4,PA5,PA6,PA8为输出
void KEY_init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能PORTB,PORTD,PORTG时钟
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_8;                        //键盘输出
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;                       //键盘输入
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;   //输入模式
	
	GPIO_Init(GPIOA,&GPIO_InitStructure);
}




//mode:0,不支持连续按;1,支持连续按;
u8 KEY_Scan(u8 mode)
{
	static u8 key0_up=1;//按键按松开标志
	static u8 key1_up=1;//按键按松开标志
	static u8 key2_up=1;//按键按松开标志
	static u8 key3_up=1;//按键按松开标志
	static u8 key4_up=1;//按键按松开标志
	static u8 key5_up=1;//按键按松开标志
	static u8 key6_up=1;//按键按松开标志
	static u8 key7_up=1;//按键按松开标志
	static u8 key8_up=1;//按键按松开标志
	static u8 key9_up=1;//按键按松开标志
	static u8 keyA_up=1;//按键按松开标志
	static u8 keyB_up=1;//按键按松开标志
	static u8 keyC_up=1;//按键按松开标志
	static u8 keyD_up=1;//按键按松开标志
	static u8 keyX_up=1;//按键按松开标志
	static u8 keyJ_up=1;//按键按松开标志
	
	if(mode)
	{
			key0_up=1;
			key1_up=1;
			key2_up=1;
			key3_up=1;
			key4_up=1;
			key5_up=1;
			key6_up=1;
			key7_up=1;
			key8_up=1;
			key9_up=1;
			keyA_up=1;
			keyB_up=1;
			keyC_up=1;
			keyD_up=1;
			keyX_up=1;
			keyJ_up=1;	
	}
	
    //第一行
	Hang_00_L;//把第一行输出低电平
	Hang_01_H;
	Hang_02_H;
	Hang_03_H;
		if(key1_up&&Lie_00_V==0)
		{    
		   delayMs(jpys); //延时20秒,软件消抖
			
		   key1_up=0;
		   if(Lie_00_V==0) //如果第一列是低电平,说明有键被按下,如果没有直接退出if语句
		   {
			   return 1;
		   }
		}else if(Lie_00_V==1)key1_up=1;
	 
		if(key2_up&&Lie_01_V==0)//如果第二列是低电平,
		{    
		   delayMs(jpys);//延时20秒,软件消抖
		   key2_up=0;
		   if(Lie_01_V==0)//如果第二列是低电平,说明有键被按下,如果没有直接退出if语句
		   {
			  return 2; 
		   }
		}else if(Lie_01_V==1)key2_up=1;
	 
		if(key3_up&&Lie_02_V==0)
		{    
		   delayMs(jpys);
		   key3_up=0;
		   if(Lie_02_V==0)
		   {
			  return 3;
		   }
		}else if(Lie_02_V==1)key3_up=1;
	 
		if(keyA_up&&Lie_03_V==0)//如果第四列是低电平
		{    
		   delayMs(jpys);
		   keyA_up=0;
		   if(Lie_03_V==0)//如果第四列是低电平,说明有键被按下,如果没有直接退出if语句
		   {
			  return 4;
		   }
		}else if(Lie_03_V==1)keyA_up=1;
 
	//第二行
	Hang_00_H;
	Hang_01_L;//把第二行拉低
	Hang_02_H;
	Hang_03_H;
		if(key4_up&&Lie_00_V==0)//如果第一列是低电平
		{    
		   delayMs(jpys);
		   key4_up=0;
		   if(Lie_00_V==0)//说明有键被按下,如果没有直接退出if语句
		   {
				return 5;
		   }
		}else if(Lie_00_V==1)key4_up=1;
		 
		if(key5_up&&Lie_01_V==0)
		{    
		   delayMs(jpys);
		   key5_up=0;
		   if(Lie_01_V==0)
		   {
		       return 6;
		   }
		}else if(Lie_01_V==1)key5_up=1;
		 
		if(key6_up&&Lie_02_V==0)
		{    
		   delayMs(jpys);
		   key6_up=0;
		   if(Lie_02_V==0)
		   {
			   return 7;
		   }
		}else if(Lie_02_V==1)key6_up=1;
		 
		if(keyB_up&&Lie_03_V==0)
		{    
		   delayMs(jpys);
		   keyB_up=0;
		   if(Lie_03_V==0)
		   {
		       return 8;  
		   }
		}else if(Lie_03_V==1)keyB_up=1;
 
	//第三行
	Hang_00_H;
	Hang_01_H;
	Hang_02_L;//把第三行置低
	Hang_03_H;
		if(key7_up&&Lie_00_V==0) //如果第一列是低电平
		{    
		   delayMs(jpys);//延时20秒
		   key7_up=0;
		   if(Lie_00_V==0)//说明有键被按下,如果没有直接退出if语句
		   {
			   return 9;
		   }
		}else if(Lie_00_V==1)key7_up=1;
		 
		if(key8_up&&Lie_01_V==0)
		{    
		   delayMs(jpys);
		   key8_up=0;
		   if(Lie_01_V==0)
		   {
		       return 10;
		   }
		}else if(Lie_01_V==1)key8_up=1;
		 
		if(key9_up&&Lie_02_V==0)
		{    
		   delayMs(jpys);
		   key9_up=0;
		   if(Lie_02_V==0)
		   {
		       return 11;
		   }
		}else if(Lie_02_V==1)key9_up=1;
		 
		if(keyC_up&&Lie_03_V==0)
		{    
		   delayMs(jpys);
		   keyC_up=0;
		   if(Lie_03_V==0)
		   {
		       return 12; 
		   }
		}else if(Lie_03_V==1)keyC_up=1;
 
	//第四行
	Hang_00_H;
	Hang_01_H;
	Hang_02_H;
	Hang_03_L;//把第四行置低
		if(keyX_up&&Lie_00_V==0)//如果第一列是低电平
		{    
		   delayMs(jpys);
		   keyX_up=0;
		   if(Lie_00_V==0)//说明有键被按下,如果没有直接退出if语句
		   {
		       return 13;
		   }
		}else if(Lie_00_V==1)keyX_up=1;
		 
		if(key0_up&&Lie_01_V==0)
		{    
		   delayMs(10);
		   key0_up=0;
		   if(Lie_01_V==0)
		   {
		       return 14;
		   }
		}else if(Lie_01_V==1)key0_up=1;
		 
		if(keyJ_up&&Lie_02_V==0)//如果第三列是低电平
		{    
		   delayMs(jpys);
		   keyJ_up=0;
		   if(Lie_02_V==0)//说明有键被按下,如果没有直接退出if语句
		   {
		       return 15;
		   }
		}else if(Lie_02_V==1)keyJ_up=1;
		 
		if(keyD_up&&Lie_03_V==0)
		{    
		   delayMs(jpys);
		   keyD_up=0;
		   if(Lie_03_V==0)
		   {
		       return 16;
		   }
		}else if(Lie_03_V==1)keyD_up=1;
		
		return 0;
}

key的头文件

#ifndef __KEY_H
#define __KEY_H	 
#include "stm32f10x.h"

//4*4矩阵按键  
#define Hang_00_L  GPIO_ResetBits(GPIOA, GPIO_Pin_8)//行00
#define Hang_00_H  GPIO_SetBits(GPIOA, GPIO_Pin_8)
 
#define Hang_01_L  GPIO_ResetBits(GPIOA, GPIO_Pin_6)//行01
#define Hang_01_H  GPIO_SetBits(GPIOA, GPIO_Pin_6)
 
#define Hang_02_L  GPIO_ResetBits(GPIOA, GPIO_Pin_5)//行02
#define Hang_02_H  GPIO_SetBits(GPIOA, GPIO_Pin_5)
 
#define Hang_03_L  GPIO_ResetBits(GPIOA, GPIO_Pin_4)//行03
#define Hang_03_H  GPIO_SetBits(GPIOA, GPIO_Pin_4)
 
#define Lie_00_V GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//列00
#define Lie_01_V GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)//列01
#define Lie_02_V GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2)//列02
#define Lie_03_V GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3)//列03

#define  jpys   1   //宏定义,约定jpys==20,方便以后程序移植



void KEY_init(void);//IO初始化
u8 KEY_Scan(u8 mode);  	//按键扫描函数

#endif

这里我们采用的是定时中断的办法,来采样按键是否被按下,来进行串口数值发送

timer定时器代码配置

void TIM2_Int_Init(u16 arr,u16 psc)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //时钟使能

	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	 计数到5000为500ms
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率  
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
 
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
	TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
	
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //TIM3中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //从优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
	
	TIM_Cmd(TIM2, ENABLE);  //使能TIMx外设
							 
}

打开定时器中断

int TIM2_IRQHandler(void)
{    
	u8 temp;
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 
	{   
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源
		   if(delay_flag==1)
			 {
				 if(++delay_50==5)	 
				 delay_50=0,delay_flag=0;  //给主函数提供50ms的精准延时
			 }
		     KEY = KEY_Scan(1);//扫描按键变化	
			 Control(KEY);	  //遥控
	 return 0;	  
} 
配置控制处理代码Control
void Control(u8 key)
{
	if(key==0x06)		
	{
		printf("s");
	
	}
	if(key==0x04)		
	{
		printf("f");
	
	}
	if(key==0x08)		
	{
		printf("g");
	
	}
	if(key==0x02)		
	{
		printf("a");
	
	}
	if(key==0x0A)		
	{
		printf("o");
	
	}
	if(key==0x05)	
	{
		printf("d");
	
	}
	if(key==0x07)		
	{
		printf("i");

	}
	if(key==0x0C)		
	{
		printf("i");
		i1=5;
			}
	if(key==0x01)	
	{
		printf("q");

	}
	if(key==0x03)		
	{
		printf("w");

	}
	if(key==0x09)	
	{
		printf("e");
	
	}
	if(key==0x0B)	
	{
		printf("r");
	
	}
	if(key==0x0D)		
	{
		printf("u");

	}
	if(key==0x0E)		
	{
		printf("c");
	}
	if(key==0x0F)	
	{
		printf("t");
	
	}
	if(key==0x10)	
	{
		printf("y");

	}
	
	
}
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悟道xn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值