STM32与匿名上位机通信——使用串口DMA实现

 

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

平台:

硬件: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
 

 

 

 

 

posted @ 2020-03-08 23:31  Yu_tiann  阅读(1353)  评论(0编辑  收藏  举报