七、串口中断方式收发数据和重定向printf

1.新加库函数文件

  stm32f10x_usart.h和stm32f10x_usart.c。

  USART:同步异步收发器

  UART:异步收发器

2.USART/UART知识点

  协议:

  (1)起始位:一个逻辑0的数据位表示。

  (2)数据位:8-9位。

  (3)校验位:奇校验、偶校验、无校验。

  (4)停止位:0.5、1、1.5、2个逻辑1的数据位表示。

  (5)波特率:数据传输的速度,1S发送的比特位数,常用115200、9600。

 3.串口1为例使用库函数配置

  (1)使能时钟配置端口

复制代码
 1 //1.使能时钟,初始化端口
 2 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
 3     
 4 GPIO_InitTypeDef GPIO_InitStruct;
 5     
 6 GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
 7 GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;//发送数据端口,复用推挽输出
 8 GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
 9 GPIO_Init(GPIOA,&GPIO_InitStruct);
10     
11 GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
12 GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;//接收数据端口,浮空输入
13 GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
14 GPIO_Init(GPIOA,&GPIO_InitStruct);
复制代码

  (2)使能串口时钟,初始化串口参数

复制代码
 1 //2.使能时钟,配置串口参数
 2 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);  
 3 USART_InitTypeDef USART_InitStruct;
 4     
 5 USART_InitStruct.USART_BaudRate = 115200;//波特率
 6 USART_InitStruct.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;//模式,收发模式
 7 USART_InitStruct.USART_WordLength = USART_WordLength_8b;//数据位长度,8位
 8 USART_InitStruct.USART_Parity = USART_Parity_No;//校验位
 9 USART_InitStruct.USART_StopBits = USART_StopBits_1;//一位停止位
10 USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
11 USART_Init(USART1,&USART_InitStruct);
复制代码

  (3)使能串口,设置中断

1 //3.使能串口设置中断
2 USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//设置接收中断
3 USART_Cmd(USART1,ENABLE);//使能串口

  (4)设置NVIC优先级

1 //4.设置中断NVIC
2 NVIC_InitTypeDef NVIC_InitStruct;
3 
4 NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
5 NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
6 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
7 NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
8 NVIC_Init(&NVIC_InitStruct);

  (5)编写中断函数接收数据

复制代码
 1 //串口中断函数
 2 void USART1_IRQHandler(void)
 3 {
 4     static int recv_buf_offset=0;
 5     uint16_t temp;
 6     
 7     if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET){//接收到数据
 8         
 9         USART_ClearITPendingBit(USART1,USART_IT_RXNE);//软件清除中断状态位
10         
11         temp=USART_ReceiveData(USART1);  //接收一字节数据
12         recv_buf_temp[recv_buf_offset]=(u8)temp;
13         recv_buf_offset++;
14         
15         //接收数据
16         if(recv_buf_temp[recv_buf_offset-1]=='\r'||recv_buf_temp[recv_buf_offset-1]=='\n'){
17             Send_Data(USART1,recv_buf_temp,recv_buf_offset-1);
18             recv_buf_offset=0;
19         }
20     }
21 }
复制代码

  (6)编写发送数据函数

1 void Send_Data(USART_TypeDef* USARTx,u8* data,u16 data_len)
2 {
3     for(int i=0;i<data_len;i++){
4         while(USART_GetFlagStatus(USARTx,USART_FLAG_TXE)==RESET);//0表示数据还未转移到移位寄存器,1表示数据已经移动到移位寄存器可以发送数据
5         USART_SendData(USARTx,data[i]);
6         while(USART_GetFlagStatus(USARTx,USART_FLAG_TC)==RESET);//1表示发送完成
7     }
8 }

4.重写printf函数至串口发送数据(法一)

  (1)在串口函数中重写fputc函数

1 int fputc(int ch,FILE* f)
2 {
3     while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//0表示数据还未转移到移位寄存器,1表示数据已经移动到移位寄存器可以发送数据
4     USART_SendData(USART1,(u8)ch);
5     while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);//1表示发送完成
6     return ch;
7 }

  (2)设置使用微库

 4.重写printf函数至串口发送数据(法二)

  (1)串口函数中添加内容不使用半主机模式

复制代码
 1 #pragma inport(__use_no_semihosting);//不使用半主机模式
 2 
 3 //避免使用半主机模式
 4 void _sys_exit(int x)
 5 {
 6     x=x;
 7 }
 8 
 9 //标准库需要支持的函数
10 struct __FILE
11 {
12     int handle;
13 };
14 FILE __stdout;
复制代码

  (2)重写fputs函数

5.c语言关键字

  (1)extern:声明变量,函数在其他文件中定义,需要在这个此处引用。

  (2)static:声明变量,保存变量最后执行时候的值,初始化一次。

  (3)const:声明变量,不可更改值,可以间接的更改。

  (4)voliate:告诉编译器,这个值随时可能发生改变,取值时,从变量的内存地址处进行取值。

posted @   稚终KINO  阅读(397)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示