嵌入式C配置PIC32寄存器:无Lint告警、易读高效方案咨询
PIC32寄存器配置方案优化(符合BARR-C:2018与PC-Lint要求)
我遵循BARR-C:2018标准编写嵌入式C固件,近期使用PC-Lint做代码检查。基于PIC32处理器,寄存器配置需满足以下三个核心要求:
- 代码易读
- 无Lint告警
- 编译生成的汇编代码量少
我梳理了几种实现方案及各自优缺点,寻求最优解决方案(示例寄存器仅作演示):
方案1:使用Microchip头文件位域操作
✓ 无Lint告警,代码易读,单字段修改便捷
✗ O0优化下生成20条汇编指令(复杂寄存器指令量会更多)
ADC0TIMEbits.SAMC = 25U; ADC0TIMEbits.ADCDIV = 50U; ADC0TIMEbits.BCHEN = 0U; ADC0TIMEbits.SELRES = 2U; ADC0TIMEbits.ADCEIS = 6U;
方案2:直接赋值寄存器
✓ 无Lint告警,O0优化下仅生成2条汇编指令
✗ 代码可读性差,单字段修改难度大
ADC0TIME = 0x1A190019U;
方案3:显式移位拼接寄存器值
✓ 无Lint告警,O0优化下生成2条汇编指令,单字段修改便捷
✗ 移位数值需手动计算,验证成本高
ADC0TIME = ((25U << 0U) | /* ADC0采样时间位 */ (50U << 16U) | /* ADC0时钟分频位 */ (0U << 23U) | /* 缓冲通道使能位 */ (2U << 24U) | /* ADC0分辨率选择位 */ (6U << 26U)); /* ADC0提前中断选择位 */
方案4:结合Microchip头文件常量移位拼接
✓ O0优化下生成2条汇编指令,单字段修改便捷,移位值由厂商定义、可读性强
✗ 头文件常量为有符号类型,触发PC-Lint 8524告警:运算符'<<'混合有符号与无符号类型(违反BARR-C:2018规则5.3c)
ADC0TIME = ((25U << _ADC0TIME_SAMC_POSITION) | /* ADC0采样时间位 */ (50U << _ADC0TIME_ADCDIV_POSITION) | /* ADC0时钟分频位 */ (0U << _ADC0TIME_BCHEN_POSITION) | /* 缓冲通道使能位 */ (2U << _ADC0TIME_SELRES_POSITION) | /* ADC0分辨率选择位 */ (6U << _ADC0TIME_ADCEIS_POSITION)); /* ADC0提前中断选择位 */
方案5:方案4+强制类型转换消除告警
✓ O0优化下生成2条汇编指令,单字段修改便捷,移位值由厂商定义、可读性强,无Lint告警
✗ 类型转换代码略显冗余
ADC0TIME = ((25U << (uint32_t)_ADC0TIME_SAMC_POSITION) | /* ADC0采样时间位 */ (50U << (uint32_t)_ADC0TIME_ADCDIV_POSITION) | /* ADC0时钟分频位 */ (0U << (uint32_t)_ADC0TIME_BCHEN_POSITION) | /* 缓冲通道使能位 */ (2U << (uint32_t)_ADC0TIME_SELRES_POSITION) | /* ADC0分辨率选择位 */ (6U << (uint32_t)_ADC0TIME_ADCEIS_POSITION)); /* ADC0提前中断选择位 */
疑问:修改Microchip头文件是否可行?
我可以修改Microchip提供的头文件,将其中的常量定义改为无符号类型,但这样头文件就不再是原厂标准版本,且需要纳入项目仓库管理,这种方式是否可行?
补充:Microchip头文件片段(常量为有符号类型)
#define _ADC0TIME_SAMC_POSITION 0x00000000 #define _ADC0TIME_SAMC_MASK 0x000003FF #define _ADC0TIME_SAMC_LENGTH 0x0000000A #define _ADC0TIME_ADCDIV_POSITION 0x00000010 #define _ADC0TIME_ADCDIV_MASK 0x007F0000 #define _ADC0TIME_ADCDIV_LENGTH 0x00000007 #define _ADC0TIME_BCHEN_POSITION 0x00000017 #define _ADC0TIME_BCHEN_MASK 0x00800000 #define _ADC0TIME_BCHEN_LENGTH 0x00000001 #define _ADC0TIME_SELRES_POSITION 0x00000018 #define _ADC0TIME_SELRES_MASK 0x03000000 #define _ADC0TIME_SELRES_LENGTH 0x00000002 #define _ADC0TIME_ADCEIS_POSITION 0x0000001A #define _ADC0TIME_ADCEIS_MASK 0x1C000000 #define _ADC0TIME_ADCEIS_LENGTH 0x00000003
内容的提问来源于stack exchange,提问作者LightBlue
相关产品推荐
相关产品推荐

