STM32 HAL 陶晶池串口屏使用

STM32陶晶池串口屏使用

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

上位机部分

新建工程后选择对应型号

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

1.prints函数

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

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

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

函数部分

我们需要注意的是

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

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

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

c 复制代码
    setbuf(stdout, NULL); // 禁用缓冲

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

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

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

最后附上源码

c 复制代码
/* 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语句判断一个标志位,然后再判断帧头和帧尾以及帧数据的存储,这里其实改的更严谨点可以先判断帧头再帧尾最后帧数据存储。

相关推荐
hollq2 小时前
STM32F103RCT6+STM32CubeMX+keil5(MDK-ARM)+Flymcu实现串口重定向
arm开发·stm32·嵌入式硬件
小鱼儿电子4 小时前
17-基于STM32的宠物饲养系统设计与实现
stm32·嵌入式硬件·物联网·宠物·宠物饲养系统
小莞尔5 小时前
【51单片机】【protues仿真】基于51单片机四层电梯系统
单片机·嵌入式硬件
CFZPL5 小时前
使用江科大串口发送函数发送freertos的vTaskList出现跑飞
单片机
F133168929576 小时前
WD5030A,24V降5V,15A 大电流,应用于手机、平板、笔记本充电器
stm32·单片机·嵌入式硬件·51单片机·硬件工程·pcb工艺
易享电子7 小时前
基于单片机电器断路器保护器系统Proteus仿真(含全部资料)
单片机·嵌入式硬件·fpga开发·51单片机·proteus
爱倒腾的老唐9 小时前
01、如何学习单片机
单片机·嵌入式硬件·学习
点灯小铭9 小时前
基于单片机的夹具压力控制系统设计
单片机·嵌入式硬件·mongodb·毕业设计·课程设计
雾削木15 小时前
stm32解锁芯片
javascript·stm32·单片机·嵌入式硬件·gitee
热爱编程的小刘16 小时前
STM32学习路线开启篇:外部中断
stm32