【目的】
实战使用寄存器实现LED灯的交互闪烁。
【资料准备】
一个下载工程模版:【兆易创新GD32H759I-EVAL开发板】3、Keil一步一步创建模版工程
【实现步骤】
1、解压后重命名文件夹:
2、打开工程。
3、宏定义GPIO、RCU的寄存器地址:
// 定义GPIOF时钟寄存器地址  AHB4 使能寄存器(RCU_AHB4EN)偏移 0x3C
  • // RCU 基地址:0x5802 4400  
  • #define LU_RCU_AHB4EN (*(volatile uint32_t *)(uint32_t)(0x58024400+0x3C))
  •        
  • //定义GPIOA_CTL的地址:GPIOA基地址:0x5802 0000
  • #define LU_GPIOA_CTL   (*(volatile uint32_t *)(uint32_t)0x58020000)
  • #define LU_GPIOA_OMODE (*(volatile uint32_t *)(uint32_t)0x58020004)
  • #define LU_GPIOA_OSPD  (*(volatile uint32_t *)(uint32_t)0x58020008)
  • #define LU_GPIOA_OCTL  (*(volatile uint32_t *)(uint32_t)0x58020014)
  •        
  • //GPIOF基地址:0x5802 0000
  • #define LU_GPIOF_CTL   (*(volatile uint32_t *)(uint32_t)0x58021400)
  • #define LU_GPIOF_OMODE (*(volatile uint32_t *)(uint32_t)(0x58021400+0x04))
  • #define LU_GPIOF_OSPD  (*(volatile uint32_t *)(uint32_t)(0x58021400+0x08))
  • #define LU_GPIOF_OCTL  (*(volatile uint32_t *)(uint32_t)(0x58021400+0x14))
  • #define LU_GPIOF_ISTAT (*(volatile uint32_t *)(uint32_t)(0x58021400+0x10))
  • 复制代码
    4、宏定义LEDON、OFF
    //定义LED1_ON\OFF
  • #define LED1_ON     LU_GPIOF_OCTL |= (uint32_t)0x01<<10;
  • #define LED1_OFF     LU_GPIOF_OCTL &= ~((uint32_t)0x01<<10);

  • #define LED2_ON     LU_GPIOA_OCTL |= (uint32_t)0x01<<6;
  • #define LED2_OFF     LU_GPIOA_OCTL &= ~((uint32_t)0x01<<6);
  • 复制代码
    5、根据原理图LED1为PF10,LED2为PA6,初始化代码如下:
    void led_io_init(void)
  • {
  •         //使能时钟
  •         LU_RCU_AHB4EN |= (uint32_t)0x01<<5;  //使能GPIOF时钟 Led1 PF10
  •         LU_RCU_AHB4EN  |= (uint32_t)0x01<<0; //使能GPIOA时钟 Led2 PA6
  •        
  •         //配置LED1 PF10
  •         //先清除位,因为复位后该位为0b11
  •         LU_GPIOF_CTL &= ~((uint32_t)0x03 <<(10*2));
  •         LU_GPIOF_CTL |= ((uint32_t)0x01<<10*2);        //置21:20为0x01输出模式
  •         LU_GPIOF_OMODE &= ~(0x01<<10);             //输出推挽模式
  •         LU_GPIOF_OSPD &= ~((uint32_t)0x03 <<(10*2));
  •         LU_GPIOF_OSPD &= ((uint32_t)0x01 <<(10*2));    //01:输出最大速度60M
  •         //初始化输出低电平:
  •         LU_GPIOA_OCTL &= ~((uint32_t)0x01<<10);
  •        
  •                 //先清除位,因为复位后该位为0b11
  •         LU_GPIOA_CTL &= ~((uint32_t)0x03 <<(6*2));
  •         LU_GPIOA_CTL |= ((uint32_t)0x01<<6*2);        //置21:20为0x01输出模式
  •         LU_GPIOA_OMODE &= ~(0x01<<10);             //输出推挽模式
  •         LU_GPIOA_OSPD &= ~((uint32_t)0x03 <<(6*2));
  •         LU_GPIOA_OSPD &= ((uint32_t)0x01 <<(6*2));    //01:输出最大速度60M
  •         //初始化输出低电平:
  •         LU_GPIOA_OCTL &= ~((uint32_t)0x01<<6);
  •        
  • }
  • 复制代码
    编译流水灯如下
    while(1) {
  •         /* turn on LED1, turn off LED2 */
  •         LED1_ON;
  •         LED2_OFF;

  •         delay_1ms(500);
  •         
  •         /* turn on LED2 and LED1 */
  •         LED2_ON;
  •         LED1_ON;
  •         delay_1ms(500);

  •         /* turn off LED1 and LED2 */
  •         LED2_OFF;
  •         LED1_OFF;
  •         delay_1ms(500);
  •     }
  • 复制代码
    【跳线】
    由于开发板使用的IO有重用,所以需要把JP50、JP66跳到LED上才能成功演示:
    image.png
    演示视频如下: