在C30中,可以用printf函数,将数据输出到串口。很多PIC24/PIC30/PIC33单片机有两个串口,但是默认情况下,数据是输出到串口1的,怎样将printf输出到串口2呢?
在microchip的网站上有一篇相关的说明,说可以通过重载write函数达到使用串口2的目的。但是这篇文档说的不是很清楚,用起来也不太方便。我研究了一下,其实还有更简单的办法:
在pic的库文件libpic30.zip中,我们可以看到write.c这个文件。write.c中包含了write函数的原型:
#include
#include
#include "simio.h"
externint__C30_UART;
externvolatileUxMODEBITSU2MODEbits__attribute__((__sfr__,weak));
externvolatileUxSTABITSU2STAbits__attribute__((__sfr__,weak));
externvolatileunsignedintU2TXREG__attribute__((__sfr__,weak));
externvolatileunsignedintU2BRG__attribute__((__sfr__,weak));
staticvoid__inline__dowrite(PSIMIOpsimio){
__asm__(".pword 0xDAC000"::"a"(psimio):
"memory");
}
int__attribute__((__weak__,__section__(".libc")))
write(inthandle,void*buffer,unsignedintlen){
inti;
volatileUxMODEBITS*umode=&U1MODEbits;
volatileUxSTABITS*ustatus=&U1STAbits;
volatileunsignedint*txreg=&U1TXREG;
volatileunsignedint*brg=&U1BRG;
switch(handle)
{
case0:
case1:
case2:
if((__C30_UART!=1)&&(&U2BRG)){
umode=&U2MODEbits;
ustatus=&U2STAbits;
txreg=&U2TXREG;
brg=&U2BRG;
}
if((umode->UARTEN)==0)
{
*brg=0;
umode->UARTEN=1;
}
if((ustatus->UTXEN)==0)
{
ustatus->UTXEN=1;
}
for(i=len;i;--i)
{
while((ustatus->TRMT)==0);
*txreg=*(char*)buffer++;
}
break;
default:{
SIMIOsimio;
registerPSIMIOpsimioasm("w0")=&simio;
simio.method=SIM_WRITE;
simio.u.write.handle=handle;
simio.u.write.buffer=buffer;
simio.u.write.len=len;
dowrite(psimio);
len=simio.u.write.len;
break;
}
}
return(len);
}
注意上面switch(handle)中第一个if语句,我们可以看到如果(__C30_UART != 1)并且&U2BRG(存在串口2),那么就可以将输出转到串口2。而__C30_UART是libpic30内部定义的变量,这样毕竟简单了。
首先定义一个变量:
extern int__C30_UART;
通过这个变量就可以灵活的将printf、scanf等标准函数的输入输出定义到需要的串口上。
使用串口1:__C30_UART = 1;
使用串口2:__C30_UART = 2;