飞思卡尔XS128的基本模板程序

本文详细介绍了微控制器系统的初始化过程,包括时钟频率设置、串口通信、PWM脉宽调制、中断处理等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/********************************************** 
*   徐方鑫    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  

//----------------------------------------------------- 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值