最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 正文

STM32 串口简介

来源:动视网 责编:小OO 时间:2025-10-03 03:36:03
文档

STM32 串口简介

串口作为MCU的重要外部接口,同时也是软件开发重要的调试手段,其重要性不言而喻。STM32的串口资源相当丰富的,功能也相当强劲。ALIENTEK战舰STM32开发板所使用的STM32F103ZET6最多可提供5路串口,有分数波特率发生器、支持同步单线通信和半双工单线通讯、支持LIN、支持调制解调器操作、智能卡协议和IrDASIRENDEC规范、具有DMA等。用过单片机的人肯定都接触过串口,设置串口无非就是设置波特率、数据位、停止位、奇偶校验位。发送接收也就三种基本方式,轮询、中断和DMA。ST
推荐度:
导读串口作为MCU的重要外部接口,同时也是软件开发重要的调试手段,其重要性不言而喻。STM32的串口资源相当丰富的,功能也相当强劲。ALIENTEK战舰STM32开发板所使用的STM32F103ZET6最多可提供5路串口,有分数波特率发生器、支持同步单线通信和半双工单线通讯、支持LIN、支持调制解调器操作、智能卡协议和IrDASIRENDEC规范、具有DMA等。用过单片机的人肯定都接触过串口,设置串口无非就是设置波特率、数据位、停止位、奇偶校验位。发送接收也就三种基本方式,轮询、中断和DMA。ST
串口作为MCU的重要外部接口,同时也是软件开发重要的调试手段,其重要性不言而喻。STM32的串口资源相当丰富的,功能也相当强劲。ALIENTEK战舰STM32开发板所使用的STM32F103ZET6最多可提供5路串口,有分数波特率发生器、支持同步单线通信和半双工单线通讯、支持LIN、支持调制解调器操作、智能卡协议和IrDASIRENDEC规范、具有DMA等。

用过单片机的人肯定都接触过串口,设置串口无非就是设置波特率、数据位、停止位、奇偶校验位。发送接收也就三种基本方式,轮询、中断和DMA。STM32F10x  的USART  模块也不过如此。所以我重点讲讲我在调试代码时犯得各种错误,那些很容易得到的代码就不详细的讲解了。

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

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

2)串口复位

3)GPIO端口模式设置

4)串口参数初始化

5)开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤)

6)使能串口

7)编写中断处理函数

与串口基本配置直接相关的几个固件库函数。这些函数和定义主要分布在stm32f10x_usart.h和stm32f10x_usart.c文件中。

1.串口时钟使能。串口是挂载在APB2下面的外设,所以使能函数为:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1);

2.串口复位。当外设出现异常的时候可以通过复位设置,实现该外设的复位,然后重新配置这个外设达到让其重新工作的目的。一般在系统刚开始配置外设的时候,都会先执行复位该外设的操作。复位的是在函数USART_DeInit()中完成:

void USART_DeInit(USART_TypeDef*USARTx);//串口复位

比如我们要复位串口1,方法为:

USART_DeInit(USART1);//复位串口1

3:GPIO端口设置,首先要是能gpio时钟,然后将用到的串口占用的io口设置一下属性。

4.串口参数初始化。串口初始化是通过USART_Init()函数实现的,

void USART_Init(USART_TypeDef*USARTx,USART_InitTypeDef*USART_InitStruct);

这个函数的第一个入口参数是指定初始化的串口标号,这里选择USART1。

第二个入口参数是一个USART_InitTypeDef类型的结构体指针,这个结构体指针的成员变量用来设置串口的一些参数。一般的实现格式为:

USART_InitTypeDef  USART_InitStructure;

USART_InitStructure.USART_BaudRate=bound;//一般设置为9600;

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);

5.开启串口响应中断。有些时候当我们还需要开启串口中断,那么我们还需要使能串口中断,使能串口中断的函数是:

void USART_ITConfig(USART_TypeDef*USARTx,uint16_tUSART_IT,FunctionalStateNewState)

这个函数的第二个入口参数是标示使能串口的类型,也就是使能哪种中断,因为串口的中断类型有很多种。比如在接收到数据的时候(RXNE读数据寄存器非空),我们要产生中断,那么我们开启中断的方法是:

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开启中断,接收到数据中断

我们在发送数据结束的时候(TC,发送完成)要产生中断,那么方法是:

USART_ITConfig(USART1,USART_IT_TC,ENABLE);//开启发送数据中断

//Usart1 NVIC 配置

如下给一个例子来说明这一步:

      NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//设置中断源为串口1中断

      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级

      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        //响应优先级

      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //IRQ通道使能

      NVIC_Init(&NVIC_InitStructure);    //¸设置串口1中断优先级并使能中断通道

USART_ITConfig(USART1,USART_IT_TC,ENABLE);//开启发送数据中断

6.串口使能。串口使能是通过函数USART_Cmd()来实现的,这个很容易理解,使用方法是:USART_Cmd(USART1,ENABLE);//使能串口

7:编写中断函数,需要注意的是中断函数名字已经规定好了,不能随便改为其他的。

#if EN_USART1_RX   //如果使能了接收中断

void USART1_IRQHandler(void)                    //串口1中断服务程序

    {

    u8 Res;

#ifdef OS_TICKS_PER_SEC         //如果时钟节拍数定义了,说明要使用ucosII了.

    OSIntEnter();    

#endif

    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)

        {

     Res =USART_ReceiveData(USART1);//(USART1->DR);    //读取接收到的数据

        

        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;//接收数据错误,重新开始接收      

                    }         

                }

            }            

     } 

#ifdef OS_TICKS_PER_SEC         //如果时钟节拍数定义了,说明要使用ucosII了.

    OSIntExit();                                               

#endif

#endif    

数据发送与接收。STM32的发送与接收是通过数据寄存器USART_DR来实现的,这是一个双寄存器,包含了TDR和RDR。当向该寄存器写数据的时候,串口就会自动发送,当收到数据的时候,也是存在该寄存器内。

STM32库函数操作USART_DR寄存器发送数据的函数是:

void USART_SendData(USART_TypeDef*USARTx,uint16_tData);

通过该函数向串口寄存器USART_DR写入一个数据。

STM32库函数操作USART_DR寄存器读取串口接收到的数据的函数是:

uint16_t USART_ReceiveData(USART_TypeDef*USARTx);

通过该函数可以读取串口接受到的数据。

在固件库函数里面,读取串口状态的函数是:

FlagStatus USART_GetFlagStatus(USART_TypeDef*USARTx,uint16_tUSART_FLAG);

这个函数的第二个入口参数非常关键,它是标示我们要查看串口的哪种状态,比如RXNE(读数据寄存器非空)以及TC(发送完成)。例如我们要判断读寄存器是否非空(RXNE),操作库函数的方法是:

USART_GetFlagStatus(USART1,USART_FLAG_RXNE);

我们要判断发送是否完成(TC),操作库函数的方法是:

USART_GetFlagStatus(USART1,USART_FLAG_TC);

8.获取相应中断状态。当我们使能了某个中断的时候,当该中断发生了,就会设置状态寄存器中的某个标志位。经常我们在中断处理函数中,要判断该中断是哪种中断,使用的函数是:

ITStatus  USART_GetITStatus(USART_TypeDef*USARTx,uint16_tUSART_IT)

比如我们使能了串口发送完成中断,那么当中断发生了,我们便可以在中断处理函数中调用这个函数来判断到底是否是串口发送完成中断,方法是:

USART_GetITStatus(USART1,USART_IT_TC)

返回值是SET,说明是串口发送完成中断发生。

如果要使用串口,那么就需要配置相应的io口。需要设置相应的io口的输入输出属性。

对于stm32芯片还具有重映射功能:

一旦使用了串口,某些GPIO管脚就被占用了:

如果使用的是st官方提供的库函数的话,就需要掌握如下这些函数:

点击(此处)折叠或打开

1.//初始化IO串口1

2.//bound:波特率

3.voiduart_init(u32bound)

4.{

5.GPIO_InitTypeDefGPIO_InitStructure;

6.USART_InitTypeDefUSART_InitStructure;

7.NVIC_InitTypeDefNVIC_InitStructure;

8.//①串口时钟使能,GPIO时钟使能,复用时钟使能

9.RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|

10.RCC_APB2Periph_GPIOA,ENABLE);//使能USART1,GPIOA时钟

11.//②串口复位

12.USART_DeInit(USART1);//复位串口1

13.//③GPIO端口模式设置

14.GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//ISART1_TXPA.9

15.GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

16.GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出

17.GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化GPIOA.9

18.GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//USART1_RXPA.10

19.GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空输入

20.GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化GPIOA.10

21.//④串口参数初始化

22.USART_InitStructure.USART_BaudRate=bound;//波特率设置

23.USART_InitStructure.USART_WordLength=USART_WordLength_8b;//字长为8位

24.USART_InitStructure.USART_StopBits=USART_StopBits_1;//一个停止位

25.USART_InitStructure.USART_Parity=USART_Parity_No;//无奇偶校验位

26.USART_InitStructure.USART_HardwareFlowControl

27.=USART_HardwareFlowControl_None;//无硬件数据流控制

28.USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//收发模式

29.USART_Init(USART1,&USART_InitStructure);//初始化串口

30.#ifEN_USART1_RX//如果使能了接收

31.//⑤初始化NVIC

32.NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;

33.NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级3

34.NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;//子优先级3

35.NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//IRQ通道使能

36.NVIC_Init(&NVIC_InitStructure);//中断优先级初始化

37.//⑤开启中断

38.USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开启中断

39.#endif

40.//⑥使能串口

41.USART_Cmd(USART1,ENABLE);//使能串口

42.}

文档

STM32 串口简介

串口作为MCU的重要外部接口,同时也是软件开发重要的调试手段,其重要性不言而喻。STM32的串口资源相当丰富的,功能也相当强劲。ALIENTEK战舰STM32开发板所使用的STM32F103ZET6最多可提供5路串口,有分数波特率发生器、支持同步单线通信和半双工单线通讯、支持LIN、支持调制解调器操作、智能卡协议和IrDASIRENDEC规范、具有DMA等。用过单片机的人肯定都接触过串口,设置串口无非就是设置波特率、数据位、停止位、奇偶校验位。发送接收也就三种基本方式,轮询、中断和DMA。ST
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top