智能车制作

标题: 关于用脉冲累加器测量电机速度的程序 [打印本页]

作者: 小瓶子    时间: 2013-10-13 14:28
标题: 关于用脉冲累加器测量电机速度的程序
本帖最后由 小瓶子 于 2013-10-13 14:38 编辑

下面这个程序是我编来测电机速度的   ,但是就是PACNT的值就是一直为0,这是为什么求指教,个人觉得应该是脉冲累加器初始化不对   但是不知道哪里的问题。


#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */
#include"Init.h"
//完成PLL初始化
//功能:设置总线频率为16MHZ,晶振频率为16MHZ
void SetBusCLK_16M(void)
{
   CLKSEL_PLLSEL=0;//不使能锁相环时钟
                                    //CLKSEL_PLLSEL=0表示系统时钟Fbus=Fosc/2
                                   //PLLSEL=0只有这样才能设置锁相环的寄存器
   PLLCTL_PLLON=1;//锁相环电路允许 , PLLCTL_PLLON=1启动锁相环
   SYNR=0X43;//相当于SYNR=0100 0011 代表VCO时钟频率范围在48~80MHZ  Fvco=64MHZ
   REFDV=0X81;//相当于REFDV=1000 0001 代表参考时钟频率在6~12MHZ
                              //Fref=Fosc/(REFDV+1)  =16/(1+1)=8
   POSTDIV=0X01;//0000 0001   即Fpll=Fvco/(2*1)=32MHZ
                              //即Fbus= Fpll/2=32MHZ/2=16MHZ
   _asm(nop);//短暂延时,等待时钟频率稳定
   _asm(nop);//短暂延时,等待时钟频率稳定
   while(CRGFLG_LOCK!=1);//CRGFLG_LOCK=1表示时钟频率已经稳定,锁相环锁定
   CLKSEL_PLLSEL=1;//使能锁相环时钟,CLKSEL_PLLSEL=1表示Fbus=Fpll/2
}                                
/*//功能:设置总线频率为40MHZ,晶振频率为16MHZ
void SetBusCLK_16M(void)
{
   CLKSEL_PLLSEL=0;//不使能锁相环时钟
                                    //CLKSEL_PLLSEL=0表示系统时钟Fbus=Fosc/2
                                   //PLLSEL=0只有这样才能设置锁相环的寄存器
   PLLCTL_PLLON=1;//锁相环电路允许 , PLLCTL_PLLON=1启动锁相环
   SYNR=0X44;//相当于SYNR=0100 0100 代表VCO时钟频率范围在48~80MHZ  Fvco=80MHZ
   REFDV=0X81;//相当于REFDV=1000 0001 代表参考时钟频率在6~12MHZ
                              //Fref=Fosc/(REFDV+1)  =16/(1+1)=8
   POSTDIV=0X00;//0000 0000   即Fpll=Fvco=80MHZ
   _asm(nop);//短暂延时,等待时钟频率稳定
   _asm(nop);//短暂延时,等待时钟频率稳定
   while(CRGFLG_LOCK!=1);//CRGFLG_LOCK=1表示时钟频率已经稳定,锁相环锁定
   CLKSEL_PLLSEL=1;//使能锁相环时钟,CLKSEL_PLLSEL=1表示Fbus=Fpll/2
}   */


/***************************全桥(2个芯片)**************************************/
//PWM初始化
//  控制线为pwm1,是由通道0和通道1级联组成的,一开始通道1占空比为0%
void PWM_Init(void)
{   
    PWME=0x00;      //PWM使能寄存器,禁止PWM模块通道0和通道1
    PWMCTL_CON01=1;  //通道0和通道1级联,由通道1控制所有
    PWMCAE_CAE1=0;    //选择通道1输出模式为左对齐输出模式
    PWMPOL_PPOL1=1;  //通道1先输出高电平,计数到DTY时,反转为低电平

    PWMPRCLK=0X04;  //clockA是16分频,clockA=busclock/16=1MHz;                                   
    PWMSCLA=20;           //对clock A 进行2*20=40分频;pwm clockSA=clockA/40=25KHz;  
    PWMCLK_PCLK1=1; //通道1选择clock SA做时钟源

    PWMPER01=500; //周期20ms; 1/25KHZ=0.04ms
                                      //左对齐输出时,PWM周期=通道时钟周期*PWMPER=1/ 25KHz*500=20ms
                                      //左对齐时,占空比=1-(PWMPER-PWMDTY)/PWMPER
                                                                        //=PWMDTY/PWMPER
    PWMDTY01=0;      //通道1占空比初始化为0即全部为低电平,
                                        //该寄存器中的数值代表高电平持续时间  
    //    PWME_PWME1=1;    //开启PWM通道1  ,后面函数中有定义      
}

///////编码器模块,用脉冲累加器测速///////////////
///////////////////////////////////////////////////////
/*光电编码器只能用PWM7口*/
/*void PACN_init(void)
{
    PACTL_PAEN = 0;          //关闭脉冲累加器 (16位脉冲累加器)
    PACNT = 0X0000;          //脉冲累加器寄存器清零
    PACTL_PAMOD = 0;         //0表示脉冲累加器为事件计数方式
    PACTL_PEDGE = 1;         //1表示对PT7引脚输入信号上升沿计数,上升沿计数方式
    PACTL_PAEN = 1;          //使能脉冲累加器     
}*/
void PACN_init(void)
{
    PACTL_PAEN=0;  // 关闭脉冲累加器
    TSCR1_TFFCA=1;     //快速清除flag:PAOVF和PAIF
                                                                //=1定时器系统控制寄存器1,对TCNT寄存器的 任何访问将清除标志位

    TIOS_IOS7=1;       //单独使用16位脉冲累加器
                                                                //定时器输入捕捉|输出比较选择寄存器,开启通道7用作输出比较功能

    OC7M_OC7M7=0;//注意此时必须令IOS7=1,OC7M7=0,OM7=0,OL7=0
                                                                //输出比较7屏蔽寄存器。=0表示通道n端口引脚不受通道7输出比较事件控制
                                                               
    TCTL1_OM7=0;        //定时器控制寄存器1
    TCTL1_OL7=0;         //与上语句组合起来功能是禁止比较

    PACTL_PAMOD=0;   //事件计数方式
                                                                        //16位脉冲累加器控制寄存器,=0表示脉冲累加器为事件计数方式
        PACTL_PEDGE=1;         //脉冲累加器边沿控制位,=1表示对上升沿计数

    PACNT  =  0x0000;          //脉冲累加器计数寄存器

    PACTL_PAEN=1;          //启动脉冲累加器A
                                                                                //16位脉冲累加器控制寄存器,=1表示允许脉冲累加器功能
}


///////PIT周期性中断定时器模块////////
/*初始化PIT,设置精确定时时间为1s*/
void PIT_init(void)
{
    PITCFLMT=0X00;  //禁止PIT模块
    PITCE_PCE0=1;     //使能定时器通道0
    PITMUX=0X00;    //定时器通道0使用微定时基准0

    PITLD0=0Xf423;  //设置16位装载寄存器0初值为62499
    PITMTLD0=0XFF;    //设置微定时器器装载寄存器,初值应该为255
                                  //超时周期= (PITMTLD+1)*(PITLD+1)/Fbus
                                   //             =(62499+1)*(255+1)/16M=1s
    PITINTE=0X01;     //使能PIT定时器通道0中断
    PITCFLMT=0X80; //使能PIT模块
}
/*******************电机速度控制函数,占空比越大速度越快******************/
void sudu(unsigned int a)        
{
       PWMDTY01=a;             //占空比调节,调节精度为0.04ms
  //     PWMCNT01=0X00;    //计数器清零,PWMCNT计数到PWMPER中的值时自动清零
                                            //从零开始做加法计数,直到增加到周期计数器 PWMPER的值
       PWME_PWME1=1;      //开启PWM通道1
}
//实现电机正反转
void PWM1_Init(unsigned char x,unsigned char y )
{
         DDRA_DDRA0=1;   //设置PA口第0位为输出口
         DDRA_DDRA1=1;   //设置PA口第1位为输出口
         PUCR_PUPAE=1;//设置PA口使用上拉电阻
         PORTA_PA0=x;      //数据寄存器
         PORTA_PA1=y;      //同上
}     





#include <hidef.h>      /* common defines and macros */#include "derivative.h"      /* derivative-specific definitions */
#include"Init.h"
int shuzhi;//用来装载脉冲累加器中的值
int PIT_Int_Flag=0;//判断进入main函数里if语句计算出电机转速
int speed;//speed是电机转速
void main(void)
{
  SetBusCLK_16M();  //设置总线频率为16M
  PWM_Init();       //完成PWM初始化
  sudu(30);          //设置电机为全速转动
  PWM1_Init(1,0);  //电机正转   
PACN_init();     // 脉冲累加器设置
PIT_init();    //周期性中断定时器模块设置
          EnableInterrupts;      //等待中断产生         
for(;;)      
{      
   if(PIT_Int_Flag==1)     
       {   PIT_Int_Flag=0;//标志位  
          speed=shuzhi/100;//speed是电机转速         
         EnableInterrupts;      
        }     
}
}  /****************pit定时器通道0中断服务子程序***********/
#pragma CODE_SEG __NEAR_SEG NON_BANKED//中断服务程序
//interrupt VectorNumber_Vpit0 void  PIT_ISR(void)//和下式等价
void interrupt 66  PIT_0(void)
{  
   DisableInterrupts;   
   PITTF_PTF0=1;  //发生中断后该标志位通过写 1清零  
   shuzhi=PACNT; //将脉冲累加器寄存器中的值赋值给一个变量shuzhi  
   PACNT=0;         //将脉冲累加器寄存器中的值清零,以等待下一次计算电机速度装值  
   PIT_Int_Flag=1;   // 一旦这个值为1就执行main程序,计算出100线编码器此时电机的转速
}
#pragma CODE_SEG DEFAULT   






补充内容 (2013-10-14 11:06):
问题已经解决是我将光电编码器插反了 ,这个程序是能用的。

作者: 小布的梦    时间: 2014-1-10 20:42
:):)
作者: mnh999    时间: 2014-3-8 18:17
:):)
作者: 武狂狼    时间: 2014-5-6 23:04
脉冲累加器用pwm7口?哪款单片机啊
作者: kisschen    时间: 2014-7-19 11:54
武狂狼 发表于 2014-5-6 23:04
脉冲累加器用pwm7口?哪款单片机啊

g12吧




欢迎光临 智能车制作 (http://dns.znczz.com/) Powered by Discuz! X3.2