-
Notifications
You must be signed in to change notification settings - Fork 255
Open
Description
/* 定义各通道 */
#define CH1 0
#define CH2 1
#define CH3 2
#define CH4 3
#define CH5 4
#define CH6 5
#define CH7 6
#define CH8 7
#define CH9 8
#define CH10 9
#define CH11 10
#define CH12 11
#define CH13 12
#define CH14 13
#define CH15 14
#define CH16 15
/* 信息帧数据结构定义 */
typedef struct {
uint8_t year; // 0~99 -> 2000 ~ 2099, 7 bit
uint8_t month; // 1 ~ 12, 4 bit
uint8_t day; // 1 ~ 31, 5 bit
uint8_t hour; // 0 ~ 23, 5 bit
uint8_t min; // 0 ~ 59, 6 bit
uint8_t sec; // 0 ~ 59, 6 bit
uint16_t msec; // 0 ~ 999, 10 bit
uint32_t sampleRate; // 0 ~ 2000000, 21 bit
} ws_timestamp_t;
/* 公共函数声明 */
char ws_point_int8(char *buffer, char channel, int8_t value);
char ws_point_int16(char *buffer, char channel, int16_t value);
char ws_point_int32(char *buffer, char channel, int32_t value);
char ws_point_float(char *buffer, char channel, float value);
void ws_frame_init(char *buffer);
char ws_frame_length(const char *buffer);
char ws_add_int8(char *buffer, char channel, int8_t value);
char ws_add_int16(char *buffer, char channel, int16_t value);
char ws_add_int32(char *buffer, char channel, int32_t value);
char ws_add_float(char *buffer, char channel, float value);
char ws_send_timestamp(char *buffer, ws_timestamp_t* ts);
/*****************************************************************************
* 文件名: sendwave.c
* 版本: V1.2
* 作者: 官文亮
* 日期: 2018/9/2
* 说明: 本文件属于SerialTool软件的波形显示功能的下位机参考代码, 作用是将数
* 值转换为SerialTool可以识别的帧, 用户需实现串口发送函数, 结合本程序
* 即可实现串口发送波形的显示, 本程序适合SerialTool v1.1.6及后续版本.
*
* SerialTool源码链接: https://github.com/gztss/SerialTool
* SerialTool安装包链接: https://github.com/gztss/SerialTool/releases
*
*****************************************************************************/
/* 此处定义一些常量, 请勿修改! */
enum {
Ch_Num = 16, // 通道数量
Frame_MaxBytes = 80, // 最大帧长度
Frame_Head = 0xA3, // 帧头识别字
Frame_PointMode = 0xA8, // 点模式识别字
Frame_SyncMode = 0xA9, // 同步模式识别字
Frame_InfoMode = 0xAA, // 信息帧识别字
Format_Int8 = 0x10, // int8识别字
Format_Int16 = 0x20, // int16识别字
Format_Int32 = 0x30, // int32识别字
Format_Float = 0x00 // float识别字
};
/* 函数功能: 发送int8类型数据
* 函数参数:
* buffer : 帧缓冲区, 需要4byte
* channel: 通道, 取值范围为0~15
* value : 通道数据值, 8bit有符号整数
* 返回值 : 数据帧长度(单位为byte)
**/
char ws_point_int8(char *buffer, char channel, int8_t value)
{
if ((uint8_t)channel < Ch_Num) { // 通道验证
// 帧头
*buffer++ = Frame_Head;
*buffer++ = Frame_PointMode;
*buffer++ = channel | Format_Int8; // 通道及数据格式信息
*buffer = value; // 数据添加到帧
return 4; // 数据帧长度
}
return 0;
}
/* 函数功能: 发送int16类型数据
* 函数参数:
* buffer : 帧缓冲区, 需要5byte
* channel: 通道, 取值范围为0~15
* value : 通道数据值, 16bit有符号整数
* 返回值 : 数据帧长度(单位为byte)
**/
char ws_point_int16(char *buffer, char channel, int16_t value)
{
if ((uint8_t)channel < Ch_Num) { // 通道验证
// 帧头
*buffer++ = Frame_Head;
*buffer++ = Frame_PointMode;
*buffer++ = channel | Format_Int16; // 通道及数据格式信息
// 数据添加到帧
*buffer++ = (value >> 8) & 0xFF;
*buffer = value & 0xFF;
return 5; // 数据帧长度
}
return 0;
}
/* 函数功能: 发送int32类型数据
* 函数参数:
* buffer : 帧缓冲区, 需要7byte
* channel: 通道, 取值范围为0~15
* value : 通道数据值, 32bit有符号整数
* 返回值 : 数据帧长度(单位为byte)
**/
char ws_point_int32(char *buffer, char channel, int32_t value)
{
if ((uint8_t)channel < Ch_Num) { // 通道验证
// 帧头
*buffer++ = Frame_Head;
*buffer++ = Frame_PointMode;
*buffer++ = channel | Format_Int32; // 通道及数据格式信息
// 数据添加到帧
*buffer++ = (value >> 24) & 0xFF;
*buffer++ = (value >> 16) & 0xFF;
*buffer++ = (value >> 8) & 0xFF;
*buffer = value & 0xFF;
return 7; // 数据帧长度
}
return 0;
}
/* 函数功能: 发送float类型数据
* 函数参数:
* buffer : 帧缓冲区, 需要7byte
* channel: 通道, 取值范围为0~15
* value : 通道数据值, 类型为单精度浮点(32bit)
* 返回值 : 数据帧长度(单位为byte)
**/
char ws_point_float(char *buffer, char channel, float value)
{
// 这个联合变量用来实现浮点到整形的变换
union {
float f;
uint32_t i;
} temp;
if ((uint8_t)channel < Ch_Num) { // 通道验证
temp.f = value;
// 帧头
*buffer++ = Frame_Head;
*buffer++ = Frame_PointMode;
*buffer++ = channel | Format_Float; // 通道及数据格式信息
// 数据添加到帧
*buffer++ = (temp.i >> 24) & 0xFF;
*buffer++ = (temp.i >> 16) & 0xFF;
*buffer++ = (temp.i >> 8) & 0xFF;
*buffer = temp.i & 0xFF;
return 7; // 数据帧长度
}
return 0;
}
/* 函数功能: 同步发送模式缓冲区初始化
* 函数参数:
* buffer : 帧缓冲区, 最多需要(Frame_MaxBytes + 3) bytes
**/
void ws_frame_init(char *buffer)
{
*buffer++ = Frame_Head;
*buffer++ = Frame_SyncMode;
*buffer = 0;
}
/* 函数功能: 获取同步模式缓冲区长度(单位bytes)
* 函数参数:
* buffer : 同步模式帧缓冲区
**/
char ws_frame_length(const char *buffer)
{
return buffer[2] + 3;
}
/* 函数功能: 在数同步据帧中加入一个int8类型数据
* 函数参数:
* buffer : 已经初始化的帧缓冲区
* channel: 通道, 取值范围为0~15
* value : 通道数据值, 类型为int8
* 返回值 : 0, 加入成功, 1, 帧长度已经达到上限或通道错误
**/
char ws_add_int8(char *buffer, char channel, int8_t value)
{
char count = buffer[2];
char *p = buffer + count + 3; // 跳过前面数据
count += 2;
// 帧长度及通道验证
if (count <= Frame_MaxBytes && (uint8_t)channel < Ch_Num) {
buffer[2] = count;
*p++ = channel | Format_Int8; // 通道及数据格式信息
*p = value; // 数据添加到帧
return 1;
}
return 0;
}
/* 函数功能: 在数同步据帧中加入一个int16类型数据
* 函数参数:
* buffer : 已经初始化的帧缓冲区
* channel: 通道, 取值范围为0~15
* value : 通道数据值, 类型为int16
* 返回值 : 0, 加入成功, 1, 帧长度已经达到上限或通道错误
**/
char ws_add_int16(char *buffer, char channel, int16_t value)
{
char count = buffer[2];
char *p = buffer + count + 3; // 跳过前面数据
count += 3;
// 帧长度及通道验证
if (count <= Frame_MaxBytes && (uint8_t)channel < Ch_Num) {
buffer[2] = count;
*p++ = channel | Format_Int16; // 通道及数据格式信息
// 数据添加到帧
*p++ = (value >> 8) & 0xFF;
*p = value & 0xFF;
return 1;
}
return 0;
}
/* 函数功能: 在数同步据帧中加入一个int32类型数据
* 函数参数:
* buffer : 已经初始化的帧缓冲区
* channel: 通道, 取值范围为0~15
* value : 通道数据值, 类型为int32
* 返回值 : 0, 加入成功, 1, 帧长度已经达到上限或通道错误
**/
char ws_add_int32(char *buffer, char channel, int32_t value)
{
char count = buffer[2];
char *p = buffer + count + 3; // 跳过前面数据
count += 5;
// 帧长度及通道验证
if (count <= Frame_MaxBytes && (uint8_t)channel < Ch_Num) {
buffer[2] = count;
*p++ = channel | Format_Int32; // 通道及数据格式信息
// 数据添加到帧
*p++ = (value >> 24) & 0xFF;
*p++ = (value >> 16) & 0xFF;
*p++ = (value >> 8) & 0xFF;
*p = value & 0xFF;
return 1;
}
return 0;
}
/* 函数功能: 在数同步据帧中加入一个float类型数据
* 函数参数:
* buffer : 已经初始化的帧缓冲区
* channel: 通道, 取值范围为0~15
* value : 通道数据值, 类型为float
* 返回值 : 0, 加入成功, 1, 帧长度已经达到上限或通道错误
**/
char ws_add_float(char *buffer, char channel, float value)
{
char count = buffer[2];
char *p = buffer + count + 3; // 跳过前面数据
count += 5;
// 帧长度及通道验证
if (count <= Frame_MaxBytes && (uint8_t)channel < Ch_Num) {
union {
float f;
uint32_t i;
} temp;
buffer[2] = count;
temp.f = value;
*p++ = channel | Format_Float; // 通道及数据格式信息
// 数据添加到帧
*p++ = (temp.i >> 24) & 0xFF;
*p++ = (temp.i >> 16) & 0xFF;
*p++ = (temp.i >> 8) & 0xFF;
*p = temp.i & 0xFF;
return 1;
}
return 0;
}
/* 函数功能: 发送时间戳
* 函数参数:
* buffer : 帧缓冲区
* ts : 时间戳
* 返回值 : 数据帧长度, (单位: bytes)
**/
char ws_send_timestamp(char *buffer, ws_timestamp_t* ts)
{
uint8_t temp;
*buffer++ = Frame_Head;
*buffer++ = Frame_InfoMode;
temp = (ts->year << 1) | ((ts->month >> 3) & 0x01);
*buffer++ = (char)temp;
temp = (ts->month << 5) | (ts->day & 0x1F);
*buffer++ = (char)temp;
temp = (ts->hour << 3) | ((ts->min >> 3) & 0x07);
*buffer++ = (char)temp;
temp = (ts->min << 5) | ((ts->sec >> 1) & 0x1F);
*buffer++ = (char)temp;
temp = (ts->sec << 7) | ((ts->msec >> 3) & 0x7F);
*buffer++ = (char)temp;
temp = (ts->msec << 5) | ((ts->sampleRate >> 16) & 0x1F);
*buffer++ = (char)temp;
*buffer++ = (char)((ts->sampleRate >> 8) & 0xFF);
*buffer = (char)(ts->sampleRate & 0xFF);
return 10;
}
/* end of file sendwave.c */
void sendBuffer(char *buf, uint8_t len)
{
Serial.write(buf);
}
// include file
#include <math.h>
//#include "sendwave.h"
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed long int32_t;
// 串口示波器测试函数
void plotTest(void)
{
char buffer[100], len; // 缓冲区最大需要83bytes
static float key = 0.0f;
static ws_timestamp_t ts = { // 时间戳
17, 11, 20, // year, month, day
12, 30, 45, // hour, minute, second
120, 50 // msec, sample rate
};
// 每秒钟发送一次时间戳
if ((int64_t)(key * 50.0) % 100 == 0) {
len = ws_send_timestamp(buffer, &ts);
sendBuffer(buffer, len); // 串口发送数据
}
// 点发送模式 int8类型(8位有符号整形)
len = ws_point_int8(buffer, CH1, (int8_t)(sinf(key) * 64));
sendBuffer(buffer, len); // 串口发送数据
// 点发送模式 int16类型(16位有符号整形)
len = ws_point_int16(buffer, CH2, (int16_t)(sinf(key) * 4096));
sendBuffer(buffer, len); // 串口发送数据
// 点发送模式 int32类型(32位有符号整形)
len = ws_point_int32(buffer, CH3, (int32_t)(sinf(key) * 2048));
sendBuffer(buffer, len); // 串口发送数据
// 点发送模式 float类型(单精度浮点型)
len = ws_point_float(buffer, CH4, (float)(sinf(key) * 512));
sendBuffer(buffer, len); // 串口发送数据
// 同步模式(帧发送模式)
ws_frame_init(buffer);
ws_add_int8(buffer, CH5, (int8_t)(sinf(key) * 128));
ws_add_int16(buffer, CH6, (int16_t)(sinf(key) * 700));
ws_add_int32(buffer, CH7, (int32_t)(sinf(key) * 1024));
ws_add_float(buffer, CH9, (float)(sinf(key) * 256));
sendBuffer(buffer, ws_frame_length(buffer)); // 串口发送数据
// 更新时间计数
key += 0.02f;
}
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
}
float thisByte = 0.0f;
void loop() {
// static char buffer[83]; // maximum use of 83 bytes
// static int value = 10000; // a test value
// value+=10;
// if(value>=25600) value = 1;
//
// ws_frame_init(buffer);
// ws_add_int8(buffer, CH1, (int8_t)(value / 100));
// ws_add_int16(buffer, CH2, (int16_t)(value / 20));
// ws_add_float(buffer, CH3, (float)value * 0.1f);
// sendBuffer(buffer, ws_frame_length(buffer)); // serial port send data
delay(10);
plotTest();
}
Metadata
Metadata
Assignees
Labels
No labels