摘要:各种类型的数据传输和存储就涉及到大小端的问题,首先要简单说下芯片的大小端问题,这里主要讨论Cortex-M内核。

forum.jpg


M内核支持大端或者小端,实际应用中大部分内核都是小端。以STM32为例,全部都是小端,而且是芯片设计之初就固化进去的,不可修改。市面上其他厂家基本也都固化的小端格式。

F1编程手册

forum.jpg


F3和F4编程手册

forum.jpg


F7和H7编程手册

forum.jpg


各种数据类型编程EEPROM,SPI Flash等存储器的简易方法,一般这些存储器都是字节编程,写入浮点等数据类型时不太方便。这里分享一个方法,定义一个结构体,将各种数据类型封装进去:

forum.jpg


写入的时候采用下面方式:

forum.jpg


读取时可以采用下面方式:

forum.jpg


各种数据类型的SPI,UART,I2C等传输问题。这里我们以串口通信为例,比如主机要发送如下格式数据给从机:

forum.jpg


我们可以做一个如下结构体格式:

typedefstruct{uint8_tucStart;uint16_tusCO2;uint16_tusPM25;uint16_tusHumidity;floatTemprature;uint32_tulParam;uint8_tucEnd1;uint8_tucEnd2;   
}
UART_T;

UART_T g_tUartParam;

主机发送的时候我们就可以采用如下方法:

comSendBuf(COM1, (uint8_t*)&g_tUartParam,sizeof(UART_T));

从机工程也定义一个同样的结构体变量,比如我们把接收到一帧数据存到缓冲uint8_t buf[50]里面了。

我们就可以定义一个结构体指针变量:

UART_T*pUartParam;pUartParam= (UART_T *)buf;

那么我们就可以pUartParam->usCO2,pUartParam->Temprature等方式来访问,非常方便。

代码实现

结构体数据如下:

typedefstruct{uint8_tucStart;uint16_tusCO2;uint16_tusPM25;uint16_tusHumidity;floatTemprature;uint32_tulParam;uint8_tucEnd1;uint8_tucEnd2;   
}
USART_T;

USART_T g_tUartParam;/* 串口1发送数据使用 */USART_T *pUartParam;/* 串口2接数据使用 */uint8_tbuf[128];/* 接收记录缓冲 */

数据收发处理:

  1. /*
  2. *********************************************************************************************************
  3. * 函 数 名: main
  4. * 功能说明: c程序入口
  5. * 形 参: 无
  6. * 返 回 值: 错误代码(无需处理)
  7. *********************************************************************************************************
  8. */intmain(void){
  9. uint8_tucKeyCode;
  10. uint8_tread;
  11. uint8_tucStatus =0;
  12. /* 状态机标志 */
  13. uint8_tucCount=0;
  14. floatftest =0.11f;
  15. pUartParam = (USART_T *)buf;
  16. bsp_Init();/* 硬件初始化 */
  17. PrintfLogo();/* 打印例程名称和版本等信息 */
  18. PrintfHelp();/* 打印操作提示 */
  19. bsp_StartAutoTimer(0,100);/* 启动1个100ms的自动重装的定时器 */
  20. memset(buf,0,128);/* 进入主程序循环体 */
  21. while(1)
  22. {
  23. bsp_Idle();/* 这个函数在bsp.c文件。用户可以修改这个函数实现CPU休眠和喂狗 */
  24. /* 判断定时器超时时间 */
  25. if(bsp_CheckTimer(0))
  26. {/* 每隔100ms 进来一次 */
  27. bsp_LedToggle(2);
  28. }/* 按键滤波和检测由后台systick中断服务程序实现,我们只需要调用bsp_GetKey读取键值即可。 */
  29. ucKeyCode = bsp_GetKey();/* 读取键值, 无键按下时返回 KEY_NONE = 0 */
  30. if(ucKeyCode != KEY_NONE)
  31. {switch(ucKeyCode)
  32. {caseKEY_DOWN_K1:/* K1键按下,串口1发送数据给串口2 */
  33. g_tUartParam.ucStart ='
  34. [p=null, 2, left]测试效果[/p][p=null, 2, left] forum.jpg [/p]


  35. [p=null, 2, left]转载自:网络文章来源于一种用于嵌入式通信传输以及存储设备的简易C语言实现方法原文链接:https://mp.weixin.qq.com/s/pVd-5WHpG8-cT_EmRe1p6g[/p];
  36. g_tUartParam.usCO2 =1;
  37. g_tUartParam.usPM25 =2;
  38. g_tUartParam.usHumidity =3;
  39. g_tUartParam.Temprature = ftest++;
  40. g_tUartParam.ulParam =5;
  41. g_tUartParam.ucEnd1 ='\r';
  42. g_tUartParam.ucEnd2 ='\n';
  43. comSendBuf(COM1, (uint8_t*)&g_tUartParam,sizeof(UART_T));
  44. printf("发送数据完成\r\n");
  45. break;
  46. default:/* 其它的键值不处理 */break;
  47. }
  48. }/* 串口2接收数据解析处理 */
  49. if(comGetChar(COM2, &read))
  50. {switch(ucStatus)
  51. {/* 状态0保证接收到0x01 */
  52. case0:if(read =='
  53. [p=null, 2, left]测试效果[/p][p=null, 2, left] forum.jpg [/p]


  54. [p=null, 2, left]转载自:网络文章来源于一种用于嵌入式通信传输以及存储设备的简易C语言实现方法原文链接:https://mp.weixin.qq.com/s/pVd-5WHpG8-cT_EmRe1p6g[/p])
  55. {
  56. ucStatus =1;
  57. buf[ucCount++] = read;
  58. }break;
  59. case1:
  60. buf[ucCount] = read;/* 接收够15个数据 */
  61. if((buf[ucCount-1] =='\r')&&(buf[ucCount] =='\n'))
  62. {/* 打印接收到的数据值 */
  63. printf("接收到的数据:\r\n");
  64. printf("pUartParam->usCO2 = %d\r\n", pUartParam->usCO2);
  65. printf("pUartParam->usPM25 = %d\r\n", pUartParam->usPM25);
  66. printf("pUartParam->usHumidity = %d\r\n", pUartParam->usHumidity);
  67. printf("pUartParam->Temprature = %f\r\n", pUartParam->Temprature);
  68. printf("pUartParam->ulParam = %d\r\n", pUartParam->ulParam);
  69. printf("\r\n");memset(buf,0,128);
  70. ucStatus =0;
  71. ucCount=0;
  72. }
  73. else{
  74. ucCount++;
  75. }break;
  76. default:break;
  77. }
  78. }
  79. }
  80. }

测试效果

forum.jpg




转载自:网络文章来源于一种用于嵌入式通信传输以及存储设备的简易C语言实现方法原文链接:https://mp.weixin.qq.com/s/pVd-5WHpG8-cT_EmRe1p6g