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

平台:

硬件:STM32F405RGT6

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

软件:匿名上位机V6

数传模块操作简介:

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

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

/* usart2 for debug (Ano) */
void vUart2Config(void)
{
USART_InitTypeDef usart2;
GPIO_InitTypeDef gpio; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_USART2); gpio.GPIO_Pin = GPIO_Pin_2;
gpio.GPIO_Mode = GPIO_Mode_AF;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_Speed = GPIO_Speed_100MHz;
gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA,&gpio); gpio.GPIO_Pin = GPIO_Pin_3;
gpio.GPIO_Mode = GPIO_Mode_IN;
gpio.GPIO_Speed = GPIO_Speed_100MHz;
gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA,&gpio); USART_DeInit(USART2);
/* zigbee digital transmiter support up to 115200 */
usart2.USART_BaudRate = 115200;
usart2.USART_WordLength = USART_WordLength_8b;
usart2.USART_StopBits = USART_StopBits_1;
usart2.USART_Parity = USART_Parity_No;
usart2.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
usart2.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART2,&usart2); USART_Cmd(USART2,ENABLE); USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE); /* send dma */
{
DMA_InitTypeDef dma; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);
DMA_DeInit(DMA1_Stream6);
dma.DMA_Channel= DMA_Channel_4;
dma.DMA_PeripheralBaseAddr = (uint32_t)&(USART2->DR);
dma.DMA_Memory0BaseAddr = (uint32_t)SendToAno_Buff;
dma.DMA_DIR = DMA_DIR_MemoryToPeripheral;
dma.DMA_BufferSize = USART2_ANO_DMA_send_buffersize;
dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dma.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
dma.DMA_Mode = DMA_Mode_Normal;
dma.DMA_Priority = DMA_Priority_VeryHigh;
dma.DMA_FIFOMode = DMA_FIFOMode_Disable;
dma.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
dma.DMA_MemoryBurst = DMA_Mode_Normal;
dma.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA1_Stream6,&dma); DMA_ITConfig(DMA1_Stream6,DMA_IT_TC,ENABLE);
/* enable dma when data preparing finish */
DMA_Cmd(DMA1_Stream6,DISABLE);
}
} /* uart2 DMA send finish interrupt : send debug date (Ano) */
void DMA1_Stream6_IRQHandler(void)
{
if(DMA_GetFlagStatus(DMA1_Stream6, DMA_IT_TCIF6) == SET)
{
DMA_Cmd(DMA1_Stream6, DISABLE);
DMA_ClearFlag(DMA1_Stream6, DMA_FLAG_TCIF6);
DMA_ClearITPendingBit(DMA1_Stream6, DMA_IT_TCIF6);
}
}

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

/* start once usart2 dma send (for ANO) */
static void USART2_ANO_DMA_SEND(uint16_t sendsize)
{
DMA_Cmd(DMA1_Stream6, DISABLE);
/* set dma sendbuffer size */
DMA_SetCurrDataCounter(DMA1_Stream6, sendsize);
/* start usart dma send */
DMA_Cmd(DMA1_Stream6, ENABLE);
}

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

/* accroding to ANO earth station V6 protocol: userdata */
void ANOSend(void)
{
static uint8_t ANO_dataid = 1;
static uint16_t test_count = 0;
uint8_t senddata_cnt = 0;
uint8_t sumcheck = 0;
uint8_t errorcode_sum = 0;
int16_t yawAngle_100 = 0;
int16_t pitchAngle_100 = 0;
int16_t pctarget_yawAngle_100 = 0;
int16_t pctarget_pitchAngle_100 = 0;
int16_t sintest_data_100 = 0; switch(ANO_dataid)
{
/* id1 (F1) send gimbal angle */
case 1:
{
senddata_cnt = 0;
errorcode_sum = 0; SendToAno_Buff[senddata_cnt++] = 0xAA;
SendToAno_Buff[senddata_cnt++] = 0x05;
SendToAno_Buff[senddata_cnt++] = 0xAF;
SendToAno_Buff[senddata_cnt++] = (0xF0+ANO_dataid); /* jump over the data length byte */
senddata_cnt++; /* int16_t yawAngle */
yawAngle_100 = (int16_t)(imu.yawAngle*100);
SendToAno_Buff[senddata_cnt++] = BYTE1(yawAngle_100);
SendToAno_Buff[senddata_cnt++] = BYTE0(yawAngle_100); /* int16_t pitchAngle */
pitchAngle_100 = (int16_t)(imu.pitchAngle*100);
SendToAno_Buff[senddata_cnt++] = BYTE1(pitchAngle_100);
SendToAno_Buff[senddata_cnt++] = BYTE0(pitchAngle_100); SendToAno_Buff[4] = senddata_cnt-5; /* sum check calculate */
sumcheck = 0; for(uint8_t i=0; i < (SendToAno_Buff[4]+5); i++)
{
sumcheck += SendToAno_Buff[i];
} SendToAno_Buff[senddata_cnt++] = sumcheck; USART2_ANO_DMA_SEND(senddata_cnt); break;
} /* id2 (F2) send PC data */
case 2:
{
senddata_cnt = 0; SendToAno_Buff[senddata_cnt++] = 0xAA;
SendToAno_Buff[senddata_cnt++] = 0x05;
SendToAno_Buff[senddata_cnt++] = 0xAF;
SendToAno_Buff[senddata_cnt++] = (0xF0+ANO_dataid); /* jump over the data length byte */
senddata_cnt++; /* int16_t PCtarget_yawangle */
pctarget_yawAngle_100 = (int16_t)(PC_Recv.PCTargetYaw*100);
SendToAno_Buff[senddata_cnt++] = BYTE1(pctarget_yawAngle_100);
SendToAno_Buff[senddata_cnt++] = BYTE0(pctarget_yawAngle_100); /* int16_t PCtarget_pitchangle */
pctarget_pitchAngle_100 = (int16_t)(PC_Recv.PCTargetPitch*100);
SendToAno_Buff[senddata_cnt++] = BYTE1(pctarget_pitchAngle_100);
SendToAno_Buff[senddata_cnt++] = BYTE0(pctarget_pitchAngle_100); SendToAno_Buff[4] = senddata_cnt-5; /* sum check calculate */
sumcheck = 0; for(uint8_t i=0; i < (SendToAno_Buff[4]+5); i++)
{
sumcheck += SendToAno_Buff[i];
} SendToAno_Buff[senddata_cnt++] = sumcheck; USART2_ANO_DMA_SEND(senddata_cnt); break;
} /* id2 (F3) send test data */
case 3:
{
senddata_cnt = 0;
test_count++; SendToAno_Buff[senddata_cnt++] = 0xAA;
SendToAno_Buff[senddata_cnt++] = 0x05;
SendToAno_Buff[senddata_cnt++] = 0xAF;
SendToAno_Buff[senddata_cnt++] = (0xF0+ANO_dataid); /* jump over the data length byte */
senddata_cnt++; /* int16_t test_sindata 100times */
sintest_data_100 = (int16_t)(sin((float)test_count*3.14f/180.0f)*100);
SendToAno_Buff[senddata_cnt++] = BYTE1(sintest_data_100);
SendToAno_Buff[senddata_cnt++] = BYTE0(sintest_data_100); SendToAno_Buff[4] = senddata_cnt-5; /* sum check calculate */
sumcheck = 0; for(uint8_t i=0; i < (SendToAno_Buff[4]+5); i++)
{
sumcheck += SendToAno_Buff[i];
} SendToAno_Buff[senddata_cnt++] = sumcheck; USART2_ANO_DMA_SEND(senddata_cnt); break;
}
} ANO_dataid++; /* choose the return number */
if(ANO_TEST)
{
if(ANO_dataid >= 4)
{
ANO_dataid = 1;
}
}
else if(!ANO_TEST)
{
if(ANO_dataid >= 3)
{
ANO_dataid = 1;
}
}
}

——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. 1年之后的拿高工资的资本,Java线程

    只要开启线程,都会开启一块对应的栈内存,然后进行同步执行. -- 谈斌 线程是CPU用来处理程序的资源,线程的执行是抢占式的. 线程开启方式: 创建一个类,继承Thread类.重写 run(), 并在 ...

  2. 3、Hive-sql优化,数据倾斜处理

    一.Hive-sql优化 #增加reducer任务数量(拉取数量分流) ; #在同一个sql中的不同的job是否可以同时运行,默认为false set hive.exec.parallel=true; ...

  3. 【Spark】SparkStreaming和Kafka的整合

    文章目录 Streaming和Kafka整合 概述 使用0.8版本下Receiver DStream接收数据进行消费 步骤 一.启动Kafka集群 二.创建maven工程,导入jar包 三.创建一个k ...

  4. STM32 IAP 升级官方资料汇总

    整理了一下SMT32标准外设库进行IAP升级的官方demo: 标准库版本 STM32F10xxx in-application programming using the USART (AN2557) ...

  5. [whu1568]dp优化

    http://acm.whu.edu.cn/land/problem/detail?problem_id=1568 思路:先将所有数分解,得到2,3,5,7的个数,转化为用这些2,3,5,7" ...

  6. HMM-维特比算法理解与实现(python)

    HMM-前向后向算法理解与实现(python) HMM-维特比算法理解与实现(python) 解码问题 给定观测序列 \(O=O_1O_2...O_T\),模型 \(\lambda (A,B,\pi) ...

  7. Windows 10 IoT Core用PWM控制器控制树莓派LED灯亮度

    我接到一个需求,需要调节LED灯的亮度,且是从上位机进行控制,我了解到树莓派也有PWM,就准备通过PWM来控制灯的亮度. PWM又叫脉宽调制,是用微处理器的数字输出来对模拟电路进行控制,对模拟信号电平 ...

  8. Mysql 常用函数(8)- concat 函数

    Mysql常用函数的汇总,可看下面系列文章 https://www.cnblogs.com/poloyy/category/1765164.html concat 的作用 连接多个字符串 concat ...

  9. python--正则表达式中(.)(*)(.*?)以及re.S的认识

    https://yiyibooks.cn/xx/python_352/library/re.html 看command: #-*-coding:gb2312-*- __author__ = 'fuda ...

  10. 接口(API)测试理念

    什么是接口测试 接口测试就是针对软件对外提供服务的接口的输入输出进行测试,以及接口间相互逻辑的测试,验证接口功能与接口描述文档的一致性: 测试的重点是检查数据交互.传递.和控制管理过程以及系统间的相互 ...