在c语言开发中,有时候为了方便经常会这么访问一个地址 int a = *(int *)address。但这个方法在单片机平台中存在着隐患:
- 表现:程序死机或者数据获取不对
- 原因:取地址时内存地址和总线未对齐
- 解决方法:使用联合结构体方法进行转换
测试代码:在不同的芯片中执行会有不同的情况,大部分能正确获得数据,但有些则是卡死或者数据获取错误。
#include <stdio.h>
#include <stdint.h>
#include "math.h"
#define M_PI 3.14159265358979323846
int main()
{
int i;
uint8_t data[10]={1,2,3,4,5,6,7,8,9,10};
printf("8bit address: \n");
for(i=0;i<10;i++){
printf("%d:%lx\n",i,(uint32_t)&data[i]);
}
printf("16bit address: \n");
for(i=0;i<10;i++){
printf("%d:%lx\n",i,*(uint16_t*)&data[i]);
}
printf("32bit address: \n");
for(i=0;i<10;i++){
printf("%d:%lx\n",i,*(uint32_t*)&data[i]);
}
printf("done \n");
return 0;
}
解决代码:
typedef union param_union {
float param_float;
int32_t param_int32;
uint32_t param_uint32;
int16_t param_int16;
uint16_t param_uint16;
int8_t param_int8;
uint8_t param_uint8;
uint8_t bytes[4];
}TYPE_UNION;
//常用的数据转换函数
int8_t TR_INT8(uint8_t *in){
return *(int8_t*)in;
}
uint8_t TR_UINT8(uint8_t *in){
return *in;
}
int16_t TR_INT16(uint8_t *in){
TYPE_UNION changecore={0};
memcpy(changecore.bytes,in,2);
return changecore.param_int16;
}
uint16_t TR_UINT16(uint8_t *in){
TYPE_UNION changecore={0};
memcpy(changecore.bytes,in,2);
return changecore.param_uint16;
}
int32_t TR_INT32(uint8_t *in){
TYPE_UNION changecore={0};
memcpy(changecore.bytes,in,4);
return changecore.param_int32;
}
uint32_t TR_UINT32(uint8_t *in){
TYPE_UNION changecore={0};
memcpy(changecore.bytes,in,4);
return changecore.param_uint32;
}
float TR_FLOAT(uint8_t *in){
TYPE_UNION changecore={0};
memcpy(changecore.bytes,in,4);
return changecore.param_float;
}