历史上的今天
返回首页

历史上的今天

今天是:2025年02月18日(星期二)

正在发生

2020年02月18日 | stm32矩阵键盘原理图及程序介绍

2020-02-18 来源:elecfans

STM32F0 系列产品基于超低功耗的 ARM Cortex-M0 处理器内核,整合增强的技术和功能,瞄准超低成本预算的应用。该系列微控制器缩短了采用 8 位和 16 位微控制器的设备与采用 32 位微控制器的设备之间的性能差距,能够在经济型用户终端产品上实现先进且复杂的功能。本文为大家介绍stm32矩阵键盘原理图及程序

stm32矩阵键盘原理图

stm32矩阵键盘原理图及程序介绍

stm32矩阵键盘原理图及程序介绍

stm32矩阵键盘原理图及程序介绍

stm32矩阵键盘程序介绍

主要实现:扫描矩阵键盘,将检测到的数据通过spi 通信发送到数码管显示。

主要步骤:

1:初始化时钟

void RCC_Configuration(void)

{

//----------使用外部RC晶振-----------

RCC_DeInit(); //初始化为缺省值

RCC_HSEConfig(RCC_HSE_ON); //使能外部的高速时钟

while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); //等待外部高速时钟使能就绪

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Enable Prefetch Buffer

FLASH_SetLatency(FLASH_Latency_2); //Flash 2 wait state

RCC_HCLKConfig(RCC_SYSCLK_Div1); //HCLK = SYSCLK

RCC_PCLK2Config(RCC_HCLK_Div1); //PCLK2 = HCLK

RCC_PCLK1Config(RCC_HCLK_Div2); //PCLK1 = HCLK/2

RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9); //PLLCLK = 8MHZ * 9 =72MHZ

RCC_PLLCmd(ENABLE); //Enable PLLCLK

while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //Wait till PLLCLK is ready

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //Select PLL as system clock

while(RCC_GetSYSCLKSource()!=0x08); //Wait till PLL is used as system clock source

}


2:配置管脚

void GPIO_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

SPI_InitTypeDef SPI_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);//开启GPIOD外设时钟

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;//D0~D3

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入

GPIO_Init(GPIOD, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;//D4~D7

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出

GPIO_Init(GPIOD, &GPIO_InitStructure);

//初始化管脚电平

GPIO_SetBits(GPIOD, GPIO_Pin_0 | GPIO_Pin_1| GPIO_Pin_2| GPIO_Pin_3);

GPIO_ResetBits(GPIOD, GPIO_Pin_4 | GPIO_Pin_5| GPIO_Pin_6| GPIO_Pin_7);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_SPI1, ENABLE); //开启SPI1和GPIOA外设时钟

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;//设置SPI的四个引脚模式

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出

GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //设置GPIO A1管脚 用于锁存74HC595输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出

GPIO_Init(GPIOA, &GPIO_InitStructure);

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//SPI数据模式 双线双向全双工

SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //SPI工作模式 主模式

SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI数据大小

SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //设置时钟的极性

SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //设置时钟的相位

SPI_InitStructure.SPI_NSS = SPI_NSS_Hard; //NSS脚硬件置位

SPI_InitStructure.SPI_BaudRatePrescaler =SPI_BaudRatePrescaler_64;//预分频值

SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;// 数据从高位传输

SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值

SPI_I2S_DeInit(SPI1); //将外设SPI1寄存器重设为缺省值;

SPI_Init(SPI1, &SPI_InitStructure);

SPI_Cmd(SPI1, ENABLE);//使能SPI1外设

}


3:编写矩阵键盘扫描函数KEY.c

u8 shu=16;

void KeyScan(void)

{

u8 i;

if((GPIO_ReadInputData(GPIOD) & 0x0f) != 0x0f )

{

Delay_MS(20);

if((GPIO_ReadInputData(GPIOD) & 0x0f) != 0x0f )

{

GPIO_SetBits(GPIOD, GPIO_Pin_4 | GPIO_Pin_5| GPIO_Pin_6);

GPIO_ResetBits(GPIOD, GPIO_Pin_7);

switch(GPIO_ReadInputData(GPIOD) & 0x0f)

{

case 0x07: shu=0; break;

case 0x0b: shu=1; break;

case 0x0d: shu=2; break;

case 0x0e: shu=3; break;

}

GPIO_SetBits(GPIOD, GPIO_Pin_4 | GPIO_Pin_5| GPIO_Pin_7);

GPIO_ResetBits(GPIOD, GPIO_Pin_6);

switch(GPIO_ReadInputData(GPIOD) & 0x0f)

{

case 0x07: shu=4; break;

case 0x0b: shu=5; break;

case 0x0d: shu=6; break;

case 0x0e: shu=7; break;

}

GPIO_SetBits(GPIOD, GPIO_Pin_4 | GPIO_Pin_6| GPIO_Pin_7);

GPIO_ResetBits(GPIOD, GPIO_Pin_5);

switch(GPIO_ReadInputData(GPIOD) & 0x0f)

{

case 0x07: shu=8; break;

case 0x0b: shu=9; break;

case 0x0d: shu=10; break;

case 0x0e: shu=11; break;

}

GPIO_SetBits(GPIOD, GPIO_Pin_7 | GPIO_Pin_5| GPIO_Pin_6);

GPIO_ResetBits(GPIOD, GPIO_Pin_4);

switch(GPIO_ReadInputData(GPIOD) & 0x0f)

{

case 0x07: shu=12; break;

case 0x0b: shu=13; break;

case 0x0d: shu=14; break;

case 0x0e: shu=15; break;

}

GPIO_SetBits(GPIOD, GPIO_Pin_0 | GPIO_Pin_1| GPIO_Pin_2| GPIO_Pin_3);

GPIO_ResetBits(GPIOD, GPIO_Pin_4 | GPIO_Pin_5| GPIO_Pin_6| GPIO_Pin_7);

while((i《50)&&((GPIO_ReadInputData(GPIOD) & 0x0f) != 0x0f))

{

i++;

Delay_MS(10);

}

}

}

}


4: SPI传送数据函数

void Display_Data(u8 data)

{

u8 i=data;

PAOut(1)=0;

SPI_I2S_SendData(SPI1,DSY_CODE[i]);

Delay_MS(2);

PAOut(1)=1;

Delay_MS(1000);

}


5:主函数

#include“stm32f10x_lib.h”

#include

#include“Exboard.h”

u8 DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};

int main(void)

{ //u8 i;

RCC_Configuration();

GPIO_Configuration();

//EXTI_Configuration();

//NVIC_Configuration();

while(1)

{

KeyScan();

Display_Data(shu);

}

}


附录:Exboard.h

#ifndef _EXBOARD_H

#define _EXBOARD_H

#endif

#include“stm32f10x_lib.h”

#define GPIOA_IDR (GPIOA_BASE+0x08)

#define GPIOA_ODR (GPIOA_BASE+0x0c)

#define GPIOB_IDR (GPIOB_BASE+0x08)

#define GPIOB_ODR (GPIOB_BASE+0x0c)

#define GPIOC_IDR (GPIOC_BASE+0x08)

#define GPIOC_ODR (GPIOC_BASE+0x0c)

#define GPIOD_IDR (GPIOD_BASE+0x08)

#define GPIOD_ODR (GPIOD_BASE+0x0c)

#define GPIOE_IDR (GPIOE_BASE+0x08)

#define GPIOE_ODR (GPIOE_BASE+0x0c)

#define GPIOF_IDR (GPIOF_BASE+0x08)

#define GPIOF_ODR (GPIOF_BASE+0x0c)

#define GPIOG_IDR (GPIOG_BASE+0x08)

#define GPIOG_ODR (GPIOG_BASE+0x0c)

#define BitBang(Addr,BitNum) *((volatile unsigned long*)(((Addr&0xf0000000)+ 0x2000000)+(((Addr&0xfffff)《《5)+(BitNum《《2))))

#define PAIn(n) BitBang(GPIOA_IDR,n)

#define PAOut(n) BitBang(GPIOA_ODR,n)

#define PBIn(n) BitBang(GPIOB_IDR,n)

#define PBOut(n) BitBang(GPIOB_ODR,n)

#define PCIn(n) BitBang(GPIOC_IDR,n)

#define PCOut(n) BitBang(GPIOC_ODR,n)

#define PDIn(n) BitBang(GPIOD_IDR,n)

#define PDOut(n) BitBang(GPIOD_ODR,n)

#define PEIn(n) BitBang(GPIOE_IDR,n)

#define PEOut(n) BitBang(GPIOE_ODR,n)

#define PFIn(n) BitBang(GPIOF_IDR,n)

#define PFOut(n) BitBang(GPIOF_ODR,n)

#define PGIn(n) BitBang(GPIOG_IDR,n)

#define PGOut(n) BitBang(GPIOG_ODR,n)

#define KEY1 PEIn(0)

#define LED1 PDOut(13)

#define KEY2 PCIn(13)

#define LED2 PGOut(14)

void Delay_MS(u16 dly);

/

void RCC_Configuration(void);

void GPIO_Configuration(void);

//void EXTI_Configuration(void);

//void NVIC_Configuration(void);

extern void KeyScan(void);

void Display_Data(u8 data);

extern u8 shu;

推荐阅读

史海拾趣

Arcolectric公司的发展小趣事

Arcolectric深知合作伙伴的重要性,因此一直致力于与全球各地的优质企业建立紧密的合作关系。通过与这些合作伙伴的深入合作,Arcolectric不仅获得了更多的市场机会和资源支持,还不断吸收和借鉴先进的经验和技术,推动公司的持续发展和创新。

FerriShield公司的发展小趣事

在快速发展的同时,FerriShield始终不忘履行社会责任。公司积极参与环保事业,推动绿色生产和可持续发展。此外,FerriShield还设立了奖学金和助学金,支持贫困地区的青少年接受教育。这些举措体现了FerriShield作为行业领导者的责任与担当。

以上五个故事均基于FerriShield公司的发展历程和事实描述,展现了其在电子行业中的成长和进步。

Hirosugi-Keiki公司的发展小趣事

在快速发展的同时,FerriShield始终不忘履行社会责任。公司积极参与环保事业,推动绿色生产和可持续发展。此外,FerriShield还设立了奖学金和助学金,支持贫困地区的青少年接受教育。这些举措体现了FerriShield作为行业领导者的责任与担当。

以上五个故事均基于FerriShield公司的发展历程和事实描述,展现了其在电子行业中的成长和进步。

DIALIGHT公司的发展小趣事

DIALIGHT公司一直专注于工业LED照明领域的发展。他们深入了解工业空间照明的需求和挑战,设计了一系列专为工业应用而定制的LED照明产品。这些产品不仅易于安装和维护,而且能在恶劣的环境下持续使用。此外,DIALIGHT还提供集成系统解决方案,帮助客户降低能源成本、维护成本和碳足迹,同时提高设施的安全性和生产力。通过不断创新和优质服务,DIALIGHT在工业LED照明领域赢得了广泛的认可和信赖。

Fairchild Imaging公司的发展小趣事

面对日益激烈的市场竞争和不断变化的市场需求,Fairchild Imaging制定了面向未来的战略布局。公司将继续加大在成像技术领域的研发投入,推动技术创新和产品升级。同时,Fairchild Imaging还将积极拓展国际市场,加强与全球客户的合作与交流。此外,公司还将注重人才培养和团队建设,为公司的长期发展提供有力保障。

Acculin Inc公司的发展小趣事

Acculin Inc深知人才是企业发展的核心。为了吸引和留住优秀人才,公司建立了完善的培训体系,并为员工提供了良好的晋升机会。此外,公司还注重团队建设,通过举办各种团建活动活动增强员工之间的凝聚力。这些举措使得Acculin在人才竞争激烈的市场中保持了优势。

问答坊 | AI 解惑

一个可替代传统人机的方案,你不心动吗?

液晶终端+单片机系统=人机界面(HMI)        北京迪文科技有限公司  生产的TFT真彩液晶终端,配上一个小型单片机系统就可实现传统计人机界面的功能。液晶终端实现界面显示及触摸反馈功能,单片机系统进行与PLC的 ...…

查看全部问答>

Linux命令行大全中文版(CHM格式)

Linux命令行大全中文版(CHM格式)…

查看全部问答>

跨导OTA仿真问题

谁用ADS做过mos管OTA仿真? 教教我…

查看全部问答>

步进电机的控制(C语言)

大家好 请问怎样用并口控制两相混合式步进电机的正反转。在网上看了都是用单片来控制的,请问不用单片机直接用两相混合式步进电机细分驱动器可以控制吗? 还有就是写这种程序一般用的是keil软件吗? 小弟初学很多不懂,希望大家帮帮忙。 谢谢…

查看全部问答>

如何察看NIDS_PACKET的内容

看见网上经常有介绍NIDS_PACKET是就贴出这样的内容: Packet length : 590 005dba36:00 00 5a 42 40 86 00 10 7b 3b 90 f5 08 00 45 00 005dba46:02 40 d3 2a 40 00 7f 06 08 24 85 fc 09 70 85 fc 005dba56:09 01 04 72 00 14 02 00 d5 35 9b ...…

查看全部问答>

CListViewCtrl

请指教:   我想用一个位图来做 CListViewCtrl控件的背景,怎么实现?…

查看全部问答>

新手求助如何搭建VS 2005开发wince的环境!在线等!!!!!

  本人初次做Win ce的开发,IDE用的是VS 2005,所建项目类型是在智能设备中的Windows ce 5.0模板用的是设备应用程序,但是在调试时在弹出的“选择应用程序的部部署位置”时我选 了Windows CE Device时出现了\"连接到设备失败。  &nbs ...…

查看全部问答>

华为公司2007年社会招聘

华为内部推荐 招聘对象:        04,05年本科及硕士,06年硕士生,07年的应届生不招, 学校要求省重点大学及以上,通信、电子、计算机、经济类、管理类等相关专业毕业。 招聘的是正式“华为员工”,待遇一般不低于07年的 ...…

查看全部问答>