分享

嵌入式C语言中常量的应用实例

 zhuxrgf 2021-03-16


原创嵌入式与汽车电子2021-03-15 15:34:17

常量,我们都知道,就是数值保持不变的量。

在C语言中,常量一旦初始化了,它的值将在整个程序运行周期内,不允许发生任何变化。常量与变量是相对的,我们实际项目中经常会用到它。

定义常量的两种方式

C语言中主要有两种方式定义常量:一种是define,一种是const。define是宏定义,const是常量限定符。

比如,定义一些通用常量,

#ifndef true#define true(1)#endif#ifndef false#define false(0)#endif#ifndef NULL#define NULL(0)#endif

时间常量

#define  TIME_BASE10#define  TIME_10MS(10/TIME_BASE)#define  TIME_20MS(20/TIME_BASE)#define  TIME_30MS(30/TIME_BASE)#define  TIME_40MS(40/TIME_BASE)#define  TIME_50MS(50/TIME_BASE)#define  TIME_60MS(60/TIME_BASE)#define  TIME_70MS(70/TIME_BASE)#define  TIME_80MS(80/TIME_BASE)#define  TIME_100MS (100/TIME_BASE)

电压常量

#define LV_18216#define LV_17204#define LV_16192#define LV_15180#define LV_14168#define LV_13156#define LV_12144#define LV_11132#define LV_10120#define LV_9 108#define LV_8 96

以上都是用的define,有人会说用const更好。比如,

const bool true = 1;const bool false = 0;

理由是,const这种定义方式如果出现错误了,编译器会容易指出错误的具体位置。而不像define这种定义方式,报错都报得不直接,毕竟要考虑宏替换之后的情况。

其实,我觉得还好。在我看来,define就是为了给常数起名字。在实际编程过程中,我们应该尽量避免在程序中出现一些奇怪的数字,因为如果时间久了我们回头再来看这些程序,这些突兀的数字对于我们来说代表什么,很难一时半会弄清楚。

而const更适合定义常量数组,

const t_uint32 C_RM_ID[TOTAL_C_RM] = { C_MID_ICM_TSCO, C_MID_EMS_EEC, C_MID_EMS_CCVS, C_MID_ABM, C_MID_APM, C_MID_TESTER_BCM, C_MID_TESTER_FUN };

特别是比较大的数组,一定要定义常量数组,因为单片机的RAM空间是非常有限的,如果不加const限定,编译器就会将其分配到RAM空间中;只有加上了const,编译器才会将其分配到ROM中。普通单片机的RAM空间是要远远少于其ROM空间的。

还是举个例子,前面我有介绍的高频接收模块ATA5781,关于它的配置信息就有1K的字节,

const uint8_t ATA5781_config_data[1024]={0x32,0x06,0x03,0x68,0xDD,0x72,0x01,0xC7,0x00,0x02,0x00,0x00,0x00,0xD9,0x2C,0x88,0x03,0x40,0x00,0x59,0x01,0x03,0x00,0x10,0x03,0x24,0x40,0x10,0x00,0x85,0xC8,0x00,0x07,0x0C,0x0E,0x0F,0x0E,0x0C,0x09,0x05,0x01,0xFC,0xF7,0xF3,0xEF,0xEB,0xE9,0xE8,0xE9,0xEC,0xF0,0xF7,0x01,0x0D,0x00,0xFF,0xFF,0xFF,0xFF,0x83,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x46,0x00,0x80,0xBF,0xC3,0x14,0x20,0x40,0x00,0x50,0x03,0x60,0x00,0x01,0x00,0x11,0x00,0x21,0x00,0x01,0x00,0x11,0x00,0x21,0x00,0x01,0x00,0x11,0x00,0x21,0x00,0x01,0x00,0x11,0x00,0x21,0x00,0x01,0x02,0x03,0x14,0x86,0x86,0xA5,0xA5,0x46,0x46,0xC8,0x08,0x1F,0x1F,0x1F,0x1F,0x0F,0x0F,0x00,0x07,0x3C,0x10,0x07,0xAF,0x01,0x1B,0x02,0xD8,0x00,0x68,0x00,0x64,0x00,0x90,0x0A,0x08,0x00,0x00,0x51,0x00,0x50,0x10,0x20,0xA9,0xAA,0xAA,0xAA,0xA9,0xAA,0xAA,0xAA,0x87,0x87,0x08,0x08,0xAF,0xAF,0x0F,0x0F,0xD3,0xC9,0xB2,0xB5,0x00,0x00,0x96,0x06,0x3B,0x01,0x2F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,......};

有的单片机总共才2k的RAM空间,如果不加const,你这一个数组就占用去了一半。其他的程序整个挤在剩下的空间里,除开其他变量不说,还有堆栈什么的,肯定不够用了。

const更多的是提供锁保护功能,除了像上面这些在定义中“锁变量”,还可以在函数中“锁参数”。

uint8 CAN_TxBufConfig(const CAN_TX_CFG *txConfig) { uint8 result = CAN_FAIL; /* Write TX CMD Register */ CY_SET_REG32(CAN_TX_CMD_PTR(txConfig->txmailbox), (txConfig->txcmd | CAN_TX_WPN_SET)); if ((CY_GET_REG32(CAN_TX_CMD_PTR(txConfig->txmailbox)) & CAN_TX_READ_BACK_MASK) == (txConfig->txcmd & CAN_TX_WPN_CLEAR)) { /* Write TX ID Register */ CY_SET_REG32(CAN_TX_ID_PTR(txConfig->txmailbox), txConfig->txid); if (CY_GET_REG32(CAN_TX_ID_PTR(txConfig->txmailbox)) == txConfig->txid) { result = CYRET_SUCCESS; } } return (result); }

const在这里例子中,实际上就保护了CAN发送的配置不会被篡改。

小结

在常量定义中,define只适合给常量命名,const则适合更复杂的常量结构的定义,还能实现锁保护的功能。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多