当前位置:网站首页>The printf function is realized through the serial port, and the serial port data reception is realized by interrupt

The printf function is realized through the serial port, and the serial port data reception is realized by interrupt

2022-07-07 00:51:00 Heavy vehicle water

     stm32 The project can be used directly C Standard library functions , among printf Function is not fully implemented , A back door is reserved fputc function , By implementing fputc Print to serial port to realize printf The function of .

 1.fputc Format :

int fputc(int ch,FILE *F) {     //...... }

//stm32 Run the program on the development board , If the host runs the debugger , The program will use the input and output devices of the host

// This is called semi host mode ,printf If you want to print through serial port , Half host mode must be turned off #pragma import(__use_no_semihosting)

struct __FILE{     int handle; };

FILE __stdout;

// Definition _sys_exit Function avoid using semi host mode

void _sys_exit(int x) {     x = x; } // redefinition fputc

int fputc(int ch,FILE *F) {     // send out     USART_SendData(USART1,ch);    

 // Wait for the last data to be sent

while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);        return ch; }

———————————————————————————————————————————

2. Use interrupt to receive serial port

     When the serial port sends data is determined by CPU decision , There is no problem of invalid waiting , Interrupts can be avoided , But the reception of serial port is not controlled by CPU Decide when to receive , If polling is also used, there will be a lot of invalid waiting , At this time, interrupt should be used to provide efficiency .

     Serial port interrupt is similar to timer interrupt , Interrupt switches and NVIC.

NVIC_Init(...);// Initialization function

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);// Turn on receive interrupt

     Complete the data reception in the serial port interrupt processing function

void USART1_IRQHandler(void) {    

 // Determine whether it is a receive interrupt  ---------- USART_GetITStatus(USART1, USART_IT_RXNE);  

   // receive data  ------------------- data = USART_ReceiveData(USART1);   

  // Clear interrupt flag  --------------- USART_ClearITPendingBit(USART1, USART_IT_RXNE);

}

practice :

     Realize data receiving and control command control for serial port interrupt, and control the main function functions of buzzer

#include <stm32f4xx.h>
#include <usart.h>
#include <stdio.h>
#include <string.h>
#include <includes.h>

//stm32 Run the program on the development board , If the host runs the debugger , The program will use the input and output devices of the host 
// This is called semi host mode ,printf If you want to print through serial port , Half host mode must be turned off 
#pragma import(__use_no_semihosting)

struct __FILE{
    int handle;
};

FILE __stdout;

// Definition _sys_exit Function avoid using semi host mode 
void _sys_exit(int x)
{
    x = x;// The assignment here has no practical significance , Avoid empty functions 
}

// redefinition fputc
int fputc(int ch,FILE *F)
{
	// Wait for the last data to be sent 
	while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
    // send out 
    USART_SendData(USART1,ch);
    
	return ch;
}

void usart1_init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	USART_InitTypeDef USART_InitStruct;
	NVIC_InitTypeDef NVIC_InitStruct;
	
	//1. Turn on GPIOA and USART1 The clock 
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

	//2. To configure PA9 PA10 Serial port function 
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;// Reuse mode 
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;// Push pull output 
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;// High speed 
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;// No up and down 
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
	
	//3. Initialize serial port   8N1
	USART_InitStruct.USART_BaudRate = 115200;// Baud rate 
	USART_InitStruct.USART_WordLength = USART_WordLength_8b;//8 Digit bit 
	USART_InitStruct.USART_StopBits = USART_StopBits_1;//1 Bit stop bit 
	USART_InitStruct.USART_Parity = USART_Parity_No;// No verification 
	USART_InitStruct.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;// Send receive mode 
	USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;// No hardware flow control 
	USART_Init(USART1,&USART_InitStruct);
	
	//4. Open serial port receive interrupt ( Clear interrupt flag )
	USART_ClearITPendingBit(USART1, USART_IT_RXNE);
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
	
	//5. initialization NVIC
	NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;// A serial port 1 Interrupt channel 
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x2;// preemption 
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x2;// Response priority 
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;// Can make 
	NVIC_Init(&NVIC_InitStruct);
	
	//. Enable serial port 
	USART_Cmd(USART1,ENABLE);
}

// Send a character ( polling )
void uart1_putc(char ch)
{
	// Wait for the last data to be sent 
	while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
	
	USART_SendData(USART1,ch);
}

// Send string 
void uart1_puts(const char *s)
{
	while(*s){
		uart1_putc(*s++);
	}
}

volatile u32 uart_flag = 0;// Record whether the serial port has received a complete data  1--- complete 
volatile u8 uart_buf[64] = {0};// Record the data received by the serial port 
volatile u32 uart_cnt = 0;// Record the length of data received by the serial port 

// Processing serial port command function 
void parse_cmd(void)
{
	while(1){
		if(uart_flag){
			//BEEP command 
			if(strstr((char *)uart_buf,"beep")){
				if(strstr((char *)uart_buf,"on")){
					BEEP = 1;
					printf("beep on!\r\n");
				}
				
				if(strstr((char *)uart_buf,"off")){
					BEEP = 0;
					printf("beep off!\r\n");
				}
			}
			else{// Illegal orders 
				printf("unknow command = %s\r\n",(char *)uart_buf);
			}
			
			// The processing completion flag is clear 0, Buffer emptying , Count 0
			uart_flag = 0;
			memset((char *)uart_buf,0,sizeof(uart_buf));
			uart_cnt = 0;
		}
	}
}

// A serial port 1 Interrupt handling function 
void USART1_IRQHandler(void)
{
	//u8 data;
	
    if(USART_GetITStatus(USART1, USART_IT_RXNE)==SET){
		// Receive serial data 
		uart_buf[uart_cnt++] = USART_ReceiveData(USART1);
		
		// Judge whether the data reception is completed  ------  With * end 
		if(uart_buf[uart_cnt-1]=='*'||uart_cnt>=sizeof(uart_buf)){
			uart_flag = 1;
		}
		
		// Original route 
		//uart1_putc(data);
		
		
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
	}
}

原网站

版权声明
本文为[Heavy vehicle water]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207061707109006.html