单片机485实验

单片机:STM32F407

开发板:DMF407电机开发板

平台:keil V5.31

HSE 为8MHZ

HSI为16MHZ

原理图:

配置:

复制代码
#define RS485_TX_GPIO_PORT                  GPIOB
#define RS485_TX_GPIO_PIN                   GPIO_PIN_10
#define RS485_TX_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)   /* PB口时钟使能 */

#define RS485_RX_GPIO_PORT                  GPIOB
#define RS485_RX_GPIO_PIN                   GPIO_PIN_11
#define RS485_RX_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)   /* PA口时钟使能 */

#define RS485_UX                            USART3
#define RS485_UX_IRQn                       USART3_IRQn
#define RS485_UX_IRQHandler                 USART3_IRQHandler
#define RS485_UX_CLK_ENABLE()               do{ __HAL_RCC_USART3_CLK_ENABLE(); }while(0)  /* USART3 时钟使能 */

uint8_t g_RS485_rx_buf[RS485_REC_LEN]; /* 接收缓冲, 最大 RS485_REC_LEN 个字节. */
uint8_t g_RS485_rx_cnt = 0;            /* 接收到的数据长度 */

void RS485_UX_IRQHandler(void)
{
    uint8_t res;

    if ((__HAL_UART_GET_FLAG(&g_rs458_handler, UART_FLAG_RXNE) != RESET)) /* 接收到数据 */
    {
        HAL_UART_Receive(&g_rs458_handler, &res, 1, 1000);

        if (g_RS485_rx_cnt < RS485_REC_LEN)         /* 缓冲区未满 */
        {
            g_RS485_rx_buf[g_RS485_rx_cnt] = res;   /* 记录接收到的值 */
            g_RS485_rx_cnt++;                       /* 接收数据增加1 */
        }
    }
}

void rs485_init(uint32_t baudrate)
{

    /* IO 及 时钟配置 */
    RS485_TX_GPIO_CLK_ENABLE(); /* 使能 串口TX脚 时钟 */
    RS485_RX_GPIO_CLK_ENABLE(); /* 使能 串口RX脚 时钟 */
    RS485_UX_CLK_ENABLE();      /* 使能 串口 时钟 */

    GPIO_InitTypeDef gpio_initure;
    gpio_initure.Pin = RS485_TX_GPIO_PIN;
    gpio_initure.Mode = GPIO_MODE_AF_PP;
    gpio_initure.Pull = GPIO_PULLUP;
    gpio_initure.Speed = GPIO_SPEED_FREQ_HIGH;
    gpio_initure.Alternate = GPIO_AF7_USART3;               /* 复用为串口3 */
    HAL_GPIO_Init(RS485_TX_GPIO_PORT, &gpio_initure);       /* 串口TX 脚 模式设置 */

    gpio_initure.Pin = RS485_RX_GPIO_PIN;
    HAL_GPIO_Init(RS485_RX_GPIO_PORT, &gpio_initure);       /* 串口RX 脚 必须设置成输入模式 */

    /* USART 初始化设置 */
    g_rs458_handler.Instance = RS485_UX;                    /* 选择485对应的串口 */
    g_rs458_handler.Init.BaudRate = baudrate;               /* 波特率 */
    g_rs458_handler.Init.WordLength = UART_WORDLENGTH_8B;   /* 字长为8位数据格式 */
    g_rs458_handler.Init.StopBits = UART_STOPBITS_1;        /* 一个停止位 */
    g_rs458_handler.Init.Parity = UART_PARITY_NONE;         /* 无奇偶校验位 */
    g_rs458_handler.Init.HwFlowCtl = UART_HWCONTROL_NONE;   /* 无硬件流控 */
    g_rs458_handler.Init.Mode = UART_MODE_TX_RX;            /* 收发模式 */
    HAL_UART_Init(&g_rs458_handler);                        /* 使能对应的串口, 调用Msp */
    __HAL_UART_DISABLE_IT(&g_rs458_handler, UART_IT_TC);

#if RS485_EN_RX /* 如果使能了接收 */
                /* 使能接收中断 */
    __HAL_UART_ENABLE_IT(&g_rs458_handler, UART_IT_RXNE);   /* 开启接收中断 */
    HAL_NVIC_EnableIRQ(RS485_UX_IRQn);                      /* 使能USART1中断 */
    HAL_NVIC_SetPriority(RS485_UX_IRQn, 3, 3);              /* 抢占优先级3,子优先级3 */
#endif

}

void rs485_send_data(uint8_t *buf, uint8_t len)
{
    HAL_UART_Transmit(&g_rs458_handler, buf, len, 1000); /* 串口2发送数据 */
    g_RS485_rx_cnt = 0;
}

void rs485_receive_data(uint8_t *buf, uint8_t *len)
{
    uint8_t rxlen = g_RS485_rx_cnt;
    uint8_t i = 0;
    *len = 0;     /* 默认为0 */
    delay_ms(10); /* 等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束 */

    if (rxlen == g_RS485_rx_cnt && rxlen) /* 接收到了数据,且接收完成了 */
    {
        for (i = 0; i < rxlen; i++)
        {
            buf[i] = g_RS485_rx_buf[i];
        }

        *len = g_RS485_rx_cnt; /* 记录本次数据长度 */
        g_RS485_rx_cnt = 0;    /* 清零 */
    }
}

主函数:

复制代码
int main(void)
{
    uint8_t key;
    uint8_t i = 0, t = 0;
    uint8_t cnt = 0;
    uint8_t rs485buf[5];

    HAL_Init();                             /* 初始化HAL库 */
    sys_stm32_clock_init(336, 8, 2, 7);     /* 设置时钟,168Mhz */
    delay_init(168);                        /* 延时初始化 */
    usart_init(115200);                     /* 串口初始化为115200 */
    usmart_dev.init(84);                    /* 初始化USMART */
    led_init();                             /* 初始化LED */
    lcd_init();                             /* 初始化LCD */
    key_init();                             /* 初始化按键 */
    rs485_init(9600);                       /* 初始化RS485 */

    lcd_show_string(30,  50, 200, 16, 16, "STM32", RED);
    lcd_show_string(30,  70, 200, 16, 16, "RS485 TEST", RED);
    lcd_show_string(30,  90, 200, 16, 16, "ATOM@ALIENTEK", RED);
    lcd_show_string(30, 110, 200, 16, 16, "KEY0:Send", RED);    /* 显示提示信息 */

    lcd_show_string(30, 130, 200, 16, 16, "Count:", RED);       /* 显示当前计数值 */
    lcd_show_string(30, 150, 200, 16, 16, "Send Data:", RED);   /* 提示发送的数据 */
    lcd_show_string(30, 190, 200, 16, 16, "Receive Data:", RED);/* 提示接收到的数据 */

    while (1)
    {
        key = key_scan(0);

        if (key == KEY0_PRES)               /* KEY0按下,发送一次数据 */
        {
            for (i = 0; i < 5; i++)
            {
                rs485buf[i] = cnt + i;      /* 填充发送缓冲区 */
                lcd_show_xnum(30 + i * 32, 170, rs485buf[i], 3, 16, 0x80, BLUE);    /* 显示数据 */
            }

            rs485_send_data(rs485buf, 5);   /* 发送5个字节 */
        }

        rs485_receive_data(rs485buf, &key);

        if (key)    /* 接收到有数据 */
        {
            if (key > 5)
            {
                key = 5;                    /* 最大是5个数据. */
            }

            for (i = 0; i < key; i++)
            {
                lcd_show_xnum(30 + i * 32, 210, rs485buf[i], 3, 16, 0x80, BLUE);    /* 显示数据 */
            }
        }

        t++;
        delay_ms(10);

        if (t == 20)
        {
            LED0_TOGGLE();  /* LED0闪烁, 提示系统正在运行 */
            t = 0;

            cnt++;
            lcd_show_xnum(30 + 48, 130, cnt, 3, 16, 0x80, BLUE);    /* 显示数据 */
        }
    }
}

工具:

如果有485工具,接好线之后可以直接用SSCOM读写数据。

没有485工具,只能用普通串口工具接TP8485E的输入脚,测试数据

相关推荐
声讯电子16 小时前
AR1106 声源定位模组 让设备真正“听懂方向”
单片机·机器人·舵机·声源定位·双麦克风阵列·听声辨位
qq_4107321717 小时前
嵌入式开发-memcpy与memmove 技术详解
java·linux·开发语言·嵌入式硬件
星夜夏空9917 小时前
STM32单片机学习(29) —— SPI引脚和外设初始化
stm32·单片机·学习
xiangw@GZ17 小时前
DDR专题-CK 时钟、MT/s 与带宽的关系
单片机·嵌入式硬件
三品吉他手会点灯18 小时前
STM32F103 学习笔记-23-常用存储器原理与分类
笔记·stm32·单片机·嵌入式硬件·学习
ji1985944318 小时前
基于 dsPIC33 系列单片机的数字电源开发
单片机·嵌入式硬件
凹凸曼的大表哥18 小时前
基于凌鸥081ZYKFB开发板的编码器测转速算法学习
c语言·单片机·嵌入式硬件
m0_3771081418 小时前
stm32-TIM
stm32·单片机·嵌入式硬件
潜创微科技18 小时前
潜创微科技|ITE 联阳官方授权代理商 & 方案商 高清高速接口一站式服务商
嵌入式硬件·音视频