背景:匿名上位机功能强大,这里想要采用匿名上位机输出一些调试信息,以波形的形式显示,方便观察和调试。

平台:

硬件:STM32F405RGT6

通信:2.4G zigbee无线串口收发模块 CC2530

软件:匿名上位机V6

数传模块操作简介:

配置 代码:(注意以下代码中不包含中断优先级的配置,个人习惯将所有nvic的配置写在一个单独的函数中)

这里采用UART2 DMA发送的方式 将数据通过数传发送给匿名上位机。采用DMA传输完成中断,可以实现不定长数据的传输。

  1. /* usart2 for debug (Ano) */
  2. void vUart2Config(void)
  3. {
  4. USART_InitTypeDef usart2;
  5. GPIO_InitTypeDef gpio;
  6. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
  7. RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
  8. GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_USART2);
  9. GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_USART2);
  10. gpio.GPIO_Pin = GPIO_Pin_2;
  11. gpio.GPIO_Mode = GPIO_Mode_AF;
  12. gpio.GPIO_OType = GPIO_OType_PP;
  13. gpio.GPIO_Speed = GPIO_Speed_100MHz;
  14. gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
  15. GPIO_Init(GPIOA,&gpio);
  16. gpio.GPIO_Pin = GPIO_Pin_3;
  17. gpio.GPIO_Mode = GPIO_Mode_IN;
  18. gpio.GPIO_Speed = GPIO_Speed_100MHz;
  19. gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
  20. GPIO_Init(GPIOA,&gpio);
  21. USART_DeInit(USART2);
  22. /* zigbee digital transmiter support up to 115200 */
  23. usart2.USART_BaudRate = 115200;
  24. usart2.USART_WordLength = USART_WordLength_8b;
  25. usart2.USART_StopBits = USART_StopBits_1;
  26. usart2.USART_Parity = USART_Parity_No;
  27. usart2.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
  28. usart2.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  29. USART_Init(USART2,&usart2);
  30. USART_Cmd(USART2,ENABLE);
  31. USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
  32. /* send dma */
  33. {
  34. DMA_InitTypeDef dma;
  35. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);
  36. DMA_DeInit(DMA1_Stream6);
  37. dma.DMA_Channel= DMA_Channel_4;
  38. dma.DMA_PeripheralBaseAddr = (uint32_t)&(USART2->DR);
  39. dma.DMA_Memory0BaseAddr = (uint32_t)SendToAno_Buff;
  40. dma.DMA_DIR = DMA_DIR_MemoryToPeripheral;
  41. dma.DMA_BufferSize = USART2_ANO_DMA_send_buffersize;
  42. dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  43. dma.DMA_MemoryInc = DMA_MemoryInc_Enable;
  44. dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  45. dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  46. dma.DMA_Mode = DMA_Mode_Normal;
  47. dma.DMA_Priority = DMA_Priority_VeryHigh;
  48. dma.DMA_FIFOMode = DMA_FIFOMode_Disable;
  49. dma.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
  50. dma.DMA_MemoryBurst = DMA_Mode_Normal;
  51. dma.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  52. DMA_Init(DMA1_Stream6,&dma);
  53. DMA_ITConfig(DMA1_Stream6,DMA_IT_TC,ENABLE);
  54. /* enable dma when data preparing finish */
  55. DMA_Cmd(DMA1_Stream6,DISABLE);
  56. }
  57. }
  58. /* uart2 DMA send finish interrupt : send debug date (Ano) */
  59. void DMA1_Stream6_IRQHandler(void)
  60. {
  61. if(DMA_GetFlagStatus(DMA1_Stream6, DMA_IT_TCIF6) == SET)
  62. {
  63. DMA_Cmd(DMA1_Stream6, DISABLE);
  64. DMA_ClearFlag(DMA1_Stream6, DMA_FLAG_TCIF6);
  65. DMA_ClearITPendingBit(DMA1_Stream6, DMA_IT_TCIF6);
  66. }
  67. }

DMA发送函数:(初始化时不使能DMA,当数据准备好之后,根据待发送的数据长度,设定DMA发送的长度,同时使能DMA,启动一次发送,当每次DMA发送完成后,在传输完成中断中,关闭DMA,等待下一次数据准备好,循环以上过程)

  1. /* start once usart2 dma send (for ANO) */
  2. static void USART2_ANO_DMA_SEND(uint16_t sendsize)
  3. {
  4. DMA_Cmd(DMA1_Stream6, DISABLE);
  5. /* set dma sendbuffer size */
  6. DMA_SetCurrDataCounter(DMA1_Stream6, sendsize);
  7. /* start usart dma send */
  8. DMA_Cmd(DMA1_Stream6, ENABLE);
  9. }

匿名上位机数据打包及循环发送:(使用的是匿名V6版本的上位机,具体协议请参考对应版本的上位机协议,这里使用匿名上位机提供的用户数据格式发送数据,ID分别为F1,F2,F3的三组不定长数据)

  1. /* accroding to ANO earth station V6 protocol: userdata */
  2. void ANOSend(void)
  3. {
  4. static uint8_t ANO_dataid = 1;
  5. static uint16_t test_count = 0;
  6. uint8_t senddata_cnt = 0;
  7. uint8_t sumcheck = 0;
  8. uint8_t errorcode_sum = 0;
  9. int16_t yawAngle_100 = 0;
  10. int16_t pitchAngle_100 = 0;
  11. int16_t pctarget_yawAngle_100 = 0;
  12. int16_t pctarget_pitchAngle_100 = 0;
  13. int16_t sintest_data_100 = 0;
  14. switch(ANO_dataid)
  15. {
  16. /* id1 (F1) send gimbal angle */
  17. case 1:
  18. {
  19. senddata_cnt = 0;
  20. errorcode_sum = 0;
  21. SendToAno_Buff[senddata_cnt++] = 0xAA;
  22. SendToAno_Buff[senddata_cnt++] = 0x05;
  23. SendToAno_Buff[senddata_cnt++] = 0xAF;
  24. SendToAno_Buff[senddata_cnt++] = (0xF0+ANO_dataid);
  25. /* jump over the data length byte */
  26. senddata_cnt++;
  27. /* int16_t yawAngle */
  28. yawAngle_100 = (int16_t)(imu.yawAngle*100);
  29. SendToAno_Buff[senddata_cnt++] = BYTE1(yawAngle_100);
  30. SendToAno_Buff[senddata_cnt++] = BYTE0(yawAngle_100);
  31. /* int16_t pitchAngle */
  32. pitchAngle_100 = (int16_t)(imu.pitchAngle*100);
  33. SendToAno_Buff[senddata_cnt++] = BYTE1(pitchAngle_100);
  34. SendToAno_Buff[senddata_cnt++] = BYTE0(pitchAngle_100);
  35. SendToAno_Buff[4] = senddata_cnt-5;
  36. /* sum check calculate */
  37. sumcheck = 0;
  38. for(uint8_t i=0; i < (SendToAno_Buff[4]+5); i++)
  39. {
  40. sumcheck += SendToAno_Buff[i];
  41. }
  42. SendToAno_Buff[senddata_cnt++] = sumcheck;
  43. USART2_ANO_DMA_SEND(senddata_cnt);
  44. break;
  45. }
  46. /* id2 (F2) send PC data */
  47. case 2:
  48. {
  49. senddata_cnt = 0;
  50. SendToAno_Buff[senddata_cnt++] = 0xAA;
  51. SendToAno_Buff[senddata_cnt++] = 0x05;
  52. SendToAno_Buff[senddata_cnt++] = 0xAF;
  53. SendToAno_Buff[senddata_cnt++] = (0xF0+ANO_dataid);
  54. /* jump over the data length byte */
  55. senddata_cnt++;
  56. /* int16_t PCtarget_yawangle */
  57. pctarget_yawAngle_100 = (int16_t)(PC_Recv.PCTargetYaw*100);
  58. SendToAno_Buff[senddata_cnt++] = BYTE1(pctarget_yawAngle_100);
  59. SendToAno_Buff[senddata_cnt++] = BYTE0(pctarget_yawAngle_100);
  60. /* int16_t PCtarget_pitchangle */
  61. pctarget_pitchAngle_100 = (int16_t)(PC_Recv.PCTargetPitch*100);
  62. SendToAno_Buff[senddata_cnt++] = BYTE1(pctarget_pitchAngle_100);
  63. SendToAno_Buff[senddata_cnt++] = BYTE0(pctarget_pitchAngle_100);
  64. SendToAno_Buff[4] = senddata_cnt-5;
  65. /* sum check calculate */
  66. sumcheck = 0;
  67. for(uint8_t i=0; i < (SendToAno_Buff[4]+5); i++)
  68. {
  69. sumcheck += SendToAno_Buff[i];
  70. }
  71. SendToAno_Buff[senddata_cnt++] = sumcheck;
  72. USART2_ANO_DMA_SEND(senddata_cnt);
  73. break;
  74. }
  75. /* id2 (F3) send test data */
  76. case 3:
  77. {
  78. senddata_cnt = 0;
  79. test_count++;
  80. SendToAno_Buff[senddata_cnt++] = 0xAA;
  81. SendToAno_Buff[senddata_cnt++] = 0x05;
  82. SendToAno_Buff[senddata_cnt++] = 0xAF;
  83. SendToAno_Buff[senddata_cnt++] = (0xF0+ANO_dataid);
  84. /* jump over the data length byte */
  85. senddata_cnt++;
  86. /* int16_t test_sindata 100times */
  87. sintest_data_100 = (int16_t)(sin((float)test_count*3.14f/180.0f)*100);
  88. SendToAno_Buff[senddata_cnt++] = BYTE1(sintest_data_100);
  89. SendToAno_Buff[senddata_cnt++] = BYTE0(sintest_data_100);
  90. SendToAno_Buff[4] = senddata_cnt-5;
  91. /* sum check calculate */
  92. sumcheck = 0;
  93. for(uint8_t i=0; i < (SendToAno_Buff[4]+5); i++)
  94. {
  95. sumcheck += SendToAno_Buff[i];
  96. }
  97. SendToAno_Buff[senddata_cnt++] = sumcheck;
  98. USART2_ANO_DMA_SEND(senddata_cnt);
  99. break;
  100. }
  101. }
  102. ANO_dataid++;
  103. /* choose the return number */
  104. if(ANO_TEST)
  105. {
  106. if(ANO_dataid >= 4)
  107. {
  108. ANO_dataid = 1;
  109. }
  110. }
  111. else if(!ANO_TEST)
  112. {
  113. if(ANO_dataid >= 3)
  114. {
  115. ANO_dataid = 1;
  116. }
  117. }
  118. }

——cloud over sky

——2020/3/7

STM32与匿名上位机通信——使用串口DMA实现的更多相关文章

  1. UR机器人通信--上位机通信(python)

    一.通信socket socket()函数 Python 中,我们用 socket()函数来创建套接字,语法格式如下: socket.socket([family[, type[, proto]]]) ...

  2. USB上位机通信:CyAPI

    至今的工作中,有USB接口通信的需求,记录一下. 建立一个USB设备对象 CCyUSBDevice *USBDevice = new CCyUSBDev(Handle): 打开USB设备 一个USB设 ...

  3. C#做一个简单的进行串口通信的上位机

    C#做一个简单的进行串口通信的上位机   1.上位机与下位机 上位机相当于一个软件系统,可以用于接收数据.控制数据.即可以对接收到的数据直接发送操控命令来操作数据.上位机可以接收下位机的信号.下位机是 ...

  4. 2018最新mfc作为上位机接收硬件端USB或串口数据显示成图片 解决串口接收数据丢字节丢包问题

    原文作者:aircraft 原文地址:https://www.cnblogs.com/DOMLX/p/9490616.html 本文用的是VS2013MFC写串口数据接收: 第一步:首先建立一个MFC ...

  5. 上位机开发之三菱Q系列PLC通信实践

    经常关注我们公众号或者公开课的学员(如果还没有关注的话,左上角点击一波关注)应该知道,我们会经常使用西门子PLC,其实对于其他品牌的PLC,我们都会讲到,包括三菱.欧姆龙.基恩士.松下及国产台达.信捷 ...

  6. 上位机开发之三菱FX3U以太网通信实践

    上次跟大家介绍了一下上位机与三菱Q系列PLC通信的案例,大家可以通过点击这篇文章:上位机开发之三菱Q系列PLC通信实践(←戳这里) 今天以三菱FX3U PLC为例,跟大家介绍一下,如何实现上位机与其之 ...

  7. 上位机开发之西门子PLC-S7通信实践

    写在前面: 就目前而言,在中国的工控市场上,西门子仍然占了很大的份额,因此对于上位机开发而言,经常会存在需要与西门子PLC进行通信的情况.然后对于西门子PLC来说,通信方式有很多,下面简单列举一下: ...

  8. RT-Thread中的串口DMA分析

    这里分析一下RT-Thread中串口DMA方式的实现,以供做新处理器串口支持时的参考. 背景 在如今的芯片性能和外设强大功能的情况下,串口不实现DMA/中断方式操作,我认为在实际项目中基本是不可接受的 ...

  9. [python] 3 、基于串口通信的嵌入式设备上位机自动测试程序框架(简陋框架)

    星期一, 20. 八月 2018 01:53上午 - beautifulzzzz 1.前言 做类似zigbee.ble mesh...无线网络节点性能测试的时候,手动操作然后看表象往往很难找出真正的原 ...

随机推荐

  1. redis-py中的坑

    今天发现,使用redis-py从redis中获取的数据竟然是加密的. conn = redis.Redis(host='redis_serverip', port=6379, password='re ...

  2. python-文件字符分布【get()函数与.sort(key=lambda x:x[0],reverse = False)】

    文件字符分布 描述 统计附件文件的小写字母a-z的字符分布,即出现a-z字符的数量,并输出结果.‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬ ...

  3. 消息队列,RabbitMQ、Kafka、RocketMQ

    目录 1.消息列队概述 1.1消息队列MQ 1.2AMQP和JMS 1.2.1AMQP 1.2.2JMS 1.2.3AMOP 与 JMS 区别 1.3消息队列产品 1.3.1 Kafka 1.3.2 ...

  4. webpack----js的静态模块打包器

    webpack----js的静态模块打包器 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 简介 webpack 是一个现代 J ...

  5. Spring官网阅读(三)自动注入

    上篇文章我们已经学习了1.4小结中关于依赖注入跟方法注入的内容.这篇文章我们继续学习这结中的其他内容,顺便解决下我们上篇文章留下来的一个问题-----注入模型. 文章目录 前言: 自动注入: 自动注入 ...

  6. 简单谈谈Spring的IoC

    一.前言   这几天正在复习Spring的相关内容,同时想要对Spring的实现原理做一些深入的研究.今天看了看Spring中IoC的实现,找到了一篇非常详细的博客,研究了一个下午,看完之后唯一的感受 ...

  7. webpack4使用出现ERROR in Template execution failed: ReferenceError: HtmlwebpackPlugin is not defined

    问题描述 博主在使用webpack4的时候,使用了ejs文件,先附上ejs中的代码: <!doctype html> <html lang="zh-CN"> ...

  8. PDF怎么转换成Word,免费,完整的那种

      简介 PDF可以分为文字型PDF和图片型PDF,文字型PDF即可以选中文字内容的PDF,反之图片型PDF即无法选中文字的PDF,其内容实际上是图片. 本文针对不同类型,介绍PDF转Word方法,可 ...

  9. 如何将Altera官方提供的CADENCE.OLB应用于altium Designer中

  10. Web(4)servlet

    一.servlet.GenericServlet.HttpServlet 1.servlet具有四个生命周期方法 特性:单例模式,线程不安全,效率高 2.servletConfig接口对应根元素对应的 ...