打印
[STM32F1]

STM32串口及printf

[复制链接]
231|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
primojones|  楼主 | 2024-5-28 09:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1,开启串口相关的时钟,GPIO,USART的时钟

2,配置GPIO,注TX引脚AF的(OD和PP试过都没啥问题),RX浮空输入

3,配置USART的结构体,NVIC的分组和结构体成员,

4,选择串口通信的中断触发信号;usart_itconfig()确定中断源

5,使能串口  CMD函数;

注意;USART_GetFlagStatus函数可检测串口标志位,通过检测串口的标志位防止串口掉帧,确保数据发生或者接收完,具体标志查看手册。

USART_GetITStatus();函数可检测串口是否产生中断标志,防止误动作。

void usart1_init(void)

{

GPIO_InitTypeDef GPIORX_InitStruct;//GPIORX结构体名称

NVIC_InitTypeDef NVIC_InitStruct;//NVIC结构体名称

USART_InitTypeDef USART_InitStruct;//串口结构体名称

GPIO_InitTypeDef GPIOTX_InitStruct;//GPIOTX结构体名称

//时钟开启

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

//TX引脚初始化

GPIOTX_InitStruct.GPIO_Mode= GPIO_Mode_AF_OD;

GPIOTX_InitStruct.GPIO_Pin=GPIO_Pin_9;

GPIOTX_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_Init(GPIOA,&GPIOTX_InitStruct);

//rX引脚初始化

GPIORX_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;

GPIORX_InitStruct.GPIO_Pin=GPIO_Pin_10;

GPIORX_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_Init(GPIOA,&GPIORX_InitStruct);

//NVIC分组

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

//NVIC成员配置

NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn ;

NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;

NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;

NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;

NVIC_Init(&NVIC_InitStruct);

//串口结构体成员配置

USART_InitStruct.USART_BaudRate=9600;

USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;

USART_InitStruct.USART_Mode= USART_Mode_Rx|USART_Mode_Tx;

USART_InitStruct.USART_Parity=USART_Parity_No;

USART_InitStruct.USART_StopBits=USART_StopBits_1;

USART_InitStruct.USART_WordLength=USART_WordLength_8b;

USART_Init(USART1,&USART_InitStruct);

//串口中断源选择

USART_ITConfig( USART1, USART_IT_RXNE,ENABLE);

//使能

USART_Cmd(USART1,ENABLE);

}

//print函数重定向

int fgetc(FILE *f)

{  

while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);

return (int)USART_ReceiveData(USART1);

}

//选择窗口通信打印 不可打印中文,要加#include "stdio.h"      #include "stdarg.h"  #include "string.h"

//打印为void u1_printf(char* fmt,...) 函数

//PRINTF的核心函数  

void USART_SendByte(USART_TypeDef* USARTx, uint16_t Data)

{

/* Check the parameters */

assert_param(IS_USART_ALL_PERIPH(USARTx));

assert_param(IS_USART_DATA(Data));  

     /* Transmit Data */

USARTx->DR = (Data & (uint16_t)0x01FF);

while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);

}

//串口1printf函数 可根据串口改变函数参数 使用要在头文件声明

__align(8) char USART1_TxBuff[256];  

void u1_printf(char* fmt,...)  

{  

unsigned int i =0,length=0;

va_list ap;

va_start(ap,fmt);

vsprintf(USART1_TxBuff,fmt,ap);

va_end(ap);

length=strlen((const char*)USART1_TxBuff);

while(i<length)

{

USART_SendByte(USART1,USART1_TxBuff[i]);  

i++;  

}

while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);

}



使用 u1_printf("%d\n",a[i]);在函数中进行串口打印

串口中断服务函数

void USART1_IRQHandler(void)//只要读数据寄存器非空,就会进入中断函数

{

if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE))//也可以用USART_GetITStatus();来判断

{

USART_SendData(USART1, a++);//

while(USART_GetFlagStatus(USART1,USART_FLAG_TC));//确定发送完了信息,才出中断服务。

  }

USART_ClearFlag(USART1,USART_FLAG_RXNE);

}




使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

38

主题

1151

帖子

0

粉丝