当前位置:网站首页>通过串口实现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);
}
}
边栏推荐
- uniapp中redirectTo和navigateTo的区别
- Value Function Approximation
- C Primer Plus Chapter 14 (structure and other data forms)
- Model-Free Prediction
- Quaternion attitude calculation of madgwick
- Attention slam: a visual monocular slam that learns from human attention
- Leetcode(547)——省份数量
- Linear algebra of deep learning
- Command line kills window process
- Slam d'attention: un slam visuel monoculaire appris de l'attention humaine
猜你喜欢

Idea automatically imports and deletes package settings

If the college entrance examination goes well, I'm already graying out at the construction site at the moment

Deep understanding of distributed cache design

JWT signature does not match locally computed signature. JWT validity cannot be asserted and should

学习使用代码生成美观的接口文档!!!

uniapp中redirectTo和navigateTo的区别

Understand the misunderstanding of programmers: Chinese programmers in the eyes of Western programmers

How to set encoding in idea

Zynq transplant ucosiii

The way of intelligent operation and maintenance application, bid farewell to the crisis of enterprise digital transformation
随机推荐
. Bytecode structure of class file
如何判断一个数组中的元素包含一个对象的所有属性值
.class文件的字节码结构
stm32F407-------DAC数模转换
ActiveReportsJS 3.1中文版|||ActiveReportsJS 3.1英文版
深度学习简史(二)
【JokerのZYNQ7020】AXI_ EMC。
Explain in detail the implementation of call, apply and bind in JS (source code implementation)
C9 colleges and universities, doctoral students make a statement of nature!
Notes of training courses selected by Massey school
uniapp中redirectTo和navigateTo的区别
三维扫描体数据的VTK体绘制程序设计
Model-Free Control
Common shortcuts to idea
Command line kills window process
【批处理DOS-CMD命令-汇总和小结】-字符串搜索、查找、筛选命令(find、findstr),Find和findstr的区别和辨析
深度学习之数据处理
Leecode brush question record sword finger offer 56 - ii Number of occurrences of numbers in the array II
工程师如何对待开源 --- 一个老工程师的肺腑之言
Leecode brushes questions to record interview questions 17.16 massagist