文章目录

  • 一、实验原理
  • 1.1、关于STM32
  • 1.2、关于寄存器
  • 二、点亮LED灯
  • 2.1配置时钟
  • 2.2配置输出模式
  • 2.3点亮LED
  • 三、进阶 !流水灯
  • 3.1具体思路
  • 找到端口输出地址
  • 3.2.创建项目
  • 3.3.代码部分
  • 3.4 烧录
  • 四、烧录到芯片
  • 4.1 实验器材
  • 4.2软件部分
  • 3.5结果展示
  • 四、总结
  • 五、参考

  • 一、实验原理

    1.1、关于STM32

    STM32是意法半导体 (STMicroelectronics) 公司推出的新一代基于Cortex-M内核的32位微控制器系列。
    STM32型号的说明:以STM32F103RBT6这个型号的芯片为例,该型号的组成为7个部分,其命名规则如下:

    STM32 代表ARM Cortex-M内核的32位微控制器
    F F代表芯片子系列。
    103 代表增强型系列。
    R 代表引脚数
    B 代表内嵌Flash容量
    T 代表封装方式
    6 代表工作温度范围

    1.2、关于寄存器

    1.什么是寄存器
    正入其名,寄存器可以理解为是一种储存工具,在stm32中寄存器可以储存的东西包括地址、指令、数据等。可以明确的一点是,无论存的是哪一种数据,在寄存器中都是以机器码的形式存在的。
    我们使用单片机时,通常需要配置寄存器,这样做的目的就是可以用一个形象的“称号“找到这个寄存器,然而在配置的过程中,我们是要知道被配置寄存器的地址的。
    那么,我们是如何准确的找到每个寄存器的地址的呢?
    2.寄存器的地址
    查看手册,但是手册中并没有直接给出每个寄存器的地址,需要我们稍加计算。举个例子,如何找到PB3的引脚呢?
    第一步,找到GPIOB的地址
    通过查找手册,我们不难发现,GPIOB的引脚范围在0x4001 0C00到0x4001 0FFF内。

    第二步 ,找到该寄存器的地址偏移

    所以可以知道PB3的地址为0x4001 0C00+8 = 0x4001 0C08。
    3.访问寄存器
    在我们找到寄存器的地址后,想知道寄存器储存的值是比较简单的,我们有如下方法:

    1.继续查找手册

    2.通过代码直接访问
    代码如下

    unsigned int *pGPIOB_IDR = (unsigned int *)0x40010C08;
    unsigned char PB3 = *pGPIOB_IDR & 0x8;//取出从右往左数的第4位

    3.头文件访问
    不难看出,以上两种方法都是需要事先知道寄存器的地址的,使用起来比较繁琐,那么是不是可以做一个头文件把寄存器起一个“好听”的名字并和地址一一映射呢,事实上,意法半导体公司以及做出了这个头文件,即stm32f10x.h,可以直接使用

    二、点亮LED灯

    2.1配置时钟

    1.与51单片机不同,stm32系列的时钟初始时关闭的,我们需要先使能时钟,首先,我们要找到时钟的位置。

    下图系统结构可以看到时钟的从属关系,此图位于手册P25页,十分重要。可以看出AHB总线包含RCC时钟控制,GPIO是属于APB2的。

    我们已经知道,GPIO端口B的地址从0x4001 0C00开始。接下来只寻找时钟使能寄存器的地址:

    复位和时钟控制RCC的地址从0x4002 1000开始;
    可以在6.3.7小节找到APB2外设时钟使能寄存器(RCC_APB2ENR),偏移地址是0x18,所以APB2的地址就是0x4002 1018。

    2.2配置输出模式

    我们用的I/O口可以输入,但也可以输出,所以我们要先配置寄存器的输出模式,输出高电平有效还是低电平有效。同时,还有输出速率。


    对于一个I/O口,我们需要两位控制输入模式,两位控制输入速率,一共需要4位,所以16的I/O口需要2个寄存器,这里时高八位的寄存器。
    偏移地址是0x04,意思是在基地址的基础上再加0x04,所以,对于GPIOB来说就是0x4001 0c04。
     复位值是0x4444 4444,并不是0x0000 0000。所谓的复位值,就是指如果没有操作这个寄存器时,寄存器存放的默认值。复位值按位拆分0x4 = 0b0100,0x表示16进制,0b表示二进制,也就是默认CNF 01,MODE 00,是浮空输入。
      我们需要的是输出高低电平,所以要设置为输出。输出模式又有好几种输出:

    推挽输出:可以输出高,低电平,连接数字器件;推挽结构一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止。
      开漏输出:输出端相当于三极管的集电极,要得到高电平状态需要上拉电阻才行,适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内)。
      开漏是需要外接上拉电阻才可以输出高电平的,这里并不适合。所以需要设置为推挽输出。
      速度的影响不大,可以选择50MHZ,其他的也行。

    2.3点亮LED

    先找到PB8的位置


    这里有一个错误,PB的寄存器的偏移为0C,而不是Ch。所以,PB的地址为0x40010c0c,寄存器的第九位控制控制的就是PB8.
    C语言代码如下

    int main(void)
    {
    unsigned int *pRCC_APB2ENR = (unsigned int *)0x40021018;
    unsigned int *pGPIOB_CRH = (unsigned int *)0x40010c04;
    unsigned int *pGPIOB_ODR = (unsigned int *)0x40010c0c; 定义几个指针,分别控制时钟、工作模式、PB的电平
    *pRCC_APB2ENR = 0x00000008;
    *pGPIOB_CRH = 0x44444443;
    *pGPIOB_ODR = 0x00000000;//通过指针访问改变寄存器的电位
    return 0;
    }

    三、进阶 !流水灯

    3.1具体思路

    假设控制寄存器的I/O口位PA5,PB9,PC14
    1.配置时钟
    具体的过程同点亮LED灯的相同
    2.配置输出模式和速率
    寄存器的基地址如下


    端口PA5是低八位,偏移为0x00,PA5,PB9和PC14为高八位,偏移为0x00;
    所以寄存器的端口配置地址为
    

    GPIOA_CRL=0x40010800
    GPIOB_CRH =0x40010C04
    GPIOC_CRH =0x40011004

    找到端口输出地址

    通过上图,我们可以轻松找到PA,PB,PC的基地址,以及端口输出寄存器的偏移量。
    所以分别得出PA,PB,PC端口输出寄存器的地址
    GPIOA_ORD=0x4001080C
    GPIOB_ORD=0x40010C0C
    GPIOC_ORD=0x4001100C

    3.2.创建项目

    1.创建工程

    2.选择芯片

    3.选择模式

    4.创建.c文件

    5.生成hex文件

    3.3.代码部分

    代码如下

    #define RCC_AP2ENR ((unsigned volatile int)0x40021018)
    #define GPIOA_CRL ((unsigned volatile int)0x40010800)
    #define GPIOA_ORD ((unsigned volatile int)0x4001080C)
    #define GPIOB_CRH ((unsigned volatile int)0x40010C04)
    #define GPIOB_ORD ((unsigned volatile int)0x40010C0C)
    #define GPIOC_CRH ((unsigned volatile int)0x40011004)
    #define GPIOC_ORD ((unsigned volatile int)0x4001100C)
    //——————-???———————–
    void Delay_wxc( volatile unsigned int t)
    {
    unsigned int i;
    while(t–)
    for (i=0;i<800;i++); //延时函数
    }
    int main()
    {
    int j=100;
    RCC_AP2ENR|=1<<2; /使能/APB2-GPIOA时钟
    RCC_AP2ENR|=1<<3; //使能APB2-GPIOB时钟
    RCC_AP2ENR|=1<<4; //使能APB2-GPIOC时钟

    GPIOA_CRL&=0x0FFFFFFF;		//配置PA7的工作模式
    GPIOA_CRL|=0x20000000;		//配置PA7的最大速率
    GPIOA_ORD|=1<<7;			//PA7的端口输出为1
    
    GPIOB_CRH&=0xFFFFFF0F;
    GPIOB_CRH|=0x00000020;	
    GPIOB_ORD|=1<<9;			//同PA7
    
    GPIOC_CRH&=0x0FFFFFFF;		
    GPIOC_CRH|=0x30000000;   
    GPIOC_ORD|=0x1<<15;			//同PA7
    while(j)
    {	
    	GPIOA_ORD=0x0<<0;		//PA7灭
    	Delay_wxc(1000000);        //延时
    	GPIOA_ORD=0x1<<0;		//PA7灭
    	Delay_wxc(1000000);        //延时
    	
    	GPIOB_ORD=0x0<<9;		
    	Delay_wxc(1000000);
    	GPIOB_ORD=0x1<<9;		
    	Delay_wxc(1000000);       //同PA7
    	
    	GPIOC_ORD=0x0<<14;		
    	Delay_wxc(1000000);
    	GPIOC_ORD=0x1<<14;		
    	Delay_wxc(1000000);         //同PA7
    }
    

    }

    3.4 烧录

    四、烧录到芯片

    4.1 实验器材

    usb转ttl接口(CH340)

    STM32最小开发板

    杜邦线

    4.2软件部分

    生成hex文件

    选择正确的路径

    烧录前,需要先了解stm32的三种启动模式
    BOOT1=x BOOT0=0 从用户闪存启动,这是正常的工作模式。
    BOOT1=0 BOOT0=1 从系统存储器启动,这种模式启动的程序功能由厂家设置。
    BOOT1=1 BOOT0=1 从内置SRAM启动,这种模式可以用于调试。
    所以烧录的时候,BOOT0需要置一,烧录完后如果想打开串口助手查看程序运行需要把BOOT0置零,回归正常工作状态

    3.5结果展示

    流水灯

    四、总结

    实验时要理清思路,理解单片机中的逻辑关系,实验总体不难。

    五、参考

    1.https://blog.csdn.net/weixin_47554309/article/details/120810913

    2.https://blog.csdn.net/qq_47281915/article/details/120812867

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32下的LED灯闪烁

    发表评论