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

[复制链接]
18189|48
手机看帖
扫描二维码
随时随地手机跟帖
yzh1094602242|  楼主 | 2021-9-28 09:44 | 显示全部楼层 |阅读模式

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

使用特权

评论回复

相关帖子

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

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

使用特权

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

使用特权

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

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

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

使用特权

评论回复
评论
呐咯密密 2021-9-29 10:55 回复TA
@yzh1094602242 :你的发送中断不是靠发送数据才触发的吗?在发送数据之前加一个发送使能,如果是printf,就在printf前面加。触发发送中断之后再把使能切换为接收。 
yzh1094602242 2021-9-29 10:51 回复TA
@呐咯密密 :但是我没有接受和发送函数,是直接进接收和发送中断的,不晓得使能加什么地方了 
呐咯密密 2021-9-29 09:31 回复TA
@yzh1094602242 :如果还不懂我贴代码给你看 
呐咯密密 2021-9-29 09:31 回复TA
@yzh1094602242 :你这样处理,初始化就让他处于接收状态,然后写一个发s送的函数,就是在普通的发送函数前面加一个使能发送,发送完成再改为使能接收,需要发送就调用这个函数,这个函数执行完自动就变成接收模式了呀,不影响你的中断 
yzh1094602242 2021-9-29 08:48 回复TA
问下大佬,收发时候使能和失能放在收发中断里就行了吗 
yzh1094602242 2021-9-29 08:42 回复TA
才知道发送时候要把使能脚拉低,谢谢各位大佬 
评分
参与人数 1威望 +2 收起 理由
yzh1094602242 + 2 很给力!
yaosongjin2018| | 2021-9-28 16:34 | 显示全部楼层
呐咯密密 发表于 2021-9-28 15:36
我看不到图,是不是485使能的问题,发送和接收是需要不同的使能电平的搜索
复制
...

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

使用特权

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

使用特权

评论回复
评论
yzh1094602242 2021-9-29 08:41 回复TA
单都测了B的波形没有,才知道发送时候要把使能脚拉低,谢谢各位大佬 
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){  ...

936826153d62c6174d.png 用代码框放代码,这样我们没法看

使用特权

评论回复
评论
yzh1094602242 2021-9-29 11:02 回复TA
大佬请稍等,我点图片和代码都没反应,不知道是不是浏览器的原因,我换一个浏览器 
yzh1094602242|  楼主 | 2021-9-29 11:07 | 显示全部楼层
void UartPrg(void)
{       
        uint8_t i,j;
       
        /*Receive Checksum check*/
        if(rx_end == 1)
        {               
                rx_end = 0;
                g_uart1_rx_length = uart_rx_buf[3]+4;
                rx_checksum = 0;
                i=0;
               
                while(i < g_uart1_rx_length)
                {
                        rx_checksum += uart_rx_buf[i];
                        i++;
                }
               
                if(rx_checksum == uart_rx_buf[g_uart1_rx_length])
                {
                        work_begin = 1;      //Command response flag
                }
        }
       
        /*Send*/
        if(send_begin == 0)
                return;       
        send_begin = 0;
        g_uart1_tx_count = 0;
        uart_tx_buf[0]  = 0xAA;
        uart_tx_buf[1]  = 0x55;
        g_uart1_tx_length = uart_tx_buf[3]+4;
        j = 0;
        tx_checksum = 0;
        while(j<g_uart1_tx_length)
        {
                tx_checksum += uart_tx_buf[j];
                j++;
        }
        uart_tx_buf[g_uart1_tx_length] = tx_checksum;
        STMK1 = 1;
        TXD1 = uart_tx_buf[0];
        STMK1 = 0;
}

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

/***********************************************************************************************************************
* Function Name: r_uart1_interrupt_receive
* Description  : This function is INTSR1 interrupt service routine.
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
static void __near r_uart1_interrupt_receive(void)
{       
  volatile uint8_t rx_data;
       
        rx_data = RXD1;
       
        if(work_begin == 0)
        {
                if(g_uart1_rx_count == 0)
                {
                        if(rx_data == 0x55)
                        {
                                uart_rx_buf[0] = rx_data;
                                g_uart1_rx_count++;       
                        }
                }
                else if(g_uart1_rx_count == 1)
                {
                        if(rx_data == 0xAA)
                        {
                                uart_rx_buf[1] = rx_data;
                                g_uart1_rx_count++;
                        }
                }
                else if(g_uart1_rx_count <= 3)
                {
                        uart_rx_buf[g_uart1_rx_count] = rx_data;
                        g_uart1_rx_count++;
                }
                else
                {
                        if(g_uart1_rx_count <= 255)
                        {
                                uart_rx_buf[g_uart1_rx_count] = rx_data;
                                g_uart1_rx_count++;
                                if(g_uart1_rx_count >=(uart_rx_buf[3]+5))
                                {
                                        g_uart1_rx_count = 0;
                                        rx_end = 1;                        //receive end flag
                                }
                        }
                        else
                        {
                                g_uart1_rx_count = 0;
                        }
                }
        }
}

/***********************************************************************************************************************
* Function Name: r_uart1_interrupt_send
* Description  : This function is INTST1 interrupt service routine.
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
static void __near r_uart1_interrupt_send(void)
{       
  g_uart1_tx_count++;

        if(g_uart1_tx_count<(uart_tx_buf[3]+5))
        {
                TXD1 = uart_tx_buf[g_uart1_tx_count];
        }
        else
        {
                g_uart1_tx_count = 0;
        }
       
}

使用特权

评论回复
yzh1094602242|  楼主 | 2021-9-29 11:12 | 显示全部楼层
@呐咯密密 我用的是瑞萨,用的编译工具里的代码自动生成,在自动生成代码基础上改的
void main(void)
{
    R_MAIN_UserInit();
    /* Start user code. Do not edit comment generated here */
                R_TAU0_Channel0_Start();    //Start Timer
               
                R_UART1_Start();                                                //Start UART1
               
                LED_ALL_OFF();                                //Power on The LED is off by default      
          
    while (1U)
    {
                        if(B_Tm_2ms)
                  {
                          B_Tm_2ms = 0;
                          switch (Tm_SelR)
                    {
                            case 0:
                                                UartPrg();   //判断处理接受的命令和回复数据
                                    break;
                                        case 1:
                                                RunPrg();   //比如根据接收到的命令点亮某个灯
                                    break;
                                        default:
                                                break;
                    }                               
                                Tm_SelR++;
                          if (Tm_SelR > 1)
                          Tm_SelR = 0;
                        }
                }
    /* End user code. Do not edit comment generated here */
}

使用特权

评论回复
呐咯密密| | 2021-9-29 11:53 | 显示全部楼层
yzh1094602242 发表于 2021-9-29 11:12
@呐咯密密 我用的是瑞萨,用的编译工具里的代码自动生成,在自动生成代码基础上改的
...

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

        {

                TXD1 = uart_tx_buf[g_uart1_tx_count];

        }


使用特权

评论回复
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口,点几下就自动初始化生成代码了
微信截图_20210929130021.png

使用特权

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

使用特权

评论回复
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

粉丝