1.USART介绍
USART是串口通讯,常用于设备之间的通讯,电平标准有两种,TTL和RS232:使用两条通讯线:RX和TX
2.STM32支持通讯引脚
3.硬件电路
4.软件设计
4.1. USART1的GPIO口配置
PA9发送信号配置成复用推挽输出
PA10接收信号配置成浮空输入
使能信号随便找个GPIO口,配置成推挽输出
void RS1_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//¿ªÆôRS485 GPIO¶Ë¿ÚʱÖÓ
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//¸´Óù¦ÄÜÍÆÍìÊä³ö
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//¸¡¿ÕÊäÈë
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = RS1_GPIO_RE_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//ÍÆÍìÊä³ö
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
4.2 USART1的初始化配置
打开USART1口时钟
波特率设置:可选为400、9600、19200、115200,波特率越高,输出速度越快
数据位:8位或9位(使用奇偶校验数据位是9位,不适用则为8位)
停止位:可选0.5,1,1.5, 2
奇偶检验:可选无校验,奇校验,偶校验,无校验
模式:发送和接收
硬件流控制:有四种:
USART_HardwareFlowControl_None
硬件流控制失能
USART_HardwareFlowControl_RTS
发送请求RTS使能
USART_HardwareFlowControl_CTS
清除发送CTS使能
USART_HardwareFlowControl_RTS_CTS
RTS和CTS使能
void RS1_USART_Config(void)
{
USART_InitTypeDef USART_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //¿ªÆô´®¿Ú1 ÍâÉèʱÖÓ
USART_InitStruct.USART_BaudRate = 19200;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No ;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART1, &USART_InitStruct);
}
3.USART1的NVIC中断配置
中断通道使用哪个USART就配置哪个
static void NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //ÉèÖÃÖжÏͨµÀ
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //ÉèÖÃÇÀÕ¼ÓÅÏȼ¶
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //ÉèÖôÎÓÅÏȼ¶
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
4.USART1发送一个字节数据
打开发送使能接口
调用 USART_SendData(pUSARTx, ch);发送一个字节数据
等待发送数据寄存器为空
关闭发送使能接口
void RS1_SendByte(USART_TypeDef* pUSARTx, uint16_t ch)
{
Delay(10000);
RS1_TX_EN();
// Delay(10000);
USART_SendData(pUSARTx, ch);
while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
Delay(10000);
RS1_RX_EN();
}
5.发送半字
打开发送使能接口
发送高8位数据
等待发送寄存器为空
发送低8位数据
等待发送寄存器为空
关闭发送使能接口
void RS1_SendHalfWord(USART_TypeDef* pUSARTx, uint16_t data)
{
uint8_t temp_h,temp_l;
Delay(10000);
RS1_TX_EN();
temp_h = data>>8;
temp_l = data&0xff ;
USART_SendData(pUSARTx, temp_h);
while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
USART_SendData(pUSARTx, temp_l);
while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
Delay(10000);
RS1_RX_EN();
}
6.发送数组
打开发送使能接口
逐个发送字节
等待发送寄存器为空
关闭发送使能接口
void RS1_SendArray(USART_TypeDef* pUSARTx, uint8_t *array,uint16_t num)
{
uint8_t i;
Delay(10000);
RS1_TX_EN();
for(i=0 ; i<num; i++)
{
RS1_SendByte(pUSARTx, *array++);
}
while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET);
Delay(10000);
RS1_RX_EN();
}
7.发送字符
打开发送使能接口
逐个发送字节
等待发送寄存器为空
关闭发送使能接口
void RS1_SendChar(USART_TypeDef* pUSARTx, char *str)
{
unsigned int k=0;
Delay(10000);
RS1_TX_EN();
do
{
RS1_SendByte( pUSARTx, *(str + k) );
k++;
} while(*(str + k)!='\0');
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET);
Delay(10000);
RS1_RX_EN();
}
8.重定向C库函数peintf到串口
int fputc(int ch, FILE *f)
{
/* ·¢ËÍÒ»¸ö×Ö½ÚÊý¾Ýµ½´®¿Ú */
USART_SendData(DEBUG_USARTx, (uint8_t) ch);
/* µÈ´ý·¢ËÍÍê±Ï */
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);
return (ch);
}
9.重定向c库函数scanf到串口
int fgetc(FILE *f)
{
/* µÈ´ý´®¿ÚÊäÈëÊý¾Ý */
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET);
return (int)USART_ReceiveData(DEBUG_USARTx);
}
10.调用中断服务函数
使用哪个usart中断就调用哪个
当产生中断时就调用接收数据和发送数据函数
void USART1_IRQHandler(void)
{
uint8_t ucTemp;
if(USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE)!=RESET)
{
ucTemp = USART_ReceiveData(DEBUG_USARTx);
USART_SendData(DEBUG_USARTx,ucTemp);
}
}