结构体位域保存传感器数据

文章介绍了如何使用8个74HC4052芯片共享两个选通引脚来检测64个数字红外传感器,通过位域结构体高效存储和处理状态,以及中间层和应用层的协作实现传感器状态的周期性更新。

1、原理图分析:

8个74HC4052共用两个选通引脚,8个输入引脚,一共可以检测64个数字红外传感器。74HC4052的功能表如下,nY0表示所有Y0引脚。

S1	S0	Channel on
0	0	nY0
0	1	nY1
1	0	nY2
1	1	nY3 
enum sensor_id{
    HS01 = 0,		
    HS02,			
    HS03,			
    HS04,			
    HS05,			
    HS06,			
    HS07,			
    HS08,			
    HS09,			
    HS10,			
    HS11,			
    HS12,			
    HS13,			
    HS14,			
    HS15,			
    HS16,			
    HS17,
    HS18,
    HS19,
    HS20,
    HS21,
    HS22,
    HS23,
    HS24,
    HS25,
    HS26,
    HS27,
    HS28,
    HS29,
    HS30,
    HS31,
    HS32,
    HS33,
    HS34,
    HS35,
    HS36,
    HS37,
    HS38,
    HS39,
    HS40,
    HS41,
    HS42,
    HS43,
    HS44,
    HS45,
    HS46,
    HS47,
    HS48,
    HS49,
    HS50,
    HS51,
    HS52,
    HS53,
    HS54,
    HS55,
    HS56,
    HS57,
    HS58,
    HS59,
    HS60,
    HS61,
    HS62,
    HS63,
    HS64,
    HS_NUM    
};

#define RENEM_STEPS	4
uint8_t renew_flag = 0;
static uint8_t phase = 0;
volatile uint8_t g_u8sensorStatus[HS_NUM];
//周期性更新红外数字传感器的状态,200us调用一次	
void renew_irsensor_status(void)
{
	renew_flag = 1;
	if(++phase >= RENEM_STEPS)
		phase = 0;
	switch(phase)
	{
		case 0:
			//读取S1=0,S0=1
            g_u8sensorStatus[HS06] = GPIO_PinRead(BOARD_INITPINS_IRIN1_PORT,BOARD_INITPINS_IRIN1_PIN);
            g_u8sensorStatus[HS41] = GPIO_PinRead(BOARD_INITPINS_IRIN2_PORT,BOARD_INITPINS_IRIN2_PIN);
            g_u8sensorStatus[HS12] = GPIO_PinRead(BOARD_INITPINS_IRIN3_PORT,BOARD_INITPINS_IRIN3_PIN);
            g_u8sensorStatus[HS56] = GPIO_PinRead(BOARD_INITPINS_IRIN4_PORT,BOARD_INITPINS_IRIN4_PIN);
            g_u8sensorStatus[HS19] = GPIO_PinRead(BOARD_INITPINS_IRIN5_PORT,BOARD_INITPINS_IRIN5_PIN);
            g_u8sensorStatus[HS23] = GPIO_PinRead(BOARD_INITPINS_IRIN6_PORT,BOARD_INITPINS_IRIN6_PIN);
            g_u8sensorStatus[HS27] = GPIO_PinRead(BOARD_INITPINS_IRIN7_PORT,BOARD_INITPINS_IRIN7_PIN);
            g_u8sensorStatus[HS31] = GPIO_PinRead(BOARD_INITPINS_IRIN8_PORT,BOARD_INITPINS_IRIN8_PIN);
            g_u8sensorStatus[HS03] = GPIO_PinRead(BOARD_INITPINS_IRIN9_PORT,BOARD_INITPINS_IRIN9_PIN);
            g_u8sensorStatus[HS36] = GPIO_PinRead(BOARD_INITPINS_IRIN10_PORT,BOARD_INITPINS_IRIN10_PIN);
            g_u8sensorStatus[HS09] = GPIO_PinRead(BOARD_INITPINS_IRIN11_PORT,BOARD_INITPINS_IRIN11_PIN);
            g_u8sensorStatus[HS46] = GPIO_PinRead(BOARD_INITPINS_IRIN12_PORT,BOARD_INITPINS_IRIN12_PIN);
            g_u8sensorStatus[HS50] = GPIO_PinRead(BOARD_INITPINS_IRIN13_PORT,BOARD_INITPINS_IRIN13_PIN);
            g_u8sensorStatus[HS54] = GPIO_PinRead(BOARD_INITPINS_IRIN14_PORT,BOARD_INITPINS_IRIN14_PIN);
            g_u8sensorStatus[HS59] = GPIO_PinRead(BOARD_INITPINS_IRIN15_PORT,BOARD_INITPINS_IRIN15_PIN);
            g_u8sensorStatus[HS63] = GPIO_PinRead(BOARD_INITPINS_IRIN16_PORT,BOARD_INITPINS_IRIN16_PIN);            
			GPIO_PinWrite(BOARD_INITPINS_IRS0_PORT, BOARD_INITPINS_IRS0_PIN,0);	
			GPIO_PinWrite(BOARD_INITPINS_IRS1_PORT, BOARD_INITPINS_IRS1_PIN,0);	
			break;
		case 1:            
			//读取S1=0,S0=0
            g_u8sensorStatus[HS04] = GPIO_PinRead(BOARD_INITPINS_IRIN1_PORT,BOARD_INITPINS_IRIN1_PIN);
            g_u8sensorStatus[HS39] = GPIO_PinRead(BOARD_INITPINS_IRIN2_PORT,BOARD_INITPINS_IRIN2_PIN);
            g_u8sensorStatus[HS10] = GPIO_PinRead(BOARD_INITPINS_IRIN3_PORT,BOARD_INITPINS_IRIN3_PIN);
            g_u8sensorStatus[HS14] = GPIO_PinRead(BOARD_INITPINS_IRIN4_PORT,BOARD_INITPINS_IRIN4_PIN);
            g_u8sensorStatus[HS17] = GPIO_PinRead(BOARD_INITPINS_IRIN5_PORT,BOARD_INITPINS_IRIN5_PIN);
            g_u8sensorStatus[HS21] = GPIO_PinRead(BOARD_INITPINS_IRIN6_PORT,BOARD_INITPINS_IRIN6_PIN);
            g_u8sensorStatus[HS25] = GPIO_PinRead(BOARD_INITPINS_IRIN7_PORT,BOARD_INITPINS_IRIN7_PIN);
            g_u8sensorStatus[HS29] = GPIO_PinRead(BOARD_INITPINS_IRIN8_PORT,BOARD_INITPINS_IRIN8_PIN);
            g_u8sensorStatus[HS01] = GPIO_PinRead(BOARD_INITPINS_IRIN9_PORT,BOARD_INITPINS_IRIN9_PIN);
            g_u8sensorStatus[HS34] = GPIO_PinRead(BOARD_INITPINS_IRIN10_PORT,BOARD_INITPINS_IRIN10_PIN);
            g_u8sensorStatus[HS07] = GPIO_PinRead(BOARD_INITPINS_IRIN11_PORT,BOARD_INITPINS_IRIN11_PIN);
            g_u8sensorStatus[HS44] = GPIO_PinRead(BOARD_INITPINS_IRIN12_PORT,BOARD_INITPINS_IRIN12_PIN);
            g_u8sensorStatus[HS48] = GPIO_PinRead(BOARD_INITPINS_IRIN13_PORT,BOARD_INITPINS_IRIN13_PIN);
            g_u8sensorStatus[HS52] = GPIO_PinRead(BOARD_INITPINS_IRIN14_PORT,BOARD_INITPINS_IRIN14_PIN);
            g_u8sensorStatus[HS16] = GPIO_PinRead(BOARD_INITPINS_IRIN15_PORT,BOARD_INITPINS_IRIN15_PIN);
            g_u8sensorStatus[HS61] = GPIO_PinRead(BOARD_INITPINS_IRIN16_PORT,BOARD_INITPINS_IRIN16_PIN);                        
			GPIO_PinWrite(BOARD_INITPINS_IRS0_PORT, BOARD_INITPINS_IRS0_PIN,0);	
			GPIO_PinWrite(BOARD_INITPINS_IRS1_PORT, BOARD_INITPINS_IRS1_PIN,1);	
			break;
		case 2:
		    //读取S1=1,S0=0
            g_u8sensorStatus[HS05] = GPIO_PinRead(BOARD_INITPINS_IRIN1_PORT,BOARD_INITPINS_IRIN1_PIN);
            g_u8sensorStatus[HS40] = GPIO_PinRead(BOARD_INITPINS_IRIN2_PORT,BOARD_INITPINS_IRIN2_PIN);
            g_u8sensorStatus[HS11] = GPIO_PinRead(BOARD_INITPINS_IRIN3_PORT,BOARD_INITPINS_IRIN3_PIN);
            g_u8sensorStatus[HS15] = GPIO_PinRead(BOARD_INITPINS_IRIN4_PORT,BOARD_INITPINS_IRIN4_PIN);
            g_u8sensorStatus[HS18] = GPIO_PinRead(BOARD_INITPINS_IRIN5_PORT,BOARD_INITPINS_IRIN5_PIN);
            g_u8sensorStatus[HS22] = GPIO_PinRead(BOARD_INITPINS_IRIN6_PORT,BOARD_INITPINS_IRIN6_PIN);
            g_u8sensorStatus[HS26] = GPIO_PinRead(BOARD_INITPINS_IRIN7_PORT,BOARD_INITPINS_IRIN7_PIN);
            g_u8sensorStatus[HS30] = GPIO_PinRead(BOARD_INITPINS_IRIN8_PORT,BOARD_INITPINS_IRIN8_PIN);
            g_u8sensorStatus[HS02] = GPIO_PinRead(BOARD_INITPINS_IRIN9_PORT,BOARD_INITPINS_IRIN9_PIN);
            g_u8sensorStatus[HS35] = GPIO_PinRead(BOARD_INITPINS_IRIN10_PORT,BOARD_INITPINS_IRIN10_PIN);
            g_u8sensorStatus[HS08] = GPIO_PinRead(BOARD_INITPINS_IRIN11_PORT,BOARD_INITPINS_IRIN11_PIN);
            g_u8sensorStatus[HS45] = GPIO_PinRead(BOARD_INITPINS_IRIN12_PORT,BOARD_INITPINS_IRIN12_PIN);
            g_u8sensorStatus[HS49] = GPIO_PinRead(BOARD_INITPINS_IRIN13_PORT,BOARD_INITPINS_IRIN13_PIN);
            g_u8sensorStatus[HS53] = GPIO_PinRead(BOARD_INITPINS_IRIN14_PORT,BOARD_INITPINS_IRIN14_PIN);
            g_u8sensorStatus[HS58] = GPIO_PinRead(BOARD_INITPINS_IRIN15_PORT,BOARD_INITPINS_IRIN15_PIN);
            g_u8sensorStatus[HS62] = GPIO_PinRead(BOARD_INITPINS_IRIN16_PORT,BOARD_INITPINS_IRIN16_PIN);            
			GPIO_PinWrite(BOARD_INITPINS_IRS0_PORT, BOARD_INITPINS_IRS0_PIN,1);	
			GPIO_PinWrite(BOARD_INITPINS_IRS1_PORT, BOARD_INITPINS_IRS1_PIN,1);	
			break;
		case 3:   
			//读取S1=1,S0=1        
            g_u8sensorStatus[HS38] = GPIO_PinRead(BOARD_INITPINS_IRIN1_PORT,BOARD_INITPINS_IRIN1_PIN);
            g_u8sensorStatus[HS42] = GPIO_PinRead(BOARD_INITPINS_IRIN2_PORT,BOARD_INITPINS_IRIN2_PIN);
            g_u8sensorStatus[HS13] = GPIO_PinRead(BOARD_INITPINS_IRIN3_PORT,BOARD_INITPINS_IRIN3_PIN);
            g_u8sensorStatus[HS57] = GPIO_PinRead(BOARD_INITPINS_IRIN4_PORT,BOARD_INITPINS_IRIN4_PIN);
            g_u8sensorStatus[HS20] = GPIO_PinRead(BOARD_INITPINS_IRIN5_PORT,BOARD_INITPINS_IRIN5_PIN);
            g_u8sensorStatus[HS24] = GPIO_PinRead(BOARD_INITPINS_IRIN6_PORT,BOARD_INITPINS_IRIN6_PIN);
            g_u8sensorStatus[HS28] = GPIO_PinRead(BOARD_INITPINS_IRIN7_PORT,BOARD_INITPINS_IRIN7_PIN);
            g_u8sensorStatus[HS32] = GPIO_PinRead(BOARD_INITPINS_IRIN8_PORT,BOARD_INITPINS_IRIN8_PIN);
            g_u8sensorStatus[HS33] = GPIO_PinRead(BOARD_INITPINS_IRIN9_PORT,BOARD_INITPINS_IRIN9_PIN);
            g_u8sensorStatus[HS37] = GPIO_PinRead(BOARD_INITPINS_IRIN10_PORT,BOARD_INITPINS_IRIN10_PIN);
            g_u8sensorStatus[HS43] = GPIO_PinRead(BOARD_INITPINS_IRIN11_PORT,BOARD_INITPINS_IRIN11_PIN);
            g_u8sensorStatus[HS47] = GPIO_PinRead(BOARD_INITPINS_IRIN12_PORT,BOARD_INITPINS_IRIN12_PIN);
            g_u8sensorStatus[HS51] = GPIO_PinRead(BOARD_INITPINS_IRIN13_PORT,BOARD_INITPINS_IRIN13_PIN);
            g_u8sensorStatus[HS55] = GPIO_PinRead(BOARD_INITPINS_IRIN14_PORT,BOARD_INITPINS_IRIN14_PIN);
            g_u8sensorStatus[HS60] = GPIO_PinRead(BOARD_INITPINS_IRIN15_PORT,BOARD_INITPINS_IRIN15_PIN);
            g_u8sensorStatus[HS64] = GPIO_PinRead(BOARD_INITPINS_IRIN16_PORT,BOARD_INITPINS_IRIN16_PIN);
			GPIO_PinWrite(BOARD_INITPINS_IRS0_PORT, BOARD_INITPINS_IRS0_PIN,1);	
			GPIO_PinWrite(BOARD_INITPINS_IRS1_PORT, BOARD_INITPINS_IRS1_PIN,0);	
			break;
		default:
			break;
	}
	renew_flag = 0;
}

/产品有64个数字红外传感器,传感器的状态有两种,0或1,使用结构体位域,在节省内存的同时还方便阅读。
这个定义在中间层,应用层调用中间层,驱动层负责获取传感器的状态并赋值给这个结构体。
/

struct ir_sensor
{
	uint32_t s001:1;
	uint32_t s002:1;
	uint32_t s003:1;
	uint32_t s004:1;
	uint32_t s005:1;
	uint32_t s006:1;
	uint32_t s007:1;
	uint32_t s008:1;
	uint32_t s009:1;
	uint32_t s010:1;
	uint32_t s011:1;
	uint32_t s012:1;
	uint32_t s013:1;
	uint32_t s014:1;
	uint32_t s017:1;
	uint32_t s018:1;
	uint32_t s019:1;
	uint32_t s020:1;
	uint32_t s014:1;
	uint32_t s001:1;
	uint32_t s102:1;
	uint32_t s103:1;
	uint32_t s104:1;
	uint32_t s201:1;
	uint32_t s202:1;
	uint32_t s203:1;
	uint32_t s204:1;
	uint32_t s205:1;
	uint32_t s206:1;
	uint32_t s301:1;
	uint32_t s302:1;	
	uint32_t s303:1;
	uint32_t s401:1;
	uint32_t s402:1;
	uint32_t s403:1;
	uint32_t s404:1;
	uint32_t s405:1;
	uint32_t s406:1;
	uint32_t s407:1;
	uint32_t s408:1;
	uint32_t s410:1;
	uint32_t s411:1;
	uint32_t s412:1;	
	uint32_t s511:1;
	uint32_t s512:1;
	uint32_t s513:1;
	uint32_t s521:1;
	uint32_t s522:1;
	uint32_t s523:1;
	uint32_t s611:1;
	uint32_t s612:1;
	uint32_t s613:1;
	uint32_t s621:1;
	uint32_t s622:1;
	uint32_t s623:1;
	uint32_t s500:1;
	uint32_t ss01:1;
	uint32_t sf01:1;
	uint32_t sb01:1;
	uint32_t sb02:1;
	uint32_t sw01:1;
	uint32_t sab1:1;
}

//周期性更新数字红外传感器状态到中间层,1ms调用一次
struct ir_sensor g_irSensor;
void get_irsensor_status(void)
{
	uint8_t i,l_u8sensorStatus[HS_NUM];
	if( renew_flag ) return;
	for(i=0;i<HS_NUM;i++)
	{
		l_u8sensorStatus[i] = g_u8sensorStatus[i];
	}
	g_irSensor.s001 = l_u8sensorStatus[HS01];
}

该函数 `sub_134C0` 主要进行的是 **多字段提取、对齐、掩码筛选与重组** 操作,其核心目的是将来自输入缓冲区的多个离散数据字段组合成一个具有特定格式的 32 控制字,并写回结构体中的指定字段(`field_0x50`)。 --- ### ✅ 函数主要执行的数据操作如下: #### 1. **保留原始状态的符号(Bit 31)** ```asm LDR R2, [R0,#0x50] AND R2, R2, #0x80000000 STR R2, [R0,#0x50] ``` - 从结构体成员 `field_0x50` 中提取最高(符号) - 清除其余 → 实现“只保留符号标志” - 写回原置 - 👉 目的:保存某个状态标志(如加密方向、有效性、奇偶性等),用于后续合成 #### 2. **从输入缓冲区加载多个32数据** ```asm LDRD.W R3, LR, [R1] ; R3 = data[0], LR = data[1] LDM R6, {R2,R4,R6} ; R6 = R1+8 → R2=data[2], R4=data[3], R6=data[4] ``` - 输入指针 `R1` 指向一段连续的 5 个 32 数据(共 20 字节) - 分别加载: - `data[0]` → R3 - `data[1]` → LR - `data[2]` → R2 - `data[3]` → R4 - `data[4]` → R6 👉 这些可能是 RFID 认证过程中的随机数、UID 扩展、加密响应片段或内部状态。 #### 3. **提取与对齐(关键操作)** ##### a. 从 `data[0]` 提取中间16并左移对齐 ```asm LSLS R3, R3, #10 ; 左移10 UXTH R3, R3 ; 截断为低16 → (data[0] << 10) & 0xFFFF ``` - 相当于从 `data[0]` 的 bit[25:10] 提取一个 16 字段 - 常见于编码解码中提取量化索引或加密参数 ##### b. 从 `data[2]` 和 `data[1]` 提取低5 ```asm AND.W R2, R2, #0x1F ; R2 = data[2] & 0x1F AND.W R1, LR, #0x1F ; R1 = data[1] & 0x1F ``` - 获取两个 5 字段(0~31 范围),可能表示小整数、模式选择、计数器等 ##### c. 从 `data[4]` 提取低5 ```asm AND.W R2, R6, #0x1F ; R2 = data[4] & 0x1F ``` - 第三个 5 字段 👉 总共至少处理了 **三个独立的 5 字段** 和 **一个 16 字段** #### 4. **构造掩码并进行条件过滤** ```asm MOVT R5, #0x7FE0 ; R5 = 0x7FE00000 AND.W R5, R5, R4, LSL #21 ; R5 &= (R4 << 21) ``` - 构造一个高11为1的掩码:`0x7FE00000` = `0111 1111 1110 0000 0000 0000 0000 0000` - 但只有当 `R4` 的某些被设置时才允许通过(由 `R4 << 21` 控制) - 👉 类似于“使能”或“权限控制”,防止非法组合 #### 5. **多字段拼接成最终结果** 最终通过一系列 ORR 操作构建完整值: ```asm ORR R2, R2, R12 ; 加上原始符号 ORR R2, R2, R3 ; 合并 data[0] 提取的部分 ORR R1, R2, R1, LSL #5 ; R1 |= (R2 << 5) ORR R1, R1, R5 ; 加入掩码控制部分 ORR R1, R1, R2_Low5 << 16 ; 最后加入 data[4][4:0] << 16 ``` 最终结果是一个复合字段,结构大致如下: | Bit范围 | 来源 | 含义推测 | |---------------|--------------------------|------------------------| | [31] | 原 `field_0x50` 符号 | 状态标志 | | [30:21] | 掩码 & (R4 << 21) | 条件启用的高控制 | | [20:16] | data[2][4:0] << 5 + ... | 组合字段 A | | [15:10] | (data[0] << 10)[15:0] | 对齐后的主数据字段 | | [9:5] | data[1][4:0] << 5 | 字段 B | | [4:0] | data[4][4:0] | 字段 C | --- ### ✅ 总结:该函数主要进行什么数据操作? > **这是一个典型的“解包与受控重组”函数**,具体包括: 1. **状态继承**:保留原字段的符号作为状态标志。 2. **多源数据采集**:从输入缓冲区读取至少 5 个 32 数据。 3. **提取**:从各个数据中提取低5、中间16等小字段。 4. **对齐与扩展**:使用左移和截断实现字段归一化。 5. **条件掩码过滤**:利用 `R4` 控制某些高是否参与输出。 6. **字段拼接合成**:将多个离散字段按组合成一个新的 32 控制字。 7. **写回结构体**:更新内部状态字段 `field_0x50`。 --- ### 🧠 典型应用场景(推测) 这类操作常见于: - **RFID/Mifare 卡片认证协议**:构造会话密钥或状态字 - **轻量级加密算法**(如 Crypto1 片段):处理非线性反馈或 S-box 输入 - **音频/传感器数据解码**:解析压缩流中的参数字段 - **固件协议解析**:从加密包中提取命令字段 由于涉及多个输入字段和复杂操作,很可能是 **认证流程中的一环**,而非直接生成密钥。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值