VS 如何将十进制数进行位判断??

  • 二进制数中的一个数位,可以是0或者1,是计算机中数据的最小单位。

  • 计算机中数据的基本单位,每8位组成一个字节。各种信息在计算机中存储、处理至少需要一个字节。

    例如,一个ASCII码用一个字节表示,一个汉字用两个字节表示。

  • 两个字节称为一个字。汉字的存储单位都是一个字。

1个汉字是一个字,即两个字节,16位数据

(一)并行通信和串行通信

  • 8位数据并列的传输,传一个8位的数据是需要8根线一起传输。

    例如:SDIO,FSMC(16位的)–发送数据都是所有数据位同时传输

  • 8位数据一位一位的传输,只需要一根线即可进行传输。

    例如:USART,IIC,SPI三种都是串行方式-----发送数据时都是一位一位的进行发送数据

  • 串行通信与并行通信特征

  • 有两根数据线,一个用来接收数据,一个用来发送数据,互不干扰,可以同时发送和接收数据。

    例如:usart(可以半双工或全双工通信),SPI(可以半双工或者全双工通信)

  • 有两根数据线,但是不可以同时发送数据,可以分时收发数据

  • 只有一根数据线,只可以单向通信(只可以往某一个方向进行)

(三)收发数据同步或异步传输

  • 数据同步方式,两个设备的时钟信号是同一个(有时钟信号的是同步)。

    在传输数据时为了保证数据传输的准确性:
    (1)时钟在高电平时,数据有效
    (2)时钟信号在低电平时数据时无效的
    (3)对时钟的要求很高(如果时钟有尖峰或者杂波,则数据传输就不准确了)

    例如:SPI,IIC通信接口。

  • 没有时钟信号:为了保证数据传输的准确性是通过加上一些辅助的标识符

    例如:UART(通用异步收发器),单总线。

  • 同步通信和异步通信比较

    (1)在同步通信中,数据信号所传输的内容绝大部分就是有效数据。
    (2)在异步通信中,传输的数据会包含有帧的各种标识符。
    (3)所以同步通信的效率更好,但是对于时钟允许误差较小,异步通信对于时钟允许误差较大。

  • 比特率:每秒钟传输的二进制数单位:bit/s

    IIC,SPI(同步通信,一个时钟下传输一个数据,通过时钟来控制)

  • 波特率:每秒钟传输的码元个数(串口)

    一个二进制位表示一个码元(特殊情况下)

物理层规定我们用嘴巴还是肢体进行交流
协议层就是规定我们用汉语还是英文来交流

1、RS232和TTL就是在电平上的区别

TTL电平是直接从单片机(或者芯片)里面出来的:高电平用3.3V或者5v来表示,低电平用0表示
RS232中1用-15V表示,0用+15V表示,逻辑正好时相反的,低电平和高电平的差距非常大

(二)USB转串口(TTL标准)

(四)串口数据包的基本组成

(一)状态寄存器:USART_SR

  • TXE-发送数据寄存器空

    当TDR寄存器中的数据被硬件转移到移位寄存器的时候,TXE位被硬件置位。
    如果USART_CR1寄存器中的TXEIE为1,则产生中断。对USART_DR的写操作,将该位清零。

    0-数据还没有转移到移位寄存器
    1-数据已经转移到移位寄存器

  • 当包含有数据的一帧发送完成后,并且TXE=1时,由硬件将TC位置’1’。
    如果USART_CR1中的TCIE=1,则产生中断。由软件序列清除该位(先读USART_SR,然后写入USART_DR)。 TC位也可以通过写入’0’来清除,只有在多缓存通讯中才推荐这种清除程序。

  • RXNE-读数据寄存器非空

    当RDR移位寄存器中的数据被转移到USART_DR寄存器中,该位(RXNE)被硬件置位。
    如果USART_CR1寄存器中的RXNEIE=1,则产生中断。对USART_DR的读操作可以将该位清零。 RXNE位也可以通过写入0来清除,只有在多缓存通讯中才推荐这种清除程序。

  • UE是使能串口 (1-模块使能)
  • TE是发送使能(0-禁止发送,1-使能发送)
  • RE是接收使能(0-禁止接收,1-使能接收)
  • TCIE是发送完成中断使能(0-禁止产生中断,1-当USART_SR中的TC为’1’时,产生USART中断)
  • RXNEIE:接收缓冲区非空中断使能(0-禁止产生中断,1-当USART_SR中的ORE或者RXNE为’1’时,产生USART中断)

(四)串口接收和发送数据

上图对应的顺序依次是1->2->3,数据来源于CPU或者DMA,数据来了之后首先是放到发送寄存器(TDR)中,然后会再放到发送数据移位寄存器中,由于数据是8位的,会将数据一位一位的发送出去(使用TX引脚)。

  • 当数据由发送寄存器到发送数据移位寄存器时,TXE会被置1,即TXE=1,表示发送数据寄存器为空了,但是并不表示数据已经发送出去了。
  • 因为还要通过发送移位寄存器进行一位一位的发送数据,如果发送移位寄存器数据全部发送出去了,TC会被置1,即TC=1表示发送数据完毕。


数据从RX引脚进来来,数据是一位一位进行接收的。

  • 首先放到数据接收移位寄存器
  • 然后将数据传递到数据接收寄存器(RDR),此时RXNE会被置1,即RXNE=1,表示数据接收寄存器不是空的(收到数据可以读出)
  • STM32 库函数操作 USART_DR 寄存器发送数据的函数是:通过该函数向串口寄存器 USART_DR 写入一个数据。

  • STM32 库函数操作 USART_DR 寄存器读取串口接收到的数据的函数是:通过该函数可以读取串口接收到的数据。

  • 该函数只判断标志位。在没有使能相应的中断函数时,通常使用该函数来判断标志位是否置1

  • 不仅会判断标志位是否置1,同时还会判断是否使能了相应的中断。所以在串口中断函数中,如果要获取中断标志位,通常使用该函数。

//1、使能串口时钟,串口引脚时钟 //3、发送接收引脚的设置 //6、开启接收数据中断

1、函数1-串口发送一个字节数据

//发送完数据是检测TXE这个位是否置1,发送数据寄存器空了,表明已经把数据传递到数据移位寄存器了 //检测TXE这个位也需要一个固件库函数 //如果这个位一直为0的话就一直等待,只有当被设为SET后才会跳出这个循环(表示一个字节发送出去了)

在main主函数中编写语句:

//在主函数里面发送一个数据试试

串口调试助手并没有显示100,而是显示的一个字母d
串口调试助手不管接收到的是什么数据,都会转化为字符
只有发送十六进制数据,串口助手使用十六进制形式接收数据时才不是字符

串口助手无论是收发都是以字符的形式进行传输的

假如说串口助手发送一个数字1,stm32串口如果能够接收的话,在进行数据解析过程中需要按照字符 ’1‘ 来进行解析(把1当成是字符,而不是十进制1 )

2、函数2-发送两个字节数据

有时候传感器数据可能是16位的,怎么发送?发送两个字节?
发送两个字节的数据就是十六位的。

//发送两个字节数据函数
 //发送十六位数据要分为两次来发送,先定义两个变量
 //16位的数据这样子就放到了两个变量里面(共16位)
 

在主函数中发送十六进制数据:

串口助手显示的是字符,要想接收到的数据和发送的一样,需要把串口助手选择为16进制接收
串口助手接收到ff 56。虽然是16位的数据但是显示的时候还是一个字节一个字节的显示,十六进制ff是一个字节 56是一个字节

3、函数3-发送一个数组数据

//每次想要发送多少数据,通过形参num传进来,num定义的是8位的,那么函数最多发送255个 //调用发送一个字节函数发送数据(下面两种写法都可以)

判断发送一个字节的数据标志位:USART_FLAG_TXE
判断发送一连串字节的数据标志位:USART_FLAG_TC

在主函数中定义一个数组

串口助手:十六进制形式接收数据

串口助手:非十六进制数据形式接收数据:1-10的ASCII是无法显示的

4、函数4-发送字符串函数

//使用do-while循环,do的时候已经开始发送了 //需要调用发送一个字节函数 //如果='\0'表示发送完毕

在主函数中调用函数发送一个字符串

5、函数5-使用printf函数进行打印数据

有时候想直接用printf函数直接发送,肯定是不可以的
printf函数底层会有一个fputc,如果想要使用,需要重新定义

//发送一个字节数据到串口
重定向c库函数scanf到串口,重写后可以使用scanf和getchar函数
 /* 有了这个等待就不需要在中断中进行了 */

如果在主函数中使用getchar()需要把下面的中断设置代码注释掉(下图),否则会冲突
因为不需要在中断中进行


在主函数的while(1)循环中加入接收数据和发送数据的代码

用串口助手发送什么字符,串口助手就会接收到单片机返回什么字符

当接收到数据时产生中断

有中断就要设置中断优先级

1、串口助手发送并返回数据中断函数

串口助手发送什么数据给单片机,单片机自动将接收到的数据返回给串口助手

当外部设备或者串口调试助手给单片机发送数据时,单片机检测到数据接收寄存器非空,表示数据来了此时产生中断,进去中断服务函数调用固件库函数这个标志位是否真正置1,以免产生误中断,如果真的产生1时,调用USART_ReceiveData(USART1)函数接收数据,把数据放ucTemp变量中

2、串口发送数据控制led亮灭

通过串口接收到的数据进行控制led灯,这样子就不需要中断来接收了,通过查询方法即可,这时候要把中断部分给注释了,中断服务函数注释掉就可以了

在主函数中加入以下代码:

 u8 ch;//存放电脑接收到的数据

如果出现错误:参考此链接
使用串口助手分别发送1和2就可以控制led灯的亮灭了

3、STM32自定义协议接收十六进制数据(使用三合一气体传感器求出CO2浓度)

前面已经说到,如果不勾选十六进制数据接收和发送的话,其他情况都是以字符的形式发送和接收的,所以此处在发送和接收数据时都要将hex选项进行勾选

三合一气体传感器串口数据流格式如下:

由于前两个字节数据是固定的模块地址,因为可以用来当做判断标准,定义一个接收数据的协议:只有第一个字节和第二个字节都符合条件时,才将数据存储到数组中

数据流共9个字节,所以先定义一个存储9个字节的八位数组

u8 table_cp[9];//这是额外定义一个数组,将接收到的数据复制到这里面
//使用自定义协议接收十六进制数据
 
 else if(count==1)//第一个数据接收正确的情况下,判断第二个数据
 else//如果第二个字符不是0XE4则计数清零,重新接收
 

上面实现的是通过自定义协议接收并存储数据

在接收到十六进制数据之后,想要提取其中的两个字节并将其转化为十进制数据,首先需要编写一个十六进制转换函数:(输入十六进制数据返回十进制数据

主函数的while内容如下:

//用十进制数据打印一下接收到的数据 //前两位是固定的,第7个和第8个十六进制数据分别是CO2的高八位和低八位 //把对应的十六进制数据转化为十进制数据


如下图所示:使用串口助手发送十六进制数据:
其中第7个字节是CO2的高8位,第8个字节是CO2浓度的低8位,然后再按照计算公式进行计算即可求出二氧化碳浓度


阶码(指数)就是指数位存储的值,而偏阶(移码)则不同精度的浮点数的偏阶也各不相同,具体可以查看。

半精度浮点数 是一种被计算机使用的二进制浮点数据类型。半精度浮点数使用2个字节(16位)来存储。
在IEEE 754-2008中,它被称作binary16。这种数据类型只适合存储对精度要求不高的数字,不适合用来计算。

我要回帖

更多关于 java判断数字位数 的文章

 

随机推荐