3088|4

336

帖子

2

TA的资源

纯净的硅(初级)

楼主
 

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

本帖最后由 我爱下载 于 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论坛网友我爱下载原创,如需转载或用于商业用途需征得作者同意并注明出处

最新回复

我测试过了,操作官方的库函数中GPIO_PinAFConfig和直接操作寄存器都可以实现PWM输出哦     详情 回复 发表于 2019-10-18 14:07
点赞 关注(1)
 
 

回复
举报

336

帖子

2

TA的资源

纯净的硅(初级)

沙发
 
本帖最后由 我爱下载 于 2018-10-18 16:28 编辑

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

回复

152

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
个人签名

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

 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(初级)

4
 

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

 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(初级)

5
 

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

 

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表