C语言模拟C++方式读取串口操作实现
来源:互联网 发布:淘宝店开不下去了 编辑:程序博客网 时间:2024/05/22 15:43
在使用C++编程对串口操作时,经常有用到serialport.read(),serialport.print()之类的函数,而且系统自带接收buf,不用考虑数据漏失的问题,那么在C语言环境下,怎么做呢?特别是51或STM32编程,或者要将C++代码转换成C代码时对这一块也不好移植,下面提供一个API,方便大家使用。
首先看接口文件,也就是头文件:
serialpoortAPI.h
#ifndef __SERIALPORT_H__#define __SERIALPORT_H__#define _SS_MAX_RX_BUFF 96#define INT_TYPE 0#define STRING_TYPE 1void UartBegin(unsigned int bps,void (*uart_init)(unsigned int),void (*uart_send)(unsigned char));void SerialPrint(void const *send_data,int type);void SerialPrintln(void const *send_data,int type);void SerialWrite(char send_data);int SerialRead(void);int SerialAvailable(void);int SerialInt(unsigned char rec_data);void ClearRxBuf(void);#endif头文件里提供了对串口的基本操作,在设置好之后,直接调用就好了。注意_SS_MAX_RX_BUFF设置的是接收缓存的buf,如果一帧数据量比较大,建议设置大一点。
然后就是实现文件了,serialpoortAPI.c
变量定义:
//serialportAPI#include<stdio.h> #include <stdlib.h>#include "serialportAPI.h"static char _receive_buffer[_SS_MAX_RX_BUFF]; static volatile unsigned char _receive_buffer_tail = 0;static volatile unsigned char _receive_buffer_head = 0;unsigned char _buffer_overflow = 0;//溢出标志位static void (*UartInit)(unsigned int);static void (*UartSend)(unsigned char);这里定义了一个数据接收缓存buf,还有_receive_buffer_tail和_receive_buffer_head,分别对应_receive_buffer的可用数据的终点和起点,如果起点和终点发生了相逢,就发生了溢出,设置标志位_buffer_overflow。
注意这里有两个函数指针,分别为数据初始化UartInit 和数据发送UartSend , 这两个函数需要在外面使用到,在函数初始化时需要对这两个函数指针赋值:
void UartBegin(unsigned int bps,void (*uart_init)(unsigned int),void (*uart_send)(unsigned char)){UartInit = uart_init;UartSend = uart_send;UartInit(bps);}
下面实现函数的发送部分功能,实现方法比较简单:
//发送//调用的时候如果是整数,传入的必须是int型,并加上&符void SerialPrint(void const *send_data,int type){if(type == STRING_TYPE){char *data_temp = (char *)send_data;//强制类型转换while(*data_temp != '\0'){UartSend(*data_temp++);}}else if(type == INT_TYPE){char str[7];char *index = str;int data_temp = (int)(*(int *)send_data);sprintf(index, "%d" , data_temp);while(*index != '\0'){UartSend(*index++);}}}//带换行的发送//调用的时候如果是整数,传入的必须是int型,并加上&符void SerialPrintln(void const *send_data,int type){SerialPrint(send_data,type);UartSend('\r');UartSend('\n');}void SerialWrite(char send_data){UartSend(send_data);}int SerialRead(void){unsigned char d; // Empty buffer? if (_receive_buffer_head == _receive_buffer_tail) return -1; // Read from "head" d = _receive_buffer[_receive_buffer_head]; // grab next byte _receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF; return (int)d;}
然后是接收部分,这里需要将下面的函数放在外面串口中断中运行:
//call by UART interruptint SerialInt(unsigned char rec_data){ // if buffer full, set the overflow flag and return if ((_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF != _receive_buffer_head) { // save new data in buffer: tail points to where byte goes _receive_buffer[_receive_buffer_tail] = rec_data; // save new byte _receive_buffer_tail = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF; } else { _buffer_overflow = 1; }return 1;}
然后就是几个常用的接收函数:
int SerialRead(void){unsigned char d; // Empty buffer? if (_receive_buffer_head == _receive_buffer_tail) return -1; // Read from "head" d = _receive_buffer[_receive_buffer_head]; // grab next byte _receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF; return (int)d;}int SerialAvailable(void){return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF;}在使用时一般是先使用SerialAvailable()判断有没有数据,然后用SerialRead()读取,可以看到,很多操作是基于_receive_buffer_tail和_receive_buffer_head这两个值的。
最后就是清除接收缓存的操作,也很简单,只要设置_receive_buffer_tail和_receive_buffer_head这两个值就好了
void ClearRxBuf(void){_receive_buffer_tail = 0;_receive_buffer_head = 0;_buffer_overflow = 0;}
1 0
- C语言模拟C++方式读取串口操作实现
- c语言串口操作
- C语言模拟实现字符串操作函数
- c语言实现读取ini文件操作
- 使用C语言操作串口
- 用C语言中断方式实现串口的读写
- linux环境下C语言实现非阻塞方式读取字符串数据的串口测试程序,即串口工具的编写
- 读取配置文件[方式一]之纯C语言实现
- 【C语言】keybd_event 函数,实现模拟按键操作
- 模拟实现C语言库函数
- C语言:模拟实现memmove
- C语言:模拟实现memcpy
- C语言:模拟实现strcpy
- c语言模拟实现memmove
- 【C语言】模拟实现memmove
- 【C语言】模拟实现strstr
- C语言 模拟实现memmove
- c语言模拟实现strcat
- kuku大神排查错误过程
- Android属性动画完全解析(三)-Interpolator和ViewPropertyAnimator的用法
- protobuf 理解
- Mysql Select if 语句中实现的判断
- 关于size_t(2)
- C语言模拟C++方式读取串口操作实现
- [Machine Learning] 机器学习常见算法分类汇总
- vector学习
- 快学Scala 第四章习题答案
- Android如何在java代码中设置margin
- 通过生活中例子模拟java面向接口编程实例
- Servlet和JSP工作原理
- Lua chunk(程序块)
- 《Unix环境高级编程》之popen函数使用