ssczmy 2024-07-23 21:32 采纳率: 0%
浏览 115

GD32F303的RS485通讯设计

想要设计一个简单的温湿度读取系统,使用GD32F303RCT6芯片,RS485,但是串口调试助手接收不到数据,一直是空白,程序编写没有报错,请问为什么?串口使用的是USART0。

int main(void)
{
    int b;
    extern uint32_t rs485buf[5];
    uint16_t cnt = 0;
    rcu_ahb_clock_config(RCU_AHB_CKSYS_DIV1);
    nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);  // 优先级分组
    systick_config();                //滴答定时器初始化 1us
    rcu_periph_clock_enable(RCU_AF);

    delay_1ms(10);
    //SPI1_Init();
    RS485_int();
    while(1)
    {
     int i;
     rs485_de_high();
     for (i = 0; i < 5; i++)
            {
                rs485buf[i] = cnt + i;      /* 填充发送缓冲区 */
                delay_1ms(1);
        }
            rs485_send_data(rs485buf, 5);   /* 发送5个字节 */
        delay_1ms(100);
            i=0;
    }
}

void RS485_int(void)
{
        /* connect port to USARTx_Tx */
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9 );
    /* connect port to USARTx_Rx */
    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
    /* connect port to USARTx_DE */
    gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
    //rs485使能
    /* enable the RS485_OE clock */
    rcu_periph_clock_enable(RCU_GPIOA);
    
    rcu_periph_clock_enable(RCU_GPIOB);
    /* enable USART clock */
    rcu_periph_clock_enable(RCU_USART0);

     /* USART configure */
    usart_deinit(USART0);                                       //选用串口0
    usart_word_length_set(USART0,USART_WL_8BIT);
    usart_stop_bit_set(USART0,USART_STB_1BIT);
    usart_parity_config(USART0,USART_PM_NONE);

    usart_hardware_flow_rts_config(USART0,USART_RTS_DISABLE);
    usart_hardware_flow_cts_config(USART0,USART_CTS_DISABLE);
    usart_baudrate_set(USART0, 115200U);                         //波特率选择
    usart_receive_config(USART0, USART_RECEIVE_ENABLE);        //默认接收使能
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
    usart_enable(USART0);
    gpio_bit_set(DE_GPIO_PORT, DE_PIN);
    
}
    
//发送数据
void rs485_send_data(uint32_t*buf, uint32_t len)
{   
    gpio_bit_set(GPIOB,GPIO_PIN_2); // 设置为发送模式
    
    for(uint16_t i = 0;i<len;i++)
    {
        while(usart_flag_get(USART0,USART_FLAG_TBE)==RESET);
        usart_data_transmit(USART0,buf[i]);
    }// 等待发送区为空
while(usart_flag_get(USART0,USART_FLAG_TC)==RESET);
gpio_bit_reset(DE_GPIO_PORT, DE_PIN);
}

//接收数据
uint16_t rs485_receive(uint8_t*buf,uint16_t maxlen)
{
    uint16_t cnt = 0;
    gpio_bit_reset(GPIOB,GPIO_PIN_2);//设置为接收模式
    while(usart_flag_get(USART0,USART_FLAG_RBNE))
    {
        buf[cnt++] = usart_data_receive(USART0);
        if(cnt>=maxlen)
            break;
    }
    return cnt;
}


void rs485_de_high(void) {
    delay_1ms(1000);
    gpio_bit_set(DE_GPIO_PORT, DE_PIN);
    delay_1ms(1000);
}

void rs485_de_low(void) {
    delay_1ms(1000);
    gpio_bit_reset(DE_GPIO_PORT, DE_PIN);
    delay_1ms(1000);
}
```c++
#ifndef __RS485_H
#define __RS485_H
#include <stdint.h>

#define USARTx                           USART0
#define USARTx_CLK                       RCU_USART0

#define USARTx_TX_PIN                    GPIO_PIN_9
#define USARTx_TX_GPIO_PORT              GPIOA
#define USARTx_TX_GPIO_CLK               RCU_GPIOA

#define USARTx_RX_PIN                    GPIO_PIN_10
#define USARTx_RX_GPIO_PORT              GPIOA
#define USARTx_RX_GPIO_CLK               RCU_GPIOA

#define DE_PIN                           GPIO_PIN_2
#define DE_GPIO_PORT                     GPIOB
#define DE_GPIO_CLK                      RCU_GPIOB


//void RS485_Config(void);
void RS485_int(void);
void rs485_send_data(uint32_t *buf, uint32_t len);
uint16_t rs485_receive(uint8_t*buf,uint16_t maxlen);
void rs485_de_high(void);
void rs485_de_low(void);
#endif


原理图

![img](https://img-mid.csdnimg.cn/release/static/image/mid/ask/8ce75d34cc9f40e4a80456c3580bd85b.png "#left")

![img](https://img-mid.csdnimg.cn/release/static/image/mid/ask/cdf0d0d104754ccda4366eb01d98a134.png "#left")

![img](https://img-mid.csdnimg.cn/release/static/image/mid/ask/30721ae4be324b19a0653fde7532bfaa.jpeg "#left")
  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-07-23 21:32
    关注

    引自免费微信小程序:皆我百晓生

    在您的程序中,您尝试将数据发送到RS485端口,并且您正在使用rs485_send_data()函数来发送数据。这个函数似乎存在问题,因为它在等待收到响应时一直保持空闲状态。

    首先,让我们分析一下您的程序结构。您已经定义了一个名为rs485_send_data()的函数,用于向RS485端口发送数据。然而,它并没有正确地处理接收数据的情况。为了修复这个问题,我们需要修改rs485_send_data()函数,使其能够在接收到数据后立即返回,而不是仅仅等待发送完成。

    以下是修改后的rs485_send_data()函数:

    void rs485_send_data(uint32_t* buf, uint32_t len)
    {
        gpio_bit_set(GPIOB, GPIO_PIN_2); // 设置为发送模式
    
        for(uint16_t i = 0;i<len;i++)
        {
            while(usart_flag_get(USART0,USART_FLAG_TBE)==RESET);
            usart_data_transmit(USART0,*buf+i);
        }
    
        while(usart_flag_get(USART0,USART_FLAG_TC)==RESET);
        gpio_bit_reset(GPIOB, GPIO_PIN_2); // 设置为接收模式
    
        return len;
    }
    

    此外,我们还需要在主函数中添加一个循环,以便不断调用rs485_send_data()函数直到所有数据都被发送完毕。这可以通过在循环外增加一个变量来实现:

    int main(void)
    {
        int b;
        extern uint32_t rs485buf[5];
        uint16_t cnt = 0;
        rcu_ahb_clock_config(RCU_AHB_CKSYS_DIV1);
        nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);  // 优先级分组
        systick_config();                //滴答定时器初始化 1us
        rcu_periph_clock_enable(RCU_AF);
    
        delay_1ms(10);
        //SPI1_Init();
        RS485_int();
        while(1)
        {
            int i;
            rs485_de_high();
            for (i = 0; i < 5; i++)
                {
                    rs485buf[i] = cnt + i;      /* 填充发送缓冲区 */
                    delay_1ms(1);
            }
            rs485_send_data(&rs485buf, 5);   /* 发送5个字节 */
            delay_1ms(100);
            i=0;
        }
    }
    

    现在,当您运行此程序时,应会成功发送并接收数据。如果您仍然遇到问题,请检查其他部分的代码,例如输入/输出、通信链路配置等。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 7月23日