STM32陶晶池串口屏使用

详见快速入门 — 淘晶驰资料中心 1.1.0-2024-07-15 23:52:37 文档 (tjc1688.com),官方文档讲解的很清晰

上位机部分

新建工程后选择对应型号

介绍一下几个上位机的函数

1.prints函数

QQ_1721462011160

注意prints函数串口打印变量时要加上位数,默认是0的话会发送四个字节数据

QQ_1721185702459

就会有三个字节都是0,不方便单片机识别

QQ_1721185732707

我们将位数设置为1,同时加上帧头0xaa,帧尾0x0d,中间留两个字节给数据部分,这样一串数据就是四字节

QQ_1721223856022

函数部分

我们需要注意的是

  1. 配置的波特率与上位机中要一致
  2. 线不要接错

同时,还可能遇到一种问题就是数据可以发送给单片机,只有第一次能收到,后续单片机无法接收

QQ_1721315098528

先注意下printf函数的问题,C语言中printf函数的数据是预先存放的,等到缓存堆满后再输出,或者就是遇到\n换行符直接输出,而陶晶驰这个是\ff\ff\ff做帧尾不允许有\n,我们在第一行加上

    setbuf(stdout, NULL); // 禁用缓冲

就可以禁用缓冲区,直接printf输出了。

注意printf函数要在标志位之前放,因为printf函数可能会影响串口的正常接收,这时候如果你的串口接收中断函数写的不严谨就会出现问题。

同时,我们注意重定向的printf函数是有一个发送的最大等待延时的,如果一口气接收多帧数据,那么你的printf函数最好用在接收完最后一组数据之后再用。笔者就曾经出现过因为两帧之间用了printf函数导致第二帧接收的数据有错乱

最后附上源码

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
#define DataLength 4
#define datanum 10
#define AdcNum 5
/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
volatile bool   rx_data_receive     = false;//串口接收标志位
extern bool get_shape_shut;
volatile uint16_t   sweep_flag      = 0;//扫频标志位
uint8_t         rx_data_sta         =0;//辅助判断接收进度变量
uint16_t        rx_data_cache[1]    = {0};//串口接收数据缓存
uint16_t        rx_data[DataLength] = {0};//串口接收数据(毛)
uint16_t        rx_data_buffer[DataLength] = {0};//串口接收数据(精)
uint16_t        rx_data_sine[DataLength]={0};//点频的数据存放
uint32_t        adc_buffer[2000]    ={0};//未使用到
/* USER CODE END PV */

//……

/* USER CODE BEGIN 2 */

  HAL_TIM_Base_Start_IT(&htim3);
  AD9854_Init();
  AD9854_InitRFSK();
  HAL_UART_Receive_IT(&huart1, (uint8_t *)rx_data_cache, 1);

  /* USER CODE END 2 */

/* USER CODE BEGIN WHILE */
  while (1)
  {

      if (rx_data_receive == true)
      {
          if (rx_data[1] == 0x09 )
          {//此部分可以封装进赋值函数
              rx_data_sine[0]   = rx_data[0];


              rx_data_receive = false;
          }
          else if (rx_data[1] == 0x11 )
          {
              rx_data_sine[1]   = rx_data[0];

              printf("%d",rx_data_sine[0]);
              printf("%d",rx_data_sine[1]);
              rx_data_receive = false;
              //以下部分为点频输出语句
              bsp_set_sine(rx_data_sine[0],rx_data_sine[1]);
          }


          else if (rx_data[1] == 0x01 )
          {
              rx_data_buffer[0] = rx_data[0];


              rx_data_receive = false;

          }
          else if (rx_data[1] == 0x03 )
          {
              rx_data_buffer[1] = rx_data[0];


              rx_data_receive = false;

          }
          else if (rx_data[1] == 0x05 )
          {
              rx_data_buffer[2] = rx_data[0];


              rx_data_receive = false;

          }
          else if (rx_data[1] == 0x07 )
          {
              rx_data_buffer[3] = rx_data[0];
              printf("%d,%d,%d,%d",rx_data_buffer[0],rx_data_buffer[1],rx_data_buffer[2],rx_data_buffer[3]);

              rx_data_receive = false;
              memset(rx_data,0, sizeof(rx_data));
              //以下部分为扫频输出语句
              sweep_flag = 1;
              get_shape_shut = false;

          }
          else if (rx_data[1] == 0x15 )
          {
              sweep_flag = 0;
              get_shape_shut = true;
              AD9854_Init();
              rx_data_receive = false;
          }
      }
    /* USER CODE END WHILE */
      
//……
    
      
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    UNUSED(huart);

    if (huart->Instance == USART1)//串口1执行接收操作
    {
        if (rx_data_receive == false)
        {
            if (rx_data_cache[0] == 0xaa)//判断是否为帧头
            {

            }
            else if (rx_data_cache[0] == 0x0d)
            {
                rx_data_sta = 0;
                rx_data_receive = true;
            }
            else if((rx_data_cache[0] != 0xaa ) &&  (rx_data_cache[0] != 0x0d))
            {
                rx_data[rx_data_sta]    =   rx_data_cache[0];
                rx_data_sta ++;
            }
        }
        HAL_UART_Receive_IT(&huart1, (uint8_t *)rx_data_cache, 1);
    }

}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim ->Instance == htim3.Instance)
    {
        //此处为扫频输出函数
        if (sweep_flag!=0)
        {
            bsp_set_sweep(rx_data_buffer[0],rx_data_buffer[1],rx_data_buffer[2]);
            HAL_TIM_Base_Start(&htim8);
            HAL_ADC_Start_DMA(&hadc1,&adc_buffer[(sweep_flag-1)*AdcNum],AdcNum);
        }
    }
}
      
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)//ADC中断回调函数
{
    UNUSED(hadc);
    HAL_TIM_Base_Stop(&htim8);
}

以上可能有部分诸如AD9854之类的函数,是无关项,可忽略

注意串口的中断回调函数中,我们先用if语句判断一个标志位,然后再判断帧头和帧尾以及帧数据的存储,这里其实改的更严谨点可以先判断帧头再帧尾最后帧数据存储。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部