在调试代码的过程中,我们经常采用输出调试信息的方式来查看代码执行顺序和结果,
而且对于高效的程序开发来说,也是必不可少的。所以,在一个系统建立起来之前,打造一个好用的调试系统是如此的重要和必要。
在pc系统上,我们一般使用printf来实现该功能,而且在标准嵌入式环境也提供了对该函数的支持,前提是我们实现int fputc(int ch, FILE *f)的接口即可。在实现该接口的过程中,我们一般采用串口来输出调试信息。
如何简单的来实现一个串口的该功能呢?
在STOpen系统中,只需要经过下面简单三步就可以实现串口的功能,并且能够验证功能。
第一步 初始化串口
分别按照顺序:使能中断通道->设置串口参数->配置硬件IO->使能串口模块时钟和相关中断->最后启动串口模块。
具体使用哪一个串口,要根据你的系统和平台来调整,在STM32F103中,我们默认使用USART1。
void Usart1Init(void)
{
USART_InitTypeDef USART;
GPIO_InitTypeDef GPIO;
NVIC_InitTypeDef NVIC_InitStructure;
//Enable the USART global Interrupt
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//set baud rate
USART.USART_BaudRate = 115200;
USART.USART_WordLength = USART_WordLength_8b;
USART.USART_StopBits = USART_StopBits_1;
USART.USART_Parity = USART_Parity_No;
USART.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
//config AF io
GPIO.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO.GPIO_Speed = GPIO_Speed_50MHz;
GPIO.GPIO_Pin = GPIO_Pin_9; //tx
GPIO_Init(GPIOA, &GPIO);
GPIO.GPIO_Mode = GPIO_Mode_IN_FLOATING; //rx
GPIO.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA, &GPIO);
//enable clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); //enable usart1
USART_Init(USART1,&USART);
//config interrput
USART_ITConfig(USART1,USART_IT_TXE,DISABLE); //开始不能enable,否则 TXE和TC中断会不停的来
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
USART_Cmd(USART1, ENABLE);
}
第二步:实现串口的接收和发送的中断函数
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1,USART_IT_TXE) != RESET) //发送数据完成
{
USART_ClearITPendingBit(USART1,USART_IT_TXE);
USART_ITConfig(USART1,USART_IT_TXE,DISABLE); //发送完毕要关闭TXE中断,否则会一直中断
}
else if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET) //收到数据
{
UINT8 c;
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
c = (UINT8)(USART1->DR & 0x00FF);
USART1->DR = c;
}
else if(USART_GetFlagStatus(USART1,USART_FLAG_ORE) != RESET) //接收数据溢出中断。是固定打开的,要处理
{
volatile BYTE t = USART1->DR;
USART_ClearFlag(USART1, USART_FLAG_ORE);
}
}
第三步:实现一个以阻塞方式发送的接口
对于串口调试来说,不是必须的,为下一步实现printf的功能打下基础。
void Usart1TxAlways(UINT8 *pData,UINT32 len)
{
UINT32 timeout = 0xFFFF;
while(len--)
{
while((!((USART1->SR)&(1 << 7))) && (timeout--)); //防止硬件死机
USART1->DR= *pData++;
}
}
完成上面几步后我们就可以测试串口功能了。
打开任意一个串口调试助手,发送一些数据过去,串口立即原封不动的返回该数据,如下图所示。
测试表明我们的串口已经正常工作,下一步就是实现调试接口了。
原创文章,欢迎转载,请注明来源,未经书面允许,请勿用于商业用途。