打印
[STM8]

关于ST8的固件V2.2.0中bug问题

[复制链接]
1278|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
LZR13179|  楼主 | 2015-6-10 10:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  • /**
  •   * @brief  Reads the specified GPIO input data pin.
  •   * @param  GPIOx : Select the GPIO peripheral number (x = A to I).
  •   * @param  GPIO_Pin : Specifies the pin number.
  •   * @retval BitStatus : GPIO input pin status.
  •   */  
  • BitStatus GPIO_ReadInputPin(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin)  
  • {  
  •     return ((BitStatus)(GPIOx->IDR & (uint8_t)GPIO_Pin));  
  • }  
  • 这个代码是来STm8的固件库V2.2.0版
  • 这个代码存在一个问题当使用
    if(GPIO_ReadInputPin(GPIOA, GPIO_PIN_1) == SET)是存在问题的
  • 【分析】
  • 而BitStatus的原型是
    typedef enum {
      RESET = 0,
      SET = !RESET
    }
    BitStatus;

    可见该枚举型常量中定义了2个数值:RESET为0,SET为1
  • 如果GPIOA 的Pin1输入电平为高的话,GPIO_ReadInputPin(GPIOA, GPIO_PIN_1)结果为0x02,
  • 在GPIO_ReadInputPin()函数定义中,将结果进行了(BitStatus)的强制转换,但是返回结果依然是0x02,也就是说其强制转换是失败的,如果你判断该引脚的高电平用if(GPIO_ReadInputPin(GPIOA, GPIO_PIN_1) == SET)的话,永远得不到正确的结果
  • 或者使用if(GPIO_ReadInputPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_1),这样而这样可以达到预期的结果,但是与
  • BitStatus GPIO_ReadInputPin(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin)  定义的函数类型不符。
  • 或者使用if(GPIO_ReadInputPin(GPIOA, GPIO_PIN_1) != RESET)来实现。
  • 但是这样在一些没有深入了解该函数的开发人员带来一些设计上隐患。在STM32的固件库的也有类似功能的代码具体如下
  • uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
    {
      uint8_t bitstatus = 0x00;
      
      /* Check the parameters */
      assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
      assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
      
      if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET)
      {
        bitstatus = (uint8_t)Bit_SET;
      }
      else
      {
        bitstatus = (uint8_t)Bit_RESET;
      }
      return bitstatus;
    }
  • 就不存在ST8这样的问题
  • 希望st的工作人员能够及时的处理好该问题。



沙发
mmuuss586| | 2015-6-10 12:25 | 只看该作者

那要反馈给香水城版主;

使用特权

评论回复
板凳
wyde518| | 2015-6-10 12:42 | 只看该作者
这个地方的确问题,我去年调试模拟I2C的时候遇到的,确实很**,开始我用的PO口,没啥问题,改板子后换做别的IO,怎么都不正常,害的我调了好几天

使用特权

评论回复
地板
mzhboy| | 2015-6-11 07:54 | 只看该作者
我爱这样用,可以避免这个问题
if(GPIO_ReadInputPin(GPIOA, GPIO_PIN_1))
{
    balabala;
}

使用特权

评论回复
5
LZR13179|  楼主 | 2015-6-11 08:50 | 只看该作者
本帖最后由 LZR13179 于 2015-6-11 09:02 编辑
mzhboy 发表于 2015-6-11 07:54
我爱这样用,可以避免这个问题
if(GPIO_ReadInputPin(GPIOA, GPIO_PIN_1))
{

嗯这样使用是没有问题的。但是和他原先设想的有出路。如果没有细看他提供的代码的话。很容易出现一个“bug”问题。毕竟他提供返回类型是一个枚举。
而写库的没有考虑(数据类型强制转化带来的问题)。
这个是我现在的做法修改库的这个段代码,修改后如下:
return ((GPIOx->IDR & (uint8_t)GPIO_Pin) ? SET : RESET);

使用特权

评论回复
6
LZR13179|  楼主 | 2015-6-12 08:56 | 只看该作者
mmuuss586 发表于 2015-6-10 12:25
那要反馈给香水城版主;

呵呵游总

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

87

帖子

1

粉丝