chickop level
获赞
128
粉丝
20
关注
5
看过 TA
525
吉林大学
2022
嵌入式软件开发
IP属地:浙江
暂未填写个人简介
私信
关注
为一个32位控制寄存器(地址为0x40021000)设计一个初始化函数。该寄存器包含多个位域,其布局如下表所示。函数需要根据配置参数,安全、高效地初始化该寄存器。#include <stdint.h>#include <stddef.h>// 定义寄存器地址#define CTRL_REG_ADDR (*(volatile uint32_t *)0x40021000)// 定义位域掩码和偏移量(更清晰、可维护性更强的方式)#define MODE_MASK        0x00000003UL#define MODE_OFFSET      0#define CLK_SRC_MASK     0x0000000CUL#define CLK_SRC_OFFSET   2#define PRESCALER_MASK   0x00000030UL#define PRESCALER_OFFSET 4#define EN_INT_MASK      0x00000100UL#define EN_INT_OFFSET    8#define DIV_MASK         0xFFFF0000UL#define DIV_OFFSET       16// 保留位的掩码,用于确保这些位被清零#define RESERVED_MASK    0x0000FE00UL // 位15:9int register_init(const struct reg_config *config) {// 1. 参数基础校验if (config == NULL) {return -1;}// 2. 详细的参数值合法性校验if (config->mode > 2) {return -1; // MODE值非法}if (config->clk_src > 2) {return -1; // CLK_SRC值非法}if (config->prescaler > 3) {return -1; // PRESCALER值非法}if (config->en_int > 1) {return -1; // EN_INT值非法}// DIV 是16位无符号整数,其取值范围0-65535都是合法的,无需额外校验// 3. 组装寄存器值uint32_t reg_value = 0; // 从0开始构建reg_value |= ((uint32_t)(config->mode) & 0x3) << MODE_OFFSET;reg_value |= ((uint32_t)(config->clk_src) & 0x3) << CLK_SRC_OFFSET;reg_value |= ((uint32_t)(config->prescaler) & 0x3) << PRESCALER_OFFSET;reg_value |= ((uint32_t)(config->en_int) & 0x1) << EN_INT_OFFSET;reg_value |= ((uint32_t)(config->div) & 0xFFFF) << DIV_OFFSET;// 注意:由于我们是从0开始按位或,并且保留位对应的值始终为0,所以自然就保证了保留位为0。// 这是一种更安全的方法。// 4. 写入寄存器CTRL_REG_ADDR = reg_value;return 0; // 成功}
查看8道真题和解析
0 点赞 评论 收藏
分享

创作者周榜

更多
关注他的用户也关注了:
牛客网
牛客网在线编程
牛客网题解
牛客企业服务