程序中包含打印 发送 以及接收 在线程中调用函数即可应用
适合平台 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