STM32F103开发

news/2024/11/17 16:52:07/文章来源:https://www.cnblogs.com/zyly/p/18550731

本节我们将会对STM32的硬件资源进行介绍,包括如下内容:

  • 点亮LED
  • 检测按键按下和松开事件;
  • 串口;
  • 点亮128*128 TFT_LCD液晶屏;

一、点亮LED

1.1 电路原理图

LED电路原理图如下图所示:

其中:

  • LED1连接到PA8`引脚,低电平点亮;
  • LED2连接到PD2引脚,低电平点亮;

1.2 GPIO引脚介绍

STM32F103RTC6共有5组GPIO,分别为 GPIOA, GPIOB, GPIOC, GPIOD, 和 GPIOE。其中,GPIOAGPIOBGPIOCGPIOD是常用的,GPIOE只有一部分引脚在某些型号的STM32F103系列中有效。

每组GPIO通常包含16个引脚。但并非所有引脚都在所有STM32F103型号中都有效,具体取决于具体芯片封装。

  • GPIOA:16 个引脚(PA0 - PA15);
  • GPIOB:16 个引脚(PB0 - PB15
  • GPIOC:16 个引脚(PC0 - PC15
  • GPIOD:16 个引脚(PD0 - PD15);
  • GPIOE(在某些型号上有效):16个引脚(PE0 - PE15);

1.3 GPIO寄存器

STM32F103RTC6中,GPIO引脚的配置和控制是通过寄存器来实现的。每个GPIO端口(如GPIOAGPIOB 等)都有一组寄存器来控制引脚的方向、输出类型、上拉/下拉电阻、输入模式等。;

  • 两个32位配置寄存器,GPIOx_CRHGPIOx_CRL;
  • 两个32位数据寄存器,GPIOx_IDRGPIOx_ODR
  • 一个32位设置/清除寄存器,GPIOx_BSRR
  • 一个16位复位寄存器,GPIOx_BRR
  • 一个32位锁定寄存器,GPIOx_LCKR
1.3.1 端口配置低寄存器(GPIOx_CRL

GPIOx_CRL端口配置低8位寄存器(x=A~E),四位控制1个引脚,共控制8个引脚(0~7引脚);

31:28 27:24 23:20 19:16 15:12 11:8 7:4 3:0
CNF7[1:0]
MODE7[1:0]
... .... .... .... .... ..... CNF0[1:0]
MODE0[1:0]

其中:

MODE[1:0] CNF[1:0]
输入模式 0 0 0 0:模拟输入模式
0 1:浮空输入模式
1 0:上拉/下卡输入模式
1 1:保留
输出模式 0 1:最大速度10MHz
1 0:最大速度2MHz
1 1:最大速度50MHz
0 0:通用推挽输出模式
0 1:通用开漏输出模式
1 0:复用功能推挽输出模式
1 1:复用功能开漏输出模式
1.3.3 端口配置高寄存器(GPIOx_CRH

GPIOx_CRH四位控制1个引脚(x=A~E),共控制8个引脚(8~15引脚);同上不再重复介绍。

1.3.3 端口输入数据寄存器(GPIOx_IDR

GPIOx_IDR端口输入数据寄存器(x=A~E);

31~16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
保留 IDR15 .. .. .. .. .. .. .. .. .. .. .. .. .. .. IDR0

31~16位始终读0,低16位为只读,并只能以16位的形式读出。

1.3.4 端口输出数据寄存器(GPIOx_ODR

GPIOx_ODR端口输出数据寄存器(x=A~E);

31~16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
保留 ODR15 .. .. .. .. .. .. .. .. .. .. .. .. .. .. ODR0

31~16位始终读0,低16位可读可写,并只能以16位的形式操作。

1.3.5 端口设置/清除寄存器(GPIOx_BSRR

GPIOx_BSRR端口设置/清除寄存器(x=A~E);

31~16 15~0
BR15~BR0 BS15~BS0
0:对对应的ODRy位不产生影响
1:清除对应的ODRy位为0
0:对对应的ODRy位不产生影响
1:设置对应的ODRy位为1
1.3.6 端口清除寄存器(GPIOx_BRR

GPIOx_BRR端口清除寄存器(x=A~E);

31~16 15~0
保留 BR15~BR0
0:对对应的ODRy位不产生影响
1:清除对应的ODRy位为1

1.4 代码实现

1.4.1 GPIO初始化函数
 /******************************************************** ********************
* File Name          : gpio.c
* Author             : Zhengyang
* Description        : 初始化GPIO口portx:端口号PORTA~Epinx:引脚号PORT0~15gpio_cfg:输入输出模式配置bit:输出电平设置 高:HIGH  低:LOW
********************************************************************************/ 
void gpio_init(PORTx_PINx portx_pinx,GPIO_CFG gpio_cfg,BIT_ACTION bit)
{GPIO_TypeDef *GPIO;u8 portx = portx_pinx/16;                 //获取端口号u8 pinx = portx_pinx%16;	        	  //获取引脚号if(portx==0)GPIO=GPIOA;else if(portx==1)GPIO=GPIOB;else if(portx==2)GPIO=GPIOC;else if(portx==3)GPIO=GPIOD;elseGPIO=GPIOE;RCC->APB2ENR|=1<<(portx+2);	                   //外设时钟使能if(pinx<8){GPIO->CRL &=~(0x0F<<(pinx*4));             //该引脚模式配置四位清零GPIO->CRL|=gpio_cfg<<(4*pinx);             //端口配置寄存器CRL}else if(pinx>=8)    {GPIO->CRH &=~(0x0F<<((pinx-8)*4));             //该引脚模式配置四位清零GPIO->CRH|=gpio_cfg<<(4*(pinx-8));             //端口配置寄存器CRH}if((gpio_cfg&0x03)!=0x00)             				                //输出{if(pinx<8)GPIO->ODR|=bit<<pinx;		        //端口数据输出寄存器ODRelse								GPIO->ODR|=bit<<pinx;	   	        //端口数据输出寄存器	 }
} 

这里PORTx_PINxGPIO_CFGBIT_ACTION均是枚举类型;

/************************************* 端口配置 ************************************************************/
typedef  enum   			    //宏定义端口配置
{//这里的值不能改!!!GPI                     = 0x00,                       //定义管脚输入方向    GPO_SpeedMax_10         = 0x01,                       //定义管脚输出方向   最大速度10MHZGPO_SpeedMax_2          = 0x02,                       //定义管脚输出方向   最大速度2MHZGPO_SpeedMax_50         = 0x03,                       //定义管脚输出方向   最大速度50MHZ//输入模式可用GPI_DOWN    = 0x08|GPI,                       //输入下拉        PxODR需配置为0          GPI_UP      = 0x08|GPI,                       //输入上拉        PxODR需配置为1       		 复用功能时一般采用GPI_ANALOG  = 0x00|GPI,                       //模拟输入GPI_FLOAT   = 0x04|GPI ,                      //浮空输入//输出模式不能用GPO_PUSH_PULL     = 0x00,                     //通用推挽输出GPO_OPEN_DRAIN    = 0x04,                     //通用开漏输出GPO_MULPUSH_PULL  = 0x08,                     //复用推挽输出GPO_MULOPEN_DRAIN = 0x0C,                     //复用开漏输出//输出模式可用GPO_PUSH_PULL_50         =  GPO_SpeedMax_50| GPO_PUSH_PULL,                 //通用推挽输出,最大速度50MHZ   通用输出一般设置GPO_PUSH_PULL_10         =  GPO_SpeedMax_10| GPO_PUSH_PULL,                 //通用推挽输出,最大速度10MHZ   GPO_PUSH_PULL_2          =  GPO_SpeedMax_2 | GPO_PUSH_PULL,                 //通用推挽输出,最大速度2MHZGPO_MULPUSH_PULL_2       =  GPO_SpeedMax_2| GPO_MULPUSH_PULL,  				//复用推挽输出,最大速度2MHZGPO_MULPUSH_PULL_10      =  GPO_SpeedMax_10| GPO_MULPUSH_PULL, 				//复用推挽输出,最大速度10MHZGPO_MULPUSH_PULL_50      =  GPO_SpeedMax_50| GPO_MULPUSH_PULL               //复用推挽输出,最大速度50MHZ   复用功能 输出模式一般采用这样设置
}GPIO_CFG;/***************************************** 宏定义引脚号 *************************************************************/ 
typedef enum 
{PA0=0,PA1=1,PA2=2,PA3=3,PA4=4,PA5=5,......PE13=77,PE14=78,PE15=79} PORTx_PINx;typedef enum   					    //外部端口输出电平
{ LOW  = 0,HIGH = 1
} BIT_ACTION;
1.4.2 PXout/PxIn

定义GPIO输入输出宏:

/********************** 位运算符优先级低于算术运算符 <<  &  | ~  所以位运算符必须加括号	 ***********************/
#define  Bit_Band(Addr,Bit_Num)     *((volatile unsigned long *)((Addr&0xF0000000)+0x02000000+((Addr&0xfffff)<<5)+(Bit_Num<<2)))/********************************************** I/O 地址映射 **************************************************/
#define GPIOA_IDR         (GPIOA_BASE + 0x08)       //0x40010808
#define GPIOA_ODR         (GPIOA_BASE + 0x0C) 		//0x4001080C
#define GPIOB_IDR         (GPIOB_BASE + 0x08) 		//0x40010C08
#define GPIOB_ODR         (GPIOB_BASE + 0x0C)  		//0x40010C0C
#define GPIOC_IDR         (GPIOC_BASE + 0x08) 		//0x40011008
#define GPIOC_ODR         (GPIOC_BASE + 0x0C) 		//0x4001100C
#define GPIOD_IDR         (GPIOD_BASE + 0x08) 		//0x40011408
#define GPIOD_ODR         (GPIOD_BASE + 0x0C) 		//0x4001180C
#define GPIOE_IDR         (GPIOE_BASE + 0x08) 		//0x40011808
#define GPIOE_ODR         (GPIOE_BASE + 0x0C)  		//0x4001180C/********************************************** 宏定义输入输出	 ************************************************/
#define  PAout(Bit_Num)		                    Bit_Band(GPIOA_ODR,Bit_Num)	  //输出  1位输出
#define  PAin(Bit_Num)							Bit_Band(GPIOA_IDR,Bit_Num)	  //输入
#define  PBout(Bit_Num)		                    Bit_Band(GPIOB_ODR,Bit_Num)
#define  PBin(Bit_Num)							Bit_Band(GPIOB_IDR,Bit_Num)
#define  PCout(Bit_Num)		                    Bit_Band(GPIOC_ODR,Bit_Num)
#define  PCin(Bit_Num)							Bit_Band(GPIOC_IDR,Bit_Num)
#define  PDout(Bit_Num)		                    Bit_Band(GPIOD_ODR,Bit_Num)
#define  PDin(Bit_Num)							Bit_Band(GPIOD_IDR,Bit_Num)
#define  PEout(Bit_Num)		                    Bit_Band(GPIOE_ODR,Bit_Num)
#define  PEout(Bit_Num)		                    Bit_Band(GPIOE_ODR,Bit_Num)

这里利用到了STM32的位段功能,Cortex-M3储存器包含两个位段(bit-band)区,将别名寄存器的每个字映射到位段寄存器的一个位。

映射公式(外设寄存器和SRAM可被映射):

\[bit\_word\_addr = bit\_band\_base + (byte\_offset \times 32) +(bit\_number * 4) \]

其中:

  • bit_word_addr:别名寄存器中的地址映射到某一个目标位;
  • bit_band_base:别名区的起始地址;
  • byte_offset:目标位的字节在位段的序号;
  • bit_number:目标位所在位置(0~31);

例如:SRAM中某一变量地址为0x20000300字节中的位2;

\[0x22006008 = 0x22000000 + ((0x20000300 - 0x20000000) \times 8 + 2) \times 4% \]

1.4.3 点亮LED

如需点亮LED,我们只需要在main函数添加如下代码:

gpio_init(PD2,GPO_SpeedMax_50,HIGH);	             // PD2接入LED2 
gpio_init(PA8,GPO_SpeedMax_50,HIGH);                 // PA8接入LED1 
while(1)
{	    PAout(8) = 0;PDout(2) = 1;delay_ms(1500);PAout(8) = 1;PDout(2) = 0;delay_ms(1500);
}		 

这里我们简单介绍一下PAoutPDout宏的实现;

1.4.3 烧录

编译完成后通过ISP烧录到开发版,我们可以看到LED1LED2交替点亮,时间间隔为1.5s

二、检测按键

三、串口

三、点亮TFT

四、源码下载

源码下载路径:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/835407.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

团队项目Scrum冲刺-day7

一、每天举行站立式会议 站立式会议照片一张昨天已完成的工作成员 任务陈国金 协助代码沙箱Docker实现凌枫 创建题目页面陈卓恒 协助开发创建题目页面谭立业 协助开发创建题目页面廖俊龙 接口测试曾平凡 前端页面测试曾俊涛 代码沙箱Docker实现薛秋昊 协助代码沙箱Docker实现今…

爱码单车队-冲刺日志第四天

会议记录:今天主要是投入一些后端的开发任务,然后开始实现基础的登录绑定用户的功能。

2024-2025-1 20241314 《计算机基础与程序设计》第八周学习总结

2024-2025-1 20241314 《计算机基础与程序设计》第八周学习总结 作业信息这个作业属于哪个课程 <班级的链接>(2024-2025-1-计算机基础与程序设计)这个作业要求在哪里 2024-2025-1计算机基础与程序设计第八周作业这个作业的目标 功能设计与面向对象设计 面向对象设计过…

bolt.new只要5分钟就能完成1个网站,神奇惊艳

下面是我用bolt.new5分钟完成的首页,前端页面配色和css都很好看,我觉得很惊艳啦!网站截图如下# 网站介绍生成随机yes或者no答案的网站,每次点击oracle按钮,可以生成yes或者no的随机答案,帮助选择困难症用户,轻松选择yes还是no 网站网址https://yesnooracle.dev 功能特点…

2024-2025-1 20241415《计算机基础与程序设计》第八周学习总结

如2024-2025-1 20241415 《计算机基础与程序设计》第八周学习总结 作业信息这个作业属于哪个课程 2024-2025-1-计算机基础与程序设计这个作业要求在哪里 2024-2025-1计算机基础与程序设计第八周作业这个作业的目标 功能设计与面向对象设计,面向对象设计过程,面向对象语言三要…

爱码单车队-冲刺日志第二天

会议记录:在第二天的冲刺中,团队成员在接口文档设计与前端框架方面取得了一定进展。经过小组的共同努力,确定了前段设计与后端对接的接口, 为后续的开发工作奠定了基础。虽然目前前端设计与预期原型存在较大差距,但基本功能已经得以实现。 接下来,团队将继续优化功能,并…

猿人学web端爬虫攻防大赛赛题第20题——2022新春快乐

题目网址:https://match.yuanrenxue.cn/match/20 解题步骤解题之前需要先了解wasm是什么:https://docs.pingcode.com/ask/294587.html看数据包。sign是一串加密的字符串,t一看就是时间戳。全局搜索api/match/20,只有一处。打断点,触发。看下sign的生成逻辑。 "sign&q…

[Tricks-00004]CF1954F(自己胡的 trick,被 Burnside 完爆)

介绍下自己的离奇思路: 先读清楚题意!要求是旋转等价,即两个以 \(c\) 个 \(1\) 开头,总 \(1\) 个数不超过 \(k+c\) 的字符串算一种。 那怎么刻画"只算一种"这个条件呢?一个想法可以是,对每个字符串赋一个权值,一种字符串的权值即旋转出来的每个合法的,把它们…

工控机维修数据恢复

工控机是一种加固的增强型个人计算机,由于经常在环境比较恶劣的情况下运行,对数据的安全性要求也更高。 一、数据丢失的原因 用户误操作:如错误删除文件、不小心切断电源等,这些操作可能导致数据丢失或损坏。 入侵与感染:恶意程序可能破坏硬盘数据,甚至具有格式硬盘的功能…

RAG 系统高效检索提升秘籍:如何精准选择 BGE 智源、GTE 阿里与 Jina 等的嵌入与精排模型的完美搭配

RAG 系统高效检索提升秘籍:如何精准选择 BGE 智源、GTE 阿里与 Jina 等的嵌入与精排模型的完美搭配RAG 系统高效检索提升秘籍:如何精准选择 BGE 智源、GTE 阿里与 Jina 等的嵌入与精排模型的完美搭配 Text Embedding 榜单:MTEB、C-MTEB 《MTEB: Massive Text Embedding Benc…

Golang的GMP调度模型与源码解析

0、引言 我们知道,这当代操作系统中,多线程和多进程模型被广泛的使用以提高系统的并发效率。随着互联网不断的发展,面对如今的高并发场景,为每个任务都创建一个线程是不现实的,使用线程则需要系统不断的在用户态和内核态之间不断的切换,引起不必要的损耗,于是引入了协程…

有限状态机(FSM)的使用

有限状态机的使用 有限状态机在游戏制作中十分常见,它既可以作为玩家角色的控制框架,纯代码控制动画的播放,免去动画间的“连连看”;也可以制作简单的AI,甚至还可以搭配其它AI决策方式做出更复杂易用的AI控制……本文仅是个人对有限状态机的理解,与大家一同交流有限状态机…