当前位置:首页 > 技术文章 > 正文内容

嵌入式C语言中常量的应用实例(c语言嵌入式是什么意思)

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

在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_BASE							10
#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_18								216
#define LV_17								204
#define LV_16								192
#define LV_15								180
#define LV_14								168
#define LV_13								156
#define LV_12								144
#define LV_11								132
#define LV_10								120
#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则适合更复杂的常量结构的定义,还能实现锁保护的功能。

扫描二维码推送至手机访问。

版权声明:本文由AR编程网发布,如需转载请注明出处。

本文链接:http://www.arlanguage.com/post/4299.html

分享给朋友:

“嵌入式C语言中常量的应用实例(c语言嵌入式是什么意思)” 的相关文章

小程序开发SSL证书申请

打开JoySSL官网注册并填写注册码230918申请免费试用;目前各大平台均要求小程序平台强制要求使用HTTPS加密协议,这意味着小程序上线必须部署SSL证书以确保所有网络请求的安全性,否则无法正常上线使用。这是小程序大规模使用的背景下确保用户敏感信息安全的必然措施。小程序专用SSL证书申请1.注册...

Java 加密解密和数字签名

在做项目中,只要涉及敏感信息,或者对安全有一定要求的场景,都需要对数据进行加密。在Java中原生API即可实现对称加密与非对称加密,并支持常用的加密算法。对称加密对称加密使用单钥完成加解密,加密和解密采用相同的密钥。对称加密的速度快,常用于大量数据进行加密。主流的算法有:AES,3DES。生成3DE...

如何在 NGINX 中创建自定义 404 错误页面

每次NGINX在尝试处理客户端请求时遇到错误,它都会返回一个错误。每个错误都包含一个HTTP响应代码和一个简短描述。错误通常通过简单的默认HTML页面显示给用户。幸运的是,您可以配置NGINX以向您的站点或 Web 应用程序的用户显示自定义错误页面。这可以使用 NGINX 的 error_page指...

宝塔面板——永久免费的服务器运维面板

宝塔面板是什么?宝塔面板,简单好用的服务器运维面板。官称永久免费。Linux版请确保纯净系统安装(支持CentOS、Ubuntu、Debian、Fedora、deepin),Web端管理,一键创建网站、FTP、数据库、SSL;安全管理,计划任务,文件管理,PHP多版本共存及切换;自带LNMP与LAM...

从入门到精通,超详细的程序员Java学习路线指南

说明最近也有很多人来向我"请教",他们大都是一些刚入门的新手,还不了解这个行业,也不知道从何学起,开始的时候非常迷茫,实在是每天回复很多人也很麻烦,所以在这里统一作个回复吧。Java学习路线当然,这里我只是说Java学习路线,因为自己就是学Java的,对Java理当很熟悉,对于其它方...

IT运维面试问题总结-运维(Ceph、Docker、Apache、Nginx等

木二 YP小站运维工具简述Ansible及其优势?Ansible是一款极其简单的开源的自动化运维工具,基于Python开发,集合了众多运维工具(puppet, cfengine, chef, func, fabric)的优点。实现了批量系统配置,批量程序部署,批量运行命令等功能。同时Ansible是...