智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 5102|回复: 4
打印 上一主题 下一主题

[电磁] 关于用脉冲累加器测量电机速度的程序

[复制链接]

7

主题

54

帖子

0

精华

高级会员

Rank: 4

积分
830
威望
428
贡献
240
兑换币
261
注册时间
2012-12-13
在线时间
81 小时
跳转到指定楼层
1#
发表于 2013-10-13 14:28:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
5贡献
本帖最后由 小瓶子 于 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):
问题已经解决是我将光电编码器插反了 ,这个程序是能用的。

6

主题

673

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2357

优秀会员奖章活跃会员奖章

QQ
威望
1073
贡献
634
兑换币
740
注册时间
2013-7-5
在线时间
325 小时
2#
发表于 2014-1-10 20:42:38 | 只看该作者
:):)
回复

使用道具 举报

0

主题

61

帖子

0

精华

高级会员

Rank: 4

积分
623
威望
302
贡献
165
兑换币
209
注册时间
2013-11-10
在线时间
78 小时
3#
发表于 2014-3-8 18:17:57 | 只看该作者
:):)
回复

使用道具 举报

4

主题

71

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
400
威望
205
贡献
133
兑换币
132
注册时间
2013-5-10
在线时间
31 小时
毕业学校
鲁南大学
4#
发表于 2014-5-6 23:04:09 | 只看该作者
脉冲累加器用pwm7口?哪款单片机啊
回复

使用道具 举报

12

主题

42

帖子

0

精华

高级会员

Rank: 4

积分
721
威望
384
贡献
177
兑换币
236
注册时间
2013-9-13
在线时间
80 小时
5#
发表于 2014-7-19 11:54:08 | 只看该作者
武狂狼 发表于 2014-5-6 23:04
脉冲累加器用pwm7口?哪款单片机啊

g12吧
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关于我们|联系我们|小黑屋|智能车制作 ( 黑ICP备2022002344号

GMT+8, 2024-6-2 23:58 , Processed in 0.087899 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表