高级会员
- 积分
- 830
- 威望
- 428
- 贡献
- 240
- 兑换币
- 261
- 注册时间
- 2012-12-13
- 在线时间
- 81 小时
|
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):
问题已经解决是我将光电编码器插反了 ,这个程序是能用的。
|
|