在用printf时,很多人都用的如下语句来重定义fputc
// while((USART1->SR & 0X80)==0);//等待发送寄存器空 1000 0000=== B7位
// USART1->DR = (u8) ch;
这个语句,问题显而易见,就是太占用CPU时序了,下面程序尝试使用存入队列,然后在发送完成中断中按顺序字符输出(第一个字符是直接放入DR的):
已经上机实测了2周了都没有任何问题,分享给大家,欢迎批评指正,觉得好的话顶下哦~
头文件,变量:
#include <stm32f10x_lib.h>
#include "sysinit.h"
#define TXBUFLIM 390
#define TXBUFCAP 400
extern u8 txbuf[]; //400 时 0-399
extern u32 txpoint; //指向正在准备发送的位置 值范围0到CAP-1
extern u32 txtail; //指向最后一个被存入队列的位置
extern u32 arynum; //记录队列中准备发送的数量
//putc函数中只管往队列写值
#include "stdio.h"
u8 txbuf[TXBUFCAP]; //400 时 0-399
u32 txpoint=0; //指向下一个发送数据在队列的位置 值范围0到CAP-1
u32 txtail =0; //指向下一个数据该,存入队列的位置
u32 arynum =0; //记录队列中准备发送的数量
//重定义fputc函数 放入队列 //发送程序在:void USART1_IRQHandler(void)
int fputc(int ch, FILE *f)
{ static s32 firstone=0; //第一个值时=1
while( arynum >= TXBUFLIM ); //满时,等待
if((arynum==0) && (firstone==0)) { //第一个数,直接出
USART1->DR = (u8) ch;
firstone=1;
}
else{
txbuf[txtail] = (u8)ch;
txtail++; if(txtail >= TXBUFCAP)txtail=0;
arynum++;
firstone=0;
}
// while((USART1->SR & 0X80)==0);//等待发送寄存器空 1000 0000=== B7位
// USART1->DR = (u8) ch;
return ch;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
//加入以下代码,include stdio,自定义fputc,即可支持printf函数,而不需要选择use MicroLIB
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
/* Whatever you require here. If the only file you are using is */
/* standard output using printf() for debugging, no file handling */
/* is required. */
};
/* FILE is typedef’ d in stdio.h. */
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
_sys_exit(int x)
{
x = x;
}
中断函数中,按顺序发送:
void USART1_IRQHandler(void)
{ u8 Res;
if(USART1->SR&(1<<5))//接收到数据
{
Res=USART1->DR;
////发回去
// while((USART1->SR & 0X80)==0);
// USART1->DR = Res;
Res=Res;
}
if(USART1->SR&(1<<6))//发送完成
{ USART1->SR&=~(1<<6); //置零
//USART_ClearITPendingBit(USART1,USART_IT_TC); //IT FLAG 函数内部相同的都是清除SR
//USART_ClearFlag(USART1,USART_FLAG_TC);
if(arynum!=0){
USART1->DR = txbuf[txpoint];
txpoint++; if(txpoint >= TXBUFCAP)txpoint=0;
arynum--;
//检查用,安全保障
if(arynum==0)txtail=txpoint;
}
}
}
//初始化配置:
void USART_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
//U1:57600串口接电脑,printf /*9600;//57600;//19200;115200;//*/
USART_InitStructure.USART_BaudRate = 57600;//test~9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART1, &USART_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //接收中断
USART_ITConfig(USART1, USART_IT_TC, ENABLE); //发送完成中断
USART_Cmd(USART1, ENABLE);
//串口1中断 调试
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //NVIC响应 1 1级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
-----------------------------------------------------------------------
不错,顶~~
一周热门 更多>