Bootstrap

Cubemx 串口接收十六进制的数据做fft处理

Cubemx配置,注意你要记得自己选那个USART的I/O脚,因为他自己选的可能不是你要用那个

kiel配置

把这个自动生成的中断删了,等一下我们会自己重新写一下

main.c文件:

头文件定义

#include "stdio.h"
#include "arm_math.h"
#include "arm_const_structs.h"
#include "string.h"

做好数据存放准备,设立数组

//串口接收数据定义的数组
#define USART_REC_MAX  1024 //最大接收字节数
#define RX_Buffer_size 1 //缓存大小
uint8_t USART1_RX_BUF[USART_REC_MAX];//接收缓存
volatile uint16_t USART1_RX_STA=0;//接收状态标记
uint8_t aRXBuffer1[RX_Buffer_size];//接收缓冲
uint16_t len1;//接收到的数据长度

//fft使用调用的数组

float data_in[USART_REC_MAX*2]={0};//实部和虚部,所以是两倍长度
//float data_t[USART_REC_MAX]={0};
float data_out[USART_REC_MAX/2];//输出信号
int j=0,i=-0;

重定义串口发送,使用printf函数

void USART1_Printf(const char* str);
int fputc(int c,FILE*stream)
{
	 HAL_UART_Transmit(&huart1,(unsigned char *)&c,1,HAL_MAX_DELAY);
	 return 1;
}

串口接收回调函数


void HAL_UART_RxCpltCallback(UART_HandleTypeDef* huart)
{
	if(huart->Instance == USART1)
	{
		
		if ((USART1_RX_STA & 0x8000) == 0) // 接收未完成
		{
//			HAL_UART_Transmit(&huart1,"开始中断\r\n",strlen("开始中断\r\n"),0xffff);
			if (USART1_RX_STA & 0x4000) // 接收到了0x0d
			{
				if (aRXBuffer1[0] != 0x0a) // 接收错误,重新开始
					USART1_RX_STA = 0;
				else // 接收完成了
					USART1_RX_STA |= 0x8000;
			}
			else // 还没收到0X0D
			{
				if (aRXBuffer1[0] == 0x0d)
					USART1_RX_STA |= 0x4000;
				else 
				{
					USART1_RX_BUF[USART1_RX_STA & 0X3FFF] = aRXBuffer1[0];
					USART1_RX_STA++;
					if (USART1_RX_STA > (USART_REC_MAX - 1))
						USART1_RX_STA = 0; // 接收数据错误,重新开始接收
				}
			}	
		}
//		HAL_UART_Receive_IT(&huart1,aRXBuffer1,RX_Buffer_size);
	}
}

串口中断函数

void USART1_IRQHandler(void)
{
    unsigned int timeout = 0;
    unsigned int maxDelay = 0x1ffff;//超时时间

    HAL_UART_IRQHandler(&huart1); // 调用HAL库中断处理公用函数
    timeout = 0;
    while (HAL_UART_GetState(&huart1) != HAL_UART_STATE_READY) // 等待就绪
    {
        timeout++; // 超时处理
        if (timeout > maxDelay)
            break;
    }

    timeout = 0;
    // 一次处理完成之后,重新开启中断并设置RxXferCount为1
    while (HAL_UART_Receive_IT(&huart1, (unsigned char*)aRXBuffer1, RX_Buffer_size) != HAL_OK) 
	{
        timeout++; // 超时处理
        if (timeout > maxDelay)
            break;
    }
}

main函数

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MPU Configuration--------------------------------------------------------*/
  MPU_Config();

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();

  MX_ADC1_Init();
  /* USER CODE BEGIN 2 */
  
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  HAL_ADC_Start_DMA(&hadc1,(uint32_t*)AdcRes,6);//6:字节
 
   HAL_UART_Receive_IT(&huart1, (unsigned char*)aRXBuffer1, RX_Buffer_size);

   while (1)
   {  
	  if(USART1_RX_STA & 0x8000)//判断是否有回车换行
	  {

		  len1=USART1_RX_STA & 0x3fff;
		  USART1_RX_STA=0;
		  
		 // memset(data_in, 0, sizeof(data_in));
		  for(j=0;j<USART_REC_MAX;j++)
		  {
			  data_in[j*2]=(float)USART1_RX_BUF[j];//实部
			  data_in[j*2+1]=0;//虚部
		  }
		  //调用FFT进行计算  
		  
		  arm_cfft_f32(&arm_cfft_sR_f32_len1024,data_in,0,1);
		  //将复数数据转换为实数,取模
		  arm_cmplx_mag_f32(data_in,data_out,len1/2);
		  for(i=0;i<512;i++)
		  {
			  //printf("hello");
			  printf("%f\r\n",data_out[i]/512);
		  }
		  HAL_Delay(10000);
		  memset(USART1_RX_BUF, 0, len1);
	  }
		
   }
}

最后说一下,如果你的fft得出来的数据全部都是很大的数,那是错的。。。。。。

;