最近在做蓝桥杯往届试题,遇到了要求利用串口2接收数据,还需要使用PA1,PA2输出PWM信号,但是USART2的TXD和PWM的PA2脚是同一个引脚,导致按照正常初始化步骤运行,会发现串口可以正常使用,PA1可以正常输出PWM,但是PA2始终是高电平,无法输出PWM。
现解决方案有两种:
1.分时复用
顾名思义,分时复用就是分时间段来使用,自我们这里也就是用一会串口,用一会PWM,来回切换。
#define PWM_ENABLE 1
#define UART_ENABLE 2
void PWM_UART_Enable(u8 flag)
{
if(flag==PWM_ENABLE)
{
USART_Cmd(USART2, DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_Cmd(TIM2, ENABLE);
}
if(flag==UART_ENABLE)
{
TIM_Cmd(TIM2, DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
USART_Cmd(USART2, ENABLE);
}
}
这里通过调用PWM_UART_Enable函数实现串口和定时器的时钟失能、使能,来让串口和PWM分别工作,因为PWM不需要一直开着的所以可以这样切换,但是也有缺点,那就是PA2在做PWM输出时串口无法使用。
2.软件模拟PWM
因为我们只需要使用串口接收的功能,所以只需要把PA2初始化为推挽输出,在定时器里面改变该引脚的电平即可实现PWM功能,同时也不会影响到串口的接收功能,但是如果还需要串口的发送功能,那还是用方法一吧,应该不会有这样奇怪的要求吧 :)
//PA2初始化为推挽输出
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//中断服务函数 频率和定时器配置有关
time++;
if(time》=100) time=0;
if(time《=50) //占空比%50,可改
GPIO_SetBits(GPIOA,GPIO_Pin_2);
else
GPIO_ResetBits(GPIOA,GPIO_Pin_2);
如有错误欢迎指正,如果你们有更好的方案也可以在评论告诉我
最近在做蓝桥杯往届试题,遇到了要求利用串口2接收数据,还需要使用PA1,PA2输出PWM信号,但是USART2的TXD和PWM的PA2脚是同一个引脚,导致按照正常初始化步骤运行,会发现串口可以正常使用,PA1可以正常输出PWM,但是PA2始终是高电平,无法输出PWM。
现解决方案有两种:
1.分时复用
顾名思义,分时复用就是分时间段来使用,自我们这里也就是用一会串口,用一会PWM,来回切换。
#define PWM_ENABLE 1
#define UART_ENABLE 2
void PWM_UART_Enable(u8 flag)
{
if(flag==PWM_ENABLE)
{
USART_Cmd(USART2, DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_Cmd(TIM2, ENABLE);
}
if(flag==UART_ENABLE)
{
TIM_Cmd(TIM2, DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
USART_Cmd(USART2, ENABLE);
}
}
这里通过调用PWM_UART_Enable函数实现串口和定时器的时钟失能、使能,来让串口和PWM分别工作,因为PWM不需要一直开着的所以可以这样切换,但是也有缺点,那就是PA2在做PWM输出时串口无法使用。
2.软件模拟PWM
因为我们只需要使用串口接收的功能,所以只需要把PA2初始化为推挽输出,在定时器里面改变该引脚的电平即可实现PWM功能,同时也不会影响到串口的接收功能,但是如果还需要串口的发送功能,那还是用方法一吧,应该不会有这样奇怪的要求吧 :)
//PA2初始化为推挽输出
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//中断服务函数 频率和定时器配置有关
time++;
if(time》=100) time=0;
if(time《=50) //占空比%50,可改
GPIO_SetBits(GPIOA,GPIO_Pin_2);
else
GPIO_ResetBits(GPIOA,GPIO_Pin_2);
如有错误欢迎指正,如果你们有更好的方案也可以在评论告诉我
举报