GPIO 输出寄存器位值未更新
GPIO Output Register Bit value not updating
我刚开始学习嵌入式系统,在我的 stm32f746ng-discovery 板上正确设置 LED 引脚时遇到了一些麻烦。我不确定我是否没有正确进行类型转换或引脚地址错误但是,我相信我已经正确解决了所有问题并且我没有看到手表中 GPIO 输出数据寄存器的值发生变化 window 这让我相信我的代码可能存在问题。
要定义寄存器及其各自的地址,这是我采用的方法:
//Referring to STM32F746xx Memory Map and Register Boundary Addresses:
#define PERIPH_BASE (0x40000000UL)
#define AHB1PERIPH_OFFSET (0x00020000UL)
#define AHB1PERIPH_BASE (PERIPH_BASE + AHB1PERIPH_OFFSET)
#define GPIOI_OFFSET (0x2000UL)
#define GPIOI_BASE (AHB1PERIPH_BASE + GPIOI_OFFSET)
#define RCC_OFFSET (0x3800UL)
#define RCC_BASE (AHB1PERIPH_BASE + RCC_OFFSET)
#define RCC_AHB1EN_R_OFFSET (0x30UL)
#define RCC_AHB1EN_R (*(volatile unsigned int *)(RCC_BASE + RCC_AHB1EN_R_OFFSET)) //register
#define MODE_R_OFFSET (0x00UL)
#define GPIOI_MODE_R (*(volatile unsigned int *)(GPIOI_BASE + MODE_R_OFFSET)) //register
#define OD_R_OFFSET (0x14UL)
#define GPIOI_OD_R (*(volatile unsigned int *)(GPIOI_BASE + OD_R_OFFSET)) //register
#define GPIOIEN (1U << 0)
#define PIN_1 (1U << 1)
#define LED_PIN PIN_1
以上十六进制地址我从stm32f746xx数据表的内存中找到map/table和stm32f74xxx的RM0385参考手册
下面的代码是我尝试更改 GPIOI_OD_R 寄存器的位值的主要函数:
int main(void)
{
/* 1. Enable clock access for GPIOI.*/
/* 1.1 I use the OR operator to only change the first bit instead of the whole 32bit chain. */
RCC_AHB1EN_R |= GPIOIEN;
/* 2. Sets PIN_1 as output.*/
GPIOI_MODE_R |= (1U << 2);
GPIOI_MODE_R &=~(1U << 3);
while(1)
{
/* 3. Sets PIN_1 high */
GPIOI_OD_R |= LED_PIN;
}
}
我遇到的问题是 GPIOI_OD_R 寄存器的位值没有正确更新并设置为 00 而不是 01,这是 GPIOI Pin_1 所需的值( LED)设置为通用输出模式。
以上参数是我从stm32f74xxx的RM0385参考手册中得到的,如下图所示:
然而,当 运行 代码时 GPIOI_MODE_R 和 GPIOI_OD_R 位值不会改变,如下图所示:
我需要正确的寄存器值才能将我的 stm32f746ng-discovery 板上的 LED PIN 设置为高电平。
我尝试将 GPIOI_MODE_R 设置操作合并为一个操作:GPIOI_MODE_R = (GPIOI_MODE_R | (1U << 2)) & ~(1U << 3)
但是这会导致程序与调试器失去连接。
我正在使用具有以下 MCU GCC 编译器设置的 STM32CubeIDE:
提前致谢,如果引用不正确,请原谅我是嵌入式系统的新手。
我发现了问题并意识到我正在为 GPIOIEN 寻址错误的位值。我没有使用:#define GPIOIEN (1U << 8)
查看 GPIOIEN 的位地址,而是错误地使用:#define GPIOIEN (1U << 0)
查看 GPIOAEN 的位地址。
我这边犯了一个超级愚蠢的错误,但我认为像我这样的许多初学者可能会犯这个错误。根据我的经验和解决问题的过程,我能给出的唯一建议是在阅读各种板的参考手册和数据表时尝试更加准确和适当地集中注意力。在解决问题时,我会说与您的代码保持一致很重要,这使得调试过程更容易,因为我遵循了这种方法,我能够跟踪代码的每个 srep 并比较我期望的值与我实际得到的相比。
我附在下面的最终代码解决方案:
//Referring to STM32F746xx Memory Map and Register Boundary Addresses:
#define PERIPH_BASE (0x40000000UL)
#define AHB1PERIPH_OFFSET (0x00020000UL)
#define AHB1PERIPH_BASE (PERIPH_BASE + AHB1PERIPH_OFFSET)
#define GPIOI_OFFSET (0x2000UL)
#define GPIOI_BASE (AHB1PERIPH_BASE + GPIOI_OFFSET)
#define RCC_OFFSET (0x3800UL)
#define RCC_BASE (AHB1PERIPH_BASE + RCC_OFFSET)
#define RCC_AHB1EN_R_OFFSET (0x30UL)
#define RCC_AHB1EN_R (*(volatile unsigned int *)(RCC_BASE + RCC_AHB1EN_R_OFFSET))
#define MODE_R_OFFSET (0x00UL)
#define GPIOI_MODE_R (*(volatile unsigned int *)(GPIOI_BASE + MODE_R_OFFSET))
#define OD_R_OFFSET (0x14UL)
#define GPIOI_OD_R (*(volatile unsigned int *)(GPIOI_BASE + OD_R_OFFSET))
#define GPIOIEN (1U << 8) // updated from (1U << 0)
#define PIN_1 (1U << 1)
#define LED_PIN PIN_1
int main(void)
{
/* 1. Enable clock access for GPIOI.*/
/* 1.1 I use the OR operator to only change the first bit instead of the whole 32bit chain. */
RCC_AHB1EN_R |= GPIOIEN;
/* 2. Sets PIN_1 as output.*/
GPIOI_MODE_R |= (1U << 2);
GPIOI_MODE_R &=~(1U << 3);
while(1)
{
/* 3. Sets PIN_1 high */
GPIOI_OD_R |= LED_PIN;
}
}
我刚开始学习嵌入式系统,在我的 stm32f746ng-discovery 板上正确设置 LED 引脚时遇到了一些麻烦。我不确定我是否没有正确进行类型转换或引脚地址错误但是,我相信我已经正确解决了所有问题并且我没有看到手表中 GPIO 输出数据寄存器的值发生变化 window 这让我相信我的代码可能存在问题。
要定义寄存器及其各自的地址,这是我采用的方法:
//Referring to STM32F746xx Memory Map and Register Boundary Addresses:
#define PERIPH_BASE (0x40000000UL)
#define AHB1PERIPH_OFFSET (0x00020000UL)
#define AHB1PERIPH_BASE (PERIPH_BASE + AHB1PERIPH_OFFSET)
#define GPIOI_OFFSET (0x2000UL)
#define GPIOI_BASE (AHB1PERIPH_BASE + GPIOI_OFFSET)
#define RCC_OFFSET (0x3800UL)
#define RCC_BASE (AHB1PERIPH_BASE + RCC_OFFSET)
#define RCC_AHB1EN_R_OFFSET (0x30UL)
#define RCC_AHB1EN_R (*(volatile unsigned int *)(RCC_BASE + RCC_AHB1EN_R_OFFSET)) //register
#define MODE_R_OFFSET (0x00UL)
#define GPIOI_MODE_R (*(volatile unsigned int *)(GPIOI_BASE + MODE_R_OFFSET)) //register
#define OD_R_OFFSET (0x14UL)
#define GPIOI_OD_R (*(volatile unsigned int *)(GPIOI_BASE + OD_R_OFFSET)) //register
#define GPIOIEN (1U << 0)
#define PIN_1 (1U << 1)
#define LED_PIN PIN_1
以上十六进制地址我从stm32f746xx数据表的内存中找到map/table和stm32f74xxx的RM0385参考手册
下面的代码是我尝试更改 GPIOI_OD_R 寄存器的位值的主要函数:
int main(void)
{
/* 1. Enable clock access for GPIOI.*/
/* 1.1 I use the OR operator to only change the first bit instead of the whole 32bit chain. */
RCC_AHB1EN_R |= GPIOIEN;
/* 2. Sets PIN_1 as output.*/
GPIOI_MODE_R |= (1U << 2);
GPIOI_MODE_R &=~(1U << 3);
while(1)
{
/* 3. Sets PIN_1 high */
GPIOI_OD_R |= LED_PIN;
}
}
我遇到的问题是 GPIOI_OD_R 寄存器的位值没有正确更新并设置为 00 而不是 01,这是 GPIOI Pin_1 所需的值( LED)设置为通用输出模式。
以上参数是我从stm32f74xxx的RM0385参考手册中得到的,如下图所示:
然而,当 运行 代码时 GPIOI_MODE_R 和 GPIOI_OD_R 位值不会改变,如下图所示:
我需要正确的寄存器值才能将我的 stm32f746ng-discovery 板上的 LED PIN 设置为高电平。
我尝试将 GPIOI_MODE_R 设置操作合并为一个操作:GPIOI_MODE_R = (GPIOI_MODE_R | (1U << 2)) & ~(1U << 3)
但是这会导致程序与调试器失去连接。
我正在使用具有以下 MCU GCC 编译器设置的 STM32CubeIDE:
提前致谢,如果引用不正确,请原谅我是嵌入式系统的新手。
我发现了问题并意识到我正在为 GPIOIEN 寻址错误的位值。我没有使用:#define GPIOIEN (1U << 8)
查看 GPIOIEN 的位地址,而是错误地使用:#define GPIOIEN (1U << 0)
查看 GPIOAEN 的位地址。
我这边犯了一个超级愚蠢的错误,但我认为像我这样的许多初学者可能会犯这个错误。根据我的经验和解决问题的过程,我能给出的唯一建议是在阅读各种板的参考手册和数据表时尝试更加准确和适当地集中注意力。在解决问题时,我会说与您的代码保持一致很重要,这使得调试过程更容易,因为我遵循了这种方法,我能够跟踪代码的每个 srep 并比较我期望的值与我实际得到的相比。
我附在下面的最终代码解决方案:
//Referring to STM32F746xx Memory Map and Register Boundary Addresses:
#define PERIPH_BASE (0x40000000UL)
#define AHB1PERIPH_OFFSET (0x00020000UL)
#define AHB1PERIPH_BASE (PERIPH_BASE + AHB1PERIPH_OFFSET)
#define GPIOI_OFFSET (0x2000UL)
#define GPIOI_BASE (AHB1PERIPH_BASE + GPIOI_OFFSET)
#define RCC_OFFSET (0x3800UL)
#define RCC_BASE (AHB1PERIPH_BASE + RCC_OFFSET)
#define RCC_AHB1EN_R_OFFSET (0x30UL)
#define RCC_AHB1EN_R (*(volatile unsigned int *)(RCC_BASE + RCC_AHB1EN_R_OFFSET))
#define MODE_R_OFFSET (0x00UL)
#define GPIOI_MODE_R (*(volatile unsigned int *)(GPIOI_BASE + MODE_R_OFFSET))
#define OD_R_OFFSET (0x14UL)
#define GPIOI_OD_R (*(volatile unsigned int *)(GPIOI_BASE + OD_R_OFFSET))
#define GPIOIEN (1U << 8) // updated from (1U << 0)
#define PIN_1 (1U << 1)
#define LED_PIN PIN_1
int main(void)
{
/* 1. Enable clock access for GPIOI.*/
/* 1.1 I use the OR operator to only change the first bit instead of the whole 32bit chain. */
RCC_AHB1EN_R |= GPIOIEN;
/* 2. Sets PIN_1 as output.*/
GPIOI_MODE_R |= (1U << 2);
GPIOI_MODE_R &=~(1U << 3);
while(1)
{
/* 3. Sets PIN_1 high */
GPIOI_OD_R |= LED_PIN;
}
}