STM32F103 串口的使用方法
扫描二维码
随时随地手机看文章
串口通讯简介:
通讯结构
电平标准
协议层
1.数据包
2.波特率
3.起始和停止信号
4.有效数据
5.数据校验
1) 串口时钟使能,GPIO 时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟
2) GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
//USART1_TX GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
//USART1_RX GPIOA.10初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10
3)Usart1 NVIC 配置(如果需要开启中断,才进行本步骤的设置)
NVIC_InitTypeDef NVIC_InitStructure;
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ; //抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化NVIC寄存器
//如果需要接收串口数据,则开启串口接收中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
4) 串口参数初始化
USART_InitTypeDef结构体,内部包含串口通讯相关工作参数:
typedef struct {
uint32_t USART_BaudRate; // 波特率
uint16_t USART_WordLength; // 字长
uint16_t USART_StopBits; // 停止位
uint16_t USART_Parity; // 校验位
uint16_t USART_Mode; // USART 模式
uint16_t USART_HardwareFlowControl; // 硬件流控制
} USART_InitTypeDef;
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART1, &USART_InitStructure); //初始化串口1
5) 使能串口
USART_Cmd(USART1, ENABLE); //使能串口1
6) 编写串口发送函数
//发送一个字节
void USART1_Send_Byte(u8 Data)
{
USART_GetFlagStatus(USART1, USART_FLAG_TC);
USART_SendData(USART1,Data);
while( USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET );
}
//发送字符串,遇到字符串结尾标志'\0'结束
void USART1_Send_String(u8 *Data)
{
while(*Data)
USART1_Send_Byte(*Data++);
}
//按长度发送字符串,这种方法可以发送含0x00的字符串
void USART1_Send_String_By_Lens(u8 *Data, int Len)
{
int i;
for(i=0; i<Len; i++)
{
USART_SendData(USART1, Data[i]);
while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET); //串口1发送数据
}
}
//重定向printf函数发送字符串,一般使用此函数直接输出打印调试信息,使用方法跟C语言中的使用方法一致。
int fputc(int ch, FILE *f)
{
USART_SendData( DEBUG_USARTx, (uint8_t) ch);
/* 等待发送完毕 */
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);
return ch;
}
7) 编写中断处理函数
void USART1_IRQHandler(void)
{
u8 Res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
USART_ClearFlag(USART1, USART_IT_RXNE); //清除标志位
Res =USART_ReceiveData(USART1); //读取接收到的数据
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(Res==0x0D)
USART_RX_STA|=0x4000;
else if(Res!=0x0a)
USART_RX_STA=0;//接收错误,重新开始
else
USART_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(Res==0x0d)
USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))
USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}
//接收完数据之后,在main函数中对接收到的数据进行处理。
if(USART_RX_STA&0x8000)
{
//得到此次接收到的数据长度,即USART_RX_BUF数组中的有效数据长度
uart1Len=USART_RX_STA&0x3f;
//对接收到的数据进行数据处理,接收的数据暂存在USART_RX_BUF数组中
//... ...
USART_RX_STA=0;
memset(USART_RX_BUF, 0, sizeof(USART_RX_BUF)); //清空数组
}
串口应用:
与TTL串口传感器或模块直接通讯;
转为RS232与PC通讯;
转为RS485与485部件的传感器或器件通讯;
USB转串口的原理图:
TTL串口转RS232原理图:
TTL串口转RS485原理图:
参考资料:
- 【正点原子】MiniSTM32开发板资料
有啥想玩的模块,留言给我,咱们一起玩
免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!