当前位置:网站首页>通过串口实现printf函数,中断实现串口数据接收
通过串口实现printf函数,中断实现串口数据接收
2022-07-06 17:07:00 【车水码浓】
stm32的工程可以直接使用C标准库函数,其中printf函数没有完全实现,预留了一个后门fputc函数,可以通过实现fputc往串口打印从而实现printf的功能。
1.fputc格式:
int fputc(int ch,FILE *F) { //...... }
//stm32开发板上运行程序,如果主机运行了调试器,程序就会使用主机的输入输出设备
//这是方式叫半主机模式,printf如果要通过串口打印,必须关闭半主机模式 #pragma import(__use_no_semihosting)
struct __FILE{ int handle; };
FILE __stdout;
//定义_sys_exit函数避免使用半主机模式
void _sys_exit(int x) { x = x; } //重定义fputc
int fputc(int ch,FILE *F) { //发送 USART_SendData(USART1,ch);
//等待上一个数据发送完成
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET); return ch; }
———————————————————————————————————————————
2.使用中断实现串口的接收
由于串口何时发送数据由CPU决定,不存在无效等待的问题,可以不使用中断,但是串口的接收不由CPU决定何时接收,如果还使用轮询就会存在大量无效等待,此时要使用中断提供效率。
串口中断和定时器中断类似,需要配置中断开关和NVIC。
NVIC_Init(...);//初始化函数
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启接收中断
在串口中断处理函数中完成数据的接收
void USART1_IRQHandler(void) {
//判断是否为接收中断 ---------- USART_GetITStatus(USART1, USART_IT_RXNE);
//接收数据 ------------------- data = USART_ReceiveData(USART1);
//清除中断标志 --------------- USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
练习:
为串口中断实现数据接收和控制命令控制蜂鸣器主要功能函数
#include <stm32f4xx.h>
#include <usart.h>
#include <stdio.h>
#include <string.h>
#include <includes.h>
//stm32开发板上运行程序,如果主机运行了调试器,程序就会使用主机的输入输出设备
//这是方式叫半主机模式,printf如果要通过串口打印,必须关闭半主机模式
#pragma import(__use_no_semihosting)
struct __FILE{
int handle;
};
FILE __stdout;
//定义_sys_exit函数避免使用半主机模式
void _sys_exit(int x)
{
x = x;//这里的赋值没有实际意义,避免空函数
}
//重定义fputc
int fputc(int ch,FILE *F)
{
//等待上一个数据发送完成
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
//发送
USART_SendData(USART1,ch);
return ch;
}
void usart1_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
//1.开启GPIOA和USART1时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
//2.配置PA9 PA10为串口功能
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;//复用模式
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;//高速
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;//无上下拉
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.初始化串口 8N1
USART_InitStruct.USART_BaudRate = 115200;//波特率
USART_InitStruct.USART_WordLength = USART_WordLength_8b;//8位数据位
USART_InitStruct.USART_StopBits = USART_StopBits_1;//1位停止位
USART_InitStruct.USART_Parity = USART_Parity_No;//无校验
USART_InitStruct.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;//发送接收模式
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件流控制
USART_Init(USART1,&USART_InitStruct);
//4.开启串口接收中断(清除中断标志)
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
//5.初始化NVIC
NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;//串口1中断通道
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x2;//抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x2;//响应优先级
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//使能
NVIC_Init(&NVIC_InitStruct);
//.使能串口
USART_Cmd(USART1,ENABLE);
}
//发送一个字符(轮询)
void uart1_putc(char ch)
{
//等待上一个数据发送完成
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
USART_SendData(USART1,ch);
}
//发送字符串
void uart1_puts(const char *s)
{
while(*s){
uart1_putc(*s++);
}
}
volatile u32 uart_flag = 0;//记录串口是否收到了一个完整的数据 1---完整
volatile u8 uart_buf[64] = {0};//记录串口收到的数据
volatile u32 uart_cnt = 0;//记录串口收到的数据长度
//处理串口命令函数
void parse_cmd(void)
{
while(1){
if(uart_flag){
//BEEP命令
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{//非法命令
printf("unknow command = %s\r\n",(char *)uart_buf);
}
//处理完成标志清0,缓冲区清空,个数清0
uart_flag = 0;
memset((char *)uart_buf,0,sizeof(uart_buf));
uart_cnt = 0;
}
}
}
//串口1中断处理函数
void USART1_IRQHandler(void)
{
//u8 data;
if(USART_GetITStatus(USART1, USART_IT_RXNE)==SET){
//接收串口数据
uart_buf[uart_cnt++] = USART_ReceiveData(USART1);
//判断数据是否接收完成 ------ 以*结束
if(uart_buf[uart_cnt-1]=='*'||uart_cnt>=sizeof(uart_buf)){
uart_flag = 1;
}
//原路发回
//uart1_putc(data);
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
}
边栏推荐
- [software reverse - solve flag] memory acquisition, inverse transformation operation, linear transformation, constraint solving
- stm32F407-------DAC数模转换
- Idea automatically imports and deletes package settings
- Attention SLAM:一种从人类注意中学习的视觉单目SLAM
- [software reverse automation] complete collection of reverse tools
- Understand the misunderstanding of programmers: Chinese programmers in the eyes of Western programmers
- 深度学习之数据处理
- 深度学习之环境配置 jupyter notebook
- The programmer resigned and was sentenced to 10 months for deleting the code. Jingdong came home and said that it took 30000 to restore the database. Netizen: This is really a revenge
- Five different code similarity detection and the development trend of code similarity detection
猜你喜欢

Dr selection of OSPF configuration for Huawei devices

基於GO語言實現的X.509證書

Data analysis course notes (V) common statistical methods, data and spelling, index and composite index

如何判断一个数组中的元素包含一个对象的所有属性值

Everyone is always talking about EQ, so what is EQ?

uniapp中redirectTo和navigateTo的区别

Win10 startup error, press F9 to enter how to repair?

Configuring OSPF basic functions for Huawei devices

37 pages Digital Village revitalization intelligent agriculture Comprehensive Planning and Construction Scheme

Zynq transplant ucosiii
随机推荐
深度学习之环境配置 jupyter notebook
[force buckle]41 Missing first positive number
ActiveReportsJS 3.1中文版|||ActiveReportsJS 3.1英文版
Data sharing of the 835 postgraduate entrance examination of software engineering in Hainan University in 23
JWT signature does not match locally computed signature. JWT validity cannot be asserted and should
Jenkins' user credentials plug-in installation
Advanced learning of MySQL -- basics -- multi table query -- self join
Learn self 3D representation like ray tracing ego3rt
MySQL learning notes (mind map)
Zynq transplant ucosiii
equals()与hashCode()
How to judge whether an element in an array contains all attribute values of an object
stm32F407-------DAC数模转换
Encryption algorithm - password security
@TableId can‘t more than one in Class: “com.example.CloseContactSearcher.entity.Activity“.
The programmer resigned and was sentenced to 10 months for deleting the code. Jingdong came home and said that it took 30000 to restore the database. Netizen: This is really a revenge
Hero League | King | cross the line of fire BGM AI score competition sharing
Model-Free Control
【JokerのZYNQ7020】AXI_ EMC。
Leecode brush questions record sword finger offer 44 A digit in a sequence of numbers