STM32F103系列 Proteus仿真 4*4矩阵键盘 串口+LCD1602显示

这篇具有很好参考价值的文章主要介绍了STM32F103系列 Proteus仿真 4*4矩阵键盘 串口+LCD1602显示。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        最近一直在肝STM32系列芯片,这里我想要检验一下自己的初步学习成果,简单的运用一下IO口的配置,代码使用正点的库函数模板写的,仿真软件是Proteus 8.13,代码编写编译软件是Keil MDK5,仿真芯片是STM32F103R6小容量芯片。


目录

一、硬件设计

 二、软件设计

1、LCD1602的编写       

2、4*4 矩阵键盘的编写

 3、串口通信的编写

 4、主函数

三、仿真

 四、结尾


一、硬件设计

        stm32f103R6芯片的IO口中以下为硬件的具体配置

        PA9、PA10为串口通讯的发送和接收引脚

        PA15我用到了其他的功能(在本文中并没有用到,也懒得删除)

        PB0-PB3是矩阵键盘的列输入(需要设置为输入,至于是下拉输入还是上拉输入,需要看你代码怎么写,我用的是下拉输入)

        PB4-PB7是矩阵键盘的行输出(需要设置为推挽输出,因为我PB0-PB3设置的是下拉输入,所以输出的初始化应该设置为低电平)

        PB13-PB15是LCD1602的功能端,分别为E端、RW端、RS端

        PC0-PC7为LCD1602的数据输入端

        以下为Proteus中的连接图。

proteus矩阵键盘仿真电路,stm32,proteus,单片机,嵌入式硬件,arm

     

proteus矩阵键盘仿真电路,stm32,proteus,单片机,嵌入式硬件,arm

proteus矩阵键盘仿真电路,stm32,proteus,单片机,嵌入式硬件,arm

proteus矩阵键盘仿真电路,stm32,proteus,单片机,嵌入式硬件,arm

 二、软件设计

         本程序主要记录4*4矩阵键盘的逻辑和LCD1602的驱动方法,次要编写串口通信的程序。在矩阵键盘中,这里用的是按行扫描的方法,每次只返回一个值,不会产生重复的按键响应,并且每按下一次按键只会给串口发送一次数据,不会重复发送,松开按键后才会等待下一次按键响应;LCD1602的驱动方法可以去查看数据手册,这里只列出几个重要的配置数据,本程序中有显示单个字节,显示一行字符等;另外例如在严谨的程序中,防止程序跑飞,还应加入看门狗之类的,本文并没有列出,有需要的请自行在主函数中加入喂狗就可以。

1、LCD1602的编写       

        lcd1602指令介绍:

proteus矩阵键盘仿真电路,stm32,proteus,单片机,嵌入式硬件,arm

        指令1:清显示,指令码01H,光标复位到地址00H位置

        指令2:光标复位,光标返回到地址00H

        指令3:光标和显示位置设置I/D,光标移动方向,高电平右移,低电平左移,S:屏幕上所有文字是否左移或右移,高电平表示有效,低电平表示无效。

        指令4:显示开关控制。D:控制整体的显示开与关,高电平表示开显示,低电平表示关显示。C:控制光标的开与关,高电平表示有光标,低电平表示无光标B:控制光标是否闪烁,高电平闪烁,低电平不闪烁。

        指令5:光标或显示移位 S/C :高电平时显示移动的文字,低电平时移动光标

        指令6:功能设置命令 DL:高电平时为4位总线,低电平时为8位总线N:低电平时为单行显示,高电平时为双行显示,F:低电平时显示5X7的点阵字符,高电平时显示5X10的显示字符。

        指令7:字符发生器RAM地址设置。

        指令8:DDRAM地址设置。

        指令9:读忙信号和光标地址 BF:忙标志位,高电平表示忙,此时模块不能接收命令或数据,如果为低电平表示不忙。

        本程序中的初始化函数中用到的有指令1、指令4、指令6、指令7。

        下图为写指令和写数据所用图。

proteus矩阵键盘仿真电路,stm32,proteus,单片机,嵌入式硬件,arm

         当写指令时,需要先将RS和RL全部置低电平,然后再写指令;当写数据时,需要先将RS置为高电平,将RW置为低电平,然后再写入数据;当使能端口E有上升沿时便会将执行指令或者执行数据。

 lcd1602.h文件

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

//PC引脚定义为 lcd的数据输入端
#define LCD_DATA GPIOC

//lcd的RS端定义 PB15
#define LCD_RS_EN GPIO_SetBits(GPIOB,GPIO_Pin_15)
#define LCD_RS_CLEAR GPIO_ResetBits(GPIOB,GPIO_Pin_15)

//lcd的RW端定义 PB14
#define LCD_RW_EN GPIO_SetBits(GPIOB,GPIO_Pin_14)
#define LCD_RW_CLEAR GPIO_ResetBits(GPIOB,GPIO_Pin_14)

//lcd的E端定义 PB13
#define LCD_E_EN GPIO_SetBits(GPIOB,GPIO_Pin_13)
#define LCD_E_CLEAR GPIO_ResetBits(GPIOB,GPIO_Pin_13)

//lcd输入数据
#define DATAOUT(x) GPIO_Write(LCD_DATA,x)

void LCD1602_Init(void);
void LCD1602_gpio_Init(void);
void LCD1602_CMD(u8 cmd);
void LCD1602_DATA(u8 data);
void LCD1602_Busy(void);
void LCD1602_Clear(void);
void LCD1602_Show_Str(u8 rol,u8 line,u8 *str);
void LCD1602_Show_Bit(u8 rol,u8 line,u8 showdata);

#endif

 lcd1602.c文件

#include "lcd1602.h"
#include "delay.h"

void LCD1602_Init(void)
{
	LCD1602_gpio_Init();     //GPIO初始化
	
	delay_ms(15);
	LCD1602_CMD(0x38);       //16*2显示 8位数据线  5*7点阵
	delay_ms(5);
	LCD1602_CMD(0x0c);       //开显示 无光标
	LCD1602_CMD(0x06);			 //文字不动 地址自动+1
	LCD1602_CMD(0x01);       //清屏
}

//写指令
void LCD1602_CMD(u8 cmd)
{
	LCD1602_Busy();  //检测忙不忙
	LCD_RS_CLEAR;    //RS 0
	LCD_RW_CLEAR;    //RW 0
	LCD_E_CLEAR;
	DATAOUT(cmd);
	delay_ms(1);
	LCD_E_EN;
	delay_ms(5);
	LCD_E_CLEAR;
}

//写数据
void LCD1602_DATA(u8 data)
{
	LCD1602_Busy();   //检测忙不忙
	LCD_RS_EN;        //RS 1
	LCD_RW_CLEAR;     //RW 0
	LCD_E_CLEAR;
	DATAOUT(data);
	delay_ms(1);
	LCD_E_EN;
	delay_ms(5);
	LCD_E_CLEAR;
}

//清屏
void LCD1602_Clear(void)
{
	LCD1602_CMD(0x01);
}

//字符串显示 rol 行 line 列
void LCD1602_Show_Str(u8 rol,u8 line,u8 *str)
{
	if(rol == 1)
		LCD1602_CMD(0x00+line+0x80);
	else if(rol == 2)
		LCD1602_CMD(0x40+line+0x80);
	while(*str != '\0')
	{
		LCD1602_DATA(*str);
		str++;
	}
}

//字符显示
void LCD1602_Show_Bit(u8 rol,u8 line,u8 showdata)
{
	if(rol == 1)
		LCD1602_CMD(0x00+line+0x80);
	else if(rol == 2)
		LCD1602_CMD(0x40+line+0x80);
	LCD1602_DATA(showdata);
}

//检测忙函数
void LCD1602_Busy(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;   //浮空输入
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_7;        //PC7
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOC,&GPIO_InitStruct);
	
	LCD_RS_CLEAR;   //RS 0
	LCD_RW_EN;      //RW 1
	
	while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_7));
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;   //推挽输出
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_7;        //PC7
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOC,&GPIO_InitStruct);
}

//gpio初始化
void LCD1602_gpio_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;   //推挽输出
	GPIO_InitStruct.GPIO_Pin=0X00FF;        //PC0-PC7
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOC,&GPIO_InitStruct);
	GPIO_ResetBits(GPIOC,0x00ff);
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;   //推挽输出
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;        //PB13-PB15
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	GPIO_ResetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
}

2、4*4 矩阵键盘的编写

        本程序逻辑比较简单,采用的是行扫描方法,程序中有一点需要注意就是一定要搞清楚两个for循环的逻辑开始和结束,否则很容易导致虽然设置了按键按下标志位,但是还是会出现重复按键的问题,另外就是对gpio口的配置,到底是应该设置为输出还是输入,其他的emmmm我还没想到,这两点注意到应该就没问题了。虽然写的程序有点啰嗦,但是简单易懂,还有很多可以优化的方法,我就简单说一个简化方法,可以将列扫描函数在头文件里面直接define也是可以的,大家可以自行简化和优化。

 key.h

#ifndef __KEY_H
#define __KEY_H

#include "sys.h"
#include "stm32f10x.h"

//这里将按键重定义 方便后期修改IO口

#define Key_Gpio GPIOB

#define line1 GPIO_Pin_4
#define line2 GPIO_Pin_5
#define line3 GPIO_Pin_6
#define line4 GPIO_Pin_7

#define rol1 GPIO_Pin_0
#define rol2 GPIO_Pin_1
#define rol3 GPIO_Pin_2
#define rol4 GPIO_Pin_3


void Key_Init(void);
u8 Key_Scan(void);
void Key_gpio_Init(void);
void Key_set(u8 key,u8 mode);  
u8 Rol_state(u8 rol);


#endif

key.c

#include "key.h"
#include "stm32f10x.h"
#include "delay.h"
#include "uart.h"

void Key_Init(void)
{
	Key_gpio_Init();
}

u8 Key_Scan(void)
{
	u8 i,j;
	u8 Key_Value = '.';
	static u8 Key_up_flag = 1;            //不支持连按
	
	for(i=1;i<=4;i++)       //一共是四行,i的值为行数
	{
		Key_set(i,1);		      //将改行置为高电平,其余行置为低电平,保证只有一行是高电平

		for(j=1;j<=4;j++)           // 一共四列 四列分别检测  另一种方法可以不去单个检测,去做一个统一的判断
		{
			if(Rol_state(j) == 1)
			{
				delay_ms(5);           //按键消抖
				
				if(Rol_state(j) == 1 && Key_up_flag == 1)      
				{
					Key_up_flag = 0;
					
					switch(j)
					{
						case 1:Key_Value = (4*(i-1))+1;break;
						case 2:Key_Value = (4*(i-1))+2;break;
						case 3:Key_Value = (4*(i-1))+3;break;
						case 4:Key_Value = (4*(i-1))+4;break;
						default:break;
					}
					
					//USART_SendData(USART1,Key_Value);      //此条注释可以验证是否是每次只触发一次按键响应,即不支持连按
				} 
			}
		}		
	}
	
	//在for循环结束之后 将行全部置为高电平  检测列是否有高电平 如果没有 即没有按键按下 此时就将行全部置为低电平 标志位置为1 等待下一次按键按下
	Key_set(5,1);            
	if(Rol_state(1) == 0 && Rol_state(2) == 0 && Rol_state(3) == 0 && Rol_state(4) == 0 && Key_up_flag == 0) 
	{
		Key_up_flag = 1;
		Key_Value = '.';
		Key_set(5,0);
	}	
	
	
	//进行按键的重定义
	switch(Key_Value)
	{
		case 1:Key_Value = '1';break;
		case 2:Key_Value = '2';break;
		case 3:Key_Value = '3';break;
		case 4:Key_Value = 'A';break;
		case 5:Key_Value = '4';break;
		case 6:Key_Value = '5';break;
		case 7:Key_Value = '6';break;
		case 8:Key_Value = 'B';break;
		case 9:Key_Value = '7';break;
		case 10:Key_Value = '8';break;
		case 11:Key_Value = '9';break;
		case 12:Key_Value = 'C';break;
		case 13:Key_Value = '*';break;
		case 14:Key_Value = '0';break;
		case 15:Key_Value = '#';break;
		case 16:Key_Value = 'D';break;
		default:Key_Value = '.';break;
	}
		
	return Key_Value;
}


//gpio的初始化 
void Key_gpio_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPD;            //下拉输入
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;            //推挽输出
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	
	GPIO_ResetBits(GPIOB,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
}


//行的置电平函数
void Key_set(u8 key,u8 mode)   //key: 哪一行  mode: 高电平还是低电平
{
	switch(key)
	{
		case 1: 
			if(mode == 1)
			{
				GPIO_SetBits(Key_Gpio,line1);
				GPIO_ResetBits(Key_Gpio,line2);
				GPIO_ResetBits(Key_Gpio,line3);
				GPIO_ResetBits(Key_Gpio,line4);
			}
			else if(mode == 0)
				GPIO_ResetBits(Key_Gpio,line1);
			break;
		case 2: 
			if(mode == 1)
			{
				GPIO_SetBits(Key_Gpio,line2);
				GPIO_ResetBits(Key_Gpio,line1);
				GPIO_ResetBits(Key_Gpio,line3);
				GPIO_ResetBits(Key_Gpio,line4);
			}
			else if(mode == 0)
				GPIO_ResetBits(Key_Gpio,line2);
			break;
		case 3: 
			if(mode == 1)
			{
				GPIO_SetBits(Key_Gpio,line3);
				GPIO_ResetBits(Key_Gpio,line2);
				GPIO_ResetBits(Key_Gpio,line1);
				GPIO_ResetBits(Key_Gpio,line4);
			}
			else if(mode == 0)
				GPIO_ResetBits(Key_Gpio,line3);
			break;
		case 4: 
			if(mode == 1)
			{
				GPIO_SetBits(Key_Gpio,line4);
				GPIO_ResetBits(Key_Gpio,line2);
				GPIO_ResetBits(Key_Gpio,line3);
				GPIO_ResetBits(Key_Gpio,line1);
			}
			else if(mode == 0)
				GPIO_ResetBits(Key_Gpio,line4);
			break;
		case 5: 
			if(mode == 1)
				GPIO_SetBits(Key_Gpio,line4|line3|line2|line1);
			else if(mode == 0)
				GPIO_ResetBits(Key_Gpio,line4|line3|line2|line1);
			break;
		default:break;
	}
}

//列的检测函数
u8 Rol_state(u8 rol)
{
	u8 Rol_state;
	switch(rol)
	{
		case 1: rol = rol1;break;
		case 2: rol = rol2;break;
		case 3: rol = rol3;break;
		case 4: rol = rol4;break;
	}
	Rol_state = GPIO_ReadInputDataBit(Key_Gpio,rol);
	return Rol_state;
}

 3、串口通信的编写

        由于本文重点不是在串口通信,不在过多具体讲解,需要注意的是在串口程序里面出现的PA15引脚和motor字眼,这是我做的电机验证程序,自行忽略和删除即可。

uart.h

#ifndef __UART_H
#define __UART_H
#include "sys.h"

void Uart_Init(u32 bound);
void Uart_gpio_Init(void);
void Uart_NVIC_Init(void);
void USART1_IRQHandler(void);

#endif

 uart.c

#include "uart.h"
#include "stm32f10x.h"
#include "motor.h"

void Uart_Init(u32 bound)
{
	USART_InitTypeDef USART_InitStruct;
	
	Uart_gpio_Init();
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	
	USART_DeInit(USART1);
	
	USART_InitStruct.USART_BaudRate=bound;
	USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
	USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
	USART_InitStruct.USART_Parity=USART_Parity_No;
	USART_InitStruct.USART_StopBits=USART_StopBits_1;
	USART_InitStruct.USART_WordLength=USART_WordLength_8b;
	USART_Init(USART1,&USART_InitStruct);
	
	Uart_NVIC_Init();
	
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);	
	
	USART_Cmd(USART1,ENABLE);
}

void Uart_gpio_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
}

void Uart_NVIC_Init(void)
{
	NVIC_InitTypeDef NVIC_InitStruct;
	
	NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
	NVIC_Init(&NVIC_InitStruct);
}

void USART1_IRQHandler(void)
{
	u8 res;
	if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)
	{
		res = USART_ReceiveData(USART1);
		USART_SendData(USART1,res);
		while(USART_GetFlagStatus(USART1,USART_IT_TC));
		GPIO_SetBits(GPIOA,GPIO_Pin_15);
		USART_ClearITPendingBit(USART1,USART_IT_RXNE);
	}
}

 4、主函数

main.c

#include "stm32f10x.h"
#include "lcd1602.h"
#include "delay.h"
#include "motor.h"
#include "uart.h"
#include "key.h"

int main(void)
{
	u8 str[] = "I LOVE YOU"; 
	u8 Key_Val;
	static int Key_val_Flag = 1;
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	delay_init();
	Uart_Init(9600);
	LCD1602_Init();
	Motor_Init();
	Key_Init();
	
	while(1)
	{
		Key_Val = Key_Scan();
		if(Key_Val != '.'&& Key_val_Flag == 1)     
		{	
			Key_val_Flag = 0;
			LCD1602_Show_Bit(2,7,Key_Val);
			USART_SendData(USART1,Key_Val);
		}
		else if(Key_Val == '.' && Key_val_Flag == 0)
		{
			Key_val_Flag = 1;
		}
		LCD1602_Show_Str(1,3,str);
	}
}

三、仿真

         在仿真上的话,因为采用了串口,所以就需要用到虚拟串口和串口助手,串口助手我直接用的是在微软商店的串口调试助手,虚拟串口采用的是虚拟串口助手VSPD。

        Proteus也可能存在一些对stm32系列仿真的bug,我就把我遇到的bug列在这里,可能大家可以用的到。

        1、芯片频率

        建议设置为48MHz,这样就差不多可以和实际时间一样,不然仿真会很慢。

proteus矩阵键盘仿真电路,stm32,proteus,单片机,嵌入式硬件,arm

        2、 LCD1602

        把我圈中的值设大一点,可能是刷新频率,不然屏幕上显示不出来或者就是有问题。

proteus矩阵键盘仿真电路,stm32,proteus,单片机,嵌入式硬件,arm

         3、COMPIM

        这两个波特率设置为9600和57600,另外没有奇偶校验,8位数据,1个停止位,相应的串口助手设置为9600波特率,其他一样。

proteus矩阵键盘仿真电路,stm32,proteus,单片机,嵌入式硬件,arm

        4、 VIRTUAL TERMIN

        波特率设置成57600,8位数据,没有奇偶校验,1个停止位。

proteus矩阵键盘仿真电路,stm32,proteus,单片机,嵌入式硬件,arm

         这样大差不差就可以成功运行了!!!

 四、结尾

        新手一枚,文章有些冗杂,但是还是希望本文能够对大家有所帮助,加油兄弟们,总有一天会头秃的!文章来源地址https://www.toymoban.com/news/detail-778060.html

到了这里,关于STM32F103系列 Proteus仿真 4*4矩阵键盘 串口+LCD1602显示的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Stm32f103c8t6(proteus仿真)学习——1.点亮LED流水灯

    软件准备:keil uVsion 5 和 proteus 8.15 打开proteus8.15 - 新建项目 - 改名 - 一直next 鼠标右键 - 放置 - 元件 - From Libraries 搜索Stm32 - 选择stm32f103c8 画出点亮一个LED灯的原理图 提示,各元器件搜索: 主控芯片:stm32 电阻:res LED灯:led 鼠标右键 - 放置 - 元件 - From Libraries 地和VCC 在左侧

    2024年02月08日
    浏览(61)
  • [proteus]STM32F103单片机直流电机PID算法PWM波电机调速正反转Proteus仿真

    1、实现功能: (1)、基于STM32F103单片机PID算法PWM控制直流电机正反转调速,LCD1602显示转速等。可通过“加速”、“减速”按键修改“目标转速”并实时测量“实际转速”送到LCD1602上显示。 (2)、“启动”按键控制电机启动,默认启动电机是正转(示波器上的黄色PWM波)。 (3)、“

    2024年02月06日
    浏览(50)
  • 矩阵键盘之门锁小项目(stm32f103zet6)

    今天,给大家分享的是自己弄着玩的一个矩阵键盘控制控制舵机模拟一个智能门锁的功能。 用到的硬件: 开发板我用的是原子哥的精英板(杀鸡用宰牛刀了)。 矩阵键盘(宝上十几块买的): 外加一个舵机和一个0.96的oled显示屏。 矩阵键盘: 有VCC,GND,SCL,SDO四条线,这个矩阵键

    2024年02月10日
    浏览(50)
  • STM32F103基础(寄存器)——(1)3*3矩阵键盘控制5161as数码管

    本篇介绍的是基于 STM32——寄存器 版本的矩阵键盘控制 5161as数码管 显示数字的实例。我们赋予每一个按键从1到9的数字,当我们按下对应的数字按键时,程序会检测出被按下的是哪一个按键并在5261as数码管上显示相应的数字。 (1)原理 为了读取每一个按键的状态,最简单

    2024年02月11日
    浏览(35)
  • RFID课程设计--基于STM32F103RCT6的智能门禁系统,STM32RCT6+RC522+OLED+DHT11+4*4矩阵键盘

      本次课程设计要求如下,我们团队两人完成了90%的功能。   其中我们设置的是刷卡错误3次不报警,密码输入错3次报警(原理相同,大家根据需要自行修改)   然后暂时只能显示卡号和卡是第几个录入到系统中的,想到身份证号和电话(身份信息)输进去有点长就没

    2024年01月16日
    浏览(81)
  • STM32F103 点亮LED闪烁与仿真

    今天给大家分享一下STM32 流水灯简单的仿真吧,我感觉这个提供有用的,但是自己也是第一次使用,主要是感觉曲线很高级。在PWM中查看脉宽很有用。 code: led.c #include \\\"led.h\\\" #include \\\"delay.h\\\" /* GPIO的控制寄存器的配置 1、配置输出引脚 2、打开对应的输出的寄存器的时钟 3、配置

    2024年02月16日
    浏览(43)
  • STM32F103C8T6制作USB键盘

            1、原因:电脑每次开机都需要输入登录密码,感觉很麻烦,就想着能不能用单片机做一个USB键盘,按一下自动给电脑发一串密码实现开机。后来又想,其实不用按键也行,用延时,延时到电脑开机再发送密码就好了,于是便有了这个制作。         2、 功能:将做好

    2024年01月22日
    浏览(46)
  • STM32F103系列之按键控制LED灯

    上篇已经介绍了点灯的操作了,本篇主要介绍按键控制LED灯进行相关操作。 同样,我们需要对GPIO进行相关的初始化配置,这里我们将LED相关的代码全部放在LED.C和LED.H文件里面。 LED.C文件: LED.H文件: 然后我们开始写KEY.C和KEY.H文件里面的相关代码: 首先我们需要知道按键的

    2024年02月05日
    浏览(46)
  • [嵌入式软件][启蒙篇][仿真平台] STM32F103实现串口输出输入、ADC采集

    上一篇:[嵌入式软件][启蒙篇][仿真平台] STM32F103实现LED、按键 学C语言时,使用的printf()函数,就是通过串口打印出来的。 跟外部器件通信,比如GPS模块、蓝牙模块、wifi模块; 两个开发板之间通信,制定私有协议。 PC电脑通信,使用上位机显示数据或控制下位机。 操作:打

    2024年01月22日
    浏览(71)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包