📄 m9s12db128.c
字号:
/***************************************************************
// Name : M9s12DB128.c
// Organization : Hunan University
// Author : Huangzhi
// Date : 2007.09.1
// Description : hardware drivers for M9s2DB128 CPU
// Version : V1.0
// History :
****************************************************************/
#include <hidef.h>
#include "hcs12db128.h" /* derivative information */
#include "GlobalDef.h"
// external variables
extern struct PUMP_CTL PumpCtl[];
extern char CurWorkMode;
extern char fMDC10ms;
extern char fRTI2ms;
// global variables
uint TimerTick;
uint MDCounter;
PRIVATE int AD0Que[PUMP_NUM][AD_QUE_LEN];
PRIVATE int AD1Que[PUMP_NUM][AD_QUE_LEN];
PRIVATE char ADQueIndex = 0;
// local variables
PRIVATE uint HSCTmp[PUMP_NUM]={0,0,0,0};
PRIVATE uint HSC100ms[PUMP_NUM]={0,0,0,};
PRIVATE uchar HSCTick=0;
PRIVATE uint LSCTmp=0;
PRIVATE uint LSC100ms=0;
PRIVATE char Direction=0xff;
//PRIVATE char PreZeroSW=0;
//PRIVATE char PreUpSW =0;
//PRIVATE char PreLowSW =0;
//PRIVATE char fFirstStart= 1;
// global routines
void InitPLL(void);
void InitPIM(void);
void InitATD(void);
void InitECT(void);
void InitPWM(void);
void InitRTI(void);
void InitSCI(uchar Port, uint BaudRate);
void PrintString(uchar Port, char * pBuf);
/********************* S12 hardware initialization routines *************************/
void InitS12(void) {
DisableInterrupts;
InitPLL();
InitPIM();
InitPWM();
InitSCI(0, DEBUG_BAUD_RATE);
InitECT();
InitATD();
InitRTI();
}
/********************************* initialize PLL **********************************/
void InitPLL(void) {
CLKSEL &= ~BM_PLLSEL; // make sure PLL is *not* in use
PLLCTL |= (BM_PLLON+BM_AUTO); // enable PLL module, Auto Mode
REFDV = S12_REFDV; // set up Reference Divider
SYNR = S12_SYNR; // set up Synthesizer Multiplier
while((CRGFLG & BM_LOCK) == 0) ; // wait until PLL is locked
CLKSEL |= BM_PLLSEL; // switch over to PLL clock
}
/********************************* initialize real timer **********************************/
void InitRTI() {
CRGINT |= BM_RTIE; // enable Real time interrupt
COPCTL |= BM_RSBCK;
RTICTL = 0x2f; // prescale= 16*2048, osc_clk= 16000000, period= 2.048ms
TimerTick = 0;
}
/********************************* COP failure **********************************/
void interrupt VEC_CMF COPFail_ISR() {
// add cop failure routine here
return;
}
/********************************* COP interruption **********************************/
void interrupt VEC_COP COP_ISR() {
// add cop routine here
return;
}
/******************************* Real time interrupt **********************************/
void interrupt VEC_RTI RTI_ISR() {
// 2.048ms timer interruption
char i,Pulse,j;
int tmp;
CRGFLG |= 0x80; // clear RTI flag
TimerTick += 2; // 2.048ms
fRTI2ms = 1;
SET_MC0_P; // set Pulse output to 1
SET_MC1_P;
SET_MC2_P;
SET_MC3_P;
// Get AD result
AD0Que[0][ADQueIndex] = ATD0DR0;
AD0Que[1][ADQueIndex] = ATD0DR1;
AD0Que[2][ADQueIndex] = ATD0DR2;
AD0Que[3][ADQueIndex] = ATD0DR3;
AD1Que[0][ADQueIndex] = ATD1DR0;
AD1Que[1][ADQueIndex] = ATD1DR1;
AD1Que[2][ADQueIndex] = ATD1DR2;
AD1Que[3][ADQueIndex] = ATD1DR3;
START_AD0; // trigger a sequence conversion
START_AD1;
ADQueIndex ++;
if (ADQueIndex >= AD_QUE_LEN)
ADQueIndex = 0;
// Set direction control signal
Direction = 0;
if (PumpCtl[0].Dest > PumpCtl[0].Cur) {
SET_MC0_DIR;
Direction |= 0x01;
}
else
CLR_MC0_DIR;
if (PumpCtl[1].Dest > PumpCtl[1].Cur){
SET_MC1_DIR;
Direction |= 0x2;
}
else
CLR_MC1_DIR;
if (PumpCtl[2].Dest > PumpCtl[2].Cur){
SET_MC2_DIR;
Direction |= 0x4;
}
else
CLR_MC2_DIR;
if (PumpCtl[3].Dest > PumpCtl[3].Cur){
SET_MC3_DIR;
Direction |= 0x8;
}
else
CLR_MC3_DIR;
// adjust speed of servo motor
for (i=0; i< PUMP_NUM; i++) {
if (PumpCtl[i].Dest > PumpCtl[i].Cur)
tmp = PumpCtl[i].Dest - PumpCtl[i].Cur;
else
tmp = PumpCtl[i].Cur - PumpCtl[i].Dest;
if (tmp < ACC_DIST)
PumpCtl[i].Spd = tmp * (MAX_SERVO_SPD / ACC_DIST) ;
else
PumpCtl[i].Spd = MAX_SERVO_SPD;
}
Pulse = 0;
j = 0x01;
// generate pulse
for (i=0; i< PUMP_NUM; i++) {
if (PumpCtl[i].Dest != PumpCtl[i].Cur) {
PumpCtl[i].Count += PumpCtl[i].Spd;
if (PumpCtl[i].Count > 0x7f) {
PumpCtl[i].Count &= 0x7f;
Pulse |= j;
}
}
j <<= 1;
}
// output pulse
if (Pulse & 0x01) {
if (Direction & 0x01)
PumpCtl[0].Cur++;
else
PumpCtl[0].Cur--;
CLR_MC0_P;
}
if (Pulse & 0x02) {
if (Direction & 0x02)
PumpCtl[1].Cur++;
else
PumpCtl[1].Cur--;
CLR_MC1_P;
}
if (Pulse & 0x04) {
if (Direction & 0x04)
PumpCtl[2].Cur++;
else
PumpCtl[2].Cur--;
CLR_MC2_P;
}
if (Pulse & 0x08) {
if (Direction & 0x08)
PumpCtl[3].Cur++;
else
PumpCtl[3].Cur--;
CLR_MC3_P;
}
//
return;
}
/************************ initialize port integrated module ****************************/
void InitPIM(void) {
// IO port definition
// PA0~PA6 Output
// PB0~PB5 Output
// PE0~PE3 Input, Pull-up , PE1 used as external pulse counter
// PH0~PH6 Output
// PT0~PT3 High Speed Pulse Counter input
// PT4~PT7 Input, Pull-up
// PK0~PK5 Input, pull-up
// PM2~PM7 Input, Pull-up
// AN0~AN6 AN8,AN9 Analog Input
// PP0~PP7 PWM output
// PS0---RXD0, PS1---TXD0
// PS2---RXD1, PS3---TXD1
// PS4---MISO0,PS5---MOSI0,PS6---SCK0, PS7---/SS0
// PM0---RXCAN0, PM1---TXCAN0
DDRT = 0x00; // port T= input
PERT = 0xff;
PPST = 0x00; // pull-up enabled
DDRM &= 0x03; // PM2~PM7= input
PERM |= 0xfc;
PPSM &= 0x03;
MODRR = 0x00; // CAN0--PM0~1, CAN4--PJ6~7 SPI0--PS4~7, SPI1--PP0~3
DDRP = 0xff; // output
RDRP = 0x00; // full drive strength
DDRH = 0xff;
RDRH = 0x00;
DDRA |= 0x7f; // output
DDRB |= 0x3f; // output
DDRE &= 0xf0; // PE0~PE3 = input
DDRK &= 0xc0; // PK0~PK5 = input
PEAR = 0x10; // ECLK is enabled
PUCR = 0x93; // A,B,K,E pull-up enabled
IRQCR = 0xc0; // IRQ is enabled, falling edges is effective.
return;
}
/****************************** Initialize PWM ************************************/
// interface function:
// void InitPWM()
void InitPWM() {
return;
}
/****************************** Initialize ECT ************************************/
void InitECT() {
// PAC0~PAC3 work as high speed 8 Bits counter. Interruption routine latches and resets PAC0~PAC3 every 10ms,
// that means counter can work properly at speed of 25.5KHz.
// Since at least 5 counters is needed, another counter is implemented using general IO port.
// 5 counters are for sensing of Engine speed(2500rpm), 4 wheels speed.
// timer enable, freeze while BDM
uchar i;
TIOS &= 0xf0; // PT0~PT3 = input capture , PT4~PT7 = out capture
TCFORC = 0x0;
TCTL4 = 0x55; // capture on rising edegs only
TIE = 0x0; // disable timer interrupt
TSCR2 = 0x00; // TOI=0; TCRE=0; PR0~2=0
PACTL = 0x00;
PBCTL = 0x00;
MCFLG |= 0x80; // clear Modulus down counter underflow flag(MCZF)
ICPAR = 0x0f; // enable PA0~PA3
DLYCT = 0x01; // 256bus clock cycles delay
ICSYS = 0x07; // TFMOD=0,PACMX=1, BUFFEN= 1; LATQ=1
TSCR1 |= (BM_TEN + BM_TFFCA + BM_TSBCK + BM_TSWAI);
PACN0 = 0;
PACN1 = 0;
PACN2 = 0;
PACN3 = 0;
// MDCU Interrupt enable, modulus mode, counter enable,
MCCTL |= ((1<<7) + (1<<6) + (0<<5) + (1<<3) + (1<<2) + MDC_PRSEL); // MCZI=1, MODMC=1, FLMC=1,RDMCL=0, MCEN=1
MCCNT = TIMER_MDC_COUNT;
MCCTL |= ((1<<7) + (1<<6) + (0<<5) + (1<<3) + (1<<2) + MDC_PRSEL); // force to reload MDC counter
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -