当前位置:网站首页>通过串口实现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);
}
}
边栏推荐
- What is time
- 【批处理DOS-CMD命令-汇总和小结】-查看或修改文件属性(ATTRIB),查看、修改文件关联类型(assoc、ftype)
- Matlab learning notes
- 【软件逆向-自动化】逆向工具大全
- Telerik UI 2022 R2 SP1 Retail-Not Crack
- How to judge whether an element in an array contains all attribute values of an object
- Configuring the stub area of OSPF for Huawei devices
- Leecode brush questions record sword finger offer 44 A digit in a sequence of numbers
- The way of intelligent operation and maintenance application, bid farewell to the crisis of enterprise digital transformation
- Testers, how to prepare test data
猜你喜欢
Js+svg love diffusion animation JS special effects
@TableId can‘t more than one in Class: “com.example.CloseContactSearcher.entity.Activity“.
【vulnhub】presidential1
英雄联盟|王者|穿越火线 bgm AI配乐大赛分享
JWT signature does not match locally computed signature. JWT validity cannot be asserted and should
智能运维应用之道,告别企业数字化转型危机
Everyone is always talking about EQ, so what is EQ?
5种不同的代码相似性检测,以及代码相似性检测的发展趋势
深度学习之环境配置 jupyter notebook
37 pages Digital Village revitalization intelligent agriculture Comprehensive Planning and Construction Scheme
随机推荐
Amazon MemoryDB for Redis 和 Amazon ElastiCache for Redis 的内存优化
[daily problem insight] prefix and -- count the number of fertile pyramids in the farm
Leecode brushes questions to record interview questions 17.16 massagist
Article management system based on SSM framework
Levels - UE5中的暴雨效果
Use mujoco to simulate Cassie robot
Deep understanding of distributed cache design
三维扫描体数据的VTK体绘制程序设计
On February 19, 2021ccf award ceremony will be held, "why in Hengdian?"
What is time
New feature of Oracle 19C: automatic DML redirection of ADG, enhanced read-write separation -- ADG_ REDIRECT_ DML
【批处理DOS-CMD命令-汇总和小结】-跳转、循环、条件命令(goto、errorlevel、if、for[读取、切分、提取字符串]、)cmd命令错误汇总,cmd错误
接口(接口相关含义,区别抽象类,接口回调)
How to set encoding in idea
Idea automatically imports and deletes package settings
Telerik UI 2022 R2 SP1 Retail-Not Crack
基于GO语言实现的X.509证书
Leetcode (547) - number of provinces
Memory optimization of Amazon memorydb for redis and Amazon elasticache for redis
Advanced learning of MySQL -- basics -- multi table query -- external connection