/**********************************************
* 徐方鑫 2011.2.16
* 280599580@qq.com
***********************************************/
#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
#include <MC9S12XS128.h> /* derivative information */
//1M=1006080
//40MHz BUS_CLOCK
/*
#define SynrDefine 0x53
#define RefdvDefine 0x07 //时钟频率等于2*晶振频率*(SYNR0+1)/(REFDV0+1)
#define SciDefine 0x106 //串行总线频率=时钟频率/(16*SCI0BDL)
*/
//-----------------------------------------------------
//80MHz BUS_CLOCK
#define SynrDefine 0xD3
#define RefdvDefine 0x03 //时钟频率等于2*晶振频率*(SYNR0+1)/(REFDV0+1)
#define SciDefine 0x20c //串行总线频率=时钟频率/(16*SCI0BDL)
#define WAITTIME 100000 //启动延时时间
#define SpeedInterrupt 1000 //速度周期采样时间,定时1000 * 0.01ms = 10ms
#define AdInterrupt 100 //Ad周期采样时间,定时100 * 0.01ms = 1ms
int SpeedNow=0; //速度采样初始化
int sensor_ad[5]=0; //i=0~4,AD数据采样结果
//-----------------------------------------------------
//92MHz BUS_CLOCK
/*
#define SynrDefine 0xD6
#define RefdvDefine 0x03 //时钟频率等于2*晶振频率*(SYNR0+1)/(REFDV0+1)
#define SciDefine 0x25a //串行总线频率=时钟频率/(16*SCI0BDL)
*/
//-----------------------------------------------------
/******************************************************************
*函数名:Wait_Time
*入口参数无
*出口参数: 无
*功能描述: 简单延迟程序
*******************************************************************/
void Wait_Time(ulong cnt) {
unsigned char a,b;
while(--cnt) {
for(b=4;b>0;b--)
for(a=248;a>0;a--);
}
}
//-----------------------------------------------------
/******************************************************************
*函数名:PLL_Init
*入口参数SNNR寄存器值,REFDV0寄存器值
*出口参数: 无
*功能描述:使用PLLCLK,时钟频率=2*晶振频率*(SYNR0+1)/(REFDV0+1)
*******************************************************************/
void PLL_Init(byte SYNR0,byte REFDV0)
{
CLKSEL=0x00; //disable pll;
CLKSEL_PLLSEL = 0;
PLLCTL_PLLON = 0;
SYNR = SYNR0; //
REFDV = REFDV0;
PLLCTL = 0xc0; //0xC0 CME=1,PLLON=1
PLLCTL_PLLON = 1;
while(!CRGFLG_LOCK);
CLKSEL_PLLSEL = 1;
return;
}
//-----------------------------------------------------
/******************************************************************
*函数名:SCI_Init
*入口参数SCI0BD寄存器值
*出口参数: 无
*功能描述:使用SCI_Init,串行总线频率=时钟频率/(16*SCI0BDL)
*******************************************************************/
static void SCI_Init(int SCI0)
{
SCI0CR1 =0x00;
SCI0CR2 =0x2c; //enable Receive Full Interrupt,RX enable,Tx enable
SCI0BD =SCI0; //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
}
//-----------------------------------------------------
/******************************************************************
*函数名:Sci0Tx
*入口参数SCI0DRL寄存器值
*出口参数: 无
*功能描述: 发送串口数据
*******************************************************************/
void Sci0Tx(unsigned char text)
{
unsigned char temp;
temp=SCI0SR1; /*clear flag*/
//发送前判断SC0DR是否处于忙状态。SC0DR.7=0:处于忙状态
while (!SCI0SR1_TDRE); /* wait for output buffer empty */
while(!SCI0SR1_TC); //等待数据发送结束
SCI0DRH=0;
SCI0DRL=text;
}
//-----------------------------------------------------
/******************************************************************
*函数名:Sci0Rx
*入口参数无
*出口参数: 串口数据
*功能描述: 接收串口数据
*******************************************************************/
byte Sci0Rx(void)
{
byte result,temp;
temp=SCI0SR1; /*clear flag*/
if((temp&0x20)>0)
result=SCI0DRL;
return result;
}
//-----------------------------------------------------
/******************************************************************
*函数名:PWM_Init
*入口参数无
*出口参数: 无
*功能描述: 脉宽调制初始化( BUS_CLOCK=80M ),1口马达,6口舵机
*******************************************************************/
void PWM_Init(void) {
PWME=0x00; //禁止PWM模块
PWMCAE=0x00; //全部左对齐输出
PWMPOL=0xFF; //全部为先输出高电平再输出低电平
PWMCLK=0xFF; //01级联-马达,6-舵机预分频
//其中CLOCK A或CLOCK SA控制0,1,4,5通道的PWM,CLOCK B或CLOCK SB控制2,3,6,7通道的PWM
PWMPRCLK=0x22; //CLOCK SA与CLOCK SB都进行4分频
//设置频率A=bus clock/4=20MHz,B=bus clock/4=20MHz
PWMSCLA=0x01; //CLOCK SA进行10分频,即20MHZ/2/1=10MHZ
PWMSCLB=0x05; //CLOCK SB进行10分频,即20MHZ/2/5=2MHZ
PWMCTL_CON01=1; //01级联
PWMPER01=2500; //输出频率的算法:SA clock/2500=4KHz;
PWMDTY01=1250; //通道01初始化占空比50%
PWMPER6=2000; //输出频率的算法:SB clock/2000=100Hz;
PWMDTY6=1000; //通道6初始化占空比50%
PWME=0x22; //打开01,6通道(只需开通高位即可)
}
//-----------------------------------------------------
/******************************************************************
*函数名:PIT_Init
*入口参数无
*出口参数: 无
*功能描述: 时钟周期中断初始化程序
*******************************************************************/
void PIT_Init(void)
{
PITCFLMT_PITE=0; //关闭PIT
//微定时器的装载寄存器
PITMTLD0= 80-1;//8位定时器初值设定。80分频,在80MHzBusClock下,为0.1MHz,即10us=0.01ms
//PITMTLD1= 80-1;//8位定时器初值设定。80分频,在80MHzBusClock下,为0.1MHz,即10us=0.01ms
//PITMTLD1= 160-1;//8位定时器初值设定,160分频,在16MHz的总线时钟频率下,为0.1MHz,即1us=0.01ms
//定时器的装载寄存器
//中断定时基准时间设定
PITLD0 = SpeedInterrupt - 1 ;//16位定时器初值设定。PITTIME*0.01MS,定时1000 * 0.01ms = 10ms
PITLD1 = AdInterrupt - 1 ;//定时100*0.01ms = 1ms
PITCE_PCE0=1;//使能通道0
PITCE_PCE1=1;//使能通道0
PITMUX_PMUX0=0;//0:相应16位定时器与微时基0连接
PITMUX_PMUX1=0;//0:相应16位定时器与微时基0连接
//PITMUX_PMUX1=1;//1:相应16位定时器与微时基1连接
PITINTE_PINTE0=1;//开通PIT0定时器的溢出中断
PITINTE_PINTE1=1;//开通PIT1定时器的溢出中断
PITCFLMT_PITE=1; //使能PIT
}
//-----------------------------------------------------
/******************************************************************
*函数名:ECT_Init
*入口参数无
*出口参数: 无
*功能描述: 脉冲累加计数,PTT7口,电路接法:需要上拉电阻5.1千欧姆
*******************************************************************/
void ECT_Init(void)
{
TSCR1 = 0x00; //禁止时钟
TIOS = 0x7f; //设置通道7为输入捕捉功能
PACTL=0x50;
PACNT=0x00;
TSCR2 = 0x00;
TCTL3 = 0x40; //设置通道7上升沿捕捉
TSCR1=0x80; //允许时钟计数
}
//-----------------------------------------------------
/******************************************************************
*函数名:AD_Init
*入口参数无
*出口参数: 无
*功能描述: AD模块转换程序
*******************************************************************/
void AD_init()
{
ATD0CTL1=0b00000000; // 8位转换
//ATD0CTL1=0b00100000; // 10位转换
//ATD0CTL1=0b01000000; // 12位转换
ATD0CTL2=0x40; //上电,标志位快速清零,忽略外部触发,中断禁止。
ATD0CTL3 = 0b10101000; //转换序列长度为7,结果寄存器数据右对齐
//S8C S4C S2C S1C 转换序列长度
// 0 0 0 0 8 ATD0CTL3 = ob10000000
// 0 0 0 1 1 ATD0CTL3 = ob10001000
// 0 0 1 0 2 ATD0CTL3 = ob10010000
// 0 0 1 1 3 ATD0CTL3 = ob10011000
// 0 1 0 0 4 ATD0CTL3 = ob10100000
// 0 1 0 1 5 ATD0CTL3 = ob10101000
// 0 1 1 0 6 ATD0CTL3 = ob10110000
// 0 1 1 1 7 ATD0CTL3 = ob10111000
// 1 x x x 8 ATD0CTL3 = ob11xxx000
ATD0CTL4=0x44; // 采样周期个数为8, A/D Clocks= 80M / 2*(4+1) = 8M
//SMP2 SMP1 SMP0 PRS4 PRS3 PRS2 PRS1 PRS0
//SMP2 SMP1 SMP0 PS,DG128的第七位为SRES8
// 0 0 0 采样周期个数为4
// 0 0 1 采样周期个数为6
// 0 1 0 采样周期个数为8
// 0 1 1 采样周期个数为10
// 1 0 0 采样周期个数为12
// 1 0 1 采样周期个数为16
// 1 1 0 采样周期个数为20
// 1 1 1 采样周期个数为24
//ATDCLK = BUSCLK / ( 2 * ( PRS + 1 ) )
//AD时钟分频,设置预分频因子时,应使ATDCLK不小于0.25MHz,同时不大于8.3MHz。
ATD0CTL5 = 0b00110000; //0 SC SCAN MULT | CD CC CB CA
//6:0特殊通道禁止,5:1连续转换,4:1多通道轮流采样
ATD0DIEN=0x00; //禁止数字输入
}
//-----------------------------------------------------
/******************************************************************
*函数名:Read_ad
*入口参数无
*出口参数: 无
*功能描述: 读取AD采样数据,简单平均值滤波,3次平均值
*******************************************************************/
void Read_ad(void)
{
int ad_temp[5][3]={0}; //AD临时采样存储
int i;
for(i=0; i<=2; i++) //采集3次
{
while(!ATD0STAT2_CCF0); //等待转换结束
ad_temp[0][i] = ATD0DR0; //读取转换的结果
while(!ATD0STAT2_CCF1); //等待转换结束
ad_temp[1][i] = ATD0DR1; //读取转换的结果
while(!ATD0STAT2_CCF2); //等待转换结束
ad_temp[2][i] = ATD0DR2; //读取转换的结果
while(!ATD0STAT2_CCF3); //等待转换结束
ad_temp[3][i] = ATD0DR3; //读取转换的结果
while(!ATD0STAT2_CCF4); //等待转换结束
ad_temp[4][i] = ATD0DR4; //读取转换的结果
//while(!ATD0STAT2_CCF5); //等待转换结束
//ad_temp[5][i] = ATD0DR5; //读取转换的结果
//while(!ATD0STAT2_CCF6); //等待转换结束
//ad_temp[6][i] = ATD0DR6; //读取转换的结果
}
//计算平均值
for(i=0; i<=4; i++)
{
sensor_ad[i] = (ad_temp[i][0] +
ad_temp[i][1] +
ad_temp[i][2]) /3 ;
}
//适当的滤波
}
//-----------------------------------------------------
/******************************************************************
*函数名:ALL_Init
*入口参数无
*出口参数: 无
*功能描述: 全部初始化函数
*******************************************************************/
void ALL_Init(void) {
PLL_Init(SynrDefine,RefdvDefine); //PLL总线初始化
SCI_Init(SciDefine); //串口初始化
PWM_Init(); //PWM脉宽初始化
PIT_Init(); //PIT时钟周期中断初始化
ECT_Init(); //ECT脉冲累加器初始化
AD_init(); //AD采样初始化
Sci0Tx('w');
Sci0Tx('a');
Sci0Tx('i');
Sci0Tx('t');
Wait_Time(WAITTIME); //启动延时
Sci0Tx('r');
Sci0Tx('u');
Sci0Tx('n');
}
//-----------------------------------------------------
/******************************************************************
*函数名:main
*入口参数无
*出口参数: 无
*功能描述: 主函数
*******************************************************************/
void main(void) {
//初始化
/* put your own code here */
ALL_Init(); //系统初始化
EnableInterrupts; //允许中断
for(;;)
{
Sci0Tx(sensor_ad[0]);
_FEED_COP(); //定时喂看门狗
}
}
//-----------------------------------------------------
/******************************************************************
*函数名:PIT0
*入口参数无
*出口参数: 无
*功能描述: 中断测速函数,速度为全局变量SPEED_NOW
*******************************************************************/
#pragma CODE_SEG __NEAR_SEG NON_BANKED //指示该程序在不分页区
void interrupt 66 PIT0(void)
{
//相应代码
DisableInterrupts;
PITTF=0x01; //清中断标志位
SpeedNow=PACNT; //获取车速
PACNT=0; //编码器计数重置
EnableInterrupts;
}
#pragma CODE_SEG DEFAULT
//-----------------------------------------------------
/******************************************************************
*函数名:PIT1
*入口参数无
*出口参数: 无
*功能描述: 后台AD处理程序
*******************************************************************/
#pragma CODE_SEG __NEAR_SEG NON_BANKED //指示该程序在不分页区
void interrupt 67 PIT1(void)
{
//相应代码
DisableInterrupts;
PITTF=0x02; //清中断标志位
Read_ad(); //读取AD结果
EnableInterrupts;
}
#pragma CODE_SEG DEFAULT
//-----------------------------------------------------