freescale MC9S12G128 SCI,printf使用

Serial Communication Interface (SCI)

SCI异步串行通信:
术语词汇:
IR: InfraRed
IrDA: Infrared Design Associate
IRQ: Interrupt Request
LIN: Local Interconnect Network
LSB: Least Significant Bit
MSB: Most Significant Bit
NRZ: Non-Return-to-Zero
RZI: Return-to-Zero-Inverted
RXD: Receive Pin
SCI : Serial Communication Interface
TXD: Transmit Pin

功能框图:

在这里插入图片描述

相关寄存器:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

SCI轮询方式收发数据代码:

#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define D_BUSCLK_FREQ   (16000000) // 总线频率 16MHz
#define D_SCI_BAUDRATE  (9600)     // 串口波特率  


unsigned char txbuff[256]={
    
    0};   // 发送缓存
unsigned char rxbuff[256]={
    
    0};   // 接收缓存


/*************************************************************/
/*                       串口发送函数                        */
/*************************************************************/
void csi_send(unsigned char data) 
{
    
    
  while(!SCI0SR1_TDRE);       //等待发送数据寄存器(缓冲器)为空
  SCI0DRL = data;
}


void send_string(unsigned char *putchar) 
{
    
    
  while(*putchar!=0x00)       //判断字符串是否发送完毕
  {
    
    
   csi_send(*putchar++);  
  }
}



unsigned char csi_receive(void) 
{
    
    
  while(!SCI0SR1_RDRF);          //等待接收数据寄存器满
    return(SCI0DRL);
}



/*************************************************************/
/**   定义了这个两个接口就可以使用printf函数格式化输出      **/
/**   TERMIO_PutChar                                        **/
/**   TERMIO_GetChar                                        **/
/*************************************************************/
void TERMIO_PutChar(char ch){
    
    
  csi_send((unsigned char)ch);
}

char TERMIO_GetChar(void){
    
    
  return (char)csi_receive();
}



void sci_init(void) {
    
    
  SCI0BD = D_BUSCLK_FREQ/16/D_SCI_BAUDRATE;    // 设置SCI0波特率 busCLK/16/BAUDRATE;
  SCI0CR1 = 0x00;       //设置SCI0为正常模式,八位数据位,无奇偶校验
  SCI0CR2 = 0x08 | 0x04;//允许收发送数据,禁止中断功能  7:TIE, 6:TCIE, 5:RIE, 4:ILIE, 3:TE, 2:RE, 1:RWU, 0:SBK
}


/**
* @brief 锁相环 初始化
* @param none
* @return none
*/
void pll_init(void) {
    
    
  CPMUPROT = 0x26;              //保护时钟配置寄存器
  
  CPMUCLKS_PSTP = 0;            //禁用PLL
  CPMUCLKS_PLLSEL = 1;          //选择PLL作为系统时钟源
  
  CPMUOSC_OSCE = 1;             //外部晶振使能
  while(CPMUOSC_OSCPINS_EN==0); //等待外部晶振使能

  // BUSCLK = (PLLCLK / 2)   总线频率=(锁相环频率/2)
  
  
  #if 1
  //fVOC= 2*fOSC*(SYNDIV + 1)/(REFDIV + 1) 
  CPMUSYNR = 0x07;                                                  
  //CPMUREFDIV = 0x0F; // PLLCLK:16M  BUSCLK:8M   
  CPMUREFDIV = 0x07; // PLLCLK:32M  BUSCLK:16M   
  //CPMUREFDIV = 0x03; // PLLCLK:64M  BUSCLK:32M        
  #endif
  
  #if 0
  //fVOC配置 fVOC = 2*fREF*(SYNDIV +1)
  //CPMUSYNR = 0x45; // PLLCLK:48M     BUSCLK:24M
  //CPMUSYNR = 0x44; // PLLCLK:40M     BUSCLK:20M
  //CPMUSYNR = 0x43; // PLLCLK:32M     BUSCLK:16M
  //CPMUSYNR = 0x42; // PLLCLK:24M     BUSCLK:12M
  CPMUSYNR = 0x01; // PLLCLK:16M    BUSCLK:8M
  CPMUREFDIV = 0x81;//REFDIV基准分频器配置
  #endif
    
  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
}

void main(void) {
    
    
  //int c;

  /* put your own code here */
  DisableInterrupts;
  pll_init();
  sci_init();
	EnableInterrupts;

  
  for(;;) {
    
    
    /* TODO:单字符收发 */
    rxbuff[0] = csi_receive();  // 接收一个字符 这里会阻塞
    
    csi_send(rxbuff[0]+1);      // 接收字符+1 并发送字符
    csi_send('\n');             // 发送换行'\n'
    
    
    /* TODO:发送字符串 */ 
    (void)memset((char*)txbuff, 0, sizeof((char*)txbuff));
    (void)sprintf((char*)txbuff, "%s", "This is freescale sci send.\n");
    send_string(txbuff);       // 发送字符串
    
     
    /* TODO:printf 函数使用 */ 
    (void)printf("sci test\n");
    (void)printf("%s, %d\n","hello", 1234);

     
     #if 0
     c = getchar();
     if (putchar(c)) {
    
    
     
     } else {
    
    
     
     }
     #endif
    

    _FEED_COP(); /* feeds the dog */
  } /* loop forever */
  /* please make sure that you never leave main */
}

SCI中断方式收发数据代码:

#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */
#include <stdio.h>
#include <string.h>

#define D_BUSCLK_FREQ   (16000000) // 总线频率 16MHz
#define D_SCI_BAUDRATE  (9600)     // 串口波特率  


unsigned char txbuff[256]={
    
    0};   // 发送缓存
unsigned char rxbuff[256]={
    
    0};   // 接收缓存

unsigned char *send;

/*************************************************************/
/*                       串口发送函数                        */
/*************************************************************/
void csi_send(unsigned char data) 
{
    
    
  while(!SCI0SR1_TDRE);         //等待发送数据寄存器(缓冲器)为空
  SCI0DRL = data;
}

/*************************************************************/
/*                       串口接收函数                        */
/*************************************************************/
unsigned char csi_receive(void) 
{
    
    
  while(!SCI0SR1_RDRF);          //等待发送数据寄存器满
  return(SCI0DRL);
}

/*************************************************************/
/**   定义了这个两个接口就可以使用printf函数格式化输出      **/
/**   TERMIO_PutChar                                        **/
/**   TERMIO_GetChar                                        **/
/*************************************************************/
void TERMIO_PutChar(char ch){
    
    
  csi_send((unsigned char)ch);
}

char TERMIO_GetChar(void){
    
    
  return (char)csi_receive();
}


void sci_init(void) {
    
    
  SCI0BD = D_BUSCLK_FREQ/16/D_SCI_BAUDRATE;    // 设置SCI0波特率 busCLK/16/BAUDRATE;
  SCI0CR1 = 0x00;    //设置SCI0为正常模式,八位数据位,无奇偶校验  7:LOOPS 6:SCISWAI 5:RSRC 4:M 3:WAKE 2:ILT 1:PE 0:PT
  SCI0CR2 = 0xAC;    //允许收发数据,允许收发中断功能   7:TIE, 6:TCIE, 5:RIE, 4:ILIE, 3:TE, 2:RE, 1:RWU, 0:SBK
}


/**
* @brief 锁相环 初始化
* @param none
* @return none
*/
void pll_init(void) {
    
    
  CPMUPROT = 0x26;              //保护时钟配置寄存器
  
  CPMUCLKS_PSTP = 0;            //禁用PLL
  CPMUCLKS_PLLSEL = 1;          //选择PLL作为系统时钟源
  
  CPMUOSC_OSCE = 1;             //外部晶振使能
  while(CPMUOSC_OSCPINS_EN==0); //等待外部晶振使能

  // BUSCLK = (PLLCLK / 2)   总线频率=(锁相环频率/2)
  
  
  #if 1
  //fVOC= 2*fOSC*(SYNDIV + 1)/(REFDIV + 1) 
  CPMUSYNR = 0x07;                                                  
  //CPMUREFDIV = 0x0F; // PLLCLK:16M  BUSCLK:8M   
  CPMUREFDIV = 0x07; // PLLCLK:32M  BUSCLK:16M   
  //CPMUREFDIV = 0x03; // PLLCLK:64M  BUSCLK:32M        
  #endif
  
  #if 0
  //fVOC配置 fVOC = 2*fREF*(SYNDIV +1)
  //CPMUSYNR = 0x45; // PLLCLK:48M     BUSCLK:24M
  //CPMUSYNR = 0x44; // PLLCLK:40M     BUSCLK:20M
  //CPMUSYNR = 0x43; // PLLCLK:32M     BUSCLK:16M
  //CPMUSYNR = 0x42; // PLLCLK:24M     BUSCLK:12M
  CPMUSYNR = 0x01; // PLLCLK:16M    BUSCLK:8M
  CPMUREFDIV = 0x81;//REFDIV基准分频器配置
  #endif
    
  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
}


/*************************************************************/
/*                   串口中断发送字符串函数                  */
/*************************************************************/
#pragma CODE_SEG __NEAR_SEG NON_BANKED
interrupt VectorNumber_Vsci0 void sci_irq(void) 
{
    
    
  /* 字符收发 */ 
  if (SCI0SR1_RDRF) {
    
    
     rxbuff[0] = csi_receive(); // 接收数据
     csi_send(rxbuff[0]);       // 发送数据
  }

  
  /* TODO:发送字符串 */
  if(*send!=0x00) {
    
     //判断字符串是否发送完毕
      csi_send(*send++);
  } else {
    
    
    send = txbuff;         //重新装载发送的数据
  }
  
}
#pragma CODE_SEG DEFAULT



void main(void) {
    
    
  /* put your own code here */
  
  DisableInterrupts;
  pll_init();
  sci_init();
	EnableInterrupts;

  (void)memset((char*)txbuff, 0, sizeof((char*)txbuff));
  (void)sprintf((char*)txbuff, "%s\n", "interrupt mode send and receive sci data");
  
  (void)printf("************** CSI ****************\n");
  for(;;) {
    
    
    _FEED_COP(); /* feeds the dog */
  } /* loop forever */
  /* please make sure that you never leave main */
}

printf函数使用:

/*************************************************************/
/**   定义了这个两个接口就可以使用printf函数格式化输出      **/
/**   TERMIO_PutChar                                        **/
/**   TERMIO_GetChar                                        **/
/*************************************************************/
void TERMIO_PutChar(char ch){
    
     
}
char TERMIO_GetChar(void){
    
    
}

猜你喜欢

转载自blog.csdn.net/u013420428/article/details/112920351