关于DR16数据的获取和处理

DR16

关于DR16数据的获取和处理

DR16&DT7

采用DBUS协议数据

  1. 波特率要调至100kbps
  2. 单位数据长度 8
  3. 奇偶校验位 偶校验
  4. 结束位 1
  5. 流控 无

注意!!!

cubemx配置的时候,长度要配成9

因为那个是包括校验位的

遥控器不同遥杆传输的数据类型

4b9pLV.png鼠标及按键信息

4b9KeK.png

遥控器通道与控制开关

4b93JH.png

控制代码

1.定义相应结构体

typedef struct 
{
	struct 
	{
		int16_t ch0;
		int16_t ch1;
		int16_t ch2;
		int16_t ch3;
		int8_t s1;
		int8_t s2;
    }remote;
    struct 
    {
        int16_t x;
        int16_t y;
        int16_t z;
        int8_t press_left;
        int8_t press_right;

    }mouse;

    union {
        uint16_t key_code;
        struct 
        {
            uint16_t W :1;
            uint16_t S :1;
            uint16_t A :1;
            uint16_t D :1;
            uint16_t Q :1;
            uint16_t E :1;
            uint16_t Shift :1;
            uint16_t Ctrl :1;
        }bit;
    }key;
 }RC_Ctrl_t;

2.写它的解包函数

减掉1024是想要把初始值变为0

`void Get_DR16_Data(uint8_t *Buff)
	{
		RC_CtrlData.remote .ch0 =(Buff[0]|Buff[1]<<8)&0x07FF;
		RC_CtrlData.remote .ch0 -=1024;
	    RC_CtrlData.remote .ch1 =(Buff [1]>>3|Buff[2]<<5)&0x07FF;
		RC_CtrlData.remote .ch1 -=1024;
		RC_CtrlData.remote .ch2 =(Buff[2]>>6|Buff[3]<<2|Buff[4]<<10)&0x07FF;
		RC_CtrlData.remote .ch2 -=1024;
		RC_CtrlData.remote .ch3 =(Buff[4]>>1|Buff[5]<<7)&0x07FF;
		RC_CtrlData.remote .ch3 -=1024;
		RC_CtrlData.remote .s1 =(Buff[5]>>4&0x000C)>>2;
		RC_CtrlData.remote .s2 =(Buff[5]>>4&0x003);
		RC_CtrlData.mouse .x =(Buff[6]|Buff[7]<<8);
		RC_CtrlData.mouse .y =(Buff[8]|Buff[9]<<8);
		RC_CtrlData.mouse .z =(Buff[10]|Buff[11]<<8);
		RC_CtrlData.mouse .press_left =(Buff[12]);
		RC_CtrlData.mouse .press_right =(Buff[13]);
	}`

串口1接收原始数据并进行储存

串口dma空闲中断接收

  1. cubemx配置

串口2接收配置

4bpsr6.png

串口2 dma接收配置

4b9aef.png

串口1 发送到上位机配置

4b9DYQ.png

串口1 dma发送配置

因为我用的上位机内部函数有写好要用dma发送,所以才开了dma

4b9RmV.png

  1. 串口2dma不定长收

串口2中断函数

`if(__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE))
 {
	 USART_Receive_IDLE(&huart2);
 }
 RecHandle(usart2_rx__buffer,usart2_tx__len);`

另外USART_Receive_IDLE()定义如下

void USART_Receive_IDLE(UART_HandleTypeDef *huart)
{
	uint16_t i=0;
	BaseType_t pxHigherPriorityTaskWoken = pdFALSE;
	static USART_COB Usart_RxCOB;
    if(__HAL_UART_ENABLE_IT(&huart2 ,UART_IT_IDLE)!=RESET ) //触发空闲中断
    {
        if(huart->Instance ==USART2 ) //判断是串口2
        {
            __HAL_UART_CLEAR_FEFLAG(&huart2); //清除中断标志位
            HAL_UART_DMAStop (&huart2);       //关闭dma
            i= huart->Instance->SR;           //软件序列清零 先SR后DR
            i= huart->Instance->DR;
            i=hdma_usart2_rx.Instance->NDTR; //计算dma里未传输的数目
             usart2_tx__len=128-i; //计算dma传输的数目

            /*用队列替代简单的mencpy操作*/
            if(USART_RXPORT != NULL)
            {
                Usart_RxCOB.port_num=1;
                Usart_RxCOB.len = usart2_tx__len;
                Usart_RxCOB.address = usart2_rx__buffer;
                		xQueueSendFromISR(USART_RXPORT,&Usart_RxCOB,&pxHigherPriorityTaskWoken);
            }
/*本来是利用简单的将usart2_rx__buffer copy到usart1_tx__buffer中,将其作为一个缓存
            if(usart2_rx__flag==0)
            {
               //把接收到的东西发送出去
                memcpy(usart1_tx__buffer,usart2_rx__buffer,usart2_tx__len); 
                usart2_rx__flag =1;
            }
            */
            HAL_UART_Receive_DMA(huart,(uint8_t *)usart2_rx__buffer,128);
		}
	}
}
  1. 用freertos的队列暂存串口2中接受的数据,并在任务中解包并发送至上位机
`/*对DR16的数据进行处理,然后发送到上位机*/
TaskHandle_t Freertos_DR16_Data_Handle;
void Freertos_DR16_Data(void * argument);
void Freertos_DR16_Data_Init(void)
{
	xTaskCreate(Freertos_DR16_Data , "Freertos_DR16_Data",128 ,NULL ,6,&Freertos_DR16_Data_Handle);
}
void Freertos_DR16_Data(void * argument)
{
	static USART_COB Usart_RxCOB;
	TickType_t xLastWakeTime_t = xTaskGetTickCount();
	TickType_t _xTicksToWait = pdMS_TO_TICKS(1);
  for(;;)
  {
//		if( usart2_rx__flag==1)`

`//启用队列处理函数
		if(xQueueReceive(USART_RXPORT,&Usart_RxCOB,portMAX_DELAY) == pdPASS)   
		{
			Get_DR16_Data(Usart_RxCOB.address);    //解包得到的DR16的数据
			vTaskDelayUntil(&xLastWakeTime_t, _xTicksToWait);
//			usart2_rx__flag = 0;
			Sent_Contorl(&huart1); //发送数据到上位机
		}
	}
}`
出现的问题
  1. 本来想外加queue.cqueue.h文件

    原因:对freertos的功能概念等不清,不明白队列的含义(这个会在关于freertos那张笔记进行介绍)

  2. 在接收回调函数里面把数据放到队列以后用memset()usart2_rx__buffer这个数组进行清零操作

    原因

    1. 没有考虑到这样子做由于传的是地址,清空会导致freertos在执行对数据进行解包的任务时,数据发生丢失。
    2. 下次写入数据时它本身便会对已有数据进行一个覆盖,根本就不需要清空
  • 16
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
对于AT32F403A微控制器的ADC数据处理,您可以按照以下步骤进行: 1. 初始化ADC模块:配置ADC通道、时钟源、采样时间等参数。 2. 启动ADC转换:通过设置相关寄存器,开始进行ADC转换。 3. 等待转换完成:可以使用轮询方式或者中断方式等待ADC转换完成。 4. 读取转换结果:通过读取相关寄存器,获取ADC转换结果。 5. 数据处理:根据应用需求对ADC转换结果进行处理。例如,可以进行数据滤波、数据校准、数据转换等操作。 下面是一个示例代码,演示了如何对AT32F403A的ADC数据进行处理: ```c #include <stdio.h> #include "at32f4xx.h" void ADC_Init(void) { /* 配置ADC通道和采样时间 */ ADC1->SMPR1 = 0x00000000; // 采样时间为1.5个周期 ADC1->SQR1 = 0x00000000; // 选择通道0作为转换顺序1 } void ADC_StartConversion(void) { /* 启动ADC转换 */ ADC1->CR2 |= ADC_CR2_ADON; } void ADC_WaitForConversionComplete(void) { /* 等待转换完成 */ while (!(ADC1->SR & ADC_SR_EOC)) ; } uint16_t ADC_GetConversionResult(void) { /* 读取转换结果 */ return ADC1->DR; } int main(void) { ADC_Init(); while (1) { ADC_StartConversion(); ADC_WaitForConversionComplete(); uint16_t adcValue = ADC_GetConversionResult(); // 在这里进行数据处理操作 // ... printf("ADC Value: %hu\n", adcValue); } } ``` 在上述示例代码中,我们首先进行了ADC的初始化配置,然后在主循环中启动ADC转换,并等待转换完成。之后,我们可以对ADC转换结果进行数据处理,并将结果打印输出。 请注意,以上示例代码仅供参考,具体的数据处理操作需根据您的应用需求进行相应的修改和扩展。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Teviour Camdylre

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值