Introducción popular y uso de STM32 y puerto serie (Usart) (ejemplo: luces pequeñas de control de puerto serie)

Introducción popular y uso de STM32 y puerto serie (Usart) (ejemplo: luces pequeñas de control de puerto serie)

1. Descripción

El propósito de escribir este artículo es ayudar a esos amigos a comprender y dominar la configuración y el uso de los puertos serie desde la perspectiva de amigos que no tienen un conocimiento claro de los puertos serie o que son nuevos en ellos.
La configuración específica de los tres grupos de puertos seriales se presenta arriba, y se da un ejemplo al final del artículo: el puerto serial controla una pequeña luz.

2. Una breve introducción al puerto serie

¿Qué es un puerto serie?
En pocas palabras, es implementar printf(""), getchar() y otras funciones, es decir, realizar la recepción y el envío de caracteres o cadenas, para realizar la comunicación.
Entre ellos, el puerto serie se divide en: USART (transceptor asíncrono síncrono) - intercambio de datos full-duplex y UART (transceptor asíncrono) - solo función de transmisión asíncrona, este artículo solo presenta la configuración y el uso de tres USART.

3. El diagrama de flujo de la función de interrupción en serie (de derecha a izquierda)

Este diagrama se utiliza para ayudar a comprender el flujo de ejecución de la interrupción.

4. Introducción al diagrama esquemático del circuito de los pines.

Diagrama esquemático del circuito sobre pines.
Como se muestra en la figura anterior: la placa tiene tres conjuntos de puertos serie (TX es el pin de envío, RX es el pin de recepción), correspondientes a:
RX1/TX1 ——> PA10/PA9 ——> USART1
RX2/TX2 —— > PA3/PA2 ——> USART2
RX3/TX3 ——> PB11/PB10 ——> USART3

alfiler USART1 USART2 USART3
Texas PA9 PA2 PB10
RX PA10 PA3 PB11
línea de reloj APB2 APB1 APB1
Nombre de la función de interrupción USART1_IRQHandler (vacío) USART2_IRQHandler (vacío) USART3_IRQHandler (vacío)

Cinco, configuración de código

1.USART1
(1) enviar, recibir configuración de pin y configuración de puerto serie

void USART1_Config(void)  
{
    
      
  	GPIO_InitTypeDef x;
	USART_InitTypeDef y;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);		//开启管脚PA9,PA10对应的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);		//开启串口USART1的时钟,注意:**APB2**
	
	x.GPIO_Pin=GPIO_Pin_9;
	x.GPIO_Mode=GPIO_Mode_AF_PP;
	x.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&x);				//配置发送引脚——选择管脚9,模式为复用推挽输出(因为是发送引脚),频率为50MHz,初始化到GPIOA
	
	x.GPIO_Pin=GPIO_Pin_10;
	x.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA,&x);				//配置接收引脚——选择管脚10,模式为浮空输入(因为是接收引脚),输入模式不用配置频率,初始化到GPIOA
	
	y.USART_BaudRate=9600;											//配置波特率9600/115200等,具体看你的硬件配置要求
	y.USART_WordLength=USART_WordLength_8b;							//配置数据位8位
	y.USART_StopBits=USART_StopBits_1;								//配置停止位为1
	y.USART_Parity=USART_Parity_No;									//奇偶校验位为无校验
	y.USART_HardwareFlowControl=USART_HardwareFlowControl_None;		//配置硬件控制流选择为无
	y.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;						//配置串口模式为接收和发送
	USART_Init(USART1,&y);				//初始化到USART1
	
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);		//开启窗口接收中断(即当发生接收数据或发送数据时将触发对应的中断处理函数)
	USART_Cmd(USART1,ENABLE);			//使能USART1,也就是打开USART1功能
	
	NVIC_Configuration();    			//中断优先级配置
} 

(2) Configurar prioridad de interrupción

agrupación prioritaria prioridad maestra sub-prioridad
NVIC_PriorityGroup0 (0 bits para prioridad de prioridad 4 bits para subprioridad) 0 0~15
NVIC_PriorityGroup1 (1 bit para prioridad de preferencia 3 bits para subprioridad) 0~1 0~7
NVIC_PriorityGroup2 (2 bits para prioridad de preferencia y 2 bits para subprioridad) 0~3 0~3
NVIC_PriorityGroup3 (3 bits para prioridad de preferencia 1 bit para subprioridad) 0~7 0~1
NVIC_PriorityGroup4 (4 bits para prioridad de preferencia 0 bits para subprioridad) 0~15 0
void NVIC_Configuration()
{
    
    
	NVIC_InitTypeDef NVIC_InitStruct;	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);				//配置分组为组2
	NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;				//配置中断源为USART1
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;		//配置主优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;				//配置子优先级
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;				//中断使能
	NVIC_Init(&NVIC_InitStruct);		//初始化NVIC
}

(3) Función de procesamiento de interrupciones

void USART1_IRQHandler(void)  
{
    
      
  	u8 res;  
	if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)  		//若当前USART1的状态为接收
	{
    
     
		res= USART_ReceiveData(USART1);   		//读取此时接收的数据
		USART_SendData(USART1,res);				//将数据重新发回去,用于告诉它接收成功
	}
}

(4) Redirección de funciones de envío y recepción (en las funciones estándar C de Keil, funciones como printf no han implementado su capa inferior, y los desarrolladores de programas necesitan redirigir las funciones fgets y fputs para usar funciones estándar como printf, scanf, gets, puts, etc., recuerde agregar #include " stdio.h " oh)

#include "stdio.h"
int fputc(int ch,FILE *f)
{
    
    
	USART_SendData(USART1,(uint8_t)ch);		//发送一个字符
	while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);	//直到发送完毕
	return (ch);	
}
int fgetc(FILE *f)
{
    
    
	while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==RESET);	//直到接收完毕
	return (int)USART_ReceiveData(USART1);
}

(5) Finalmente la función principal

int main(void)  
{
    
      
	USART1_Config();
  	while(1);
} 

¡Se realiza una configuración de puerto serie tan completa! ! !
A continuación, siga los mismos pasos para utilizar los otros dos puertos serie para realizar esta función.

2.USART2
(1) enviar, recibir configuración de pin y configuración de puerto serie

void USART2_Config(void)  
{
    
      
  	GPIO_InitTypeDef x;
	USART_InitTypeDef y;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);		//注意**APB1**,**USART2**
	
	x.GPIO_Pin=GPIO_Pin_2;
	x.GPIO_Mode=GPIO_Mode_AF_PP;
	x.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&x);
	
	x.GPIO_Pin=GPIO_Pin_3;
	x.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA,&x);
	
	y.USART_BaudRate=9600;
	y.USART_WordLength=USART_WordLength_8b;
	y.USART_StopBits=USART_StopBits_1;
	y.USART_Parity=USART_Parity_No;
	y.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
	y.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
	USART_Init(USART2,&y);
	
	USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
	USART_Cmd(USART2,ENABLE);
	
	NVIC_Configuration();    
} 

(2) Configurar prioridad de interrupción

void NVIC_Configuration()
{
    
    
	NVIC_InitTypeDef NVIC_InitStruct;	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	
	NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn;		//注意:**USART2_IRQn**
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStruct);
}

(3) Función de procesamiento de interrupciones

void USART2_IRQHandler(void)  		//注意:**USART2_IRQHandler**
{
    
      
  	u8 res;  
	if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET)  
	{
    
     
		res= USART_ReceiveData(USART2);   
		USART_SendData(USART2,res);	
  }  
}

(4) Redirigir la función de envío y recepción (recuerde agregar #include " stdio.h ")

#include "stdio.h"
int fputc(int ch,FILE *f)
{
    
    
	USART_SendData(USART2,(uint8_t)ch);
	while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
	return (ch);
}
int fgetc(FILE *f)
{
    
    
	while(USART_GetFlagStatus(USART2,USART_FLAG_RXNE)==RESET);
	return (int)USART_ReceiveData(USART2);
}

(5) Finalmente la función principal

int main(void)  
{
    
      
	USART2_Config();
  	while(1);
} 

2.USART3
(1) enviar, recibir configuración de pin y configuración de puerto serie

void USART3_Config(void)  
{
    
      
  GPIO_InitTypeDef x;
	USART_InitTypeDef y;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);		//注意:**GPIOB**
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);		//注意:**APB1**,**USART3**
	
	x.GPIO_Pin=GPIO_Pin_10;
	x.GPIO_Mode=GPIO_Mode_AF_PP;
	x.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&x);			//注意:**GPIOB**
	
	x.GPIO_Pin=GPIO_Pin_11;
	x.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOB,&x);			//注意:**GPIOB**
	
	y.USART_BaudRate=9600;
	y.USART_WordLength=USART_WordLength_8b;
	y.USART_StopBits=USART_StopBits_1;
	y.USART_Parity=USART_Parity_No;
	y.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
	y.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
	USART_Init(USART3,&y);
	
	USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);
	USART_Cmd(USART3,ENABLE);
	
	NVIC_Configuration();    
} 

(2) Configurar prioridad de interrupción

void NVIC_Configuration()
{
    
    
	NVIC_InitTypeDef NVIC_InitStruct;	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	
	NVIC_InitStruct.NVIC_IRQChannel = USART3_IRQn;		//注意:**USART3_IRQn**
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
}

(3) Función de procesamiento de interrupciones

void USART3_IRQHandler(void)  		//注意:**USART3_IRQHandler**
{
    
      
 	u8 res;  
	if(USART_GetITStatus(USART3,USART_IT_RXNE)!=RESET)  
	{
    
     
		res= USART_ReceiveData(USART3);   
		USART_SendData(USART3,res);	
  }  
}

(4) Redirigir la función de envío y recepción (recuerde agregar #include " stdio.h ")

#include "stdio.h"
int fputc(int ch,FILE *f)
{
    
    
	USART_SendData(USART3,(uint8_t)ch);
	while(USART_GetFlagStatus(USART3,USART_FLAG_TXE)==RESET);
	return (ch);
}
int fgetc(FILE *f)
{
    
    
	while(USART_GetFlagStatus(USART3,USART_FLAG_RXNE)==RESET);
	return (int)USART_ReceiveData(USART3);
}

(5) Finalmente la función principal

int main(void)  
{
    
      
	USART3_Config();
  	while(1);
} 

6. Finalmente, un ejemplo de control de una pequeña luz a través de un puerto serie

(1) Configure el puerto serie (seleccione uno de los tres grupos anteriores al azar, aquí tomamos el grupo 1-PA9, PA10 como ejemplo) (2) Inicialice
la luz pequeña (el pin de mi STM32 para controlar la luz LED es PC13 )
CONDUJO

void LED_GPIO_Config(void)
{
    
    
    GPIO_InitTypeDef GPIO_InitStruct;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);    
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStruct);
}

(3) función de control de luz pequeña

void LED_G(uint8_t n)                    //LED_G(0): 灯亮            LED_G(1):灯灭
{
    
    
    if(n)
                GPIO_SetBits(GPIOC, GPIO_Pin_13);
    else
                GPIO_ResetBits(GPIOC, GPIO_Pin_13);
}

(4) Modificar la función principal

#include "stm32f10x.h"

int main(void)  
{
    
      
    USART_Config();
    LED_GPIO_Config(); 
    while(1);
} 

(5) Modificar la función de interrupción en serie

void USART1_IRQHandler(void)    //如果串口发送‘0’则灯亮,(若其他数据)否则灯灭
{
    
      
    u8 res;  
    if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)  
    {
    
     
        res= USART_ReceiveData(USART1);   
        USART_SendData(USART1,res);
        if(res=='0')
        {
    
    
            LED_G(0);
        }
        else
        {
    
    
            LED_G(1);
        }        
  }  
}

7. Intercambio completo de recursos del proyecto

Enlace: https://pan.baidu.com/s/1UvxMlFSzKVpQfpDA3zxnBA
Código de extracción: o8c7

Supongo que te gusta

Origin blog.csdn.net/weiybin/article/details/107378505
Recomendado
Clasificación