#include <hidef.h> /* common defines and macros */ #include "derivative.h" /* derivative-specific definitions */ #include <MC9S12XS128.h> /* derivative information */ /*全局变量定义*/ uint speed; uchar speedl; //脉冲数低八位 uchar speedh; //脉冲数高八位 uint cnt; //用于测试计数 int count; //用于起跑线计数 byte RXBUF[512]={0}; byte RXBUF1[512]={0}; byte res=0; void SET_PLL(void) ; //单片机时钟初始化 void PWM_Init(void); //PWM初始化 void IOC_Init(void);//测速模块 void ECT_Init(void); void PAI_PIT_Init(); void PAI_RTI_Init(void); void SCI_Init();//SCI串行通信初始化 void Uart_putchar( unsigned char c); void Uart_putstr(char ch[]); unsigned char Uart_getchar(void); void DelayKey(int cnt); //延时函数 cnt*1ms void DelayKey(int cnt) //1ms基准延时 { int i,j; for(i=0;i<cnt;i++) { j=5750; //0x1300=4864 ,20为5us基准 while(j--); } } //单片机时钟初始化 void SET_PLL(void) { //设置锁相环时钟频率为48M SYNR=2; REFDV=1; //PLLCLK=2*OSCCLK*(SYNR+1)/(REFDV+1) asmNOP; asmNOP; asmNOP; while((CRGFLG&0X08)==0);//等待锁相环频率锁定 CLKSEL=0X80; //选定锁相环时钟 } //PWM初始化 void PWM_Init(void) { PWME=0X00;//关闭所有PWM输出 PWMPRCLK=0X22;//24M/4=6M PWMSCLA=0X06; //6M/(2*6)=0.5M PWMSCLB=0X03; //6M/(2*3)=1M PWMCTL=0X20; //通道2和通道2合并 PWMCLK=0X3C; //通道23,4,5选择clocksA PWMPOL=0X3C; //PWM先输出高电平 PWMCAE=0X00; //左对齐 PWMPER23=10000;//周期为10ms PWMDTY23=1500;//输出角度为0度 PWMPER4 = 100; //5KHz PWMPER5 = 100; //5KHz PWMDTY4 =30;//初始速度设置为0 PWMDTY5 =0; PWME=0X3C;//开启PWM23,PWM4,PWM5 } /*输入捕捉定时器+脉冲累加测速模块*/ void IOC_Init(void) //龙丘例程 { TCNT =0x00; TSCR1=0x80;//时钟允许 TSCR2=0x04;//div by 16,禁止定时器溢出中断,预分频系数为16 PACTL=0xc0;//PT7 PIN,PACN32 16BIT,FALLing edge,NOT INTERRUPT TCTL3=0xc0;//c-输入捕捉7任何沿有效, TCTL4=0x03;//0表示ICx禁止, 1表示上升沿, 2表示下降沿, 3表示任何沿 TIE =0x00;//每一位对应相应通道中断允许,0表示禁止中断 TIOS =0x00;//每一位对应通道的: 0输入捕捉,1输出比较 TCTL3_EDG7x=1;//c-输入捕捉7任何沿有效, TCTL4_EDG0x=1; } /*输入捕捉定时器+脉冲累加测速模块*/ void ECT_Init(void) { TCNT =0x00; TSCR1=0x80;//时钟允许 TSCR2=0x04;//div by 16,禁止定时器溢出中断,预分频系数为16 PACTL=0x50;//PAI系统使能,事件计数模式,PT7脉冲输入上升沿有效 TCTL3=0x40;//输入捕捉7上升沿有效 TIE =0x00;//每一位对应相应通道中断允许,0表示禁止中断 TIOS =0x00;//每一位对应通道的: 0输入捕捉,1输出比较 } /*实时中断+脉冲累加测速模块已成功设置*///实测100线码盘一圈,小车走0.035m void PAI_RTI_Init(void) { RTICTL=0xC7;//1ms实时中断,采用十进制分频系数16×10^3 CRGFLG_RTIF=1; CRGINT_RTIE=1;//RTIE是RTI的中断使能位,为1使能 //PORTB=0x00; PACTL=0x50;//PAI系统使能,事件计数模式,PT7脉冲输入上升沿有效 } /*PIT 周期中断定时器+脉冲累加器测速模块*/ void PAI_PIT_Init() { PITCFLMT=0x00;//关闭PIT PITCE=0x01; //打开定时器0 PITMUX=0x00; //打开8位微计数器0 PITMTLD0=199; //给8位微计数器0赋值 PITLD0=19999; //给16位定时器0赋值,定时周期=(N+1)×(M+1)/ BusClk; //定时period=(199+1)×(19999+1)/(40×10^6)=100ms (0.1s) PITINTE=0x01; //使能定时器通道0的中断 PITCFLMT=0x80;//使能PIT PACTL=0x50; //PAI系统使能,事件计数模式,PT7脉冲输入上升沿有效 } /*PIT 一般初始化*/ void PIT_Init() { PITCFLMT=0x00;//关闭PIT PITCE=0x01; //打开定时器0 PITMUX=0x00; //打开8位微计数器0 PITMTLD0=199; //给8位微计数器0赋值 PITLD0=999; //给16位定时器0赋值,定时周期=(N+1)×(M+1)/ BusClk; //定时period=(199+1)×(999+1)/(40×10^6)=5ms (0.005s) PITINTE=0x01; //使能定时器通道0的中断 PITCFLMT=0x80;//使能PIT } /*初始化SCI0*/ void SCI_Init() { SCI0BD=313;//48MHz总线频率,9600的分频SCI系数,波特率=总线时钟/(16×SCIxBD); SCI0CR1 =0x00;//正常8位模式,偶校验 SCI0CR2 =0x2c;//接收中断允许 } void Uart_putchar ( unsigned char c) { while(!(SCI0SR1&0x80)) ; //keep waitingwhen not empty SCI0DRL=c; } void Uart_putstr(char ch[]) { unsigned char ptr=0; while(ch[ptr]){ Uart_putchar((unsigned char)ch[ptr++]);} } unsigned char Uart_getchar(void) { byte res=0; while(!(SCI0SR1&0x80)) ; //keep waitingwhen not empty return (SCI0DRL); } /*系统初始化部分*/ void System_Init() { /*系统时钟*/ void SET_PLL(void); /*PWM*/ PWM_Init(); /*ECT脉冲捕捉*/ PAI_RTI_Init(); } /************************************ 中断设置部分 *************************************/ #pragma CODE_SEG __NEAR_SEG NON_BANKED //测速模块专用 voidinterrupt 7 RTI(void) { CRGFLG_RTIF=1; speed=PACNT; PACNT=0; } void interrupt 20 SCI(void) { SCI0CR2_RIE=1; } voidinterrupt 66 PIT(void) { /*一般测速之用*/ /* */ speed=PACNT; PACNT=0; speedh=speed/256; //记录脉冲数的高八位 speedl=speed%256; //记录脉冲数的第八位 RXBUF1[2*cnt]=speedh; RXBUF1[2*cnt+1]=speedl; cnt++; if(count==0) { PWMDTY4=15; DisableInterrupts; } PITTF_PTF0=1; //清中断标志位,写1清零该标志位 } #pragma CODE_SEG DEFAULT /****************************************** 主函数部分 *******************************************/ void main(void) { DelayKey(300); SET_PLL(); PWM_Init(); DDRB=0xFF; DDRA=0x00; EnableInterrupts; ; PWMDTY5=0; for(;;) {PWMDTY4=20; if (Uart_getchar() == 'c') Uart_putstr("Usart Is Working!"); } }
|