基本信息
源码名称:STM32与迪文屏通讯 DMA模式
源码大小:2.87M
文件格式:.rar
开发语言:C/C++
更新时间:2021-03-16
   友情提示:(无需注册或充值,赞助后即可获取资源下载链接)

     嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300

本次赞助数额为: 2 元 
   源码介绍
使用DMA传送通过串口发送数据

#include "stm32f1xx_hal.h"
#include "usart/bsp_usartx.h"
#include "led/bsp_led.h"
#include "string.h"
#include "GeneralTIM/bsp_GeneralTIM.h"

/* 私有类型定义 --------------------------------------------------------------*/
/* 私有宏定义 ----------------------------------------------------------------*/
#define SENDBUFF_SIZE        20         // 串口DMA发送缓冲区大小
/* 私有变量 ------------------------------------------------------------------*/

__IO uint8_t RxBuffer[50]; 

__IO uint8_t  RX_5A_OK      = 0;        // 接收帧头0xA5标志
__IO uint8_t  RX_A5_OK      = 0;        // 接收帧头0x5A标志
__IO uint8_t  Rx_Cnt        = 0;        // 串口接收计数

__IO uint8_t  aRxBufferTemp = 0;        // 串口接收缓存
__IO uint8_t  Rx_Finish     = 0;        // 串口数据接收完成标志
__IO uint16_t timer_count   = 0;        // 定时计数

uint8_t aRxBuffer;                      // 接收数据 
uint8_t aTxBuffer[SENDBUFF_SIZE];       // 串口DMA发送缓冲区

/* 扩展变量 ------------------------------------------------------------------*/
/* 私有函数原形 --------------------------------------------------------------*/

void Fill_DATA(void);
void Analytical_Data(void);
/* 函数体 --------------------------------------------------------------------*/
/**
  * 函数功能: 系统时钟配置
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明: 无
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;  // 外部晶振,8MHz
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;  // 9倍频,得到72MHz主时钟
  HAL_RCC_OscConfig(&RCC_OscInitStruct);

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;       // 系统时钟:72MHz
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;              // AHB时钟:72MHz
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;               // APB1时钟:36MHz
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;               // APB2时钟:72MHz
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);

  // HAL_RCC_GetHCLKFreq()/1000    1ms中断一次
// HAL_RCC_GetHCLKFreq()/100000 10us中断一次
// HAL_RCC_GetHCLKFreq()/1000000 1us中断一次
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);  // 配置并启动系统滴答定时器
  /* 系统滴答定时器时钟源 */
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
  /* 系统滴答定时器中断优先级配置 */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}

/**
  * 函数功能: 主函数.
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明: 无
  */
int main(void)
{
  /* 复位所有外设,初始化Flash接口和系统滴答定时器 */
  HAL_Init();
  /* 配置系统时钟 */
  SystemClock_Config();

  /* 初始化LED */
  LED_GPIO_Init();
  
  /* 基本定时器初始化:1ms中断一次 */
  GENERAL_TIMx_Init();
  
  /* 在中断模式下启动定时器 */
  HAL_TIM_Base_Start_IT(&htimx);
  
  /* 初始化串口并配置串口中断优先级 */
  MX_USARTx_Init();
   
  /* 使能接收,进入中断回调函数 */
   HAL_UART_Receive_IT(&husartx,&aRxBuffer,1);
  
  /* 无限循环 */
  while (1)
  {
    /* 串口使用DMA传输数据不占用CPU,可以正常运行其他函数 */
    Analytical_Data();    //调用数据解析函数
    
    if(timer_count==1000) //串口定时发送数据
    {
      /* 计时清零 */
      timer_count = 0;
      /* 调用函数刷新数据 */
      Fill_DATA();
      /* 使用DMA传输数据到电脑端 */
      HAL_UART_Transmit_DMA(&husartx,aTxBuffer, SENDBUFF_SIZE);
    }
  }
}

/**
  * 函数功能: 填充要发送的数据
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
void Fill_DATA(void)
{
  /*填充将要发送的数据*/

  aTxBuffer[0]  = 0x5A;
  aTxBuffer[1]  = 0xA5;
  
  aTxBuffer[2]  = 0x10;
  aTxBuffer[3]  = 0x82;
  
  aTxBuffer[4]  = 0x00;
  aTxBuffer[5]  = 0x01;
  aTxBuffer[6]  = 0x02;
  aTxBuffer[7]  = 0x03;
  aTxBuffer[8]  = 0x04;
  aTxBuffer[9]  = 0x05;
  aTxBuffer[10] = 0x06;
  aTxBuffer[11] = 0x07;
  aTxBuffer[12] = 0x08;
  aTxBuffer[13] = 0x09;
  aTxBuffer[14] = 0x0A;
  aTxBuffer[15] = 0x0B;
  aTxBuffer[16] = 0x0C;
  aTxBuffer[17] = 0x0D;
  aTxBuffer[18] = 0x0E;
  aTxBuffer[19] = 0x0F;
}


/**
  * 函数功能: 解析串口接收到的数据
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
void Analytical_Data(void)
{
  if(Rx_Finish)
  {
    if((RxBuffer[0]==0x06)&&(RxBuffer[1]==0x83)&&(RxBuffer[2]==0x00)
     &&(RxBuffer[3]==0x00)&&(RxBuffer[4]==0x01)&&(RxBuffer[5]==0x00))
    {
      if(RxBuffer[6]==0x00)
      {
        LED1_TOGGLE;
      }
      if(RxBuffer[6]==0x01)
      {
        LED2_TOGGLE;
      }
    }
    Rx_Finish = 0;
  }
}

/**
  * 函数功能: 串口接收完成回调函数
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
  if(UartHandle->Instance==USART1)
  { 
    aRxBufferTemp = aRxBuffer;

    if(RX_5A_OK)
    {
      if(RX_A5_OK)
      {
        RxBuffer[Rx_Cnt] = aRxBufferTemp;
        Rx_Cnt ;

        if(Rx_Cnt == RxBuffer[0] 1) //接收完成
        {              
          RX_5A_OK  = 0;
          RX_A5_OK  = 0;
          Rx_Finish = 1;
        }
      }
      else
      {
        if(aRxBufferTemp == 0xA5)
        {
          RX_A5_OK = 1;
          Rx_Cnt   = 0;
        }
      }
    }
    else 
    {
      if(aRxBufferTemp == 0x5A)
      {
        RX_5A_OK = 1;
      }
    }

    HAL_UART_Receive_IT(&husartx,&aRxBuffer,1); //开启下一次接收中断
  }
}

/**
  * 函数功能: 非阻塞模式下定时器的回调函数
  * 输入参数: htim:定时器句柄
  * 返 回 值: 无
  * 说    明: 无
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  timer_count ;
}