当前位置:   article > 正文

STM32串口(USART)详解2 收发数据类型_senddata函数能用浮点数么

senddata函数能用浮点数么

1.重复概念

串口(USART)是一种通用的同步/异步收发器,可以实现串行通信的功能。串行通信是指数据按位顺序依次传输,相比并行通信,占用的引脚资源少,但速度较慢。串口通信需要有一定的通信协议,即双方约定的数据传输的规则和约定。通常,串口通信的协议包括以下几个要素:

  • 波特率:表示每秒钟传输的码元(信号单元)的个数,单位是波特(Baud)。波特率越高,数据传输的速率越快,但也越容易出错。波特率是由串口的波特率寄存器(USART_BRR)控制的,通常可以通过计算或查表的方式得到波特率寄存器的值。
  • 数据位:表示每个码元包含的二进制位的个数,一般有5、6、7、8、9等几种选择。数据位越多,可以传输的信息量越大,但也占用的时间越长。
  • 奇偶校验位:表示是否对数据位进行奇偶校验,用于检测数据传输是否正确。一般有无校验、奇校验、偶校验三种选择。无校验表示不进行校验,奇校验表示数据位的1的个数为奇数时,校验位为0,否则为1,偶校验则相反。
  • 停止位:表示数据传输结束的标志位,可以是1位、1.5位或2位。停止位的位数越多,数据传输的稳定性越高,但速度也越慢。

2.类型解释

串口通信的数据类型主要有两种:字符型和数值型。字符型数据是指按照ASCII码或其他编码方式传输的字符,如字母、数字、符号等。数值型数据是指按照二进制或十六进制等方式传输的数值,如整数、浮点数等。不同的数据类型在串口通信中有不同的处理方式,下面分别介绍。

字符型数据的收发

字符型数据的收发比较简单,只需要调用库函数即可。STM32提供了以下几个库函数:

  • void USART_SendData(USART_TypeDef* USARTx, uint16_t Data):用于发送单个字符,第一个参数是串口号,第二个参数是要发送的字符。该函数会将字符写入发送数据寄存器(USART_DR),然后等待发送移位寄存器为空,再将数据逐位发送出去。
  • uint16_t USART_ReceiveData(USART_TypeDef* USARTx):用于接收单个字符,参数是串口号。该函数会从接收数据寄存器(USART_DR)读取字符,然后返回给调用者。
  • int fputc(int ch, FILE *f):用于重定义标准输出函数,使得可以使用printf等函数向串口发送字符。该函数需要调用USART_SendData函数来实现。
  • int fgetc(FILE *f):用于重定义标准输入函数,使得可以使用scanf等函数从串口接收字
  • 符。该函数需要调用USART_ReceiveData函数来实现。 

3.字符型数据的收发的示例代码

以下是一个使用字符型数据的收发的示例代码,实现了STM32通过串口1和上位机(PC)对话的功能,即将接收到的字符原样返回给上位机。

  1. /* 发送单个字符 */
  2. void Usart_SendByte(USART_TypeDef* pUSARTx, uint8_t data)
  3. {
  4. USART_SendData(pUSARTx, data); // 调用库函数发送数据
  5. while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); // 等待发送完成
  6. }
  7. 发送字符串 **
  8. void Usart_SendString( USART_TypeDef * pUSARTx, char *str)
  9. {
  10. unsigned int k=0;
  11. do
  12. {
  13. Usart_SendByte( pUSARTx, *(str + k) );
  14. k++;
  15. } while(*(str + k)!='\0');
  16. /* 等待发送完成 */
  17. while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET)
  18. {}
  19. }
  20. /* 串口接收中断服务函数 */
  21. void USART1_IRQHandler(void)
  22. {
  23. uint8_t ucTemp;
  24. if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) // 判断是否有接收中断
  25. {
  26. ucTemp = USART_ReceiveData(USART1); // 调用库函数接收数据
  27. USART_SendData(USART1, ucTemp); // 调用库函数发送数据
  28. }

4.数值型数据的收发的示例代码 

数值型数据的收发比较复杂,因为需要考虑数据的格式和大小端问题。数据的格式是指数据是按照二进制、十进制、十六进制等方式表示的,不同的格式在串口通信中有不同的表示方法。数据的大小端是指数据在内存中的存储顺序,大端模式是指高位字节存放在低地址,低位字节存放在高地址,小端模式则相反。STM32是小端模式的处理器,而串口通信一般是大端模式的,所以在数据收发时需要进行大小端的转换。

数值型数据的收发一般有以下几种方法:

  • 使用sprintf和sscanf函数:这种方法可以将数值转换成字符串,然后使用字符型数据的收发函数进行传输。这种方法的优点是简单易用,缺点是占用内存和时间较多,而且不能传输浮点数。
  • 使用memcpy和union结构体:这种方法可以将数值拆分成字节,然后逐个字节进行传输。这种方法的优点是占用内存和时间较少,而且可以传输浮点数。
  • 使用位运算和移位操作:这种方法可以将数值按位进行操作,然后按照一定的顺序进行传输。这种方法的优点是效率最高,而且可以灵活地控制数据的格式和大小端,缺点是编程较复杂,而且需要注意数据的溢出和符号问题。
  1. /* 发送浮点数 */
  2. void Usart_SendFloat(USART_TypeDef* pUSARTx, float data)
  3. {
  4. uint8_t i;
  5. union
  6. {
  7. float f;
  8. uint8_t c[4];
  9. }u; // 定义一个联合体,用于浮点数和字节数组的转换
  10. u.f = data; // 将浮点数赋值给联合体
  11. for(i = 0; i < 4; i++)
  12. {
  13. Usart_SendByte(pUSARTx, u.c[3-i]); // 逆序发送字节,实现大小端的转换
  14. }
  15. }
  16. /* 接收浮点数 */
  17. float Usart_ReceiveFloat(USART_TypeDef* pUSARTx)
  18. {
  19. uint8_t i;
  20. union
  21. {
  22. float f;
  23. uint8_t c[4];
  24. }u; // 定义一个联合体,用于浮点数和字节数组的转换
  25. for(i = 0; i < 4; i++)
  26. {
  27. u.c[3-i] = USART_ReceiveData(pUSARTx); // 逆序接收字节,实现大小端的转换
  28. while(USART_GetFlagStatus(pUSARTx, USART_FLAG_RXNE) == RESET); // 等待接收完成
  29. }
  30. return u.f; // 返回浮点数
  31. }
  32. 串口发送数字
  33. * 参 数:Number 要发送的数字,范围:0~4294967295
  34. * 参 数:Length 要发送数字的长度,范围:0~10
  35. * 返 回 值:无
  36. */
  37. void Serial_SendNumber(uint32_t Number, uint8_t Length)
  38. {
  39. uint8_t i;
  40. for (i = 0; i < Length; i ++) //根据数字长度遍历数字的每一位
  41. {
  42. Serial_SendByte(Number / Serial_Pow(10, Length - i - 1) % 10 + '0'); //依次调用Serial_SendByte发送每位数字
  43. }
  44. }

5.结语

其实说到底无非就是发送和接收这两个函数,那种类型的发送按照自己的需求进行封装,这样当然最好,当然上面的程序使用或者用来参考也是可以的。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/399655
推荐阅读
相关标签
  

闽ICP备14008679号