STM32
直播中

回头太晚

10年用户 921经验值
擅长:可编程逻辑 电源/新能源
私信 关注
[问答]

STM32有六个GPIO口(不在同一组)要相同信号输出,请问怎么设置?

例如GPIOE的pin10重映射到tiM1,设置好TIM1的PWM信号输出;其他的IO口如GPIOA的pin5、GPIOA的pin6、GPIOB的pin5、GPIOB的pin6、GPIOC的pin5也要输出与GPIOE的pin10相同的信号,请问大侠怎么设置?

回帖(2)

王红

2024-4-7 16:25:53
用定时器中断吧,把PWM的脉宽配置成定时中断,把GPIO引脚都配置好,相应时钟都使能,然后到定时器中断函数中做相同的处理。
举报

贾大林

2024-4-7 17:03:42
实现这个需求可以按照以下步骤进行设置:

1. 配置TIM1为PWM输出模式:

```c
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // 使能TIM1的时钟

TIM1->PSC = 0; // 设置时钟预分频系数
TIM1->ARR = 10; // 设置自动重装载寄存器的值,决定PWM周期的长度
TIM1->CCR1 = 5; // 设置占空比,决定PWM波形的占空比

TIM1->CCMR1 &= ~TIM_CCMR1_CC1S; // 通道1设置为输出模式
TIM1->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; // 当计数值小于CCR1时PWM输出高电平,否则输出低电平
TIM1->CCER |= TIM_CCER_CC1E; // 使能通道1的输出
TIM1->BDTR |= TIM_BDTR_MOE; // 使能主输出使能
TIM1->CR1 |= TIM_CR1_CEN; // 使能TIM1
```

2. 配置GPIOE的pin10作为TIM1的重映射引脚:

```c
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // 使能系统配置的时钟

SYSCFG->PMC &= ~SYSCFG_PMC_MII_RMII_SEL; // 清除MII_RMII_SEL位
SYSCFG->PMC |= SYSCFG_PMC_MII_RMII_SEL; // 设置MII_RMII_SEL位,选择系统管脚映射控制寄存器(SYSCFG_PMC)的重映射引脚功能

GPIOE->AFR[1] &= ~(0x0F << ((10 - 8) * 4)); // 清除GPIOE的pin10位的重映射功能
GPIOE->AFR[1] |= 0x01 << ((10 - 8) * 4); // 设置GPIOE的pin10位的重映射功能为TIM1_CH1
```

3. 配置GPIOA的pin5、GPIOA的pin6、GPIOB的pin5、GPIOB的pin6、GPIOC的pin5为GPIO输出模式:

```c
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN; // 使能GPIOA、GPIOB和GPIOC的时钟

GPIOA->MODER &= ~(GPIO_MODER_MODE5 | GPIO_MODER_MODE6); // 清除GPIOA的pin5和pin6的模式位
GPIOA->MODER |= GPIO_MODER_MODE5_0 | GPIO_MODER_MODE6_0; // 设置GPIOA的pin5和pin6的模式位为输出模式
GPIOA->OTYPER &= ~(GPIO_OTYPER_OT5 | GPIO_OTYPER_OT6); // 清除GPIOA的pin5和pin6的输出类型位

GPIOB->MODER &= ~(GPIO_MODER_MODE5 | GPIO_MODER_MODE6); // 清除GPIOB的pin5和pin6的模式位
GPIOB->MODER |= GPIO_MODER_MODE5_0 | GPIO_MODER_MODE6_0; // 设置GPIOB的pin5和pin6的模式位为输出模式
GPIOB->OTYPER &= ~(GPIO_OTYPER_OT5 | GPIO_OTYPER_OT6); // 清除GPIOB的pin5和pin6的输出类型位

GPIOC->MODER &= ~GPIO_MODER_MODE5; // 清除GPIOC的pin5的模式位
GPIOC->MODER |= GPIO_MODER_MODE5_0; // 设置GPIOC的pin5的模式位为输出模式
GPIOC->OTYPER &= ~GPIO_OTYPER_OT5; // 清除GPIOC的pin5的输出类型位
```

4. 设置GPIOA的pin5、GPIOA的pin6、GPIOB的pin5、GPIOB的pin6、GPIOC的pin5与GPIOE的pin10的输出值保持一致:

```c
while (1) {
    // 读取GPIOE的pin10的值
    uint16_t value = GPIOE->IDR & GPIO_IDR_ID10;

    // 设置GPIOA的pin5、GPIOA的pin6、GPIOB的pin5、GPIOB的pin6、GPIOC的pin5的值
    if (value) {
        GPIOA->ODR |= GPIO_ODR_OD5 | GPIO_ODR_OD6;
        GPIOB->ODR |= GPIO_ODR_OD5 | GPIO_ODR_OD6;
        GPIOC->ODR |= GPIO_ODR_OD5;
    } else {
        GPIOA->ODR &= ~(GPIO_ODR_OD5 | GPIO_ODR_OD6);
        GPIOB->ODR &= ~(GPIO_ODR_OD5 | GPIO_ODR_OD6);
        GPIOC->ODR &= ~GPIO_ODR_OD5;
    }
}
```

通过以上代码设置后, GPIOA的pin5、GPIOA的pin6、GPIOB的pin5、GPIOB的pin6、GPIOC的pin5的输出信号与GPIOE的pin10的信号将保持一致。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分