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

原创嵌入式与汽车电子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)

相关推荐

  • php中const与define用法示例

    感兴趣的小伙伴,下面一起跟随512笔记的小玲来看看吧! 1.const用于类成员变量定义,一旦定义且不能改变其值.define定义全局常量,在任何地方都可以访问. 2.define不能在类中定义而co ...

  • 嵌入式C语言中宏的使用技巧

    在整个嵌入式C语言系列中,我一直都是用嵌入式去限定C语言,而不是针对整个C语言,因为我们这里主要讨论的是嵌入式中的C语言.<C语言程序设计>这门课,大家基本上都在大学课程里学过或者有所了解 ...

  • 嵌入式C语言中字节对齐的问题

    嵌入式C语言中,字节对齐的问题主要出现在结构体中,我们先来看一下结构体的定义. 结构体struct的定义 在C语言中,结构体是一种复合数据类型,其构成元素既可以是基本数据类型(如int.long.fl ...

  • R语言中的隐马尔可夫HMM模型实例

    原文链接:http://tecdat.cn/?p=17592  最近,我们使用隐马尔可夫模型开发了一种解决方案,并被要求解释这个方案. HMM用于建模数据序列,无论是从连续概率分布还是从离散概率分布得 ...

  • (C语言中的常量)乐创DIY C语言讲义​——3.6节

    3.6 常量 常量,顾名思义就是在程序执行期间不会改变的固定值.在C语言中,常量的主要作用有两个,其一为给变量赋值,其二为与变量比较,作为判断条件. 在C语言程序中的常量有四大类,分别是整数型常量,浮 ...

  • 嵌入式C语言开发者必知:“设计模式”

    介绍如何使用设计模式为嵌入式系统创建高效且优化的C语言设计.针对嵌入式系统中从内存访问到事件调度,从状态机设计到安全性.可靠性保证,对系统设计以及性能表现的方方面面进行了详细阐述,也提出了很好的设计规 ...

  • 初学编程,如何玩转C语言?C语言中最重要的知识献上!

    一.C语言的指针 1.指针说明 指针是包含另一变量的地址变量. (1)int *p p是一个指针,指向一个整形数. (2)int *p() p是一个函数,该函数返回一个指向整数的指针. (3)int ...

  • 学习嵌入式C语言的6个层级,你在哪一层?

    C语言可以说是一中经典的编程语言,没有C语言就没有今天的各种操作系统. C语言是基础,你掌握了多少? 嵌入式专栏 1 新手级别 学习目的:过计算机二级,考证,应付期末考试. 需要掌握的程度:掌握C语言 ...

  • 嵌入式C语言自我修养:从芯片、编译器到操作系统(附送书籍)

    最近,阅读了王工(王利涛)赠送的一本由他编著的书籍<嵌入式C语言自我修养>,感觉写的挺不错.今天分享一下这本书籍<嵌入式C语言自我修养>:从芯片.编译器到操作系统. 然后,再送 ...

  • c语言中结构体成员变量使用“.”符号赋值方法

    在C语言中定义结构体类型的变量时,其内部的成员变量赋值除常规的方法外,也可以通过点号"."进行赋值,如下图所示: 备注:在Linux系统上使用gcc / g++编译器调试通过,其它 ...