##用NB-IOT上的stm32单片机通过UART和USART串口与电脑通信
###串口通信流程下收发数据流程:
中断触发—>进入中断服务函数—>根据中断服务函数中的状态(中断向量表)运行相对应的函数—>执行回调(callback)函数
[有关callback函数的定义请参见《windows环境下32位汇编》.作者罗云彬.第二章.windows环境下消息处理队列]
###函数解释:
USART2_IRQ_HANDLER(void);//中断服务函数,主要工作是判断标志位,判断接收的数据是否是错误的,如果是错的就进入对应的回调函数,如果没错的话就进入static void UART_RxlSR_8BIT(UART_HandleTypeDef *huart2);
static void UART_RxlSR_8BIT(UART_HandleTypeDef *huart2);//隶属于接收使能函数,这个函数就是在流程中提到的中断服务函数相对应的函数
HAL_UART_RECEIVE_IT(UART_HandleTypeDef *huart2,uint8_t *pData,uint16_t Size);
/*接收使能函数,如果通信过程中收到数据想要保存,必须运行接收使能函数。我在调试过程中,因为没有加这个函数,所以一直收不到32发来的数据。 参数解释:*huart2指串口2的句柄。[关于句柄的定义请参见《windows32位环境下的汇编语言》]pData指要传入的数据的地址,因为传入的数据很可能不止一位,所以一般用数组传入,数组以数组名做首地址。所以一般传入地址名即可,但是要记得类型转换。Size指的是每次传输的位数。/
在一次数据传输结束后,接收自动不使能,如果要再次传输,必须再次使能。所以建议把使能函数写在callback函数里,这样每次执行完一次数据传输后又会自动使能。
HAL_UART_RxpltCallback();//这是一个弱定义回调函数(弱定义强定义函数定义请参见<轻松玩转ARM架构—基于k60>)
printf();
HAL_UART_Transmit(&huart2,(uint8_t*)&ch,1,0xff);
//这两个函数是配套起来用的
//printf();作为标准输入输出函数,作用是在显示器上显示,实际上是利用到了Windows显示的底层API。在这里不能直接使用,第二个函数的作用就相当于底层驱动。
###串口接收方式:单字节接收,特定字节接收
###程序实现过程:
1.使能接收函数: HAL_UART_RECEIVE_IT(huart2,(uint8_t)aRxBuffer,1);
2.多字节接收过程:接收到数据后,并不接受一位保存一位,而是根据使能函数中给出的位数N大小一直暂存在暂存数组aRxBuffer中,直到存满N个,保存一次。
实现过程:
1.先接收N个位数据,暂存在aRxBuffer数组中
2.接收够N位数据后,进入callback回调函数
3.在回调函数中将暂存在aRxBuffer数组中的值存放在自定义的数组中
3.1 USART_REC_BUFFER自定义的数组 usart2_rcv_len 可变的数组下标
4.将该数据存放到flash或ram中(这已经不需要我们再操心了)
5.在保存好数据后,将自定义的数组和数组下标都清空,重新下一次接收数据
3.特定字节接收过程:以特定字符作为标志位,当接收到特定字符时,自动认为是停止传输标志。在市面上最常见的是以\r\n作为结束标识符。\r的16进制码为0x0d,\n的hex进制码为0x0a
实现过程:
1.在callback函数中定义
在函数中先判断当前字符是不是\r(0x0d)
如果是\r,则再判断下一个字符是不是\n
如果是\n,则表示当前数据传输结束。
如果不是\n,则表示当前数据暂未结束,继续判断下下一个字符
如果输入的不是\r,则继续判断下下一个字符。
在上一个数据暂未保存完的时候,如果出现了下一段数据已经开始传输的问题怎么办?
------在通信中有一个标志位寄存器,系统根据这个寄存器中的位是1还是0判断当前数据是否已经完整保存,如果当前 数据还没保存好,那么下一段数据也不会开始保存。
具体代码请参见示例教程
来源:CSDN
作者:猫老板来嗨
链接:https://blog.csdn.net/qq_21464351/article/details/103990238