dwwdwdfefefbvr(2)USART1的设置
USART1接口的模式设置
(1)Mode:工作模式,设置为Asynchronous(异步)
(2)Hardware Flow Control(RS232):硬件流控制。开发板 的USART接口并没有使用硬件流信号,所以设置为 Disable。
USART1接口的参数置
(1)Baud Rate:波特率,设置为57600 bps
(2)Word Length:字长(包括奇偶校验位),可选8位或9 位,设置为8位
(3)Parity:奇偶校验位。 可选None(无)、Even(偶 校验)、Odd(奇校验)。这里设置为None。如果设置有奇 偶校验,字长应该设置为9
(4)Stop Bits:停止位个 数。可选1或2,这里设置为1。STM32处理器扩展的2个参数
(1)Data Direction:数据 方向,这里设置为Receive and Transmit,也就是收发 双向
(2)Over Sampling:过采样,可选16或8采样点, 这里设置为16
打开USART1的全局中断
由于RTC唤醒中断和串口中断的程序中都可能用到延时函 数HAL_Delay(),所以设置这两个中断的抢占优先级为1,即要 低于System tick timer的抢占优先级。
中断事件宏定义 ,中断事件描述, 回调函数:
UART_IT_CTS CTS 信号变化中断 无
UART_IT_LBD LIN 打断检测中断 无
UART_IT_TXE 发送数据寄存器非空中断 无
UART_IT_TC 传输完成中断,用于发送完成 HAL_UART_TxCpltCallback(huart)
UART_IT_RXNE 接收数据寄存器非空中断 HAL_UART_RxCpltCallback(huart)
UART_IT_IDLE 线路空闲状态中断 无
UART_IT_PE 奇偶校验中断 HAL_UART_ErrorCallback(huart)
UART_IT_ERR 发生帧错误、噪声错误、溢出错误 的中断 HAL_UART_ErrorCallback(huart)
1. 常用宏函数
__HAL_UART_ENABLE(__HANDLE__),使能一个UART口,如__HAL_UART_ENABLE(&huart1);
__HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__),使能某个中断事件源,如
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE); //使能接收中断
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能空闲中断
__HAL_UART_DISABLE_IT(__HANDLE__, __INTERRUPT__),禁止某个中断事件源
__HAL_UART_GET_FLAG(__HANDLE__, __FLAG__),检查一个串口的某个中断标志是否被置位,返回值为宏定义常量SET或RESET。
中断事件标志的宏定义如下:
UART_FLAG_CTS: CTS 信号变化标志
UART_FLAG_LBD: LIN 打断检测标志
UART_FLAG_TXE: 发送数据寄存器空标志
UART_FLAG_TC: 发送完成标志
UART_FLAG_RXNE: 接收数据寄存器非空标志
UART_FLAG_IDLE: 线路空闲标志
UART_FLAG_ORE: 出错误标志
UART_FLAG_NE: 声错误标志
UART_FLAG_FE: 帧错误标志
UART_FLAG_PE: 奇偶校验错误标志
__HAL_UART_CLEAR_FLAG(__HANDLE__, __FLAG__),清除一个UART口的某个事件标志位
2. 数据传输模式
串口数据传输有两种模式:
阻塞模式(Blocking mode)就是轮询模式,
例如使用函数HAL_UART_Transmit()发送一个缓冲区的数据时,这个函数会一直执行直到数据传输完成之后函数才返回。
非阻塞模式(Non-blocking mode)是使用中断或DMA模式进行数据传输,例如使用函数HAL_UART_Transmit_IT()启动一个缓冲区的数据传输后,该函数立刻返回。数据传输的过程引发各种中断,用户在相应的回调函数里去处理。
3. 阻塞式数据传输函数
函数HAL_UART_Transmit()和HAL_UART_Receive()用于阻塞模式数据发送和接收。以阻塞模式发送一个缓冲区的数据,若返回值为HAL_OK表示传输成功。
参数pData是缓冲区指针;参数Size是需要传输的字节数;参数Timeout是超时限制节拍数,表示超过这个时间时函数无条件返回。例如:
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart,
uint8_t *pData, uint16_t Size, uint32_t Timeout)
uint8_t timeStr[]="15:32:06\n";
HAL_UART_Transmit(&huart1,timeStr,sizeof(timeStr),200);
以阻塞模式接收指定长度的数据道缓冲区,若返回值为HAL_OK表示接收成功。参数pData是用于存放接收数据的缓冲区的指针;参数Size是需要接收的字节数;参数Timeout是超时限制节拍数。例如:
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart,
uint8_t *pData, uint16_t Size, uint32_t Timeout)
uint8_t recvStr[10];
HAL_UART_Receive(&huart1, recvStr,10 ,200);
4. 非阻塞式数据传输函数
用中断或DMA方式进行非阻塞模式的数据传输以中断方式发送一定长度的数据,若返回值为HAL_OK表示启动成功,但并不表示数据发送完成了。参数pData是需要发送数据缓冲区的指针,参数Size是需要发送的字节数。例如:
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData,uint16_t Size)
uint8_t timeStr[]="15:32:06\n";
HAL_UART_Transmit_IT(&huart1,timeStr,sizeof(timeStr));
发送结束后会调用回调函数HAL_UART_TxCpltCallback()以中断方式接收一定长度的数据,若返回值HAL_OK表示启动成功,但并不表示已经接收完数据了。参数pData是存放接收数据的缓冲区的指针,参数Size是需要接收的字节数。例如:
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart,
uint8_t *pData, uint16_t Size)
uint8_t rxBuffer[10]; //接收数据缓冲区
HAL_UART_Receive_IT(huart, rxBuffer,10);
接收完成后会调用回调函数HAL_UART_RxCpltCallback()
函数HAL_UART_Receive_IT()有一些特性需要注意:
(1)这个函数执行一次只能接收固定长度的数据,即使设置为接收一个字节的数据。
(2)在完成数据接收后会自动关闭接收中断,不会再继续接收下一批数据。
若要再接收下一批数据,需要再执行一次这个函数,且不能在回调函数HAL_UART_RxCpltCallback()里调用这个函数。
可以在USART1_IRQHandler()函数最后加上HAL_UART_Receive_IT()注意使用extern定义全局变量。另一博客有写。
int main(void)
{
/* USER CODE BEGIN 2 */
TFTLCD_Init(); //LCD软件初始化
LCD_ShowString(10,10, (uint8_t *)"Demo12_1:USART1+RTC");
sprintf(rxBuffer,(char *)"Hello word!!!Hello \r");
HAL_UART_Transmit (&huart1,(uint8_t *)rxBuffer,sizeof(rxBuffer),5000);
HAL_Delay(10);
sprintf(rxBuffer,"Hello No Blocking \n");
HAL_UART_Transmit_IT (&huart1,(uint8_t *)rxBuffer,sizeof(rxBuffer));
HAL_Delay(10);
HAL_UART_Receive_IT(&huart1,(uint8_t *)rxBuffer,5); //中断方式接收5个字节
while(1);
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) //串口接收完成回调函数
{
if (huart->Instance == USART1)
{
LCD_ShowString(10,10, (uint8_t *)"Demo12_1:USART1+RTC");
} }
步骤:在USART中选择Mode为Asynchronous,选择波特率,要用中断方式发送就打开中断,剩下的就是以上的程序,阻塞发送或者中断方式,中断方式要重写回调函数。
接收不定长度的字符串:
1.main.h:
extern uint8_t Str_Tra[20];//全局变量声明
extern uint8_t Str_Rec[20];
extern uint8_t Char_Rec;
2.main.c:
uint8_t Str_Tra[20]="hello,taoj123456789\n";//全局变量定义
uint8_t Str_Rec[20]="hello,taoj123765489\n";
uint8_t Char_Rec;
HAL_UART_Receive_IT (&huart1,&Char_Rec,1);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
static int i=0;
if(Char_Rec!='\n')
{
Str_Rec[i++]=Char_Rec;
}
else{
HAL_UART_Transmit_IT(&huart1,Str_Rec,i);
i=0;
}
}
3.f1xx.it.c内加入
HAL_UART_Receive_IT (&huart1,&Char_Rec,1);//继续打开接收中断开关。
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
__HAL_UART_CLEAR_FLAG(&huart3,UART_FLAG_RXNE);清除标志位
HAL_UART_Receive_IT (&huart1,&Char_Rec,1);
/* USER CODE END USART1_IRQn 1 */
}