⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pwm.c

📁 基于TMS320LF2407A的PWM波产生的PID算法实现
💻 C
字号:
#include  "LF2407REGS.h" 
#include  "pid.c" 

#define PWMT 1000	 			 //PWM周期,50us,50/(1/(4*10)*2)
#define NMAX 3000                //电机最高转速,r/min
#define SPER 100            	 //100个PWM周期速度调节一次
#define S_K  2341                //Q12
#define N_K  10
unsigned long int i=0;
void inline disable() 
{
	asm(" setc INTM");
}
void inline enable()
{
	asm(" clrc INTM"); 
}
void initial()
{
  	asm(" setc	SXM");			// 符号位扩展有效
	asm(" clrc	OVM");			// 累加器中结果正常溢出
	asm(" clrc	CNF");			// B0被配置为数据存储空间
	SCSR1=0x81FE;		    	// CLKIN=10M,CLKOUT=4*CLKIN=40M
	WDCR=0x0E8;				// 不使能看门狗,因为SCSR2中的WDOVERRIDE
		     					// 即WD?の桓次缓蟮娜笔≈滴?,故可以用
		     					// 软件禁止看门狗
	IMR=0x0000;					// 禁止所有中断
	IFR=0x0FFFF;				// 清除全部中断标志,"写1清0"
	WSGR=0X00;					// 禁止所有的等待状态

}
void	interrupt nothing()
{
	return;						// 中断直接返回
}
//        给定 ,P  ,I  D,
	PID	n_pid = {0,20000,0,0,0,0,0,200,3500,1638400,-1638400},
	p_pid = {4020,400,0,0,0,0,0,0,2500,14336000,-14336000};

int	encincr,encoderold=0,speedtmp=0,direction=1;
int  temp = 0;
int speedstep=10;

 int n_in=0;
long int n_out = 0;
	 int change=0;
long int sum_plus = 0;
long int s_in = 0;
long int s_out = 0;
	 int flag2 = 10;
	 int positionstep = 10;
long int p_out = 0;
void main(void)
{
	disable();						// 总中断禁止
	initial();						// 系统初始化
	
	T2PER = 0XFFFF;                //最大周期
	T2CNT = 0X0000;
	T2CON = 0X9870;                //定向增减,允许编码接口
	T1PER = PWMT;					//PWM设置,周期50微秒,2*500*(1/20)us
	T1CNT = 0X0000;
	ACTRA = 0x0099;//0X0096;//01101001      //PWM1,4高有效,2,3低有效
	DBTCONA = 0X01F4;              //死区1.6微秒,死区定时周期1个(X/32),0.05*32=1.56us
	CMPR1 = PWMT*0.9;      		   //占空比0.5,500*0.5,(还可以增加实现6个pwm)
	CMPR2 = PWMT*0.5;               
	COMCONA = 0X8200;              //允许比较,T1下溢重载
	T1CON = 0X0840;                //连续增减计数,内部时钟,不分频

	MCRA = 0X03D8;                 //引脚设置为PWM1-4,QEP1-2
	IMR = 0X0002;                  //允许INT6中断
	IFR = 0X0000;                  //清标志
	EVAIFRA = 0Xffff;              //应写1清除
	EVAIFRB = 0X0000;
	EVAIFRC = 0X0000;
	EVAIMRA = 0X0000;
	EVAIMRB = 0X0000;
	EVAIMRC = 0X0000;
	
	EVAIMRA=EVAIMRA|0X0080;	// 允许定时器1的周期中断
	EVAIFRA=EVAIFRA&0X0080;	// 清除定时器1周期中断标志
	MCRA=MCRA&0Xdfff;  //IOPB5,对SN74LVC4245输出使能
	PBDATDIR=PBDATDIR|0X2000;
	PBDATDIR=PBDATDIR&0Xffdf;
	
	enable();

	while(1)
	{
		;		
	}
}

void interrupt timer(void)
{
	EVAIFRA = EVAIFRA;
	if (--speedstep)
	{
	 	return;
	}
	else{
		temp 	= T2CNT;
		T2CNT = 0;
		speedtmp += temp;                    //编码脉冲累计
		speedstep = SPER;
		}
	n_in = temp;
	n_out = PIDCalc ( &n_pid,n_in);
	n_out = n_out>>12;
	change = n_out; 
	change = change + 500;
	if(change>960)
		change = 960;
	else if(change<=0)
		change = 0;
	CMPR2 = change;                    //更新占空比
	CMPR1 = change;
	
	//位置控制
	if (--positionstep)		return;
	positionstep = 10;
	
	p_out = PIDCalc ( &p_pid,speedtmp);
	p_out = p_out>>12;
	change = p_out;
	if(change>400)
		change = 400;
	else if(change<-400)
		change = -400;
	n_pid.SetPoint = change;
	return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -