freetech

MC9RS08KA4下的定时器模拟UART例子程序

0
阅读(1773)

RS系列单片机既不支持中断,又没有UART串口。然而有人希望用来也串口通信。用定时器的输出比较功能可以在比较准的时间翻转引脚,用查询方式查到输出比较中断标识后,可以把下一次引脚状态写入定时器……,下面给出一段例程,程序采用TPMCH0,PTA0引脚,软件模拟成UART发送脚,本程序在MC9RS08KA4下调试通过。下面是完整代码:

#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
#define CPU_CLK 16000000
#define BUS_CLK (CPU_CLK/2)
#define BUARD_RATE 1200
#define BIT_TIME ((BUS_CLK+(BUARD_RATE/2))/BUARD_RATE)//16MHz cpu频率下是6667

//本程序采用TPMCH0,PTA0引脚,软件模拟成UART发送脚
void putchar(char c)
{
  unsigned char cnt;
  TPMCNTL = 0;//计数清0
  TPMC0V = 100;//匹配
  TPMC0SC = 0x58;//匹配时输出0,发送起始位
  //TPMSC = 0x08;
  TPMC0SC_CH0F = 0;
  //等待上一次匹配 
  while(TPMC0SC_CH0F != 1)//等待定时器输出比较中断标识
  {
     __RESET_WATCHDOG(); // feeds the dog
  }
  TPMC0V += BIT_TIME;
  // 发送8个数据位
  for(cnt=0 ; cnt<8 ;cnt++)
  {
    if( (c&1) == 0)
    {
      TPMC0SC = 0x58;//匹配时输出0
    }
    else
    {
      TPMC0SC = 0x5C;//匹配时输出1
    }
    c >>= 1;;
    TPMC0SC_CH0F = 0;
    while(TPMC0SC_CH0F != 1)//等待定时器输出比较中断标识
    {
       __RESET_WATCHDOG(); // feeds the dog
    }
    TPMC0V += BIT_TIME;
  }
  TPMC0SC = 0x5C;
  TPMC0SC_CH0F = 0;
  while(TPMC0SC_CH0F != 1)//等待定时器输出比较中断标识
  {
     __RESET_WATCHDOG(); // feeds the dog
  }
  //TPMSC_TOF = 0;
  TPMC0SC = 0x1C;
  //TPMSC = 0;//关闭定时器
}

void InitTPM()
{
  TPMC0SC = 0x1C;//匹配时输出1
  TPMC0V = 0;//立即匹配
  TPMSC = 0x08;
  TPMCNTL = 0;//计数清0
}
void ICS_Init()
{
  if (*(unsigned char* __paged)CONVERT_TO_PAGED(0x3FFA) != 0xFF)
  { // Test if the device trim value is stored on the specified address
    ICSTRM = *(unsigned char* __paged)CONVERT_TO_PAGED(0x3FFA); // Initialize ICSTRM register from a non volatile memory
    ICSSC = *(unsigned char* __paged)CONVERT_TO_PAGED(0x3FFB); // Initialize ICSSC register from a non volatile memory
  }

  ICSC1 = 0x06;//ICSC1: CLKS=0,RDIV=0,IREFS=1,IRCLKEN=1,IREFSTEN=0
  ICSC2 = 0x00;//ICSC2: BDIV=0,RANGE=0,HGO=0,LP=0,EREFS=0,ERCLKEN=0,EREFSTEN=0

}
void delay()
{
  unsigned int cnt;
  for(cnt=0 ; cnt<6000 ; cnt++)
  {
    __RESET_WATCHDOG();
  }
}
void main(void) {

  EnableInterrupts; /* enable interrupts */
  /* include your code here */
  ICS_Init();
  InitTPM();
  for(;;) {
    putchar(0x33);
    delay();
    __RESET_WATCHDOG(); /* feeds the dog */
  } /* loop forever */
  /* please make sure that you never leave main */
}

下面是波形:

image

上图中:最左面的低电平是停止位(0.83mS),接着是2个1,2个0,2个1,2个0,最后停止位与空闲电平相同。