照着原理图焊的,用stc12c5a60s2驱动的无刷电机,驱动芯片是ir2101,mos管是IRF540,通电后电机没反应,用手动转电机,万用表检测ir2101的两个输入引脚2.3会有5v,但输出567没信号,有时5引脚会有12v
/*************************************************************************
***************************/
#include "lcd1602.h"
#include "pid.h"
//开关管控制管脚
sbit AL=P1^0;
sbit AH=P1^1;
sbit BL=P1^2;
sbit BH=P1^3;
sbit CL=P1^2;
sbit CH=P1^3;
sbit HC=P3^7;//霍尔元件传感器C
sbit HB=P3^6;//霍尔元件传感器B
sbit HA=P3^5;//霍尔元件传感器A
//定义按键
sbit KEY_add=P2^0;//加速
sbit KEY_sub=P2^1;//减速
sbit KEY_reverse=P2^2;//正反转
/********************************变量定义********************************/
u8 fankui;//定义电机反馈输出信号
u8 cnt = 0;//定义比较器变量
bit dir_flag = 0;//定义电机方向标志位
bit direct = 0;//定义电机当前方向
int PWM = 0;//定义电机初始占空比
int PID_OUT = 0;//定义PID控制器输出
u16 speed = 100;//定义电机目标速度
u16 velocity;//定义电机实际速度
u16 T1_NUM;//T0长定时计数值
long int TIME_COUNT;//定义电机转圈(1圈)总计时
/********************************函数声明********************************/
void Timer0_Init(void);//定时器0初始化函数
void Timer1_Init(void);//定时器1初始化函数
void INT0_Init(void);//外部中断0初始化函数
void MotorControl(void);//电机控制函数
void keyscan(void);//定义按键扫描函数
void display(void);//液晶显示函数
/*************************************************************************
* 函数名称:main(void)
* 功能说明:主函数
* 参数说明:无
* 函数返回:无
* 备 注:无
*************************************************************************/
void main(void)
{
u8 count;//定义液晶刷新频率
Timer0_Init();//定时器0初始化
Timer1_Init();//定时器1初始化
INT0_Init();//外部中断0初始化
LCD1602_Init();//液晶初始化
LCD1602_Display_String(0x80,"exp:");
LCD1602_Display_String(0xc0,"cur:");
PidInit(&Motor_PID);//PID结构体初始化
SetPidCtr(&Motor_PID,1.2,0.001,0.1,10,100);//PID参数初始化
while(1)
{
count++;
if(count>100)//刷新显示
{
count = 0;
display();//显示
}
keyscan();//按键
fankui=((unsigned char)(HA)<<2) + ((unsigned char)(HB)<<1) + (unsigned char)(HC);//传感检测
PID_OUT = PidLocCtrl(&Motor_PID,speed-velocity);//位置式PID输出控制
if(PID_OUT<100&&PID_OUT>-100)//PID控制器输出限幅
{
PWM = PID_OUT;
}
else if(PID_OUT>=100)
{
PWM = 100;
}
else if(PID_OUT<=-100)
{
PWM = -100;
}
}
}
/*************************************************************************
* 函数名称:Timer0_Init(void)
* 功能说明:定时器0初始化函数
* 参数说明:无
* 函数返回:无
* 备 注:定时1ms
*************************************************************************/
void Timer0_Init(void)
{
TMOD=0x01; //使用定时器0方式1
TH0 = (65535-1000)/256; //1ms
TL0 = (65535-1000)%256;
ET0 = 1;//开启定时器0中断
TR0 = 1;//启动定时器0
EA = 1;//开全局中断
}
/*************************************************************************
* 函数名称:Timer1_Init(void)
* 功能说明:定时器1中断初始化函数
* 参数说明:无
* 函数返回:无
* 备 注:霍尔元件脉冲测速
*************************************************************************/
void Timer1_Init(void)
{
TMOD |= 0x10;//使用定时器1方式1
TH1 = 0;
TL1 = 0;
TR1 = 1;//启动定时器1
ET1 = 1;//开启定时器1中断
EA = 1;//开全局中断
}
/*************************************************************************
* 函数名称:INT0_Init(void)
* 功能说明:外部中断0初始化函数
* 参数说明:无
* 函数返回:无
* 备 注:检测霍尔元件脉冲
*************************************************************************/
void INT0_Init(void)
{
EA = 1;//开全局中断
EX0 = 1;//开启外部中断0中断
IT0 = 1;//下降沿触发
}
/*************************************************************************
* 函数名称:keyscan(void)
* 功能说明:按键扫描函数
* 参数说明:无
* 函数返回:无
* 备 注:无
*************************************************************************/
void keyscan(void)
{
if(!KEY_add)//加速
{
speed = speed>=500?500:speed+100;
while(!KEY_add);
}
if(!KEY_sub)//减速
{
speed = speed<=100?100:speed-100;
while(!KEY_sub);
}
if(!KEY_reverse)//正反转
{
dir_flag = ~dir_flag;
while(!KEY_reverse);
}
}
/*************************************************************************
* 函数名称:display(void)
* 功能说明:液晶显示函数
* 参数说明:无
* 函数返回:无
* 备 注:无
*************************************************************************/
void display(void)
{
//显示预期速度
LCD1602_Display_Char(0x84,speed/100+'0');
LCD1602_Display_Char(0x85,speed%100/10+'0');
LCD1602_Display_Char(0x86,speed%10+'0');
//显示实际速度
LCD1602_Display_Char(0xc4,velocity/100+'0');
LCD1602_Display_Char(0xc5,velocity%100/10+'0');
LCD1602_Display_Char(0xc6,velocity%10+'0');
//显示辅助调试变量
if(PWM<0)
{
LCD1602_Display_Char(0xca,'-');
LCD1602_Display_Char(0xcb,-PWM/100+'0');
LCD1602_Display_Char(0xcc,-PWM%100/10+'0');
LCD1602_Display_Char(0xcd,-PWM%10+'0');
}
else
{
LCD1602_Display_Char(0xca,'+');
LCD1602_Display_Char(0xcb,PWM/100+'0');
LCD1602_Display_Char(0xcc,PWM%100/10+'0');
LCD1602_Display_Char(0xcd,PWM%10+'0');
}
//显示方向
if(dir_flag==0)
{
LCD1602_Display_String(0x8a,"Pos");
}
else
{
LCD1602_Display_String(0x8a,"Neg");
}
}
/*************************************************************************
* 函数名称:Timer0_Int(void) interrupt 1
* 功能说明:定时器0中断服务程序
* 参数说明:无
* 函数返回:无
* 备 注:定时1ms
*************************************************************************/
void Timer0_Int(void) interrupt 1
{
TH0 = (65535-1000)/256;//重装初值
TL0 = (65535-1000)%256;
cnt++;
if(cnt == 100)
{
cnt = 0;
}
MotorControl();//电机控制
}
/*************************************************************************
* 函数名称:timer1_Int(void)
* 功能说明:定时器1中断函数
* 参数说明:无
* 函数返回:无
* 备 注:霍尔元件脉冲计时
*************************************************************************/
void timer1_Int(void) interrupt 3
{
TR1 = 0;
TH1 = 0;
TL1 = 0;
T1_NUM++;
TR1 = 1;
}
/*************************************************************************
* 函数名称:INT0_Int(void)
* 功能说明:外部中断0函数
* 参数说明:无
* 函数返回:无
* 备 注:霍尔元件测速,计算电机速度,1/(total_time*10^-6),
一个周期产生一个脉冲,通过检测下降沿周期来实现测速
*************************************************************************/
void INT0_Int(void) interrupt 0
{
TR1 = 0;
TIME_COUNT = TH1*256+TL1+T1_NUM*65536;//计算1转所用时间
T1_NUM = 0;
velocity = 60000000/TIME_COUNT;//折算成实际速度值
TH1 = 0;
TL1 = 0;
TR1 = 1;
}
/*************************************************************************
* 函数名称:MotorControl(void)
* 功能说明:电机控制函数
* 参数说明:无
* 函数返回:无
* 备 注:需要有电力电子基础
*************************************************************************/
void MotorControl(void)
{
if(PWM<0)//反接制动
{
direct = ~dir_flag;
}
else
{
direct = dir_flag;
}
if( cnt >= PWM )
{
if(!direct)//方向判断
{
switch(fankui)
{
case 0x06:AH=0;AL=0;BH=1;BL=0;CH=0;CL=0;break; //110
case 0x02:AH=0;AL=0;BH=0;BL=0;CH=1;CL=0;break; //010
case 0X03:AH=0;AL=0;BH=0;BL=0;CH=1;CL=0;break; //011
case 0x01:AH=0;AL=0;BH=0;BL=1;CH=0;CL=0;break; //001
case 0x05:AH=1;AL=0;BH=0;BL=0;CH=0;CL=0;break; //101
case 0x04:AH=0;AL=0;BH=0;BL=0;CH=0;CL=1;break; //100
default: AH=0;AL=0;BH=0;BL=0;CH=0;CL=0;break;
}
}
else
{
switch(fankui)//换向控制,同一时期两个开关管开通,换向时,需要有一个开关管保持状态不变
{
case 0x06:AH=0;AL=0;BH=0;BL=1;CH=0;CL=0;break;
case 0x02:AH=0;AL=0;BH=0;BL=0;CH=0;CL=1;break;
case 0X03:AH=0;AL=0;BH=0;BL=0;CH=0;CL=1;break;
case 0x01:AH=0;AL=0;BH=1;BL=0;CH=0;CL=0;break;
case 0x05:AH=0;AL=0;BH=0;BL=0;CH=1;CL=0;break;
case 0x04:AH=0;AL=0;BH=0;BL=0;CH=1;CL=0;break;
default: AH=0;AL=0;BH=0;BL=0;CH=0;CL=0;break;
}
}
}
else
{
if(!direct)//方向判断
{
switch(fankui)
{
case 0x06:AH=0;AL=1;BH=1;BL=0;CH=0;CL=0;break;
case 0x02:AH=0;AL=1;BH=0;BL=0;CH=1;CL=0;break;
case 0X03:AH=0;AL=0;BH=0;BL=1;CH=1;CL=0;break;
case 0x01:AH=1;AL=0;BH=0;BL=1;CH=0;CL=0;break;
case 0x05:AH=1;AL=0;BH=0;BL=0;CH=0;CL=1;break;
case 0x04:AH=0;AL=0;BH=1;BL=0;CH=0;CL=1;break;
default: break;
}
}
else
{
switch(fankui)//换向控制,同一时期两个开关管开通,换向时,需要有一个开关管保持状态不变
{
case 0x06:AH=1;AL=0;BH=0;BL=1;CH=0;CL=0;break;
case 0x02:AH=1;AL=0;BH=0;BL=0;CH=0;CL=1;break;
case 0X03:AH=0;AL=0;BH=1;BL=0;CH=0;CL=1;break;
case 0x01:AH=0;AL=1;BH=1;BL=0;CH=0;CL=0;break;
case 0x05:AH=0;AL=1;BH=0;BL=0;CH=1;CL=0;break;
case 0x04:AH=0;AL=0;BH=0;BL=1;CH=1;CL=0;break;
default: break;
}
}
}
}
根据您提供的信息,您使用的是STC12C5A60S2单片机驱动一个无刷电机,使用IR2101作为驱动芯片,IRF540作为MOS管。您遇到的问题是电机没有反应,检测IR2101的输入引脚2和3为5V,但输出引脚5、6和7没有信号,有时候引脚5会有12V。以下是一些可能的解决方案和排查步骤:
检查电源和接地:确保电机供电稳定,并且单片机的地和电机的地连接在一起。
检查驱动信号:使用示波器或逻辑分析仪检查IR2101的输出引脚(5、6和7)是否产生预期的驱动信号。如果没有信号,请检查引脚的连接是否正确,并确保IR2101的控制信号正确配置。
检查MOS管连接:确保IRF540的引脚正确连接到电机,并且根据IR2101的数据表设置合适的电源电压和电流限制。
检查霍尔元件传感器:确保霍尔元件传感器(HA、HB和HC)连接正确,并且在转动电机时能够正确检测到脉冲信号。您可以使用示波器或逻辑分析仪检查这些信号。
检查电机连接:确保电机的三个相线正确连接到驱动器的输出引脚,并且相序正确。如果相序颠倒,电机将无法正常工作。
检查程序逻辑:检查程序中的控制逻辑,确保正确配置和使用了正确的引脚和寄存器设置。
如果按照上述步骤检查仍然没有解决问题,您可能需要进一步调试和排除故障。可以尝试使用调试工具如示波器、逻辑分析仪或调试器,逐步检查信号和电路的运行情况,以确定具体的问题所在。
以下答案由GPT-4.0Plus大模型与博主A努力中.......共同编写:
可能是驱动芯片IR2101的输出部分出现了故障导致电机无反应。有几个可能的原因:
综上,首先应Checking以下几点:
如果以上检查都正常但问题仍未解决,则IR2101内部可能存在故障,需要更换芯片。