社区导航

 

搜索
查看: 1259|回复: 4

[原创] [原创] 新驱动力MM32F031开发板评测3:发现和修正MM32F031库中的bug

[复制链接]

231

TA的帖子

1

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2018-10-18 10:10 | 显示全部楼层 |阅读模式
本帖最后由 我爱下载 于 2018-10-18 16:30 编辑

库函数bug更改——
GPIO_PinAFConfig()


在调试PWM输出函数过程中,发现一处MM32F031库函数的bug。样例代码库中TIM3_PWM_OUTPUT例程中使用的代码如下:

//PWM输出初始化

//arr:自动重装值

//psc:时钟预分频数

void TIM3_PWM_Init(u16 arr,u16 psc)

{  

    GPIO_InitTypeDef GPIO_InitStructure;

    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

    TIM_OCInitTypeDef  TIM_OCInitStructure;

   

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

   

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);  //¿ªÆôGPIOBʱÖÓ

   

    //SYSCFG->CFGR|=0x1<<11;

   GPIOB->AFRL=0x10000;   //大家注意这条为寄存器操作方式

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //TIM3_CH1

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //¸´ÓÃÍÆÍìÊä³ö

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOB, &GPIO_InitStructure);

   。。。 。。。

   
}

这里大家注意到

GPIOB->AFRL = 0x10000;这行代码采用了寄存器操作方式,而不是函数库操作方式,感觉非常不协调,于是我改成HAL_gpio库中提供的函数

void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)

经过测试,使用GPIO_PinAFConfig()函数后,PWM的输出就消失了。如下为源库文件中函数代码:

/**

注释省略

*/

void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)

{

    uint32_t temp = 0x00;

    uint32_t temp_2 = 0x00;

   

    /* Check the parameters */

    assert_param(IS_GPIO_ALL_PERIPH(GPIOx));

    assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));

    assert_param(IS_GPIO_AF(GPIO_AF));

      

    temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4));

    if((GPIO_PinSource >> 0x03) ==0)

    {

        GPIOx->AFRL &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4));

        temp_2 = GPIOx->AFRL | temp;

        GPIOx->AFRL = temp_2;

    }

    else

    {

        GPIOx->AFRH &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4));

        temp_2 = GPIOx->AFRH | temp;

        GPIOx->AFRH = temp_2;

    }

}

对照MM32F031的手册中的相关说明,AFRL和AFRH两个寄存器分别负责IO引脚序号为0-7和8-15的IO转换功能的配置,因此上述代码存在如下几处问题。
1、 ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4));该语句用于生成掩码时错误的。

2temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)); 该语句用于生成统一的IO引脚号0-15的或码也是错误的。

鉴于上述问题,我修改的代码如下两种:

修改如下

void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)
{

    uint32_t temp = 0x00;
    uint32_t temp_2 = 0x00;
   

    /* Check the parameters */

    assert_param(IS_GPIO_ALL_PERIPH(GPIOx));

    assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));

    assert_param(IS_GPIO_AF(GPIO_AF));

//    temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4));

    if((GPIO_PinNum >> 0x03) ==0)
    {
//        GPIOx->AFRL &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4));
         temp = ((uint32_t)(GPIO_AF) << ((uint32_t)GPIO_PinSource * 4));
        GPIOx->AFRL &= ~((uint32_t)0xF<< ((uint32_t)GPIO_PinSource * 4));
        temp_2 = GPIOx->AFRL | temp;
        GPIOx->AFRL = temp_2;

    }
    else
    {
//        GPIOx->AFRH &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4));
              temp = ((uint32_t)(GPIO_AF) << ((uint32_t)(GPIO_PinSource-8) * 4));
        GPIOx->AFRH &= ~((uint32_t)0xF<< ((uint32_t)(GPIO_PinSource-8) * 4));
        temp_2 = GPIOx->AFRH | temp;
        GPIOx->AFRH = temp_2;
    }

}



经过测试,修改后代码是有效的。



此内容由EEWORLD论坛网友我爱下载原创,如需转载或用于商业用途需征得作者同意并注明出处



回复

使用道具 举报

231

TA的帖子

1

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2018-10-18 16:27 | 显示全部楼层
本帖最后由 我爱下载 于 2018-10-18 16:28 编辑

之前由于没有充分理解库函数中GPIO_PinAFConfig的使用方法,因此将GPIO_PinSource的使用方法理解错误了,导致分析的一部分是有问题,已经将错误部分删除,但是剩下的部分我认为依然存在问题,因此保留了,希望大家批评指正。


回复

使用道具 举报

159

TA的帖子

0

TA的资源

版主

Rank: 6Rank: 6

发表于 2018-10-18 23:38 | 显示全部楼层
感谢支持

欢迎大家来到电机驱动控制技术天地,一起在EEworld交流、学习。



回复

使用道具 举报

5

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2019-10-18 14:06 | 显示全部楼层

楼主,其实你修改之后的代码和官方库函数中GPIO_PinAFConfig的代码就是·同一个意思啊



回复

使用道具 举报

5

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2019-10-18 14:07 | 显示全部楼层

我测试过了,操作官方的库函数中GPIO_PinAFConfig和直接操作寄存器都可以实现PWM输出哦

 



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

关闭

站长推荐上一条 1/4 下一条

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

Archiver|手机版|小黑屋|电子工程世界 ( 京ICP证 060456 )

GMT+8, 2020-4-6 17:40 , Processed in 0.184418 second(s), 18 queries , Gzip On, MemCache On.

快速回复 返回顶部 返回列表