stm32-串口

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了stm32-串口相关的知识,希望对你有一定的参考价值。

 

USART:(Universal Synchronous/Asynchronous Receiver/Transmitter)
通用同步/异步串行接收/发送器
USART是一个全双工通用同步/异步串行收发模块,该接口是一个高度灵活的串行通信设备。

 

 

串口设置的一般步骤可以总结为如下几个步骤:

1) 串口时钟使能,GPIO 时钟使能

2) 串口复位

3) GPIO 端口模式设置

4) 串口参数初始化

5) 开启中断并且初始化 NVIC(如果需要开启中断才需要这个步骤)NVIC :提供中断控制器,用于总体管理异常,称之为“嵌套向量中断控制器:Nested Vectored Interrupt Controller (NVIC)”。NVIC和处理器内核紧密相连.具体看这个点击打开链接

6) 使能串口

7) 编写中断处理函数 

接下来我们按照以上步骤来编写串口初始化函数

#include "stm32f10x.h"
#include "usart.h"  


#if EN_USART1_RX   //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误   
u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字节数目
u16 USART_RX_STA=0;       //接收状态标记  
  
void uart_init(u32 bound)//这里有个疑问,为什么命名是uart,a代表异步,为什么是异步
{
    GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA,ENABLE);//要用到的外设时钟使能,均在总线APB2上

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_Mode=GPIO_Mode_IN_FLOATING;//浮空输入模式
GPIO_Init(GPIOA,&GPIO_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;//parity奇偶性 无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//关闭硬件流控制(用于防止数据因接受不及丢失)
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式

//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_Init(USART1, &USART_InitStructure); //初始化串口1
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
    USART_Cmd(USART1, ENABLE);                    //使能串口1 
}

这里没什么特别要说的,注意irq 是interrupt request,如果不打开,接收数据的中断请求信号就会发不出去,也就是说,单片机接收不到信息

 

再看中断函数

void USART1_IRQHandler(void)//串口1中断服务程序,中断服务程序的名字在core文件夹的汇编文件中定义
{
u8 Res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾),RXNE接收数据寄存器非空标志位
{
Res =USART_ReceiveData(USART1);//读取接收到的数据

if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
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;//接收数据错误,重新开始接收 
}  
}
}    
     } 

#endif

这里我一开始看不懂,发现前面原来有讲,是我没看。。。。

技术分享

 

主函数如下

#include "stm32f10x.h"
#include "usart.h"


void delayms(u16 a)
{
u16 i,j;
    for(i=0;i<a;i++)
{
   j=8000;
while(j--);
}
}
int main(void)
 {
u8 t;
u8 len;
u16 times=0; 
 
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
uart_init(9600);//串口初始化为9600


while(1)
{
if(USART_RX_STA&0x8000)
{   
len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
for(t=0;t<len;t++)
{
USART1->DR=USART_RX_BUF[t];
while((USART1->SR&0X40)==0);//等待发送结束
}
USART_RX_STA=0;
            delayms(10);
}
}  
}

今后继续补充


















































































































以上是关于stm32-串口的主要内容,如果未能解决你的问题,请参考以下文章

stm32如何启动串口中断

stm32啥触发串口接收中断

如何通过串口烧写STM32程序

stm32 串口 中断的问题

stm32串口发送正常,接受只能收到一个字符,求解,急

stm32f7的串口TX如何设置