又是一周过去。不知这一周大家过得怎么样?是否开心,是否有所收获。
秋天,是一个收获的季节。这一切都是建立在春耕夏播的基础之上。
以上是序。
通过前面的学习,我们学会了如何用串口发送数据和接收固定字节的命令。 今天,我们继续讨论串口应用协议,主要焦点还是在如何有效地使用串口发送数据。为了简化描述,假设我们基于8051单片机开发一个温湿度采集系统,周期将温度和湿度数据上报到上位机。温度和湿度定义如下:
float temperature = 25.0; //温度float humidity = 70.0; //湿度
我们至少可以设计出以下两种不同的串口应用协议:
1.固定大小的消息:先发送float类型的温度,再发送float类型的湿度。每次传输8个字节。
温度(4字节)
湿度(4字节)
代码实现:
// 固定消息发送温度和湿度函数void send_temperature_and_humidity(float temperature, float humidity){ uart_sendfloat(temperature); //发送温度 uart_sendfloat(humidity); //发送湿度}
字符串消息,先发送温度的字符串,再发送湿度的字符串,两者之间有明显的分隔符(例如空格、分号或冒号),结尾一般以“ ”结束。
25.0, 70.0
//以字符串消息发送温度和湿度函数void send_temperature_and_humidity_string(float temperature, float humidity){ printf(%f,%f, tempeature, humidity); //以字符串消息发送温度、湿度} 以上两种应用协议中,哪一种最好呢?
从消息长度来看,固定消息大小都是8个字节,而字符串消息则超过8个字节且长度不定(请思考为什么?)
从可读性来看,在ascii接收模式下,字符串消息可读性高(人可直接读),固定消息“不可读”。
从效率和保密性(假设有这一条吧),固定消息胜出,因为它发送的是原始二进制数据,占用字节最少。
为了传输更多的数据和实现更复杂的功能,我们通常在固定消息的基础上引入更多的辅助数据。例如,增加校验位保证数据传输无误,增加地址字节以区分不同设备等。但对于有些上位机(labview)来说,它对字符串数据的解释可以一步到位,无需按图索骥。
at命令常用于控制wifi模块、sms模块等,就是以字符串消息实现的。
练手项目:假设有一个多点温度采集系统,架构如下图所示。
其中,n值取决于具体的系统要求。试基于固定长度消息设计串口应用协议,实现多点数据的上报。
太简单了,一次传完n点温度,如下:
1#温度
2#温度
......
n#温度
顺序读取1#~n#的温度,先放到缓冲里,一次调用串口发送函数将n点数据发送出去。收工!
n很小时,没有毛病。假设n=128,则要求温度缓存数组长度至少为128个,一个温度数值占4字节(float),要128*4 = 512b,这超出了可用内存。如果不同的项目,n点都不一样,那么上位机的程序必须根据n点修改串口接收程序。累死。
怎么办?我们可以每读一个ds18b20,就将温度发送到串口。重复n次就完成一次温度采集与上报。
为了区分是哪个ds18b20,我们增加一个字节数据表示设备号(1~n)。所以,串口上报协议变为:
设备号(1字节, unsigned char)
温度(4字节,float)
n最大为255。这么做的好处一个是简化了程序,也便于上位机接收和处理数据。
关键代码:
unsigned char ds18b20_no= 1;//读取温度并发送到串口float temperature;temperature = ds18b20_readtermperature(ds18b20_no); //读取温度uart_senduchar(ds18b20_no); //发送设备号uart_sendfloat(temperature); //发送温度
ds18b20_readtermperature()函数是读取温度函数,本例中我们先使用模拟的(而不是真正去读一个ds18b20)。实现如下:
//读取ds18b20温度(模拟)float ds18b20_readtemperature(unsigned char no){ static unsigned char tick = 0; //为了模拟得到一个变化的温度引入的变量 float temperature; tick++; temperature = no + tick*0.1; return temperature;} 我们引入模块化编程的思想,把发送功能封装到一个函数里。函数是模块化开发的必经之路。函数的引入增强了代码的可读性和复用性,也便于修改和维护程序。经过不断积累,函数库的引入可以使开发事半功倍。例如前面我们把串口封装到uart.h和uart.c,就是模块化思想的淋漓尽致的体现。使用串口,则直接添加uart.h和uart.c到工程,然后在主程序包含uart.h,直接调用定义好的串口函数就可以访问串口。
//发送温度函数,设备号(1b)温度(4b) void sendtemperature(unsigned char no, float temperature){ uart_senduchar(no); uart_sendfloat(temperature);} 我们使用 c51编程入门(二十二)串口编程入门--串口应用协议(一) 的proteus仿真电路,使用labview开发上位机来接收多点温度数据并显示。
仿真电路(没有接ds18b20,,温度模拟产生)
labview上位机能够正确接收并解码数据。labview的程序框图如下:
结束语
附上本次串口源码,如下。如果你觉得本篇文章有所帮助,请点赞,请打赏。 您的支持是对我们的最大鼓励。如果需要仿真电路和串口工程源码以及labview上位机源码,请在后台留言。
下一篇文章我们将完善仿真电路,增加ds18b20元件及驱动程序,并完善labview上位机(增加温度保存功能)。如果有可能,后面会开发labview串口程序的相关教程,并提供labview源码。
完整的代码:(uart.h和uart.c略,前一篇文章已经给出)
//uart_firstdemo.c#include uart.h//#includereg51.hsbit beeper_en = p2^0;sbit key_s1 = p1^0;char msg[] = welcome back.;unsigned char uart_rx_buffer[2];unsigned int count = 0;//函数定义void delayms(unsigned int nms);void keyscan(); //按键扫描float ds18b20_readtemperature(unsigned char no); //读取ds18b20温度void sendtemperature(unsigned char no, float temperature); //发送温度函数void main(){ unsigned char ds18b20_no = 1; //设备号 unsigned char ds18b20_n = 3; //ds18b20总数 float temperature; //温度 uart_init(); while(1) { temperature = ds18b20_readtemperature(ds18b20_no); //读温度 sendtemperature(ds18b20_no, temperature); //发送温度 ds18b20_no++; if(ds18b20_no > ds18b20_n)//已经读完所有点的温度 { ds18b20_no = 1; delayms(1000); //等待1s左右,再开始下一次采集 } }}void keyscan(){ float temperature; if(key_s1 == 0) { delayms(10); //消抖 if(key_s1 == 0) //按键按下,读取并上报1#地点的温度 { temperature = ds18b20_readtemperature(1); //读温度 sendtemperature(1, temperature); //发送温度 } }}//延时函数void delayms(unsigned int nms){ unsigned int i,j; for(i=0;i
TWS蓝牙対箱如何配对?一台手机怎么让2台音响同时出声播放?
工信部:我国在新能源汽车发展上任重道远,已成为全球最大动力电池生产国
Nineka南卡倾力打造的挂脖式蓝牙耳机S1,轻便舒适,音质出色!
区块链将会改变电子书市场
46系列圆柱的12V电池的特点
基于8051单片机的温湿度采集系统设计
好噪声?坏噪声?教你认识ADC输入噪声
汽车雷达传感器分类 汽车雷达传感器在哪个位置
打劫无人机? 亚马逊新专利技术或能避免
电源线滤波器性能的优劣取决于什么因素?
500mA线性锂离子电池充电器的特点说明
嵌入式软件与生态系统:为嵌入式开发者提供必要的组件
西克带来了生产领域的新产品以及为智能制造量身订做的传感器应用方案
半导体材料有哪些 半导体材料是硅还是二氧化硅
进口芯片花费超石油 中国半导体产业现状剖析
家用手持吸尘器让你从此爱上做家务!用了之后离不开
前7月新兴业务同比增超20%,新基建在持续发力
什么是BGA reflow翘曲?BGA reflow过程中出现翘曲怎么办?
贴片三极管与场效应管(MOS)的识别
四川瞄准电子信息产业万千百亿工程 坐实四川第一支柱电子信息产业