rt_thread 485程序运用记录

该代码实现了一个基于STM32F103R系列的RS485通信功能,包括设置发送和接收模式,定义了接收回调函数用于统计接收到的字节数,以及使用线程和定时器处理接收数据的超时情况。同时,提供了发送和接收数据的函数。
摘要由CSDN通过智能技术生成

程序中包含打印  发送  以及接收   在线程中调用函数即可应用

适合平台 stm32F103R系列所有芯片

/*
 * File      : rs485.c
 * This file is part of dym project
 *
 * Change Logs:
 * Date           Author       Notes
 * 2018-10-21     zailiy      the first version
 */

#include <rtthread.h>
#include "server485.h"
#include "board.h"
#include <msh.h>

#define TXMODE          1
#define RXMODE          0

#define set_server485_tx_rx_mode(mode)       \
    do                                   \
    {                                    \
        rt_pin_write(SERVER485_RE_IO, mode); \
    } while (0)
    
#define SENDBUFF_SIZE  338
    
static rt_sem_t sem_server485 = RT_NULL;
static struct rt_timer timer_server485;

static rt_device_t DEV_server485;
static rt_uint16_t server485_revc_bytes = 0;

// rs485 接收回调函数,用于统计接收到的字节数
rt_err_t server485_recv_callback(rt_device_t dev, rt_size_t size)
{
    server485_revc_bytes++;
    return RT_EOK;
}

static void timer_server485_timeout(void *parameter)
{
    static rt_uint16_t oldb = 0;

    if (oldb != server485_revc_bytes)
        oldb = server485_revc_bytes;
    else if (server485_revc_bytes != 0)
    {
        rt_sem_release(sem_server485);
    }
}

static void server_485_thread(void *paramter)
{
    rt_serial_t *com_dev;
    DEV_server485 = rt_device_find(DEV_SERVER485);

    if (DEV_server485 == RT_NULL)
    {
        rt_kprintf("Not found rs485 device.\n");
        return;
    }

    com_dev = (rt_serial_t *) &DEV_server485->parent;
    com_dev->config.baud_rate = BAUD_RATE_115200;
    com_dev->config.bufsz = 3000;
    /* set serial configure */
    com_dev->ops->configure(com_dev, &(com_dev->config));

    /* open serial device */
    if (!rt_device_open(DEV_server485, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX)) 
    {
            rt_device_set_rx_indicate(DEV_server485, server485_recv_callback);
    } 
    else 
    {
            return ;
    }
    set_server485_tx_rx_mode(RXMODE);

    sem_server485 = rt_sem_create("server485_sem", 0, RT_IPC_FLAG_FIFO);
    rt_timer_init(&timer_server485, "timer_server485", timer_server485_timeout, RT_NULL, 10, RT_TIMER_FLAG_PERIODIC);
    rt_timer_start(&timer_server485);
}

int server485_communicate_init(void)
{
    rt_thread_t server485_tid = RT_NULL;
    
    rt_pin_mode(SERVER485_RE_IO,PIN_MODE_OUTPUT); 

    server485_tid = rt_thread_create("server485",
                                 server_485_thread, RT_NULL,
                                 1024, 12, 5);
    if (server485_tid != RT_NULL)
        rt_thread_startup(server485_tid);

    return 0;
}
INIT_APP_EXPORT(server485_communicate_init);

/****************************************************
 rs485接收函数 

参数:buff  接收到的数据保存缓冲区
      time  超时时间 单位为1个systick
返回值:接收到的数据长度
****************************************************/
rt_uint16_t recv_from_server485(char *buff, rt_int32_t wtime)
{
    rt_uint16_t rx_length = 0;
    rt_err_t result;
    //extern void dump(char txrx, char hex[], uint16_t lenth);
    
  rt_sem_control(sem_server485,RT_IPC_CMD_RESET,0);

    result = rt_sem_take(sem_server485, wtime);

    if (result == -RT_ETIMEOUT)
    {
        return 0;
    }
    if (result == RT_EOK)
    {
        if (buff != RT_NULL)
        {
            rx_length = rt_device_read(DEV_server485, 0, buff, server485_revc_bytes);
            server485_revc_bytes = 0;
        }
    }
    //dump(1,buff,rx_length);
    return rx_length;
}

/****************************************************
rs485发送函数

参数:buff    待发送的数据缓存区
length  待发送的数据长度
返回值 :NULL
****************************************************/
void send_by_server485(char *buff, rt_uint16_t length)
{
    
    if(DEV_server485 == RT_NULL)
    {
        return;
    }
    set_server485_tx_rx_mode(TXMODE);
    rt_device_write(DEV_server485, 0, buff, length);
    set_server485_tx_rx_mode(RXMODE);
}

void server485_kprintf(const char *fmt, ...)
{
    va_list args;
    rt_size_t length;
    char rt_buf[RT_CONSOLEBUF_SIZE];

    va_start(args, fmt);

    length = rt_vsnprintf(rt_buf, sizeof(rt_buf) - 1, fmt, args);
    if (length > RT_CONSOLEBUF_SIZE - 1)
        length = RT_CONSOLEBUF_SIZE - 1;
        
        send_by_server485(rt_buf, length);
    va_end(args);
}



#ifndef  __SERVER485_H__
#define  __SERVER485_H__

#include <rtdevice.h>
#include <string.h>

#define DEV_SERVER485       "uart3"
#define SERVER485_RE_IO     26  //GET_PIN(C,4) //24    //RS485_RE引脚        PC4
                                                    
extern int server485_communicate_init(void);
extern rt_uint16_t recv_from_server485(char *buff,rt_int32_t wtime);
extern void send_by_server485(char* buff,rt_uint16_t length);
extern void server485_kprintf(const char *fmt, ...);
extern void server485_baud_auto_change(void);
#endif


 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值