OneNote笔记移植……
串口1236为同步通信串口(即USART),串口45为异步通信串口(即UART)。

时钟——串口2345挂载在APB1上,串口1和6挂载在APB2上
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
GPIO初始化重定向
GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_USART1);
串口的硬件流控制
资料总结来于网络
http://bbs.elecfans.com/m/jishu_939361_1_1.html
我们在串行通讯处理中,常常看到rts/cts和xon /xoff这两个选项,这就是两个流控制的选项,目前流控制主要应用于调制解调器的数据通讯中。
1.流控制在串行通讯中的作用
这里讲到的“流”,当然指的是数据流。数据在两个串口之间传输时,常常会出现丢失数据的现象,或者两台计算机的处理速度不同,如台式机与单片机之间的通讯,接收端数据缓冲区已满,则此时继续发送来的数据就会丢失。现在在网络上通过modem进行数据传输,这个问题就尤为突出。流控制能解决这个问题,当接收端数据处理不过来时,就发出“不再接收”的信号,发送端就停止发送,直到收到“可以继续发送”的信号再发送数据。因此流控制可以控制数据传输的进程,防止数据的丢失。 pc机中常用的两种流控制是硬件流控制(包括rts/cts、dtr/cts等)和软件流控制xon/xoff(继续/停止),下面分别说明。
2.硬件流控制
硬件流控制常用的有rts/cts流控制和dtr/dsr(数据终端就绪/数据设置就绪)流控制。
硬件流控制必须将相应的电缆线连上,用rts/cts(请求发送/清除发送)流控制时,应将通讯两端的rts、cts线对应相连,数据终端设备(如计算机)使用rts来起始调制解调器或其它数据通讯设备的数据流,而数据通讯设备(如调制解调器)则用cts来起动和暂停来自计算机的数据流。这种硬件握手方式的过程为:
编程时根据接收端缓冲区大小设置一个高位标志(可为缓冲区大小的75%)和一个低位标志(可为缓冲区大小的25%),当缓冲区内数据量达到高位时,在接收端将cts线置低电平(送逻辑0),当发送端的程序检测到cts为低后,就停止发送数据,直到接收端缓冲区的数据量低于低位而将cts置高电平。
3、硬件流:RTS/CTS
(Request To Send/Clear To Send)即请求发送/清除发送协议。
用于半双工时的收发切换,半双工的意思是说,发的时候不收,收的时候不发。那么怎么区分收发呢?缺省时是DCE向DTE发送数据,当DTE决定向DCE发数据时,先有效RTS,表示DTE希望向DCE发送。一般DCE不能马上转换收发状态,DTE就通过监测CTS是否有效来判断可否发送,这样避免了DTE在DCE未准备好时发送所导致的数据丢失。
简单的说就是:在发送之前告诉你我要发送数据(有效RTS),通过检测CTS来查看这个时候总线是否空闲,来决定是否可以发送数据
HAL库串口操作函数记录
(1)串口发送函数
函数名称:HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
函数功能_t *
第三个参数:数据长度
第四个参数:超时时间,单位是ms
返回值:HAL状态。有四种状态,分别是HAL_OK,HAL_ERROR,HAL_BUSY,HAL_TIMEOUT。
例:
HAL_UART_Transmit(&huart1,"Hello World!!",13,100); //向串口1发送Hello World!!
printf串口发送函数(重写fputc)
我用过两个版本的fputc,分别对应不同的stm32单片机型号,因为它们的USART寄存器不一样。
版本一:
int fputc(int ch,FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR =(uint8_t)ch;
return ch;
}
版本二:
int fputc(intch,FILE *f)
{
while(!((USART1->ISR)&(1<<7)));
USART1->TDR =ch;
return ch;
}
大家的
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 100); // 发送单字节数据
return (ch);
}
/***************** 发送字符串 **********************/
void Usart_SendString(uint8_t *str)
{
unsigned int k=0;
do
{
HAL_UART_Transmit( &huart1,(uint8_t *)(str + k) ,1,1000);
k++;
}while(*(str + k)!='\0');
}
(2)串口接收函数
HAL_UART_Receive
功能:串口轮询模式接受,使用超时管理机制
例:HAL_UART_Receive(&huart1,Rec,20,0xff);
说明:HAL_UART_Receive(串口号,接收放哪,要读取多少位,延时)每当程序执行到时读取一次
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
功能:串口中断模式读取
例:HAL_UART_Receive_IT(&huart1,Rec,1);
说明:开启接收中断
HAL_UART_Transmit_DMA();
功能:串口DMA模式发送
例:HAL_UART_Transmit_DMA(&huart1,TxMsg,sizeof(TxMsg));
说明:HAL_UART_Transmit_DMA(串口号,发送的数据,要发送多少位);
HAL_UART_Receive_DMA();
功能:;串口DMA模式接受
例:HAL_UART_Receive_DMA(&huart1,RxMsg,sizeof(RxMsg));
说明:HAL_UART_Receive_DMA(串口号,接收数据存放的数组,要接收多少位);
HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
功能:串口DMA传输停止
__HAL_DMA_GET_COUNTER(&USART_DMA_RX)
串口DMA接收剩余缓存空间获得函数。
注:必须增加串口的中断配置,否则会出现只能发送一次的尴尬局面,3.1.2中的DMA中断也必须配置,否则也是只能发送一次,不过这一处的配置应该不会漏就是了;
本文详细介绍了STM32单片机中的串口通信,包括USART和UART的区别,以及如何使用HAL库进行串口发送、接收操作,特别关注了硬件流控制(RTS/CTS)在数据传输中的作用和实现方法。同时提到了DMA模式的使用和配置要点。
2802

被折叠的 条评论
为什么被折叠?



