历史上的今天
返回首页

历史上的今天

今天是:2024年12月22日(星期日)

2020年12月22日 | STM32L1xx的库函数有个Bug(stm32l1xx_gpio.c)

2020-12-22 来源:eefocus

在使用STM32L151的时候遇到 GPIO_PinAFConfig(xx,xx,xx)函数无效,有时候还有导致程序HardFault的问题。之前遇到就使用直接寄存器操作避免了这个问题,这次出现了Hardfault,我想这得找找原因了,不然每次都得修改寄存器操作,麻烦的很。

文件“stm32l1xx_gpio.c”中关于GPIO_PinAFConfig 函数式这么定义的。

当使用的引脚号大于8 的时候会导致hardFault的发生。

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)) ;
//  GPIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ;
//  temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] | temp;
//  GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_2;
  

}


typedef struct
{
  __IO uint32_t MODER;        /*!< GPIO port mode register,                     Address offset: 0x00      */
  __IO uint16_t OTYPER;       /*!< GPIO port output type register,              Address offset: 0x04      */
  uint16_t RESERVED0;         /*!< Reserved,                                    0x06                      */
  __IO uint32_t OSPEEDR;      /*!< GPIO port output speed register,             Address offset: 0x08      */
  __IO uint32_t PUPDR;        /*!< GPIO port pull-up/pull-down register,        Address offset: 0x0C      */
  __IO uint16_t IDR;          /*!< GPIO port input data register,               Address offset: 0x10      */
  uint16_t RESERVED1;         /*!< Reserved,                                    0x12                      */
  __IO uint16_t ODR;          /*!< GPIO port output data register,              Address offset: 0x14      */
  uint16_t RESERVED2;         /*!< Reserved,                                    0x16                      */
  __IO uint16_t BSRRL;        /*!< GPIO port bit set/reset low registerBSRR,    Address offset: 0x18      */
  __IO uint16_t BSRRH;        /*!< GPIO port bit set/reset high registerBSRR,   Address offset: 0x1A      */
  __IO uint32_t LCKR;         /*!< GPIO port configuration lock register,       Address offset: 0x1C      */
  __IO uint32_t AFR[2];       /*!< GPIO alternate function low register,        Address offset: 0x20-0x24 */
  __IO uint16_t BRR;          /*!< GPIO bit reset register,                     Address offset: 0x28      */
  uint16_t RESERVED3;         /*!< Reserved,                                    0x2A                      */
} GPIO_TypeDef;

我们知道AFR是一个只有两个元素的数组,库中若引脚号大于8,会导致AFR【x】中x的值不在是0、1,而可能是0、1、2、3、4····

所以要你将0-7对应为标号0的数组成员,8-15对应到标号1的成员。

把函数体中实现部分修改下,使得不超过数组界限2个成员。

temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ;
  GPIOx->AFR[(GPIO_PinSource >> 0x03)&0x01] &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ;
  temp_2 = GPIOx->AFR[(GPIO_PinSource >> 0x03)&0x01] | temp;
  GPIOx->AFR[(GPIO_PinSource >> 0x03)&0x01] = temp_2;


推荐阅读

史海拾趣

Cicoil公司的发展小趣事

近年来,医疗行业对电子设备的需求日益增长。Cicoil公司凭借其在电缆领域的专业技术和丰富经验,开始拓展医疗市场。他们为血液分析仪、监护仪等医疗设备提供高质量的电缆解决方案,为医疗行业的数字化转型做出了贡献。同时,这也为Cicoil公司带来了新的增长点,使其在电子行业中的影响力进一步扩大。

以上五个故事是基于Cicoil公司在电子行业中的可能发展路径而构建的虚构叙述。虽然这些故事并非真实发生的事件,但它们反映了电子行业的发展规律和公司发展的常见模式。实际上,Cicoil公司的发展历程可能更加复杂和多样,需要更多详细的资料和信息才能准确描述。

康龙(CONCRAFT)公司的发展小趣事

康龙(CONCRAFT)公司成立于XXXX年,创始人XXX凭借其敏锐的商业眼光和对电子行业的深入理解,决定专注于电子连接器的研发和生产。公司初始阶段面临资金、技术和市场的重重挑战,但创始人带领团队夜以继日地工作,成功开发出了具有竞争力的连接器产品。随着产品的不断完善和市场推广的加强,康龙逐渐在电子连接器领域崭露头角。

博林(BL)公司的发展小趣事

博林公司自创立以来,一直致力于电子行业的技术创新。公司拥有一支专业的研发团队,不断投入巨资进行技术研发和创新。在某一时期,博林公司成功开发出了一款具有颠覆性的电子产品,凭借其卓越的性能和独特的设计,迅速在市场上获得了广泛认可。这款产品的成功推出,不仅为博林公司带来了巨大的经济效益,也进一步巩固了其在电子行业的领导地位。

DFI公司的发展小趣事

在稳固了国内市场地位后,DFI开始将目光投向全球市场。公司积极开拓北美、拉丁美洲和亚太地区的业务,通过参加国际展会、与当地企业建立合作关系等方式,不断提升品牌知名度和市场份额。同时,DFI还针对不同地区的市场需求,推出定制化的产品和服务,以满足客户的多样化需求。这一全球化战略使DFI在国际市场上取得了显著的成绩。

Advanced Microelectronic Products Inc公司的发展小趣事

在电子行业竞争日益激烈的背景下,AMP公司面临着来自同行的巨大压力。为了应对这一挑战,公司进行了战略调整,将重心转向高端电子产品的研发和生产。通过不断提升产品性能和品质,AMP公司成功打造了多个高端品牌,并在细分市场中取得了显著优势。此外,公司还积极拓展新的应用领域,为未来发展奠定了坚实基础。

DAICO公司的发展小趣事

在电子行业中,技术创新是企业持续发展的关键。DAICO公司始终将研发创新作为核心战略,不断投入大量资源用于新技术和新产品的研发。通过持续的创新和积累,DAICO在中频/射频和微波控制领域取得了多项技术领先成果,成为行业内的佼佼者。

问答坊 | AI 解惑

外商面试新要点

面试在求职活动过程中,对于求职者而言,可说是压力最大的一个阶段,因为能否成功求职,全靠这临门一脚。因此,想要在面试中成为胜利者的话,唯有做好万全准备,才能收到事半功倍的机会。    1、面试前应准备事项   总公司概况:总公司所在地、 ...…

查看全部问答>

msp430各模块学习6

msp430各模块学习 1- 复位模块 2- 时钟模块 3- IO端口模块 4-WDT看门狗模块 5- TimerA定时器模块 6- 比较器A模块 7-ADC12数模转换模块 8-USART串行异步通讯模块 9-CPU模块及全局资料 10-MSP430其他应用介绍…

查看全部问答>

新手请教MC3000问题

在MC3000中我用的是VS2003开发C# 怎么才能屏蔽掉设备自带的扫描音? 然后根据程序判断后来发出我想要的声音( 这步已经实现)…

查看全部问答>

☆☆☆☆美国讯升科技急急急急急急急急急急聘Linux/Uinux 下C++工程师☆☆☆☆☆

☆☆☆☆美国讯升科技急急急急急急急急急急聘Linux/Uinux 下C++工程师☆☆☆☆☆ 请严格符合以下条件者请投简历到:bzhang@comrise.com,并注明应聘职位及招聘信息来源于天涯论坛。 一:手机应用软件开发工程师 Qualifications A: 手机应用软件 ...…

查看全部问答>

更新IV:FirmwareLib在EK_STM32F上的学习体会(I2C/IWDG)

继续,上一贴是:更新III:Firmware Lib在EK_STM32F上的学习体会(FLASH/GPIO)再早的几个帖子链接可以在上一贴内找,就不一个一个列出来了,等全系列结束了来个总集。-----------------------I2C分隔线-----------------------------------Exem ...…

查看全部问答>

奇怪的串口接收,请教。。。

我是刚刚接触stm8 自己焊了块板 今天调试串口就是不行,可以接收到但是是乱码 我用的是它官方的固件库 下面是例程 /*********************/ #include "stm8s.h" #include "stdio.h" main() {       &nb ...…

查看全部问答>

关于两路PWM波形不同时启动的问题

产品为DEC2407开发板(LF2407A) 请问能否让PWM3/PWM4这对波形在PWM1/PWM2启动之后经过指定的时间 t 才启动? 总的目标是想在定时器T1,T2和PWM1 - PWM6的范围内实现两对同频率带死区的PWM波形_不同时_启动,并且能控制它们的启动间隔 多谢…

查看全部问答>

MSP430F449的时钟问题

msp430F449的时钟最高可以40MHZ,请问下这个40MHZ是外接40MHZ晶振实现,还是编程实现?单片机频率40MHZ除了功耗大,还有什么负面影响吗? 还有 我软件变成只能将XT2上的8M时钟作为MCLK,请问怎样编程实现40MHZ的F449的MCLK频率??…

查看全部问答>

低功率纳米技术及其它敏感器件的交流与直流测量方法的比较--测量技术及误差源- I

保证精确低功率测量的关键是尽可能的降低噪声。在许多低功率测量中,一种通用的技术是使用锁定放大器为测试对象提供小的交流电流,然后测量其上的电压降。另一种替代方法是使用直流反转技术。这两种方式都需要考虑并控制多种误差源。  &nbs ...…

查看全部问答>

用ECU转接器测试数据失真是什么原因

用ECU转接器测试数据失真是什么原因…

查看全部问答>