当前位置:主页 > 查看内容

STM32F103调试串口(USART)模块开发(内含Printf重定向函数说明

发布时间:2021-08-05 00:00| 位朋友查看

简介:《《《《《正文》》》》》 ? ? 《前言》 基于UART的串口在实际项目中的应用相当广泛包括wifi、can、lin等均可使用uart进行通信方便且成本低而uart串口功能不仅仅体现在产品使用功能上在开发调试阶段更是一个必不可少的调试助手。今天就来构建一个基于uart的……


《《《《《正文》》》》》


?

?

《前言》

基于UART的串口在实际项目中的应用相当广泛,包括wifi、can、lin等均可使用uart进行通信,方便且成本低;而uart串口功能不仅仅体现在产品使用功能上,在开发调试阶段更是一个必不可少的调试助手。今天就来构建一个基于uart的调试串口功能模块;

?

开发需求:使用stm32f103的usart模块开发一个具有发送任意字符串的调试串口功能的模块;

?

相关代码获取地址:

https://pan.baidu.com/s/1zyrOF18WxIq0H3_4qU7Evg

关注公众号,发送1234,获取提取码;


?

《硬件设计

TXPA9
RXPA10


?

《加载USART库文件》


?

?

《软件设计》

第一步:中断等级配置函数

void NvicConfig(void){  NVIC_InitTypeDef NVIC_InitStruct;?  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);?  NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;           //USART中断通道  NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;   //设置抢占优先级为0  NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;          //设置子优先级为1  NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;             //使能外USART中断通道??NVIC_Init(&NVIC_InitStruct);???????????????????????????//中断优先级初始化函数}

?

第二步:串口初始化函数

//传入参数为波特率void USART_init(uint32_t baudrate){  GPIO_InitTypeDef GPIO_InitStruct;   //定义GPIO结构体变量  USART_InitTypeDef USART_InitStruct;   //定义串口结构体变量?  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);   //使能GPIOA、USART1的时钟?  GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;   //配置TX引脚  GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;   //配置PA9为复用推挽输出  GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;   //配置PA9速率  GPIO_Init(GPIOA,&GPIO_InitStruct);   //GPIO初始化函数?  GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;   //配置RX引脚  GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;   //配置PA10为浮空输入  GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;   //配置PA10速率  GPIO_Init(GPIOA,&GPIO_InitStruct);   //GPIO初始化函数?  USART_InitStruct.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;   //发送接收模式  USART_InitStruct.USART_Parity=USART_Parity_No;   //无奇偶校验  USART_InitStruct.USART_BaudRate=baudrate;   //波特率  USART_InitStruct.USART_StopBits=USART_StopBits_1;   //停止位1位  USART_InitStruct.USART_WordLength=USART_WordLength_8b;   //字长8位  USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;   //无硬件数据流控制  USART_Init(USART1,&USART_InitStruct);   //串口初始化函数?  USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);    //串口接收中断  USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);    //串口空闲中断?  USART_Cmd(USART1,ENABLE);   //使能USART1}

?

第三步:中断处理函数

void USART1_IRQHandler(void){    uint8_t clear = clear; //定义这个变量是针对编译出现“没有用到这个变量”的警告提示    uint8_t res;?    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断      {             res = USART1->DR;    ????????//在此做数据接收处理    }    else if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) //空闲中断    {      clear = USART1->SR; //读SR寄存器??????clear?=?USART1->DR;?//读DR寄存器(先读SR,再度DR,就是为了清除IDIE中断)    }    USART_ClearITPendingBit(USART1,USART_IT_RXNE);}

?

第四步:写发送数据函数

void usart_send(uint8_t *data,uint8_t len){  uint8_t i;?  for(i=0;i<len;i++)  {    USART_SendData(USART1,*(data+i));    while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);  }}

?

第五步:来个简单的测试,主函数:

int main(void){      uint8_t usartSendbuf[5] = {1,2,3,4,5};      NvicConfig();      USART_init(115200);?      for(;;)      {        usart_send(usartSendbuf,5);      }}

?

结果:


?

《printf函数重定向》

重定向函数:

int fputc(int ch,FILE *f)   //printf重定向函数{  USART_SendData(USART1,(uint8_t)ch);   //发送一字节数据  while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);   //等待发送完成  return ch;}

我们这里直接写是不行,因为这是C库自带的东西,但是可以重定向到这个函数(printf()在c标准库函数实质是一个宏,实际是调用fputc()函数),fputc()函数默认是把字符输出到调试器控制窗口,所以要想把数据通过USART输出到串口助手,需对基于fputc()的printf()系列函数的输出重定向到USART端口上去。

这里特别注意:打开“Options for target...”->“target”勾选“Use MiclroLIB” 不然用printf会有问题;


?

最后上测试函数:

int main(void){      NvicConfig();      USART_init(115200);?      for(;;)      {        printf("System Init Finish\n");        printf("我正在测试\n");      }}

结果:


?

?

《《《《《END》》》》》

;原文链接:https://blog.csdn.net/qq_22520215/article/details/115802140
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文


随机推荐