打印
[STM32H7]

【STM32H745I-DISCO 试用】+GPIO及使用方法学习

[复制链接]
677|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 jinglixixi 于 2025-3-17 22:35 编辑

上一次完成了基础性的测试工作,实现2个LED的按键控制。
开始还以为这样的例程很简单也很基础,在仔细看过程序之后就认识到其实并非看失去的那样平常。
下面就看一下,M4与M7的主程序。
M7的主程序为:
int main(void)
{
MPU_Config();
CPU_CACHE_Enable();
HAL_Init();
SystemClock_Config();
__HAL_RCC_HSEM_CLK_ENABLE();
HAL_HSEM_FastTake(HSEM_ID_0);
HAL_HSEM_Release(HSEM_ID_0,0);
BSP_LED_Init(LED1);
EXTI15_10_IRQHandler_Config();
while (1)
{
}
}

M4的主程序为:
int main(void)
{
__HAL_RCC_HSEM_CLK_ENABLE();
HAL_HSEM_ActivateNotification(__HAL_HSEM_SEMID_TO_MASK(HSEM_ID_0));
HAL_PWREx_ClearPendingEvent();
HAL_PWREx_EnterSTOPMode(PWR_MAINREGULATOR_ON,PWR_STOPENTRY_WFE, PWR_D2_DOMAIN);
__HAL_HSEM_CLEAR_FLAG(__HAL_HSEM_SEMID_TO_MASK(HSEM_ID_0));
HAL_Init();
BSP_LED_Init(LED2);
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
while (1)
{
}
}

发现没有,2个LED是分别存在2个不同的内核程序上运行,且在同一个按键控制下同步进行状态的切换,这就绝非是在单核的情况下,一个按控制2个LED处理场景,它是在双核下实现的一种触发同步处理呀!
所以说,它绝非是表面看上去是按键控制LED,在其背后却是双核控制下的同步机制。
由图1可知,LED1和LED2所连接的引脚分别为PJ2和PI13,这从程序中的定义也可得到印证。
#define LED1_GPIO_PORT                   GPIOJ
#define LED1_PIN                         GPIO_PIN_2
#define LED2_GPIO_PORT                   GPIOI
#define LED2_PIN                         GPIO_PIN_13


图1  LED电路
那在H745I中是如何来配置引脚输出功能呢?
这从LED的初始化函数中可以获得,其内容为:
int32_t BSP_LED_Init(Led_TypeDef Led)
{
int32_t ret = BSP_ERROR_NONE;
GPIO_InitTypeDef gpio_init_structure;
/* Enable the GPIO_LED clock */
if (Led == LED1)
{
LED1_GPIO_CLK_ENABLE() ;
}
else if (Led == LED2)
{
LED2_GPIO_CLK_ENABLE() ;
}
else
{
ret = BSP_ERROR_WRONG_PARAM;
}
/* configure the GPIO_LED pin */
gpio_init_structure.Pin = LED_PIN [Led];
gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP;
gpio_init_structure.Pull = GPIO_PULLUP;
gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(LED_PORT [Led], &gpio_init_structure);
/* By default, turn off LED */
HAL_GPIO_WritePin(LED_PORT [Led], (uint16_t)LED_PIN [Led], GPIO_PIN_SET);
return ret;
}

而对于高低电平的输出,从可从LED状态的控制函数来得到,其控制函数的内容分别为:
int32_t BSP_LED_On(Led_TypeDef Led)
{
int32_t ret = BSP_ERROR_NONE;
HAL_GPIO_WritePin(LED_PORT [Led], (uint16_t)LED_PIN [Led], GPIO_PIN_RESET);
return ret;
}


由图2可知,蓝色按键所连接的引脚为PC13,这由从程序中的定义也可得到印证。
#define BUTTON_USER_PIN                   GPIO_PIN_13
#define BUTTON_USER_GPIO_PORT             GPIOC

图2 按键电路
那在H745I中又是如何来配置引脚输入功能的呢?
这从按键的初始化函数中可以获得,其内容为:
int32_t BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode)
{
GPIO_InitTypeDef gpio_init_structure;
static BSP_EXTI_LineCallback ButtonCallback[BUTTONn] = {BUTTON_USER_EXTI_Callback};
static uint32_t BSP_BUTTON_PRIO [BUTTONn] = {BSP_BUTTON_USER_IT_PRIORITY};
static const uint32_t BUTTON_EXTI_LINE[BUTTONn] = {BUTTON_USER_EXTI_LINE};
/* Enable the BUTTON clock*/
BUTTON_USER_GPIO_CLK_ENABLE();
gpio_init_structure.Pin = BUTTON_PIN [Button];
gpio_init_structure.Pull = GPIO_PULLDOWN;
gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH;
if (ButtonMode == BUTTON_MODE_GPIO)
{
/* Configure Button pin as input */
gpio_init_structure.Mode = GPIO_MODE_INPUT;
HAL_GPIO_Init(BUTTON_PORT [Button], &gpio_init_structure);
}
else /* (ButtonMode == BUTTON_MODE_EXTI) */
{
/* Configure Button pin as input with External interrupt */
gpio_init_structure.Mode = GPIO_MODE_IT_RISING;
HAL_GPIO_Init(BUTTON_PORT[Button], &gpio_init_structure);
(void)HAL_EXTI_GetHandle(&hpb_exti[Button], BUTTON_EXTI_LINE[Button]);
(void)HAL_EXTI_RegisterCallback(&hpb_exti[Button], HAL_EXTI_COMMON_CB_ID, ButtonCallback[Button]);
/* Enable and set Button EXTI Interrupt to the lowest priority */
HAL_NVIC_SetPriority((BUTTON_IRQn[Button]), BSP_BUTTON_PRIO[Button], 0x00);
HAL_NVIC_EnableIRQ((BUTTON_IRQn[Button]));
}
return BSP_ERROR_NONE;
}

要读取引脚的电平高低,则可从按键的状态读取函数来获得,其内容为:
int32_t BSP_PB_GetState(Button_TypeDef Button)
{
return (int32_t)HAL_GPIO_ReadPin(BUTTON_PORT[Button], BUTTON_PIN[Button]);
}

下面我们再把问题转回到双核同步响应的机制上,它是以按键来触发中断处理机制,然后在不同的内核中以2个中断响应来实现的。
对中断事件的响应处理,是在M7内核配置的,其函数为:
static void EXTI15_10_IRQHandler_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOC clock */
__HAL_RCC_GPIOC_CLK_ENABLE();
/* Configure PC.13 pin as the EXTI input event line in interrupt mode for both CPU1 and CPU2*/
GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING; /* current CPU (CM7) config in IT rising */
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Pin = GPIO_PIN_13;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Enable and set EXTI lines 15 to 10 Interrupt to the lowest priority */
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
/* Configure the second CPU (CM4) EXTI line for IT*/
HAL_EXTI_D2_EventInputConfig(EXTI_LINE13 , EXTI_MODE_IT, ENABLE);
}

在M4内核的响应处理函数为:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == GPIO_PIN_13)
{
/* Toggle LED2 */
BSP_LED_Toggle(LED2);
}
}

在M7内核的响应处理函数为:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == GPIO_PIN_13)
{
/* Toggle LED1 */
BSP_LED_Toggle(LED1);
}
}

这样,就通过一个中断事件在2个内核上实现了同步的响应机制,也我们提供了一个良好应用示例。

使用特权

评论回复
沙发
yangjiaxu| | 2025-4-9 14:39 | 只看该作者
其实 要是使用cubemx来弄应该会有一个更好的开发体验,哈哈

使用特权

评论回复
板凳
jinglixixi|  楼主 | 2025-4-9 19:01 | 只看该作者
yangjiaxu 发表于 2025-4-9 14:39
其实 要是使用cubemx来弄应该会有一个更好的开发体验,哈哈

说的对!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

482

主题

2851

帖子

38

粉丝