MC9S12G128 串口通信

来源:互联网 发布:许晴家世 知乎 编辑:程序博客网 时间:2024/05/23 16:14
/*******************************************************************    程序名:MC9S12G128 串口**    参  数:BusCLK_nM 总线时钟**    功  能:使用G128串口通信  **    注  意:程序中使用的是G128的第一路串口,即(S0,S1)**    作  者:**    版  本:v1.0**    时  间:2012.5.9   ******************************************************************/#include <hidef.h>      #include "derivative.h"      #include <ctype.h>#include <string.h>#include <stdarg.h>#define BusCLK_nM 16000000#pragma CODE_SEG DEFAULT #define CR_as_CRLF  TRUE             // if true , you can use "\n" to act as CR/LF,                                      // if false, you have to use "\n\r",but can get a higher speed  static int do_padding;static int left_flag;static int len;static int num1;static int num2;static char pad_character;unsigned char uart_getkey(void){     while(!(SCI0SR1&0x80)) ;  //keep waiting when not empty     return SCI0DRL;} void uart_putchar(unsigned char ch){   if (ch == '\n')    {      while(!(SCI0SR1&0x80)) ;           SCI0DRL= 0x0d;        //output'CR'    return;  }  while(!(SCI0SR1&0x80)) ;     //keep waiting when not empty    SCI0DRL=ch;}void putstr(char ch[]){  unsigned char ptr=0;  while(ch[ptr]){      uart_putchar((unsigned char)ch[ptr++]);  }       }                                                 static void padding( const int l_flag){   int i;   if (do_padding && l_flag && (len < num1))      for (i=len; i<num1; i++)          uart_putchar( pad_character);}static void outs( char* lp){  /* pad on left if needed                          */  len = strlen( lp);  padding( !left_flag);  /* Move string to the buffer                      */  while (*lp && num2--)  uart_putchar( *lp++);  /* Pad on right if needed                         */  len = strlen( lp);  padding( left_flag);}static void reoutnum(unsigned long num, unsigned int negative, const long base ) {  char* cp;  char outbuf[32];  const char digits[] = "0123456789ABCDEF";   /* Build number (backwards) in outbuf             */  cp = outbuf;  do {    *cp++ = digits[(int)(num % base)];    } while ((num /= base) > 0);  if (negative)  *cp++ = '-';  *cp-- = 0;  /* Move the converted number to the buffer and    */  /* add in the padding where needed.               */  len = strlen(outbuf);  padding( !left_flag);  while (cp >= outbuf)    uart_putchar( *cp--);  padding( left_flag);}static void outnum(long num, const long base ,unsigned char sign)//1, signed  0 unsigned{     unsigned int negative;  if ( (num < 0L) && sign )   {      negative=1;    num = -num;  }  else negative=0;   reoutnum(num,negative,base);  } static int getnum( char** linep){   int n;   char* cp;   n = 0;   cp = *linep;   while (isdigit(*cp))      n = n*10 + ((*cp++) - '0');   *linep = cp;   return(n);}void printp( char* ctrl, ...){    int long_flag;   int dot_flag;   char ch;   va_list argp;    va_start( argp, ctrl);    for ( ; *ctrl; ctrl++) {        /* move format string chars to buffer until a  format control is found. */      if (*ctrl != '%') {         uart_putchar(*ctrl);#if CR_as_CRLF==TRUE                  if(*ctrl=='\n') uart_putchar('\r');#endif                  continue;         }       /* initialize all the flags for this format.   */      dot_flag = long_flag = left_flag = do_padding = 0;      pad_character = ' ';      num2=32767;  try_next:      ch = *(++ctrl);      if (isdigit(ch)){         if (dot_flag)            num2 = getnum(&ctrl);         else {            if (ch == '0')               pad_character = '0';             num1 = getnum(&ctrl);            do_padding = 1;         }         ctrl--;         goto try_next;      }             switch (tolower(ch)) {         case '%':              uart_putchar( '%');              continue;           case '-':              left_flag = 1;              break;           case '.':              dot_flag = 1;              break;           case 'l':              long_flag = 1;              break;           case 'd':              if (long_flag ==1 )               {              if(ch == 'D')                {outnum( va_arg(argp, unsigned long), 10L , 0);continue;}                      else  /* ch == 'd' */        {outnum( va_arg(argp, long), 10L,1);continue;}              }              else               {              if(ch == 'D') {outnum( va_arg(argp, unsigned int),10L,0);continue;}              else  /* ch == 'd' */                      {                outnum( va_arg(argp, int), 10L,1);                continue;              }              }                          case 'x':    // X 无符号 , x  有符号              if (long_flag ==1 )              {              if(ch == 'X')                              {                outnum( va_arg(argp, unsigned long), 16L,0);                continue;              }              else  /* ch == 'x' */                      {                outnum( va_arg(argp, long), 16L,1);                continue;              }               }              else              {              if(ch == 'X')                              {                outnum( va_arg(argp, unsigned int), 16L,0);                continue;              }              else  /* ch == 'x' */                      {                outnum( va_arg(argp, int), 16L,1);                continue;              }              } //如果按照16进制打印,将全部按照无符号数进行              continue;          case 's':              outs( va_arg( argp, char*));              continue;            case 'c':              uart_putchar( va_arg( argp, int));              continue;           default:              continue;         }      goto try_next;      }   va_end( argp);}/*******************************************************************    函数名: PLL_Init()**    参  数:无**    功  能:将总线时钟倍频至16M,32M,64M**    注  意:    ******************************************************************/   void PLL_Init(void) {  CPMUPROT = 0x26;            //保护时钟配置寄存器  CPMUCLKS_PSTP = 0;          //禁用PLL  CPMUCLKS_PLLSEL = 1;        //选择PLL作为系统时钟源  CPMUOSC_OSCE = 1;           //外部晶振使能    CPMUSYNR = 0x07;            //fVCO= 2*fOSC*(SYNDIV + 1)/(REFDIV + 1)                       CPMUREFDIV = 0x07;          //16M:07,0F;32M:07,07;64M:07,03      CPMUPOSTDIV = 0x00;         // PLL CLOCK = VCO CLOCK / (POSTDIV + 1)                                 _asm(nop);  _asm(nop);    CPMUPLL=0x10;               //锁相环调频启用,用以减少噪音      while(CPMUFLG_LOCK == 0);  //等待PLL稳定    CPMUPROT = 0x00;            //关闭保护时钟  CPMUCLKS_PLLSEL = 1;        //使能PLL }static void SCI_Init(void) {    SCI0CR1 = 0x00;    SCI0CR2 = 0x2c;             //使能接收中断,发送与接收使能    SCI0BD  = BusCLK_nM/16/9600;//超频至32MHz时,总线频率为16MHz                                 //SCI0BDL=busclk/(16*SCI0BDL)                                //busclk  8MHz, 9600bps,SCI0BD=0x34                                //busclk 16MHz, 9600bps,SCI0BD=0x68                                //busclk 24MHz, 9600bps,SCI0BD=0x9C}                               //busclk 32MHz, 9600bps,SCI0BD=0xD0                                  //busclk 40MHz, 9600bps,SCI0BD=0x106  /*******************************************************************    函数名: delayms()**    参  数:xms**    功  能:在32MHz总线时钟下大约延时xms毫秒  **    注  意:    ******************************************************************/void delayms(uint xms){  uint z,j;for(z=xms;z>0;z--)    for(j=5340;j>0;j--);}void main(void){  unsigned char LedCnt=0;    PLL_Init();  SCI_Init();  DDRD = 0xFF;   PORTD = 0;    EnableInterrupts;    for(;;)   {       delayms(1000);   //延时    PORTD = ~LedCnt;    //LED取反         putstr("http://blog.csdn.net/dazhaozi\n");      }}
新手上路,如有错误,欢迎指正。