2015年3月25日 星期三

Putchar in Keil C, take 8051 as an instance


 In Keil C, it is necessary to implement char putchar(char c), or the powerful function printf would not work.

We should notice in here : new line command for serial output be  "\r\n" (line feed:LF, 0x0a + carriage return:CR, 0x0d), not only "\n" in Keil C.


I do not want to write too much tedious word in here, below is my putchar code for 8051, use timer 1 as interrupt:


#define FCLK           22118400UL  
#define BAUDRATE        9600UL            





/* ref http://csserver.evansville.edu/~blandfor/EE354/SFRegisters.pdf */

void InitUART(void)
{
 EA = 0; 
 TMOD &= 0x0F;  /*timer 1 clean*/
 TMOD |= 0x20;  /*mode 2: 0~255,  auto-reload */

 REN = 0; /*forbid 8051 receive data*/
   SM1 = 1; /* Serial Control Register be set by timer*/

 /*
  BaudRate = OscillatorFreq/(N*256-TH1) 
  if SMOD = 0, N = 384
  if SMOD = 1, N = 192 

  SMOD is PCON.7  , Serial mode bit
 */
 
 TH1 = 256 - FCLK/(BAUDRATE*12*16);  
 TL1 = 256 - FCLK/(BAUDRATE*12*16);
 PCON |= 0x80;


 ES = 1;  /*Enable Serial port interrupt */
 REN = 1;   /*allow 8051 receive data */
 EA = 1;   /*Enable interrupt*/     
 

 TI = 1; /* the transmitting has been done */
 RI = 0; /* the receiving is not done yet */

 TR1 = 1;  /*Timer 1 is turned on*/
}/*InitUART*/




void UartInterrupt(void) interrupt 4
{
#if(0)
 if(RI)    
 {   
 }
 else     
 { 
 }
#endif

}/*UartInterrupt*/


char putchar(char c)  
{
 /* \n -> \r\n
   \r -> carriage return, 13
 */

 if ('\n' == c)  
 {
  SBUF = 0x0d;  
   
  while(0 == TI);
  TI = 0;
 } 

 SBUF = c;  
 while(0 == TI);

 TI = 0;

   return c;
}/*putchar*/


If you want to use the code, you should modify the FCLK macro constant for your micro chip, I use stc89c52rc, crystal be 22.1184MHz.

The baud rate, for most use, be 9600, you could modify the parameter in your serial communication software. (I suggest sscom)

沒有留言:

張貼留言