RS485通信问题,MCU收没问题,但不回复

[复制链接]
 楼主| yzh1094602242 发表于 2021-9-28 09:44 | 显示全部楼层 |阅读模式

如下图所示,圈出来的地方波形测量都没有问题(接收发送,AB的波形)但串口助手死活接收不到单片机回复的数据。串口助手发送数据控制板子上的灯没有问题,挺急的,烦请帮忙解答下。单独引rx,tx和地线出来,用ch340通信一点问题没有。后来加了ST485B芯片就这样了,485转USB线也换过不同的

 楼主| yzh1094602242 发表于 2021-9-28 09:47 | 显示全部楼层

RS485通信问题,MCU收没问题,但不回复

评论

图片上传的时候以附件方式上传,然后自己刷新看一看有没有上传完毕  发表于 2021-9-29 08:02
coody 发表于 2021-9-28 11:01 | 显示全部楼层
先用232测试,数据原样返回,看看你收到的是啥。

评论

另外大佬,我这原理图上的n管型号是DTC143XCA,里面带两个电阻的,是不是特殊些。我现在板子上的n管是别的型号的,具体什么型号不知道,这个有关系吗。  发表于 2021-9-28 12:57
请问可以再说具体点吗,本身也是小白,还是有点不太明白,谢谢大佬  发表于 2021-9-28 12:46
呐咯密密 发表于 2021-9-28 15:36 | 显示全部楼层

RS485通信问题,MCU收没问题,但不回复

我看不到图,是不是485使能的问题,发送和接收是需要不同的使能电平的搜索
复制

评论

[url=home.php?mod=space&uid=3272330]@yzh1094602242[/url] :你的发送中断不是靠发送数据才触发的吗?在发送数据之前加一个发送使能,如果是printf,就在printf前面加。触发发送中断之后再把使能切换为接收。  发表于 2021-9-29 10:55
[url=home.php?mod=space&uid=2540432]@呐咯密密[/url] :但是我没有接受和发送函数,是直接进接收和发送中断的,不晓得使能加什么地方了  发表于 2021-9-29 10:51
[url=home.php?mod=space&uid=3272330]@yzh1094602242[/url] :如果还不懂我贴代码给你看  发表于 2021-9-29 09:31
[url=home.php?mod=space&uid=3272330]@yzh1094602242[/url] :你这样处理,初始化就让他处于接收状态,然后写一个发s送的函数,就是在普通的发送函数前面加一个使能发送,发送完成再改为使能接收,需要发送就调用这个函数,这个函数执行完自动就变成接收模式了呀,不影响你的中断  发表于 2021-9-29 09:31
问下大佬,收发时候使能和失能放在收发中断里就行了吗  发表于 2021-9-29 08:48
才知道发送时候要把使能脚拉低,谢谢各位大佬  发表于 2021-9-29 08:42

评分

参与人数 1威望 +2 收起 理由
yzh1094602242 + 2 很给力!

查看全部评分

yaosongjin2018 发表于 2021-9-28 16:34 | 显示全部楼层
呐咯密密 发表于 2021-9-28 15:36
我看不到图,是不是485使能的问题,发送和接收是需要不同的使能电平的搜索
复制
...

赞同答主说的,题主应该仔细阅读一下485芯片的控制方法

评论

[url=home.php?mod=space&uid=3272330]@yzh1094602242[/url] :可以这样处理:485的使能引脚是一个通用的IO,你的USART该怎么用就怎么用,但是在发送之前加一个485使能IO的低电平输出,此时485芯片处于发送模式,发送结束再把这个IO改为高电平输出,此时485处于接收状态,有数据就能接收到,否则不能接收。如果不行就把发送和接受的电平反过来,肯定有一个是可以的。如果可以再贴一下你的电路图和代码,我这边看不到  发表于 2021-9-29 09:28
再问下大佬,收发时候使能和失能放在收发中断里就行了吗  发表于 2021-9-29 08:49
正解了,谢谢大佬,小白真的啥都不懂,好像搜问题时候瞟到过一眼说什么会自动拉高拉低的,而且三极管也不懂,就没往这方向去想。  发表于 2021-9-29 08:43
m564522634 发表于 2021-9-28 16:43 | 显示全部楼层
485 方向切换没问题的话 那就是硬件问题,A  线  B线的波形对地的电压对不对,

评论

单都测了B的波形没有,才知道发送时候要把使能脚拉低,谢谢各位大佬  发表于 2021-9-29 08:41
fxyc87 发表于 2021-9-29 08:56 | 显示全部楼层
共地一下,你会看到不一样的效果。
 楼主| yzh1094602242 发表于 2021-9-29 10:55 | 显示全部楼层

RS485通信问题,MCU收没问题,但不回复

本帖最后由 yzh1094602242 于 2021-9-29 11:15 编辑

大致就是接受命令,响应命令去控制led灯不同颜色等状态,然后会回复一串数据(回复的数据是代表哪个灯哪个状态)
呐咯密密 发表于 2021-9-29 10:58 | 显示全部楼层
yzh1094602242 发表于 2021-9-29 10:55
----------------------------------主函数就这些-------------------------------------void main(void){  ...

用代码框放代码,这样我们没法看

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

评论

大佬请稍等,我点图片和代码都没反应,不知道是不是浏览器的原因,我换一个浏览器  发表于 2021-9-29 11:02
 楼主| yzh1094602242 发表于 2021-9-29 11:07 | 显示全部楼层
  1. void UartPrg(void)
  2. {       
  3.         uint8_t i,j;
  4.        
  5.         /*Receive Checksum check*/
  6.         if(rx_end == 1)
  7.         {               
  8.                 rx_end = 0;
  9.                 g_uart1_rx_length = uart_rx_buf[3]+4;
  10.                 rx_checksum = 0;
  11.                 i=0;
  12.                
  13.                 while(i < g_uart1_rx_length)
  14.                 {
  15.                         rx_checksum += uart_rx_buf[i];
  16.                         i++;
  17.                 }
  18.                
  19.                 if(rx_checksum == uart_rx_buf[g_uart1_rx_length])
  20.                 {
  21.                         work_begin = 1;      //Command response flag
  22.                 }
  23.         }
  24.        
  25.         /*Send*/
  26.         if(send_begin == 0)
  27.                 return;       
  28.         send_begin = 0;
  29.         g_uart1_tx_count = 0;
  30.         uart_tx_buf[0]  = 0xAA;
  31.         uart_tx_buf[1]  = 0x55;
  32.         g_uart1_tx_length = uart_tx_buf[3]+4;
  33.         j = 0;
  34.         tx_checksum = 0;
  35.         while(j<g_uart1_tx_length)
  36.         {
  37.                 tx_checksum += uart_tx_buf[j];
  38.                 j++;
  39.         }
  40.         uart_tx_buf[g_uart1_tx_length] = tx_checksum;
  41.         STMK1 = 1;
  42.         TXD1 = uart_tx_buf[0];
  43.         STMK1 = 0;
  44. }

  45. /* End user code. Do not edit comment generated here */

  46. /***********************************************************************************************************************
  47. * Function Name: r_uart1_interrupt_receive
  48. * Description  : This function is INTSR1 interrupt service routine.
  49. * Arguments    : None
  50. * Return Value : None
  51. ***********************************************************************************************************************/
  52. static void __near r_uart1_interrupt_receive(void)
  53. {       
  54.   volatile uint8_t rx_data;
  55.        
  56.         rx_data = RXD1;
  57.        
  58.         if(work_begin == 0)
  59.         {
  60.                 if(g_uart1_rx_count == 0)
  61.                 {
  62.                         if(rx_data == 0x55)
  63.                         {
  64.                                 uart_rx_buf[0] = rx_data;
  65.                                 g_uart1_rx_count++;       
  66.                         }
  67.                 }
  68.                 else if(g_uart1_rx_count == 1)
  69.                 {
  70.                         if(rx_data == 0xAA)
  71.                         {
  72.                                 uart_rx_buf[1] = rx_data;
  73.                                 g_uart1_rx_count++;
  74.                         }
  75.                 }
  76.                 else if(g_uart1_rx_count <= 3)
  77.                 {
  78.                         uart_rx_buf[g_uart1_rx_count] = rx_data;
  79.                         g_uart1_rx_count++;
  80.                 }
  81.                 else
  82.                 {
  83.                         if(g_uart1_rx_count <= 255)
  84.                         {
  85.                                 uart_rx_buf[g_uart1_rx_count] = rx_data;
  86.                                 g_uart1_rx_count++;
  87.                                 if(g_uart1_rx_count >=(uart_rx_buf[3]+5))
  88.                                 {
  89.                                         g_uart1_rx_count = 0;
  90.                                         rx_end = 1;                        //receive end flag
  91.                                 }
  92.                         }
  93.                         else
  94.                         {
  95.                                 g_uart1_rx_count = 0;
  96.                         }
  97.                 }
  98.         }
  99. }

  100. /***********************************************************************************************************************
  101. * Function Name: r_uart1_interrupt_send
  102. * Description  : This function is INTST1 interrupt service routine.
  103. * Arguments    : None
  104. * Return Value : None
  105. ***********************************************************************************************************************/
  106. static void __near r_uart1_interrupt_send(void)
  107. {       
  108.   g_uart1_tx_count++;

  109.         if(g_uart1_tx_count<(uart_tx_buf[3]+5))
  110.         {
  111.                 TXD1 = uart_tx_buf[g_uart1_tx_count];
  112.         }
  113.         else
  114.         {
  115.                 g_uart1_tx_count = 0;
  116.         }
  117.        
  118. }
 楼主| yzh1094602242 发表于 2021-9-29 11:12 | 显示全部楼层
@呐咯密密 我用的是瑞萨,用的编译工具里的代码自动生成,在自动生成代码基础上改的
  1. void main(void)
  2. {
  3.     R_MAIN_UserInit();
  4.     /* Start user code. Do not edit comment generated here */
  5.                 R_TAU0_Channel0_Start();    //Start Timer
  6.                
  7.                 R_UART1_Start();                                                //Start UART1
  8.                
  9.                 LED_ALL_OFF();                                //Power on The LED is off by default      
  10.           
  11.     while (1U)
  12.     {
  13.                         if(B_Tm_2ms)
  14.                   {
  15.                           B_Tm_2ms = 0;
  16.                           switch (Tm_SelR)
  17.                     {
  18.                             case 0:
  19.                                                 UartPrg();   //判断处理接受的命令和回复数据
  20.                                     break;
  21.                                         case 1:
  22.                                                 RunPrg();   //比如根据接收到的命令点亮某个灯
  23.                                     break;
  24.                                         default:
  25.                                                 break;
  26.                     }                               
  27.                                 Tm_SelR++;
  28.                           if (Tm_SelR > 1)
  29.                           Tm_SelR = 0;
  30.                         }
  31.                 }
  32.     /* End user code. Do not edit comment generated here */
  33. }
呐咯密密 发表于 2021-9-29 11:53 | 显示全部楼层
yzh1094602242 发表于 2021-9-29 11:12
@呐咯密密 我用的是瑞萨,用的编译工具里的代码自动生成,在自动生成代码基础上改的
...

TXD1 = uart_tx_buf[g_uart1_tx_count];
如果我看的没错,这行就是发送数据,如果你想一个个发送这个数组中的数据,就在这行代码上面加上发送使能,在这行代码下面加上接收使能(你还得找一下,你的代码中不止一个发送代码,只要有TXD1=...之类的都是)
如果你想连续发送这个数组里面的数据,就在下面这个if函数上面加发送使能,在if函数结束加接收使能,
  1.         if(g_uart1_tx_count<(uart_tx_buf[3]+5))

  2.         {

  3.                 TXD1 = uart_tx_buf[g_uart1_tx_count];

  4.         }


 楼主| yzh1094602242 发表于 2021-9-29 12:02 | 显示全部楼层
呐咯密密 发表于 2021-9-29 11:53
TXD1 = uart_tx_buf[g_uart1_tx_count];
如果我看的没错,这行就是发送数据,如果你想一个个发送这个数组 ...

那我主函数先要加一下接收使能吗,因为单片机永远都是先接受数据,再做回复,如果只在上面那个发送中断中加的话,是不是收据都不能接收了呀。
呐咯密密 发表于 2021-9-29 12:46 | 显示全部楼层
yzh1094602242 发表于 2021-9-29 12:02
那我主函数先要加一下接收使能吗,因为单片机永远都是先接受数据,再做回复,如果只在上面那个发送中断中 ...

你之前不是就能接收到数据吗,你可以在IO初始化完成后就将使能设置为接收,因为每次发送完成都会被设置为接收的,所以只有第一次接收可能会被影响,只需要在初始化时设置一下就好了,不需要在主函数设置。你实际测试一下就知道了,不会有问题的
 楼主| yzh1094602242 发表于 2021-9-29 12:58 | 显示全部楼层
呐咯密密 发表于 2021-9-29 12:46
你之前不是就能接收到数据吗,你可以在IO初始化完成后就将使能设置为接收,因为每次发送完成都会被设置为 ...

一开始能接受是因为我把这个在主函数while前使能了一下,但不知道这个高低影响收发,所以就只能收到····
非常谢谢大佬耐心解答,我再试一下下
 楼主| yzh1094602242 发表于 2021-9-29 13:02 | 显示全部楼层
yzh1094602242 发表于 2021-9-29 12:58
一开始能接受是因为我把这个在主函数while前使能了一下,但不知道这个高低影响收发,所以就只能收到·· ...

这个瑞萨第一次用,也没搞懂,就选择一下io口,点几下就自动初始化生成代码了

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| yzh1094602242 发表于 2021-9-29 14:10 | 显示全部楼层
@呐咯密密 大佬问下附件这原理图,是只要把EN置高就是单片机接收,EN置低就为发吗。我怎么感觉en置低了回复还是没用

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
chunyang 发表于 2021-9-29 15:19 | 显示全部楼层
TTL侧用串口监视软件查看没问题的话,那只能说问题出在485接口电路或控制部分,先确认控制无误,注意收发切换后要留一段延时待电路稳定后再开始收发数据。
 楼主| yzh1094602242 发表于 2021-9-29 15:57 | 显示全部楼层
chunyang 发表于 2021-9-29 15:19
TTL侧用串口监视软件查看没问题的话,那只能说问题出在485接口电路或控制部分,先确认控制无误,注意收发切 ...

就是控制出问题了,我之前不知道原来单片机发送的时候要把485那边使能脚拉低
chunyang 发表于 2021-9-29 16:01 | 显示全部楼层
yzh1094602242 发表于 2021-9-29 15:57
就是控制出问题了,我之前不知道原来单片机发送的时候要把485那边使能脚拉低 ...

编程前应仔细看485接口片的器件手册,这样就不会出现如此的错误了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

48

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部

4

主题

48

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部