最近用华大 HC32L176KATA开发过程中发现一个问题,
引脚PC11控制LED指示灯,调用函数Gpio_WriteOutputIO(GpioPortC, GpioPin11, x&0x80),
程序中用这个函数来驱动LED灯,结果亮了之后不灭,单步调试,用万用表量IO脚也是低电平,用示波器看波形也一直是低电平,我去,什么情况啊,做了N年的单片机,
就这么个简单的东西,也搞不定,奇了怪了。
然后看华大公司的DEMO,发现是用Gpio_SetIO()和Gpio_ClrIO()2个函数
将程序中的Gpio_WriteOutputIO换成这2个函数,指示灯显示正常。
虽然是解决问题了,但还是很奇怪,这3个函数最终都是操作管脚的输出寄存器,结果应该是一样的,那为什么我这里会不一样呢?
带着这个问题再调试时跟踪进入函数库中,当x = 0x80时,进入函数Gpio_WriteOutputIO后其值也是0x80,该函数调用
SetBit(((uint32_t)&M0P_GPIO->PAOUT + enPort), enPin, bVal);
再进入SetBit函数中,
void SetBit(uint32_t addr, uint32_t offset, boolean_t bFlag)
{
if(TRUE== bFlag)
{
*((volatile uint32_t *)(addr)) |= ((1UL)<<(offset));
}
else
{
*((volatile uint32_t *)(addr)) &= (~(1UL<<(offset)));
}
}
发现这个函数先判断表达式 (TRUE == bFlag),其中TRUE的定义是
#define TRUE ((boolean_t) 1u)
这就能理解了,传递给SetBit函数的第三个参数bFlag是0x80,这个值和TRUE(值为1)判断不等,因而执行的是else语句,结果是指示灯一直是亮着的
C99标准的定义boolean类型,有2个值,真和假,如果表达式求值是0,则该类型值为假,表达式求值非0则该类型值为真,
而华大库函数中,判断(TRUE==bFlag),TRUE的值是1,而bFlag值是0x80,不等,这个和C99标准就有些不同了
建议华大将库函数中的判断条件(TRUE==bFlag)改为(FALSE==bFlag),即
void SetBit(uint32_t addr, uint32_t offset, boolean_t bFlag)
{
if(FALSE == bFlag)
{
*((volatile uint32_t *)(addr)) &= (~(1UL<<(offset)));
}
else
{
*((volatile uint32_t *)(addr)) |= ((1UL)<<(offset));
}
}
这样就和C99标准统一了,不会造成用户使用上的困惑。
|
讲了这么多,说了很多正确的话,不过也都没错。 这个参数定义了TRUE、FALSE,就是可以让函数参数名见文知义,为什么非要传个数据呢?