如果你想输出一些调试信息,怎么办? 一般使用的是printf(..)函数. 但有几个缺点: 1.你只是想调试时输出信息而已,做成release版本时,不需要输出调试信息. 这样势必要更改源程序,不方便. 2.printf(..)使用的函数putchar(..)一般要等待UART发送寄存器空时,才发送数据. 采用的查询-等待的方式,在某些场合会阻塞主程序的运行.
所以,我把putchar(..)函数改了下,采用中断的方式.
使用方法: 如果在调试状态: 定义1个宏 __TRACE__. 如果要生产realease版本,去掉这个宏.
在主程序开始,调用InitTrace(); 之后,在要输出调试信息的地方,用如trace("output info : %d",n);的语句就可以了. #include "trace.h" void main() { int i; InitTrace(); trace("************************\r"); for(i=0; i<600; i++) { dly(); trace("This is line: %d\r",i); } } 在"trace.c"中,可以定制 串口号,波特率等等.
附带1个uvision下的工程.
//*********** trace.h *************************** #ifndef __trace_header_file #define __trace_header_file #ifdef __TRACE__ extern void InitTrace(void); #define trace printf #else #define InitTrace() #define trace #endif #endif
/******************************************************************* * 文 件 名: trace.c *版本/时间: * 描 述: * 作 者: *------------------------------------------------------------------- * 修改记录: * 修改时间: * 描 述: * 修 改 人: *******************************************************************/
//-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- // <h> 参数设定 // <o> 使用UART // <0=> UART0 <1=>UART1 // <o1> 外设频率(PCLK) (unit:Hz) // <1000000-60000000> // <o2> 通讯波特率 // <96-115200> // <o3> 缓冲区大小(bytes) // <256=> 256 <512=> 512 <1024=>1024 <2048=>2048 // </h> #define __uart 1 #define Fpclk 11059200 #define __baud 115200 #define __bufsize 1024 /* 必须是2^n,如:512,1024,2048 */ //------------ <<< end of configuration section >>> ----------------------
typedef unsigned char uchar; typedef unsigned int uint;
#include <LPC213X.H>
#ifdef __TRACE__ #if __uart != 0 && __uart != 1 #error "must use uart0 or uart1." #endif
uchar __tracebuffer[__bufsize]; volatile uint first, next;
#if __uart==0 #define UXTHR U0THR #define UXLSR U0LSR #define UXIIR U0IIR #else #define UXTHR U1THR #define UXLSR U1LSR #define UXIIR U1IIR; #endif
// 中断,将缓冲区中还未发送的数据发送出去. void UartTraceIrq(void) __irq { uchar c = UXIIR; if(first != next) { UXTHR = __tracebuffer[first]; first ++; first &= (__bufsize - 1); } VICVectAddr = 0; }
// printf(..)函数将要调用此函数,此函数将ch放入缓冲区中 int putchar (int ch) { if(next+1 == first) return ch;
__tracebuffer[next] = ch; next ++; next &= (__bufsize - 1);
if(UXLSR & 0x40) // 如果缓冲区的数据以前已经发送完了,新的数据添加到缓冲后,因中断不会产生, //这些新数据不会被发送,所以先发送1个字符,启动中断. { ch = __tracebuffer[first]; first ++; first &= (__bufsize -1); UXTHR = ch; } return ch;
}
#define BAUD_DIVOR(baud) ( ((Fpclk/baud/8)%2) ? (Fpclk/baud/16+1) : (Fpclk/baud/16)) #if __uart == 0 #define SET_BAUD(baud) U0DLM = BAUD_DIVOR(baud) / 256; \ U0DLL = BAUD_DIVOR(baud) % 256; #else #define SET_BAUD(baud) U1DLM = BAUD_DIVOR(baud) / 256; \ U1DLL = BAUD_DIVOR(baud) % 256; #endif
void InitTrace (void) { #if __uart == 0  INSEL0 = (PINSEL0 & (~0x0f)) | 0x05; // set p0[1..0] for uart0 U0LCR = 0x83; // uart0 setting: "xxxx,n,8,1" SET_BAUD(__baud) U0LCR = 0x03; U0IER = 0x02; // enable tx interrupt. VICVectAddr14 = (unsigned long)UartTraceIrq; VICVectCntl14 = 0x20 | 6; VICIntEnable = 1 << 6 ; #else  INSEL0 = (PINSEL0 & (~0x0f0000)) | 0x050000; // set p0[9..8] for uart1 U1LCR = 0x83; // uart0 setting: "xxxx,n,8,1" SET_BAUD(__baud) U1LCR = 0x03; U1IER = 0x02; // enable tx interrupt. VICVectAddr14 = (unsigned long)UartTraceIrq; VICVectCntl14 = 0x20 | 7; VICIntEnable = 1 << 7 ; #endif } #else // #if not define __TRACE__ #pragma WA disable = 38 /*避免编译警告--空源文件*/ #endif
[此贴子已经被作者于2006-7-5 17:17:57编辑过] |