stm32学习心得

提示:写博客纯属第一次练手,不足之处希望多提建议

文章目录

  • stm32学习心得
  • 前言
  • 一、keil的安装
  • 二、跑demo之前,先了解一下stm32是啥先铺垫
  • 三、运行一个demo看现象
  • 四、根据现象提问题
    • 1.是怎么点灯的
    • 2.他点灯之前干了什么(上电开始)
  • 五.问题
  • 六 回顾详解_led
    • 寄存器
    • 库函数
  • 六 回顾详解_按键
    • stm32中按键输入的配置
  • 总结

前言


首先,小编拙见,拿到一样新的东西,先去了解什么原理啥的都是扯淡,因为在很多时候我们都更喜欢关注我们看到的,用眼睛去发现,所以我觉得拿到一样没见过的,我们可以先拿到一个成熟的demo跑一下对吧,但是工欲善其事必先利其器,在小编用过的裸机编程软件中,有keil跟cube,cube目前是一个很多新人学习的软件但是小编用了很不喜欢(网上说有一些bug,小编没发现,只是用不习惯而已),而且对于底层他好像屏蔽了(有些省略)所以第一步便是弄软件


一、keil的安装

小编不多说,这种程度的东西我找一个给您
link
这里补充几句里面的东西没有的话评论区留言,小编会更新到百度云,但是网上很多

二、跑demo之前,先了解一下stm32是啥先铺垫

. . . 在小编看来,不管是stm32还是其他的微控器像aruino跟51,都可以总结为是一些根据编译后的二进制文件运行相对应功能的可编程芯片,或者说一直可以DIY的微控器,可以通过语言(c/c++/python/lua)的编写,去控制io引脚达到数据传输或者控制外部器件以及设置内部寄存器达到一些定时啊或者dma功能,而要先去了解一些东西,像led灯,GPIO是啥,万用表示波器那些仪器的使用(看现象的同时通过数字的形式去感知),元器件跟mcu之间要共地,他的电压在多少既可以启动又不会导致烧坏(重要),led怎么亮的,5年前对于大一的我完全,,,,,所以避免有年级小一点的懵B,而这些都是小编这两年指导一些学生过程中出现最多的问题,当然都是拙见,更权威的回答应该是基于某种架构公司啊什么半导体啊,但是不关我事 ,也不管你事,刚入门只有能用就行
提示:后面还是得回去看到底是啥

三、运行一个demo看现象


最简单的就是流水灯了吧(视频手机里好像看不到),所以借鉴下原子哥的工程(对于开源,我服原子哥)

led_

四、根据现象提问题

1.是怎么点灯的

很明显,led就是发光二极管对吧,他是分正负极的,假如led共地,那么我们就是给他一个高电平亮:

库:

GPIO_SetBits(GPIOx,GPIO_Pin_x);

寄存器:

GPIOB_ODR &= ~(1<<0); // 灭灯1
GPIOB_ODR |= (1<<0);  // 点灯1

补充:GPIOB_ODR ——>#define GPIOB_ODR (*(unsigned int *)0x40010C0C) 地址映射

2.他点灯之前干了什么(上电开始)

STM32系列单片机有三种启动模式

(1)从Flash启动,将主Flash地址0x08000000映射到0x00000000,这样代码启动之后就相当于从0x08000000开始。

(2)从RAM启动,将RAM地址0x20000000映射到0x00000000,这样代码启动之后就相当于从0x20000000开始。

(3)从系统存储器启动。首先控制BOOT0 BOOT1管脚,复位后,STM32与上述两种方式类似,从系统存储器地址0x1FFF F000开始执行代码。系统存储器存储的其实就是STM32自带的bootloader代码,在bootloader中提供了UART1的接口,通过此接口可以将用户所需的程序代码下载到主Flash中,下载完毕后,此时程序代码已经存储在主Flash当中,这时切换启动模式(从主Flash启动),复位后所执行的就是刚刚下载到Flash中的代码了。

(1)用户闪存 : 芯片内置的Flash。正常的工作模式。
(2)SRAM: 芯片内置的RAM区,就是内存。可以用于调试。
(3)系统存储器: 芯片内部一块特定的区域,芯片出厂时在这个区域预置了一段Bootloader,就是通常说的ISP程序。这个区域的内容在芯片出厂后没有人能够修改或擦除,即它是一个ROM区。启动的程序功能由厂家设置。

Main Flash memory:
是STM32内置的Flash,一般我们使用JTAG或者SWD模式下载程序时,就是下载到这个里面,重启后也直接从这启动程序。

System memory:

从系统存储器启动,这种模式启动的程序功能是由厂家设置的。一般来说,这种启动方式用的比较少。
系统存储器是芯片内部一块特定的区域,STM32在出厂时,由ST在这个区域内部预置了一段BootLoader,也就是我们常说的ISP程序,这是一块ROM,出厂后无法修改。

一般来说,我们选用这种启动模式时,是为了从串口下载程序,因为在厂家提供的BootLoader中,提供了串口下载程序的固件,可以通过这个BootLoader将程序下载到系统的Flash中。但是这个下载方式需要以下步骤:

Step1:将BOOT0设置为1,BOOT1设置为0,然后按下复位键,这样才能从系统存储器启动BootLoader;

Step2:最后在BootLoader的帮助下,通过串口下载程序到Flash中;

Step3:程序下载完成后,又有需要将BOOT0设置为GND,手动复位,这样,STM32才可以从Flash中启动,可以看到,利用串口下载程序还是比较的麻烦,需要跳帽跳来跳去的,非常的不注重用户体验。

Embedded Memory:

内置SRAM,既然是SRAM,自然也就没有程序存储的能力了,这个模式一般用于程序调试。

假如我只修改了代码中一个小小的地方,然后就需要重新擦除整个Flash,比较的费时,可以考虑从这个模式启动代码(也就是STM32的内存中),用于快速的程序调试,等程序调试完成后,在将程序下载到SRAM中。

思路来源链接: link

剩下的启动流程链接: link

五.问题

其他的引脚都可以拿来点灯?有可能拿来其他用?
当然有,像串口跟usb或者输入输出
而STM32 的 IO 口可以由软件配置成如下 8 种模式:
1、输入浮空
2、输入上拉
3、输入下拉
4、模拟输入
5、开漏输出
6、推挽输出
7、推挽式复用功能
8、开漏复用功能
具体怎么用,后续讲解

六 回顾详解_led

我们可以发现在我们打开一个工程的时候,系统给我们提供了启动方式跟初始化一些硬件啥的,方便我们在这个基础上开发,而接下来就是怎么通过这个基础进行开发了
而从最简单的点灯开始,我们学习c语言最简单的是printf(“hello world”);而点灯就是c的hello word

寄存器

void LED_Init(void)
{RCC->APB2ENR|=1<<3;    //使能PORTB时钟RCC->APB2ENR|=1<<6;    //使能PORTE时钟GPIOB->CRL&=0XFF0FFFFF; GPIOB->CRL|=0X00300000;//PB.5 推挽输出GPIOB->ODR|=1<<5;      //PB.5 输出高GPIOE->CRL&=0XFF0FFFFF;GPIOE->CRL|=0X00300000;//PE.5推挽输出GPIOE->ODR|=1<<5;      //PE.5输出高
}

这是一个简单的io初始化引脚的过程,这里初始化的GPIOB5跟GPIOE5,首先,我们初始化GPIOE的时钟,然后我们可以看看rcc的结构体,

typedef struct
{__IO uint32_t CR;__IO uint32_t CFGR;__IO uint32_t CIR;__IO uint32_t APB2RSTR;__IO uint32_t APB1RSTR;__IO uint32_t AHBENR;__IO uint32_t APB2ENR;__IO uint32_t APB1ENR;__IO uint32_t BDCR;__IO uint32_t CSR;#ifdef STM32F10X_CL__IO uint32_t AHBRSTR;__IO uint32_t CFGR2;
#endif /* STM32F10X_CL */#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)uint32_t RESERVED0;__IO uint32_t CFGR2;
#endif /* STM32F10X_LD_VL || STM32F10X_MD_VL || STM32F10X_HD_VL */
} RCC_TypeDef;

今天被一兄弟问道,RCC时钟拿来干嘛的,首先时钟是单片机运行的基础,时钟信号推动单片机内各个部分执行相应的指令。时钟系统就是CPU的脉搏,决定cpu速率,像人的心跳一样 只有有了心跳,人才能做其他的事情,而单片机有了时钟,才能够运行执行指令,才能够做其他的处理 (点灯,串口,ADC), 使用任何外设都需要时钟才能启动,

而gpioBE是挂在在APB2这条线上的,继而我们参考他的寄存器手册可以发现,B引脚在第三位,所以左移了三位,而E引脚在第六位,所以左移了六位,这里是用于初始化EB类的io,而我们上面说到,一个io他有模式,不同模式对应不同功能,对于我们这次点亮led并不能说我脑子里让他输出他就输出对吧,
所以我们看看他的接下来的配置,

    GPIOB->CRL&=0XFF0FFFFF; GPIOB->CRL|=0X00300000;//PB.5 推挽输出

我么通过看手册可以知道STM32 的每个 IO 端口都有 7 个寄存器来控制:
1.配置模式的 2 个 32 位的端口配置寄存器 CRL 和 CRH;2 个 32 位的数据寄存器 IDR 和 ODR;
2.1 个 32 位的置位/复位寄存器BSRR;
3.一个 16 位的复位寄存器 BRR;
4.1 个 32 位的锁存寄存器 LCKR;
我们常用的 IO 端口寄存器只有 4 个:CRL、CRH、IDR、ODR。
CRL 和 CRH 控制着每个 IO 口的模式及输出速率,那他们两个有啥不同呢
CRL是对一类io低八位的设置,ex:PE0~PE7
CRH是对一类io高八位的设置,exc:PE0~PE7


我们说到这张图是对低八位io的设置,而CRL 是一个32位的寄存器,所以一个io对于4位,所以,0-3对应的是GPIOx.1引脚,而0-1对应的是MODEy[1:0]的设置,而2-3对应的是CNFy[1:0]的设置,这里是GPIOB.5在20-23,所以我们先把他清零,然后我们设置为推挽输出(00),输出速率为50M(11),所以为3,20-23位或上3,就设置了PB5为输出引脚,然后提供ODR使其输出1或0就行

GPIOB->CRL&=0XFF0FFFFF;
GPIOB->CRL|=0X00300000;//PB.5 推挽输出
GPIOB->ODR|=1<<5;      //PB.5 输出高

库函数

库函数就简单了,通过 RCC_APB2PeriphClockCmd使能时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);   //使能PB,PE端口时钟

通过把设置写入GPIO_InitTypeDef结构体就可以了

typedef struct
{uint16_t GPIO_Pin;             /*!< Specifies the GPIO pins to be configured.This parameter can be any value of @ref GPIO_pins_define */GPIOSpeed_TypeDef GPIO_Speed;  /*!< Specifies the speed for the selected pins.This parameter can be a value of @ref GPIOSpeed_TypeDef */GPIOMode_TypeDef GPIO_Mode;    /*!< Specifies the operating mode for the selected pins.This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;
void LED_Init(void)
{GPIO_InitTypeDef  GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);   //使能PB,PE端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;                 //LED0-->PB.5 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;          //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //IO口速度为50MHzGPIO_Init(GPIOB, &GPIO_InitStructure);                  //根据设定参数初始化GPIOB.5GPIO_SetBits(GPIOB,GPIO_Pin_5);                        //PB.5 输出高GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;                //LED1-->PE.5 端口配置, 推挽输出GPIO_Init(GPIOE, &GPIO_InitStructure);                    //推挽输出 ,IO口速度为50MHzGPIO_SetBits(GPIOE,GPIO_Pin_5);                        //PE.5 输出高
}

六 回顾详解_按键

stm32中按键输入的配置

这里的RCC->APB2ENR可以参考上面的讲解

//按键初始化函数
void KEY_Init(void)
{RCC->APB2ENR|=1<<2;     //使能PORTA时钟RCC->APB2ENR|=1<<6;     //使能PORTE时钟GPIOA->CRL&=0XFFFFFFF0; //PA0设置成输入,默认下拉GPIOA->CRL|=0X00000008; GPIOE->CRL&=0XFFF000FF;    //PE2~4设置成输入GPIOE->CRL|=0X00088800;                   GPIOE->ODR|=7<<2;        //PE2~4 上拉
}

我们也依旧可着这张图看看,我们初始化完时钟之后对于按键我们就得初始化io为输入,对于pa0,我们首先清空io配置,然后设置CNFy为10,对于MODEy我么设置00,1000那就是8,即可
sda

总结

提示:这里对文章进行总结:

此次想写一个单片机从上电到led的流程,还有一些细节性的缺漏,比如pc指针跟启动文件那些的,望各位读者大佬多多建议

stm32学习(启动+LED+按键)相关推荐

  1. STM32学习笔记:按键实验

    STM32学习笔记:按键实验 一.所使用的函数 1.时钟使能函数 RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState New ...

  2. 【STM32学习笔记-LED呼吸灯】

    STM32学习笔记-点亮LED灯 文章目录 STM32学习笔记-点亮LED灯 一.呼吸灯原理 二.呼吸灯代码 1.main.c 2.led.c 3.led.h 三.代码分析 一.呼吸灯原理 占空比:占 ...

  3. STM32学习记录--关于按键配置(PB3 PB4)

    目录 问题 解决方案 问题 有一个项目需要用到PB3与PB4配置成按键输入,这原理图的引脚配置可以看到,因为PB3和PB4在默认情况下是做JTAG调试用的.如果需要将其当普通GPIO使用,需要关闭JT ...

  4. STM32学习笔记——(5)按键检测

    按键检测 一.按键检测 一.按键检测 如上图所示, 若按键KEY1未按下时检测点为低电平,按下时检测点为高电平. 若按键KEY2/3/4未按下时检测点为高电平,按下时检测点为低电平. 程序如下: /* ...

  5. STM32学习:按键控制LED

    STM32学习:按键控制LED 文章目录 前言 一.所用知识点复习 1.stm32工作模式(*注意上下拉输入的区别*) 2.按键抖动与常见按键接法 按键抖动: 按键消抖: 常见按键接法: 3.GPIO ...

  6. 【STM32学习笔记-点亮LED灯】

    STM32学习笔记-点亮LED灯 文章目录 STM32学习笔记-点亮LED灯 一.原理图分析 二.代码分析 1.mian函数 2.led.c函数 3.led.h函数 4.函数文件整理 5.LED_In ...

  7. STM32学习 3:GPIO管脚配置与第一个STM32实验:LED灯闪烁

    STM32学习 3:GPIO管脚配置与第一个STM32实验:LED灯闪烁 1,GPIO管脚简介与配置 1.1GPIO框图 1.2GPIO不同模式 1.3 GPIO寄存器 1.4 GPIO库函数配置 2 ...

  8. 51单片机入门学习篇-led灯、按键、数码管、中断

    文章目录 前言 一.Proteus仿真 二.Keil代码编写 1.流水灯 2.来回点灯 3.按键操作 4.中断操作 5.数码管 6 动态数码管 三. 练习题 总结 前言 本文用来记录博主学习单片机的过 ...

  9. DSP28335通过按键启动LED闪烁功能

    第一章 任务介绍 在本章节,在上一篇闪烁LED灯的基础上,通过按键启动LED闪烁的程序. 第二章 硬件电路分析 研旭DSP28335至尊版一共有两个按键,一个是核心板上的复位按键Reset2,另一个是 ...

最新文章

  1. SLAM十四讲笔记1
  2. 深度理解目标检测(MMdetection)-HOOK机制
  3. 程序包com.sun.image.codec.jpeg.JPEGCo不存在解决办法
  4. 基于弹性束图匹配的人脸识别
  5. 【LeetCode从零单排】No133. clon graph (BFS广度优先搜索)
  6. debian9 没有ipv4
  7. Python、Perl 垫底,C语言才是最环保的编程语言
  8. 迪杰斯特拉算法 两点间最短路径的选择
  9. wps怎么统一修改标点符号_毕业论文的参考文献怎么加入??脚注如何降重?
  10. oracle约束或语句,oracle、DB2、Informix常用约束语句
  11. linux下nginx的基本使用
  12. 代码阅读软件kscope源码安装指导
  13. wifi定位算法 java_几种室内定位技术方案对比,室内定位种类的优缺点一目了然...
  14. [转载] python 装饰器
  15. Android Studio创建侧滑菜单使用心得
  16. 数据结构c语言版算法设计题,数据结构题集(C语言版)算法设计答案
  17. 【原创】Python 网易易盾滑块验证
  18. java Graphics2D 获取当前系统实际支持特殊字符和中文的字体
  19. 思岚A1激光雷达的测试(windows)
  20. ps保存psd后图层全没了_Photoshop文件不显示图层

热门文章

  1. ad怎么修改栅格_AD 10怎么设置栅格?
  2. 中国房价不可能下降的19个理由
  3. 计算机调查应用表格,大学计算机实验课_调查报告_表格模板_应用文书.doc
  4. HDU 1335(Basically Speaking)
  5. python10086查询系统_Python数字移动设备取证
  6. 【160312 18:00】四则运算 2
  7. Grafana自定义报警
  8. 基于VTK的PACS系统的开发 心路历程2
  9. 魔兽世界最新服务器排行榜,wow国服服务器排行榜:十大平衡服已全面解锁 | TG魔兽世界专区...
  10. 如何利用Ghost整理硬盘的磁盘碎片