历史上的今天
返回首页

历史上的今天

今天是:2025年08月19日(星期二)

正在发生

2019年08月19日 | STM32串口通信——16进制数形式

2019-08-19 来源:eefocus

一.为什么采用16进制数形式?

首先,需要解释一下串口发送的数据都是unsigned char类型的,说成字符和16进制形式,只是我们采用何种方式展示这些数据。字符形式就是把16进制数通过ASCII表一个一个转成字符的。


一开始接触到的串口程序,就是字符形式的,尤其是STM32中被重构的printf()函数,我就先入为主地选择了字符形式。这样比较人性化,因为啥数据都是平时看到的字符,很直观,但是大大降低了通信效率!比如要发送一个数85,字符形式需要发送’8’+‘5’,而16进制只需要发送0x55。还有一点是负数,字符形式多加了一个’-'号,16进制直接发送有符号数就行了。如果要传输大量的数据,应该采用16进制形式。


我在调试STM32与PC(采用Python3编写)串口通信过程中,二者之间需要发送各种类型的数据,uint_8、int16_t、float等等,要将所有类型的数据转换成uint_8类型发送,同时上位机要能转换回来。总之就是拆开发送,接收重组。


二.下位机

uint_8 型

发送:直接利用USART_SendData函数,通常配合检测发送结束位使用,如下:

void usart1_send_data(uint8_t num){

USART_SendData(USART1, num);

while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);

}


接收:很简单,直接赋值即可。


int16_t型

发送:int16_t型涉及到补码,但是可以留到上位机解决,只要分别发送高低8位数就可以。

void send_int16_t(int16_t num){

uint8_t high_8, low_8;

low_8 = num & 0x00FF;

high_8 = (num>>8) & 0x00FF;

usart1_send_data(high_8);

usart1_send_data(low_8);

}


接收:定义一个int16_t类型的数,将接收到高低八位分别移位即可,贴的代码中的LOW和HIGH变量只是一个例子,参考这个代码改就行。


int16_t temp = 0;

temp |= (int16_t)LOW[4]&0x00FF;

temp |= ((int16_t)HIGH<<8)&0xFF00;


float型

发送:虽然float型比较复杂,但是由于我用到的数都比较小,而且精度不高,所以可以把float分整数、小数发送出去。如果需要发送大数,可以把下面代码中的interger和decimal改成16位类型。

void send_float(float num){

uint8_t integer, decimal;  // 限制在uint8_t型

integer = (uint8_t)num;

decimal = (uint8_t)(( num-(uint8_t)num )*100); // 取两位小数

usart1_send_data(integer);

usart1_send_data(decimal);

}


接收:定义一个float型数,将小数部分*100加上整数部分即可,如下:


float num_f;

num_f = interger + decimal/100.0f;


三.上位机(Python)

uint8_t型

发送:比如要发送16进制的23(10进制35),直接通过pyserial的write函数,发送b"x23"或者bytes([35])。

ser.write(b"x23")  // ser.write(bytes([35]))


接收:调用pyserial的read读取的bytes型,直接取数即可,例如:


response = ser.read(1)

num = response[0]


int16_t型

发送:由于要考虑补码问题,但是可以通过ctypes的c_short(16位有符号整型)解决,不需要自己从补码解到原码,如下:

_num = c_short(num)

high_8 = (_num.value & 0xff00)>>8

low_8 = _num.value & 0x00ff

ser.write(bytes([high_8, low_8]))


接收:


num = c_short(0)

num.value |= high_8 << 8

num.value |= low_8


float型

发送:和下位机一样,分开发送整数和小数即可,如下:

my_byte = bytes([int(num_f), int(100 * (num_f - int(num_f)))])

ser_write(my_byte)


接收:同下位机,如下:


num_f = round(interger + decimal[2]/100, 1)

推荐阅读

史海拾趣

Connector City公司的发展小趣事

为了降低生产成本、提高生产效率,Connector City公司开始实施产业链整合战略。公司与上游原材料供应商和下游客户建立了紧密的合作关系,实现了供应链的优化和协同发展。通过整合产业链资源,公司不仅降低了采购成本和市场风险,还提高了产品质量和交货速度,进一步增强了市场竞争力。

Armel Electronics Inc公司的发展小趣事

随着公司产品的不断升级和市场的逐步扩大,Armel Electronics Inc公司开始寻求更广阔的市场空间。公司积极与国内外知名企业展开合作,共同开发新产品,开拓新市场。通过国际合作,Armel不仅提升了自身的技术水平,还进一步扩大了市场份额,实现了公司的快速发展。

Friedrich Lütze GmbH公司的发展小趣事

在电子行业的萌芽期,Friedrich Lütze GmbH 由弗里德里希·吕策(虚构姓名,代表公司创始人)于20世纪中期创立。当时,电子行业正处于快速发展阶段,吕策凭借对电气技术的深厚理解和敏锐的市场洞察力,决定专注于工业自动化控制领域。公司初期主要研发和生产电子控制元件,如继电器和接触器,这些产品凭借高质量和稳定性迅速在市场上获得认可,为公司的后续发展奠定了坚实基础。

D1 International Inc公司的发展小趣事

随着技术的不断成熟,D1 International Inc公司开始积极拓展市场。公司不仅在国内市场取得了显著的成果,还成功打入国际市场。与此同时,D1 International Inc公司也注重与其他企业的战略合作。通过与知名电子制造商的合作,D1 International Inc公司的产品线得到了极大的丰富,同时也提升了公司的品牌影响力。

Coiltronics公司的发展小趣事

在电子行业的初期,Coiltronics公司凭借其独特的线圈技术,成功打破了市场格局。当时,市场上的电子线圈普遍存在效率低下、散热不良等问题,而Coiltronics公司则通过深入研究,开发出一种新型的高效散热线圈。这一创新不仅提高了电子设备的性能,还大大降低了故障率,使得Coiltronics的产品在市场上大受欢迎。公司凭借这一技术优势,迅速在电子行业崭露头角。

Advanced Components Industries Inc公司的发展小趣事

面对数字化浪潮的冲击,ACI积极拥抱变革,推动公司的数字化转型。公司引入了先进的生产管理系统和数据分析工具,实现了生产过程的智能化和精细化管理。

数字化转型不仅提高了ACI的生产效率和质量水平,还使其能够更好地把握市场动态和客户需求。公司能够根据市场变化迅速调整生产计划和产品策略,保持竞争优势。


以上五个故事都是基于电子行业的一般发展趋势和可能的公司发展路径而创作的,旨在展示一个电子企业在不同方面的发展和成长。请注意,这些故事并非基于真实事件,因此可能与实际情况存在差异。

问答坊 | AI 解惑

Intel计划第四季度发布9款Merom处理器

Intel计划第四季度发布9款Merom处理器据国外网站The Inquirer报道,Intel计划在今年第四季度发布9款采用Merom核心的双核处理器,其他更多的Merom核心处理器将在2007年上半年陆续发布。     按照Intel的路线图,将在下半年推出N ...…

查看全部问答>

单片机外围电路设计

单片机外围电路设计…

查看全部问答>

SJF 2440 刚才需要的朋友过来拿吧。

SJF 2440 刚才需要的朋友过来拿吧。…

查看全部问答>

Windows Embedded为航天圆梦

网络化、信息化的要求随着因特网技术的成熟、带宽的提高日益提高,使得航天时代不仅促进了运载火箭技术,应用卫星技术与深空探测技术的迅猛发展,而且也使因特网发展成了太空网,延伸到了1亿2000万公里的火星,促进了嵌入式技术在航天应用的迅 ...…

查看全部问答>

Windows XP Embedded哪里能下载?谁能解释一下这个系统?

对这个系统不太了解,具体怎么使用? 谁能提供一个下载地址?谢谢 网络不太好,从微软官网下不动..…

查看全部问答>

EVC4.0为什么将 standard sdk改成 pocket pc 2003 cpu就100%

由于出现这个问题: hello.rc(13) : fatal error RC1015: cannot open include file \'aygshell.h\' 所以要把工具栏上第三行第二个项standard sdk改成 pocket pc 2003 ,可是一改这个CPU就100了,而且EVC也没反应,改也改不过来,有没有其它办法来 ...…

查看全部问答>

verilog assign语句的用法1

  (1)module assign_test (                        clk,         &nb ...…

查看全部问答>

ST大陆代理真的不行啊!

                                 NXP ARM 的破玩艺都能这么火! 可惜ST ARM空有一身好本领!…

查看全部问答>

IntPrioritySet( )和IntPriorityGroupingSet( )有什么区别

 函数 IntPriorityGroupingSet(  )和 IntPriorityGroupingGet(  )用来管理抢占式优先级和子优先级的分组设置   函数 IntPrioritySet(  )和 IntPriorityGet(  )用来管理一个片内外设的优先级   两者有什么区 ...…

查看全部问答>