STM32最小系统入门教程:点亮LED灯实例【附代码】

目录

一、stm32f103c8t6寄存器

1.寄存器

二、GPIO初始化设置

1.根据芯片手册查询端口地址

 2.打开时钟

3.端口配置寄存器 

​编辑

 4.配置高电平​编辑

三、点亮LED灯

1.使用GPIOA、GPIOB、GPIOC点亮红、蓝、黄三种LED灯

2.将P13口加入流水灯的闪烁中

四、Keil中的遇到的问题解决

总结


一、stm32f103c8t6寄存器

1.寄存器

        寄存器是 CPU 内部用来存放数据的一些小型存储区域,用来暂时存放参与运算的数据和运算结果。其实寄存器就是一种常用的 时序逻辑电路 ,但这种时序逻辑电路只包含存储电路。 寄存器的存储电路是由锁存器或触发器构成的,因为一个锁存器或触发器能存储1位二进制数,所以由N个 锁存器 或触发器可以构成N位寄存器。寄存器是 中央处理器 内的组成部分。寄存器是有限存储容量的高速存储部件,它们可用来暂存指令、数据和位址。在计算机领域,寄存器是CPU内部的元件,包括 通用寄存器 、专用寄存器和控制寄存器。寄存器拥有非常高的读写速度,所以在寄存器之间的数据传送非常快。

寄存器是一个存储空间,地址很容易索引到。

二、GPIO初始化设置

1.根据芯片手册查询端口地址

如上图所示GPIOA的地址在0x40010800-0x40010BFF之间,GPIOB、GPIOC均可查询得到 

 2.打开时钟

 

         时钟地址是基础地址加上偏移地址 ,即0x40021018,则打开三个IO口的时钟需要将三个位都置1,具体代码如下:

#define RCC_APB2ENR (*(unsigned int *)0x40021018)
 
// 打开时钟
RCC_APB2ENR |= (1<<3);  // 打开 GPIOB 时钟
RCC_APB2ENR |= (1<<4);  // 打开 GPIOC 时钟
RCC_APB2ENR |= (1<<2);  // 打开 GPIOA 时钟
 

3.端口配置寄存器 

端口1-7为低,端口8-15为高。每个引脚由四个位控制。

GPIO口有八种模式:

  • 输入浮空
  • 输入上拉
  • 输入下拉
  • 模拟输入
  • 开漏输出
  • 推挽式输出
  • 推挽式复用功能
  • 开漏复用功能
  • 本次实验使用推挽输出:根据手册可以知道使用此输出需要看CNF加端口号上面bit为置为00。

    此次实验最大速度是10MHz,因此MODE加端口号上面的bit位需要变为01。

    PB0、PC15、PA0的设置具体代码如下:

    #define GPIOB_CRH (*(unsigned int *)0x40010C04)
    #define GPIOC_CRH (*(unsigned int *)0x40011004)
    #define GPIOA_CRL (*(unsigned int *)0x40010800)
     
    // 设置 GPIO 为推挽输出,即00,同时频率为10MHz,即01
    	// 设置 GPIOB 最后四位为 0001 (B0)
    	GPIOB_CRL |= (1<<0);  // 最后一位设置为1
    	GPIOB_CRL &= ~(0xE);  // 倒数二、三、四位设置为0
    	// 设置 GPIOC 前四位为 0001  (C15)
    	GPIOC_CRH |= (1<<28); // 第四位设置为1
    	GPIOC_CRH &= ~(0xE0000000);  // 前三位设置为0
    	// 设置 GPIOA 最后四位为 0001 (A0)
    	GPIOA_CRL |= (1<<0);  // 最后一位设置为1
    	GPIOA_CRL &= ~(0xE);  // 倒数二、三、四位设置为0

     4.配置高电平

    将相应的bit位设置为高电位则灯不亮,GPIO的A0、B0、C15代码如下:

    //给GPIOA、GPIOB、GPIOC配置输入寄存器
    #define GPIOB_ODR (*(unsigned int *)0x40010C0C)
    #define GPIOC_ODR (*(unsigned int *)0x4001100C)
    #define GPIOA_ODR (*(unsigned int *)0x4001080C)
    // 3个LED初始化为不亮(即高点位)
    	GPIOB_ODR |= (1<<0);  // 最后一位设置为1
    	GPIOC_ODR |= (1<<15); // 倒数第15位设置为1
    	GPIOA_ODR |= (1<<0);  // 最后一位设置为1

    三、点亮LED灯

    1.使用GPIOA、GPIOB、GPIOC点亮红、蓝、黄三种LED灯

    以stm32最小板芯片,采用GPIOA、GPIOB、GPIOC点亮红、蓝、黄三种LED灯轮流闪烁。具体代码如下:

    #define GPIOB_BASE 0x40010C00   //定义GPIOB地址
    #define GPIOC_BASE 0x40011000   //定义GPIOC地址
    #define GPIOA_BASE 0x40010800   //定义GPIOA地址
    
    #define RCC_APB2ENR (*(unsigned int *)0x40021018)
    
    //给GPIOA、GPIOB、GPIOC配置寄存器
    #define GPIOB_CRL (*(unsigned int *)0x40010C00)   
    #define GPIOC_CRH (*(unsigned int *)0x40011004)
    #define GPIOA_CRL (*(unsigned int *)0x40010800)
    
    //给GPIOA、GPIOB、GPIOC配置输入寄存器
    #define GPIOB_ODR (*(unsigned int *)0x40010C0C)
    #define GPIOC_ODR (*(unsigned int *)0x4001100C)
    #define GPIOA_ODR (*(unsigned int *)0x4001080C)
    	
    
    
    void SystemInit(void);
    void Delay_ms(volatile  unsigned  int);
    
    void Delay_ms( volatile  unsigned  int  t)
    {
         unsigned  int  i;
         while(t--)
             for (i=0;i<800;i++);
    }
    
    
    int main(){
    	// 开启时钟
    	RCC_APB2ENR |= (1<<3); // 开启 GPIOB 时钟
    	RCC_APB2ENR |= (1<<4); // 开启 GPIOC 时钟
    	RCC_APB2ENR |= (1<<2); // 开启 GPIOA 时钟
    	
    	
    	// 设置 GPIO 为推挽输出,即00,同时频率为10MHz,即01
    	// 设置 GPIOB 最后四位为 0001 (B0)
    	GPIOB_CRL |= (1<<0);  // 最后一位设置为1
    	GPIOB_CRL &= ~(0xE);  // 倒数二、三、四位设置为0
    	// 设置 GPIOC 前四位为 0001  (C15)
    	GPIOC_CRH |= (1<<28); // 第四位设置为1
    	GPIOC_CRH &= ~(0xE0000000);  // 前三位设置为0
    	// 设置 GPIOA 最后四位为 0001 (A0)
    	GPIOA_CRL |= (1<<0);  // 最后一位设置为1
    	GPIOA_CRL &= ~(0xE);  // 倒数二、三、四位设置为0
    
    	
    	// 3个LED初始化为不亮(即高点位)
    	GPIOB_ODR |= (1<<0);  // 最后一位设置为1
    	GPIOC_ODR |= (1<<15); // 倒数第15位设置为1
    	GPIOA_ODR |= (1<<0);  // 最后一位设置为1
    	
    	
    	while(1){
    		GPIOB_ODR &= ~(1<<0); // 点灯1
    		Delay_ms(1000);
    		GPIOB_ODR |= (1<<0);  // 灭灯1
    		Delay_ms(1000);
    		
    		GPIOC_ODR &= ~(1<<15); // 点灯2
    		Delay_ms(1000);
    		GPIOC_ODR |= (1<<15);  // 灭灯2
    		Delay_ms(1000);
    		
    		GPIOA_ODR &= ~(1<<0); // 点灯3
    		Delay_ms(1000);
    		GPIOA_ODR |= (1<<0);  // 灭灯3
    		Delay_ms(1000);
    		
    	}
    	
    }
    
    
    void SystemInit(){
    	
    }
    

    实物效果如下:

    LED闪烁

    2.将P13口加入流水灯的闪烁中

    STM32最小系统核心板子出厂时已经焊接好了1个led灯(PC13处),一般可通过此灯的点亮让编程者验证自己烧录的代码是否正常运行,将此口P13口加入程序中重新烧录,和具体代码如下:

     
    #define GPIOB_BASE 0x40010C00
    #define GPIOC_BASE 0x40011000
    #define GPIOA_BASE 0x40010800
     
    #define RCC_APB2ENR (*(unsigned int *)0x40021018)
     
    #define GPIOB_CRH (*(unsigned int *)0x40010C04)
    #define GPIOC_CRH (*(unsigned int *)0x40011004)
    #define GPIOA_CRL (*(unsigned int *)0x40010800)
     
    #define GPIOB_ODR (*(unsigned int *)0x40010C0C)
    #define GPIOC_ODR (*(unsigned int *)0x4001100C)
    #define GPIOA_ODR (*(unsigned int *)0x4001080C)
    	
     
     
    void SystemInit(void);
    void Delay_ms(volatile  unsigned  int);
    void A_LED_LIGHT(void);
    void B_LED_LIGHT(void);
    void C_LED_LIGHT(void);
    void Delay_ms( volatile  unsigned  int  t)
    {
         unsigned  int  i;
         while(t--)
             for (i=0;i<800;i++);
    }
     
    void A_LED_LIGHT(){
    	GPIOA_ODR=0x0<<4;		//PA4低电平
    	GPIOB_ODR=0x1<<9;		//PB9高电平
    	GPIOC_ODR=0x1<<13;		//PC13高电平
    }
    void B_LED_LIGHT(){
    	GPIOA_ODR=0x1<<4;		//PA4高电平
    	GPIOB_ODR=0x0<<9;		//PB9低电平
    	GPIOC_ODR=0x1<<13;		//PC13高电平
    }
    void C_LED_LIGHT(){
    	GPIOA_ODR=0x1<<4;		//PA4高电平
    	GPIOB_ODR=0x1<<9;		//PB9高电平
    	GPIOC_ODR=0x0<<13;		//PC13低电平	
    }
     
    int main(){
    	int j=100;
    	// 开启时钟
    	RCC_APB2ENR |= (1<<3); // 开启 GPIOB 时钟
    	RCC_APB2ENR |= (1<<4); // 开启 GPIOC 时钟
    	RCC_APB2ENR |= (1<<2); // 开启 GPIOA 时钟
    	
    	
    	// 设置 GPIO 为推挽输出
    	GPIOB_CRH&= 0xffffff0f;	//设置位 清零		
    	GPIOB_CRH|=0x00000020;  //PB9推挽输出
     
    	GPIOC_CRH &= 0xff0fffff; //设置位 清零		
    	GPIOC_CRH|=0x00300000;  //PC15推挽输出
     
     
    	GPIOA_CRL &= 0xfff0ffff; //设置位 清零		
    	GPIOA_CRL|=0x00010000; //PA4推挽输出
     
    	// 3个LED初始化为不亮(即高点位)
    	GPIOB_ODR |= (1<<9); 
    	GPIOC_ODR |= (1<<13); 
    	GPIOA_ODR |= (1<<4);  
    	
    	while(j){
    		
    		B_LED_LIGHT();
    		Delay_ms(2000);//单片机上2000    100
     
    		C_LED_LIGHT();
    		Delay_ms(3000);//单片机上3000    200
     
    		A_LED_LIGHT();
    		Delay_ms(3000);//单片机上3000    200
    	}
    	
    }
     
     
    void SystemInit(){
    	
    }

    效果图如下:

    LED有p13口闪烁

     

    四、Keil中的遇到的问题解决

    在使用Keil编写程序并烧录的过程中,遇到了flash download failed ‘corte-m3’的错误,在此过程中我查询了很多资料,尝试了很多的解决办法,终于找到问题所在。

    解决办法如下:

    点击魔法棒->Debug->Setting->Flash Downloed->添加合适的芯片


    总结

            初学stm32使用寄存器点亮LED虽然简单,但是需要注意很多的细节,特别要注意Keil软件的配置 不然很有可能烧录失败。

    作者:2201_75518371

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32最小系统入门教程:点亮LED灯实例【附代码】

    发表回复