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

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

  5.         delay_1ms(500);
  6.         
  7.         /* turn on LED2 and LED1 */
  8.         LED2_ON;
  9.         LED1_ON;
  10.         delay_1ms(500);

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