📄 bldc.c
字号:
/*;========================================================================*
* File name : bldc.c *
* Author: Davidlee *
* Data: 2007.05.17*
* Version: 2.0 *
* Organization: Tianhuang Technology Co.ltd
* Description : Brushless DC motor drive using TMS320LF2407.SCI communication
* uses to control the Brushless DC motor's running direction.Also, the
* potentiometer in "A/D conversional unit" uses to control the Brushless
* DC motor's rotating speed.
;==========================================================================*
*/
#include "F2407_c.H" //the header file
asm(" .word #0ffffh ");
asm(" .word #0ffffh ");
asm(" .word #0ffffh ");
asm(" .word #0ffffh ");
void system_init();
void EVA_init();
void SCI_init();
void ADC_init();
void KICK_DOG();
void rising1();
void falling1();
void rising2();
void falling2();
void rising3();
void falling3();
unsigned int read_phase(); //读相位控制字
void interrupt nothing();
void interrupt EVA_timer1_isr();
void interrupt SCI_INT();
int temp1,temp2,i,j;
unsigned int IntCount;
unsigned int AD[8];
unsigned int sum;
unsigned int cmpr;
unsigned int phase;
unsigned int direction;
unsigned int flag;
unsigned int ph_data;
main()
{ system_init();
EVA_init();
SCI_init();
ADC_init();
IntCount=0x0;
direction=1;
cmpr=500;
while(1)
{ phase=read_phase();
if(cmpr<30)
cmpr=0; //AD采样最小值时停掉电机
if(direction==0) //反转(顺时针)
switch(phase)
{
case 1:rising2() ;break;
case 2:falling2();break;
case 3:falling1();break;
case 4:rising1() ;break;
case 5:falling3();break;
case 6:rising3() ;break;
default:break;
}
else //正转(逆时针)
switch(phase)
{
case 1:rising3() ;break;
case 2:falling3();break;
case 3:rising1() ;break;
case 4:falling1();break;
case 5:falling2();break;
case 6:rising2() ;break;
default:break;
}
}
}
void system_init() /*系统初始化子程序*/
{
asm(" SETC INTM"); //屏蔽中断
asm(" CLRC SXM "); //符号位不作扩展
asm(" SETC OVM "); //正常溢出
asm(" CLRC CNF "); //B0设置为数据存储区
temp1=0x0;
asm(" OUT _temp1,0FFFFh "); //设置整体延时为0
SCSR1=0x0FC; //使能ADC,SCI,SPI,CAN,EVB,EVA时钟
WDCR=0x6F;
KICK_DOG(); //看门狗不使能
IFR=0x0FFFF; //清除全部中断标志,"写1清0"
IMR=0x012;
MCRA=0xFFC3; //设置复用口SCITXD,SCIRXD,PWM1~PWM6为普通功能口 IOPA3,IOPA4,IOPA5为I/O管脚
MCRB=0xFFFD; //设置仿真口
PADATDIR=0x0; //所有I/O口均置为输入状态
PBDATDIR=0x0;
PCDATDIR=0x0;
PDDATDIR=0x0;
PEDATDIR=0x0;
PFDATDIR=0x0;
temp2=0x0FFFF;
asm(" OUT _temp2,2000H");
asm(" OUT _temp2,6000H");
}
void EVA_init() /*EVA初始化子程序,T1作为全局定时器,定时周期20us,晶振20MHz*/
{
EVAIMRA=0x100;
EVAIMRB=0x0;
EVAIMRC=0x0;
EVAIFRA=0xFFFF;
EVAIFRB=0xFFFF;
EVAIFRC=0xFFFF;
GPTCONA=0x41;
T1CON=0x1046;
T1PR=0x470;
T2PR=0x0;
T1CNT=0x0;
T2CNT=0x0;
CMPR1=0x400;
CMPR2=0x400;
CMPR3=0x100;
COMCONA=0xAE00;
ACTRA=0x999;
DBTCONA=0xFE0;
ACTRA=0xFE3;
asm(" CLRC INTM"); //允许中断
}
void SCI_init() /*SCI通信初始化子程序*/
{
SCICCR=0x27;
SCICTL2=0x2;
SCIHBAUD=0x0;
SCILBAUD=0x2A;
SCIPRI=0x20;
SCICTL1=0x23;
}
void ADC_init() /*A/D转换初始化子程序*/
{
ADCTRL1=0x4000;
ADCTRL1=0x3000;
MAX_CONV=0x7;
CHSELSEQ1=0x3333;
CHSELSEQ2=0x3333;
ADCTRL2=0x4000;
}
void KICK_DOG() /*复位看门狗密钥*/
{
WDKEY=0x5555;
WDKEY=0xAAAA;
}
void rising1()
{
ACTRA=0xF3E;
CMPR1=cmpr;
CMPR2=cmpr;
CMPR3=0;
}
void falling1()
{
ACTRA=0xFE3;
CMPR1=cmpr;
CMPR2=cmpr;
CMPR3=0;
}
void rising2()
{
ACTRA=0x3EF;
CMPR2=cmpr;
CMPR3=cmpr;
CMPR1=0;
}
void falling2()
{
ACTRA=0xEF3;
CMPR1=cmpr;
CMPR3=cmpr;
CMPR2=0;
}
void rising3()
{
ACTRA=0xE3F;
CMPR2=cmpr;
CMPR3=cmpr;
CMPR1=0;
}
void falling3()
{
ACTRA=0x3FE;
CMPR1=cmpr;
CMPR3=cmpr;
CMPR2=0;
}
unsigned int read_phase()
{
MCRA=0xFFC3;
PADATDIR=0xC700;
ph_data=(PADATDIR>>3)&0x7;
return(ph_data);
}
//=======================================================
//该中断服务程序主要是为了防止干扰,不作任何其他操作
//=======================================================
void interrupt nothing()
{
return; //中断直接返回
}
//=======================================================
//定时器比较中断1,AD转换改变PWM脉冲占空比,从而改变电机的转速
//=======================================================
void interrupt EVA_timer1_isr()
{
IntCount++;
if(IntCount>10)
{
ADCTRL2=0x4000; //软件启动A/D转换
ADCTRL2=0x2000;
IntCount=0;
loop: if(j==1)
{j=ADCTRL2&0x8; //等待AD转换完成
goto loop;
}
asm(" CLRC SXM ");
AD[0]=RESULT0>>6; //把AD转换的结果右移6位后存入规定的数组
AD[1]=RESULT1>>6;
AD[2]=RESULT2>>6;
AD[3]=RESULT3>>6;
AD[4]=RESULT4>>6;
AD[5]=RESULT5>>6;
AD[6]=RESULT6>>6;
AD[7]=RESULT7>>6;
for(i=0;i<8;i++)
{
sum=sum+AD[i];
}
cmpr=sum>>3; //取8次采样的平均值
sum=0;
}
EVAIMRA=0x100;
EVAIFRA=0xFFFF; //清除定时器1周期中断标志
asm(" CLRC INTM");
}
//=======================================================
//SCI通信,上位机发送55或AA控制电机转向
//=======================================================
void interrupt SCI_INT()
{ // int j;
j=SCIRXBUF&0xFF;
if(j==0xAA)
{
direction = 1; //正转(逆时针)
}
else if(j==0x55)
{
direction = 0; //反转(顺时针)
}
else
{
asm(" CLRC INTM ");
return;
}
IFR=0xFFFF;
asm(" CLRC INTM ");
}
//=======================================================
//结束
//=======================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -