关于STM32串口通信的问题

发布于 2016-04-26 17:20:40

为什么这个程序每次都读写一个字符,最后却能够完成多字符通讯。如果我想自己编写通讯协议,在which内怎么能够同时判定多字符(which内每次读写一个字符)

#include <rtthread.h> 


struct rx_msg 
{ 
  rt_device_t dev; 
  rt_size_t size; 
}; 
/* 用于接收消息的消息队列*/ 
static rt_mq_t rx_mq; 
/* 接收线程的接收缓冲区*/ 
static char uart_rx_buffer[512]; 
static char uart_sx_buffer[512]; 
/* 数据到达回调函数*/ 
rt_err_t uart_input(rt_device_t dev, rt_size_t size) 
{ 
  struct rx_msg msg; 
  msg.dev = dev; 
  msg.size = size; 
 
  /* 发送消息到消息队列中*/ 
  rt_mq_send(rx_mq, &msg, sizeof(struct rx_msg)); 
 
  return RT_EOK; 
} 
 
void device_thread_entry(void* parameter) 
{ 
  struct rx_msg msg; 
  int count = 0; 
  rt_device_t device, write_device; 
  rt_err_t result = RT_EOK; 
 
  /* 查找系统中的串口1设备 */ 
  device = rt_device_find("uart1"); 
  if (device!= RT_NULL) 
  { 
    /* 设置回调函数及打开设备*/ 
    rt_device_set_rx_indicate(device, uart_input); 
    rt_device_open(device, RT_DEVICE_OFLAG_RDWR); 
  } 
  /* 设置写设备为uart1设备 */ 
  write_device = device; 
 
  /* 查找系统中的串口2设备 */ 
  device= rt_device_find("uart2"); 
  if (device != RT_NULL) 
  { 
    /* 设置回调函数及打开设备*/ 
    rt_device_set_rx_indicate(device, uart_input); 
    rt_device_open(device, RT_DEVICE_OFLAG_RDWR); 
  } 
 
  while (1) 
  { 
    /* 从消息队列中读取消息*/ 
    result = rt_mq_recv(rx_mq, &msg,  
      sizeof(struct rx_msg), 50); 
//    if (result == -RT_ETIMEOUT) 
//    { 
//      /* 接收超时*/ 
//      rt_kprintf("timeout count:%d
", ++count); 
//    } 
// 
    /* 成功收到消息*/ 
    if (result == RT_EOK) 
    { 
      rt_uint32_t rx_length; 
      rx_length = (sizeof(uart_rx_buffer) - 1) > 
msg.size ? msg.size : sizeof(uart_rx_buffer) - 1; 
 
      /* 读取消息*/ 
      rx_length = rt_device_read(msg.dev, 0, 
&uart_rx_buffer[0], rx_length); 
      uart_rx_buffer[rx_length] = '�'; 
 
      /* 写到写设备中*/ 
      if (write_device != RT_NULL) 
        rt_device_write(write_device, 0, 
&amp;uart_rx_buffer[0], rx_length); 
    } 
  } 
} 
 
static struct rt_messagequeue s_your_mq;//消息队列控制块对象
static char s_msg_pool[1024];//消息池

int rt_application_init()
{
  

 
    /* 创建devt线程*/
  rt_thread_t thread = rt_thread_create(&quot;devt&quot;,
    device_thread_entry, RT_NULL,
    1024, 25, 7); 
    
      rt_mq_init(&amp;s_your_mq,&quot;test&quot;,&amp;s_msg_pool[0],sizeof(struct rx_msg),sizeof(s_msg_pool),RT_IPC_FLAG_FIFO);//初始化消息队列控制块
  rx_mq =&amp;s_your_mq;//将rx_mq再指向s_your_mq
  /* 创建成功则启动线程*/
  if (thread != RT_NULL)
    rt_thread_startup(thread);
}

查看更多

关注者
0
被浏览
3.2k
8 个回答
skyline
skyline 2016-05-18
我也在这段代码上遇到同样问题;区别是我把接收到的字符输出到lcd;
从结果上看 每次只能显示一个或者2个字符;

我的目的是把从uart1接收到的数据帧 解码成可读信息输出到lcd显示
开一个线程,循环读取串口缓存的数据,1字节或者多字节读到buff里,直到确定为一帧长度或者你约定某个结束符为一帧,即去处理。跟裸机fifo缓存处理方式是一样的。
zqty467896321d
zqty467896321d 2018-09-26
不知道楼主解决了吗?我也是这样的问题,我想读取串口缓存的数据,来判定接收的数据是不是完整的?但是缓存的数据变化的很快,不知道怎么办?
jeasey
jeasey 2018-10-25
你好,你使用的库函数还是HAL?我使用的HAL库,rt-thread版本为3.1.1接收数据基本就死在了串口中断里面。
你串口中断怎么处理的,能参考一下吗?谢谢!
venus5712
venus5712 2018-10-25
我是再自己程序里用到了一个简单的状态机,每接收一个字节读取判断改变状态。解析协议没得问题的。

wszdxmh
wszdxmh 2021-04-09

如果是定长数据,可以用DMA接收,做起来比较方便,如果是不定长数据,可以用中断的方式,比较简单,每接收一个数据,按通讯的协议进行判断,如按帧头,帧长度,帧命令字,校验码等进行判断,检验通过后发送信号给相关任务。也可以用DMA+空闲中断的方式,可以搜索一下DMA+环形缓存。

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览