GD MCU 例子分析

[复制链接]
 楼主| 过期的塔头 发表于 2020-10-27 23:15 | 显示全部楼层 |阅读模式
  1. int main(void)
  2. {   
  3.     /* configure systick */
  4.     systick_config();
  5.    
  6.     /* configure LEDs */
  7.     led_config();
  8.    
  9.     /* configure USART */
  10.     gd_eval_com_init(EVAL_COM1);

  11.     printf("I2C-24C02 configured....\n\r");
  12.    
  13.     /* configure GPIO */
  14.     gpio_config();
  15.    
  16.     /* configure I2C */
  17.     i2c_config();
  18.    
  19.     /* initialize EEPROM */
  20.     i2c_eeprom_init();

  21.     printf("\r\nThe I2C0 is hardware interface ");
  22.     printf("\r\nThe speed is %d", I2C0_SPEED);
  23.    
  24.     if(I2C_OK == i2c_24c02_test()){
  25.         while(1){
  26.            /* turn off all LEDs */
  27.            gd_eval_led_off(LED1);
  28.            gd_eval_led_off(LED2);
  29.            gd_eval_led_off(LED3);
  30.            gd_eval_led_off(LED4);
  31.            /* turn on a LED */
  32.            led_turn_on(count%4);
  33.            count++;
  34.            if(count >= 4){
  35.                count = 0;
  36.            }
  37.            delay_1ms(500);
  38.         }
  39.     }
  40.     /* turn on all LEDs */
  41.     gd_eval_led_on(LED1);
  42.     gd_eval_led_on(LED2);
  43.     gd_eval_led_on(LED3);
  44.     gd_eval_led_on(LED4);
  45.    
  46.     while(1);

  47. }


 楼主| 过期的塔头 发表于 2020-10-27 23:17 | 显示全部楼层
  1. gpio_config();
 楼主| 过期的塔头 发表于 2020-10-27 23:18 | 显示全部楼层
  1. void gpio_config(void)
  2. {
  3.     /* enable GPIOB clock */
  4.     rcu_periph_clock_enable(RCU_GPIOB);
  5.     /* enable I2C0 clock */
  6.     rcu_periph_clock_enable(RCU_I2C0);

  7.     /* connect PB6 to I2C0_SCL */
  8.     gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_6);
  9.     /* connect PB7 to I2C0_SDA */
  10.     gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_7);
  11.     /* configure GPIO pins of I2C0 */
  12.     gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_6);
  13.     gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_6);
  14.     gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_7);
  15.     gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_7);
  16. }
 楼主| 过期的塔头 发表于 2020-10-27 23:19 | 显示全部楼层
  1. void rcu_periph_clock_enable(rcu_periph_enum periph)
  2. {
  3.     RCU_REG_VAL(periph) |= BIT(RCU_BIT_POS(periph));
  4. }
 楼主| 过期的塔头 发表于 2020-10-27 23:19 | 显示全部楼层
涉及到三个部分,1是 RCU_REG_VAL(periph),2是 BIT(RCU_BIT_POS(periph)),3是 参数 periph
 楼主| 过期的塔头 发表于 2020-10-27 23:20 | 显示全部楼层
下面第一部分RCU_REG_VAL
 楼主| 过期的塔头 发表于 2020-10-27 23:22 | 显示全部楼层
  1. #define RCU_REG_VAL(periph) (REG32(RCU + ((uint32_t)(periph)>>6)))
 楼主| 过期的塔头 发表于 2020-10-27 23:25 | 显示全部楼层
/* bit operations */ #define REG32(addr) (*(volatile uint32_t *)(uint32_t)(addr))
 楼主| 过期的塔头 发表于 2020-10-27 23:26 | 显示全部楼层
  1. /* bit operations */ #define REG32(addr) (*(volatile uint32_t *)(uint32_t)(addr))
 楼主| 过期的塔头 发表于 2020-10-27 23:27 | 显示全部楼层
  1. /* RCU definitions */ #define RCU RCU_BASE
 楼主| 过期的塔头 发表于 2020-10-27 23:29 | 显示全部楼层
  1. #define RCU_BASE (AHB1_BUS_BASE + 0x00001000U) /*!< RCU base address */
 楼主| 过期的塔头 发表于 2020-10-27 23:29 | 显示全部楼层
  1. #define AHB1_BUS_BASE ((uint32_t)0x40020000U) /*!< ahb1 base address */
 楼主| 过期的塔头 发表于 2020-10-27 23:32 | 显示全部楼层
 楼主| 过期的塔头 发表于 2020-10-27 23:33 | 显示全部楼层
从Memory map中可以看到,AHB1_BUS_BASE的内存地址定义为了0x4002 0000,也合SEPC中介绍的一致;
 楼主| 过期的塔头 发表于 2020-10-27 23:35 | 显示全部楼层
RUC的内存地址是RCU_BASE 也和SPEC上写的0x4002 1000对应

这里说一下,GD厂商给的SPEC中memory map是用内存地址来映射到硬件地址,

ARM是统一编址的,也就是外设和内存进行统一的编址,共同形成了4G物理地址空间(32位为例子)。
 楼主| 过期的塔头 发表于 2020-10-27 23:36 | 显示全部楼层
大家知道操作外设时,实际上操作的是读写设备相关的寄存器,这些与外设相关的寄存器与不同操作模式下R0-R15那些寄存器是不同的,这些寄存器并不是所谓的物理上的寄存器,实际上是所谓的IO端口,通常会有控制、状态、数据的分类。他们被连续地编址,对于其编址的方式有两种一种是IO映射、一种是内存映射。IO映射是对x86为例的复杂指令集来说的,需要专门的IO控制指令,不详谈。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

85

主题

999

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部