UART(Universal Asynchronous Receiver and Transmitter)在 USART基础上裁剪掉了同步通信功能,只有异步通信。简单区分同步和异步就是看通信时需不需要对外提供时钟输出,我们平时用的串口通信基本都是 UART。是全双工串口总线,有两根线,一根TXD用于发送,一个RXD用于接收。UART的串口数据传输不需要使用时钟信号来同步传输,而是依赖于发送设备与接收设备之间预定的配置。
空闲时,信号线的状态都处于高电平。
起始位:开始进行数据传输时发送方要先发出一个低电平’0’来表示传输字符的开始。因为空闲位一直是高电平所以开始第一次通讯时先发送一个明显区别于空闲状态的信号即为低电平。
数据位:起始位之后就是要传输的数据,一般都是8位。先发送最低位最后发送最高位。比如TXD串口发送0x05时,数据格式是(1 0 1 0 0 0 0 0)。
奇偶校验位:
数据位传送完成后,要进行奇偶校验,校验位其实是调整个数,串口校验分几种方式:
无校验(no parity)
奇校验(odd parity):如果数据位中’1’的数目是偶数,则校验位为’1’,如果’1’的数目是奇数,校验位为’0’。
偶校验(even parity):如果数据为中’1’的数目是偶数,则校验位为’0’,如果为奇数,校验位为’1’。
mark parity:校验位始终为1。
space parity:校验位始终为0。
停止位:数据结束标志,可以是1位,1.5位,2位的高电平。
波特率:数据传输速率使用波特率来表示,单位bps(bits per second)。国际上规定一个标准的波特率系列: 110、300、600、1200、1800、2400、4800、9600、115200、14.4Kbps、19.2Kbps等。例如:115200bps是指每秒传送115200位,通信双方必须设置同样的同学速率才能正常通信。
STM32F4x中 USART测试
main.c
/* USER CODE BEGIN 0 */
/* printf() 函数重定向到串口中*/
int fputc(int ch,FILE *f)
{
while(!(USART1->SR & (1<<7))); //SR 状态寄存器, 判断第7位是否有数据
USART1->DR = ch;//DR 数据寄存器,将数据存入到寄存器中
return ch;
}
/* USER CODE END 0 */
int main(){
/* USER CODE BEGIN 1 */
uint8_t ch[10] = {0};
/* USER CODE END 1 */
/* USER CODE BEGIN 2 */
printf("this is uart test\n");
HAL_UART_Transmit(&huart1, (uint8_t *)"USART SEND\n",10, 1000);
/* USER CODE END 2 */
/* USER CODE BEGIN WHILE */
while (1)
HAL_UART_Receive(&huart1, ch, 1, 1000);
HAL_UART_Transmit(&huart1, ch,1, 1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
中断模式
main.c
/* USER CODE BEGIN PV */
uint8_t REV[2] = {0};
/* USER CODE END PV */
/* USER CODE BEGIN 0 */
int fputc(int ch,FILE *f)
{
while(!(USART1->SR & (1<<7))); //SR 状态寄存器, 判断第7位是否有数据
USART1->DR = ch;//DR 数据寄存器,将数据存入到寄存器中
return ch;
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
printf("this is uart int test\n");
//串口中断发送
HAL_UART_Transmit_IT(&huart1, (uint8_t *)"UART SEND\n", 10);
//串口接收中断
HAL_UART_Receive_IT(&huart1, REV, 2);
/* USER CODE END 2 */
usart.c
/* USER CODE BEGIN 1 */
//发送中断
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1){
printf("uart send end int\n");
}
}
//接收中断
extern uint8_t REV[2];
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1)
{
printf("REV DATA:REV[0]=%x,REV[1]=%x\n",REV[0],REV[1]);
HAL_UART_Receive_IT(&huart1,REV,2);
}
}
/* USER CODE END 1 */
关于打印
在main.c 文件添加int fputc(int ch,FILE *f)可能不行,可以在usart.c文件中添加
/* USER CODE BEGIN 1 */
int fputc(int ch,FILE *f){
uint8_t temp[1] = {ch};
HAL_UART_Transmit(&huart1,temp,1,2);
return ch;
}
/* USER CODE END 1 */