linux串口命令UART,STM32串口通信UART使用

STM32串口通信UART使用

uart使用的过程为:

1. 使能GPIO口和UART对应的总线时钟

2. 配置GPIO口的输出模式

3. 配置uart口相关的基本信息

4. 使能uart口的相关的中断,如接收中断、空闲中断等

5. 编写中断接收函数

配置对应的GPIO口

对于STM32F4_Discovery开发板而言共有五个,选择UART5作为实验串口,其对应的IO口为PC12、PD2。

UART5_TX: PC12

UART5_RX: PD2

首先需要将对应的GPIO口配置为复用功能,如下所示:

GPIO_InitTypeDef gpioInitStructure;

//

// 使能对应的GPIO口时钟

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD, ENABLE);

//

// UART5 TX:PC12 RX:PD2

//

GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_UART5);

GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_UART5);

//

// PC12

gpioInitStructure.GPIO_Pin = GPIO_Pin_12;

gpioInitStructure.GPIO_Mode = GPIO_Mode_AF;

gpioInitStructure.GPIO_OType = GPIO_OType_PP;

gpioInitStructure.GPIO_PuPd = GPIO_PuPd_UP;

gpioInitStructure.GPIO_Speed = GPIO_Speed_2MHz;

GPIO_Init(GPIOC, &gpioInitStructure);

// PD2

gpioInitStructure.GPIO_Pin = GPIO_Pin_2;

GPIO_Init(GPIOD, &gpioInitStructure);

对于GPIO口的配置,实际上是对GPIO各个寄存器的配置。GPIO_PinAFConfig()函数作用是配置GPIOx_AFR寄存器,每个口的复用功能选择由四个位来配置(具体参考STM32F4XX参考手册),因此16个GPIO空需要两个32位寄存器,在STM32F4处理器中,分别是GPIOx_AFRL、GPIOx_AFRH。而在库函数中,将寄存器的地址对应到相应的结构体上,与这两个寄存器放在一个AFR[2]数组中,如下所示。

typedef struct

{

__IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */

__IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */

__IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */

__IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */

__IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */

__IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */

__IO uint16_t BSRRL; /*!< GPIO port bit set/reset low register, Address offset: 0x18 */

__IO uint16_t BSRRH; /*!< GPIO port bit set/reset high register, Address offset: 0x1A */

__IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */

__IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */

} GPIO_TypeDef;

GPIO_Init()函数作用是配置GPIO口的输出输入功能,将GPIO_TypeDef结构体中的寄存器依次配置为相应的模式。

GPIO口配置完成之后,需要配置UART口。

UART口配置

配置UART口的同时,需要配置对应的接收中断,对应代码如下:

NVIC_InitTypeDef nvicInitStructure;

USART_InitTypeDef uartInitStructure;

//使能uart5时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5 , ENABLE);

//

// 配置UART5

uartInitStructure.USART_BaudRate = 9600;

uartInitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;

uartInitStructure.USART_WordLength = USART_WordLength_8b;

uartInitStructure.USART_StopBits = USART_StopBits_1;

uartInitStructure.USART_Parity = USART_Parity_No;

uartInitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

USART_Init(UART5, &uartInitStructure);

//

// 配置外设接受中断

nvicInitStructure.NVIC_IRQChannel = UART5_IRQn;

nvicInitStructure.NVIC_IRQChannelPreemptionPriority = 0;

nvicInitStructure.NVIC_IRQChannelSubPriority = 0;

nvicInitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&nvicInitStructure);

//

USART_Cmd(UART5, ENABLE);

配置UART5的过程主要由USART_Init()函数实现,该函数完成对UART寄存器的配置。在库函数中,UART寄存器如下所示:

typedef struct

{

__IO uint16_t SR; /*!< USART Status register, Address offset: 0x00 */

uint16_t RESERVED0; /*!< Reserved, 0x02 */

__IO uint16_t DR; /*!< USART Data register, Address offset: 0x04 */

uint16_t RESERVED1; /*!< Reserved, 0x06 */

__IO uint16_t BRR; /*!< USART Baud rate register, Address offset: 0x08 */

uint16_t RESERVED2; /*!< Reserved, 0x0A */

__IO uint16_t CR1; /*!< USART Control register 1, Address offset: 0x0C */

uint16_t RESERVED3; /*!< Reserved, 0x0E */

__IO uint16_t CR2; /*!< USART Control register 2, Address offset: 0x10 */

uint16_t RESERVED4; /*!< Reserved, 0x12 */

__IO uint16_t CR3; /*!< USART Control register 3, Address offset: 0x14 */

uint16_t RESERVED5; /*!< Reserved, 0x16 */

__IO uint16_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x18 */

uint16_t RESERVED6; /*!< Reserved, 0x1A */

} USART_TypeDef;

UART寄存器详细内容可以参考STM32F4中文手册,这里简单介绍下以下几个寄存器:

SR寄存器:状态寄存器,包含了一些标志位,如TXE(发送数据寄存器为空)、TC(发送完成)、RXNE(读取数据寄存器不为空)

DR寄存器: 数据寄存器,只用其低9位(DR[8:0])。当发送数据时,将数据写入该寄存器,该寄存器将数据发送到TDR或者移位寄存器发送,当数据写到移位寄存器时,TXE标志置1(数据写入时置0)。TXE为1时可以继续写入数据,否则新写入的数据会把原有数据覆盖。读取数据时,也是从该寄存器读取数据。

BRR波特率寄存器:波特率寄存器,用来设置波特率的值。

CR1寄存器:包含使能位UE、字长M、过采样倍率、奇偶校验、接收使能、发送使能等控制信息。

数据收发

单字符发送

//发送一个字符,USART_SendData函数实际就是将字符写入USART_DR寄存器

USART_SendData(pUSARTx,ch);

//

//等待发送寄存器为空,只有当USART_FLAG_TXE == 1 时才可以继续想DR寄存器写入数据,否则会将上一个数据覆盖掉。

while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET)

字符串发送

/***************** 发送字符串 **********************/

// 发送字符串是每个字符依次发送,相当于循环执行单字符发送函数。

//

void uart_send_str( USART_TypeDef * pUSARTx, char *str){

unsigned int k=0;

//

do {

uart_send_byte( pUSARTx, *(str + k) );

k++;

} while (*(str + k)!='\0');

//

/* 等待发送完成 */

while (USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET) ;

}

//

// USART_FLAG_TC为1的条件是,DR寄存器为空并且以为寄存器也为空。相当于所有数据都发送完毕

字符接收

uint8_t ucTemp;

if (USART_GetITStatus(UART5, USART_IT_RXNE)!=RESET){

ucTemp = USART_ReceiveData( UART5 );

// USART_SendData(UART5,ucTemp);

}

// USART_ReceiveData()函数是将DR寄存器读取并返回

// USART_IT_RXNE不为0表示数据寄存器中有数据,需要将其读出。

// 每次收一个字符,USART_IT_RXNE会被设置为1,直至数据被读出,USART_IT_RXNE再次被设置为0.

// 同时,USART_IT_RXNE也被设置为中断的标志,即接收到数据时,进入中断。

0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值