求51单片机控制无刷直流电机的例程,新人求助

求51单片机控制无刷直流电机的例程,新人求助,第1张

#include <reg52.h> // 引用标准库的头文件

#include <intrins.h>

#define uchar unsigned char

#define uint unsigned int

//=================电机驱动=====================

sbitdianji_r = P1^0 //右边电机控制口,低电平转?

sbitdianji_l = P1^3 //左边电机控制口,低电平转

//=============循迹感应接口======================

sbitxjmk_r=P3^2// 右边hall模块检测口 INT0

sbitxjmk_l =P3^3// 左边hall模块检测口 INT1

voidcheck_righet()//右边时候检测到stop测试程序

voidcheck_left()//左边时候检测到stop测试程序

void delay_50us(uint t)

void delayms(uint Ms)

uchar r_count//右边传感器检测到的次数计数单元

uchar l_count

uint time

//***********************主程序******************************

main()

{

time=50 dianji_r=0//上电时右侧电机运行

dianji_l=0//上电时左侧电机运行EA=1

EX1=1

EX0=1

IT1=0

IT0=0

xjmk_r=1//置IO为1,准备读取数据

xjmk_l=1

_nop_()

r_count=0

l_count=0

while(1)

{

_nop_()

// check_righet()//调用右边hall检测传感器

// check_left()//

if(r_count>=1)

{

delayms(time)

dianji_r=0

dianji_l=0

r_count=0

_nop_()

}

if(l_count>=1)

{

delayms(time)

dianji_r=0

dianji_l=0

l_count=0

_nop_()

}

}

}

void init0int() interrupt 2

{

l_count=5

dianji_l=1

dianji_r=0

if(r_count>0)

{ EX0=0

delayms(20)

if(time>=20)time-=19

EX0=0

}

return

}

void init1int() interrupt 0

{

r_count=5

dianji_r=1 dianji_l=0

if(l_count>0)

{ EX1=0

delayms(20)

if(time>=20)time-=19

EX1=1}

return } //*******************************************************************************

//函数名称:

//功能:左边边时候检测到stop测试程序

voidcheck_left()

{

if(xjmk_l==0)//检测右边的传感器是否感应到stop

{ delay_50us(1)//延时,去除机械振动

_nop_() if(xjmk_l==0)//再次检测

{ delay_50us(1)//延时,去除机械振动

if(xjmk_l==0) {

l_count++

xjmk_l=1 }

}

}

} //******************************************************************************* //函数名称:

//功能:右边时候检测到stop测试程序

voidcheck_righet()

{

if(xjmk_r==0)//检测右边的传感器是否感应到stop {

delay_50us(1)//延时,去除机械振动

if(xjmk_r==0)//再次检测

{

delay_50us(1)//延时,去除机械振动 if(xjmk_r==0)

{

r_count++

xjmk_r=1

}

}

}

//*******************************************************************************

//函数名称:void delay_50US(unsigned int t)

//功能:延时50*t(us)

void delay_50us(uint t)

{

uchar j

for(t>0t--)

{

for(j=19j>0j--)

}

}

/*====================================================================

设定延时时间:x*1ms ====================================================================*/

void delayms(uint Ms)

{

uint i,TempCyc

for(i=0i<Msi++)

{

TempCyc =70

while(TempCyc--)

}

}

这个是完整的程序哦,建议你别用51,过时了,有些功能还有焊接扩展电路麻烦....

用AVR的吧

另外下面的程序是获奖的大学生电子设计作品一等奖呢,电路就不给了,要不你那就没啥意思了,快毕业了就点,有好处

#include<iom16v.h>

#include<macros.h>

#define uchar unsigned char

#define uint unsigned int

uchar senserflag=0//传感器状态标志

uchar count1=0

uchar jsflag=0//金属标志

uchar task=1 //任务标志

uint distancedata=0//路程值

uint distancecount=0//路程脉冲记数

//数码管字型表,对应0,1,2,3,4,5,6,7,8,9//#pragma data:code

#pragma data:code

const uchar Table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}

#pragma data:data

static uchar Data[3]={0,0,0} //显示初始值:0 0 0

uchar CNT=0 //初始计数值:0

uchar Timer[2]={1,10} //初始时间00:00

uchar disdata[3]={0,0,0}//路程初值0

//********************T/C0中断服务函数********************//

#pragma interrupt_handler Timer0:10

void Timer0(void)

{TCNT0=0x06

CNT++ //中断次数累加

if(CNT==125)

{CNT=0 //计数到125次,计数值复位

Timer[1]-- //秒加1

if(Timer[1]==255)

{Timer[1]=59

Timer[0]--} //分进位

if(Timer[0]==10)

Timer[0]=0} //计数到达最高位,计数复位

}

void DelayMs(uint i)

{

uint j

for(i!=0i--)

{for(j=4000j!=0j--){}}

}

void Display(uchar *p) //动态显示函数,参数p为待显示的数组名

{uchar i,sel

for(i=0i<3i++)

{sel=0x02

PORTB=~(sel<<i) //选通最右边的数码管

PORTC=Table[p[i]] //送字型码

DelayMs(1)//显示延时

PORTC=0x00

//移位以显示前一位

}

}

//计数值处理函数。参数p1:时间数组名;参数p2:显示数组名//

//功能:此函数用于将计数值拆分为BCD码的10分,分,10秒,秒//

void Process(uchar *p1,uchar *p2)

{

p2[0]=p1[0]%10

p2[1]=p1[1]/10

p2[2]=p1[1]%10

}

//*****************************************************

//*************处理传感器状态**************************

#pragma interrupt_handler readportA:9

void readportA(void)

{

if(task) js_jc()

if ((PINA&0X3f)==0X00) //没有,检测小车行驶状态

senserflag=0//不调整

else bianma()

}

//*************************************************

void js_jc(void)

{if(PINA&0x40)

jsflag=1

if((jsflag==1)&(!(PINA&0x40)))

jsflag=2

}

//*****************************************************

void bianma(void)

{uchar readtemp

readtemp=PINA&0x3f

switch (readtemp)

{case 0x20 : senserflag=1break// 过左偏

case 0x30 : senserflag=1break// 过左偏

case 0x28 : senserflag=1break// 过左偏

case 0x38 : senserflag=1break// 过左偏

case 0x01 : senserflag=2break// 过右偏

case 0x03 : senserflag=2break// 过右偏

case 0x05 : senserflag=2break// 过右偏

case 0x07 : senserflag=2break// 过右偏

case 0x10 : senserflag=1break//大左偏

case 0x02 : senserflag=2break//大右偏

case 0x18 : senserflag=3break//左偏

case 0x06 : senserflag=4break//右偏

case 0x08 : senserflag=5break//微左偏

case 0x04 : senserflag=6break//微右偏

default :senserflag=0break

}

}

//****************timer1 initial**************************

void TIMER1_init(int temp_timsk ,int temp_ccra,int temp_ccrb )

{ uchar sreg

sreg=SREG

_CLI()

TIMSK=temp_timsk

TCCR1A= temp_ccra

TCCR1B= temp_ccrb

SREG=sreg

}

//*************write OCR1A***************

void set_ocr1A(int tempocr)

{ uchar sreg

sreg=SREG

_CLI()

OCR1A=tempocr

SREG=sreg

}

//************write OCR1B*******************

void set_ocr1B(int tempocr)

{ uchar sreg

sreg=SREG

_CLI()

OCR1B=tempocr

SREG=sreg

}

//************long delay*********************

void delay(int k)

{int i,j

for(i=0i<=ki++)

{for(j=0j<=5000j++)}

}

//***********初始化*************************

void system_set ()

{

DDRA=0X80 //PA7输出,其他输入

PORTA=0X00

DDRB=0XFE //PORTB0输入,其它输出

PORTB=0X0E

DDRC=0x7f

PORTC=0x7f

DDRD=0xf0

PORTD=0xc0

set_ocr1A(200)

set_ocr1B(200)

TIMER1_init( 0X04, 0XA1, 0X03 )

TCNT1=0Xff

_SEI()

}

//***********timer0 initial******************//

void timer0_init(uchar temp_tcnt0,uchar temp_tccr0)

{TCNT0=temp_tcnt0

TCCR0=temp_tccr0

}

//**************校偏***********************

void speed_revise(void)

{

switch (senserflag)

{case 0: {set_ocr1A(250)set_ocr1B(250)}break//无偏,向前走

case 1: {set_ocr1B(255)set_ocr1A(0)}break//大左偏,右电机减速

case 2: {set_ocr1A(255)set_ocr1B(0)}break//大右偏,左电机减速

case 3: {set_ocr1A(80)set_ocr1B(255)}break//左偏,右电机减速

case 4: {set_ocr1A(255)set_ocr1B(80)}break// 右偏,左电机减速

case 5: {set_ocr1B(255)set_ocr1A(150)}break//微左偏,右电机减速

case 6: {set_ocr1B(150)set_ocr1A(255)}break//微右偏,左电机减速

default:{set_ocr1A(250)set_ocr1B(250)} break

}

}

//****************停车倒转函数************************

void stop_roll_rob()

{uchar temp=0

if(jsflag==1)

{

PORTA^=0x80

}

if(jsflag==2)

{_CLI()

set_ocr1A(0)//如果jsflag==2停车

set_ocr1B(0)

task=0

PORTA^=0x80

display_data()//显示数据处理

timer0_init(0x06,0x04)

TIMSK=0x01

_SEI()

do

{Process(Timer,Data) //计数值处理

Display(Data) //动态扫描显示

}while((Timer[0]!=0)|(Timer[1]!=0))

PORTC=0

PORTB=0X0E

_CLI()

TIMSK=0x04

timer0_init(0,0x06)

PORTD=0x40 //旋转180度

set_ocr1A(150)

set_ocr1B(150)

do

{temp=TCNT0

}

while (temp<26)

set_ocr1A(0)

set_ocr1B(0)

delay(100)

if(PINC&0x80)

{timer0_init(0,0x06)

PORTD=0X80//反向旋转360度

set_ocr1A(150)

set_ocr1B(150)

do

{temp=TCNT0

}

while (temp<55)

}

PORTD=0xc0

set_ocr1A(0)

set_ocr1B(0)

delay(500)

jsflag=3

_SEI()

}

}

//****************停车扫描函数********************

void stop_scan(void)

{uchar temp

if(PIND&0x04)

{_CLI()

set_ocr1A(0)

jsflag=4

while(1)

{

if(PIND&0x08)

{set_ocr1B(0)break

}

}

delay(200)

timer0_init(0,0x06)

set_ocr1A(100)

set_ocr1B(100)

do

{temp=TCNT0

}

while (temp<18)

set_ocr1A(0)

set_ocr1B(0)

while(1)

{Display(disdata)}

}

}

//*************路程测量***********************

void distance(void)

{

if(TIFR&0X01)

{TIFR|=0x01

TCNT0=0

distancecount+=256

}

}

//***********路程计算显示数据处理***********************

void display_data(void)

{distancecount+=TCNT0

distancedata=distancecount*53/100

disdata[0]=distancedata/100

disdata[1]=(distancedata%100)/10

disdata[2]=distancedata%10

}

//************主函数***************************

void main(void)

{OSCCAL=0xBA

delay(200)

system_set ()

timer0_init(0,0x06)

while(1)

{if(jsflag!=4)

speed_revise()

if(task)

stop_roll_rob()

if(jsflag==3)

stop_scan()

if(!jsflag)

distance()

}

}

单片机控制 12V 0.3A的直流无刷电机(风扇) 驱动分为高电平驱动和低电平驱动:

电平驱动IO 口 经一个2K的电阻 ,接到一个三极管 b ,风扇正极接 12V+,风扇负极接三极管 c , 三极管 e接GND (三极管 用NPN 8050 )。

电动机的转子上粘有已充磁的永磁体 ,为了检测电动机转子的极性,在电动机内装有位置传感器。驱动器由功率电子器件和集成电路等构成,其功能是:接受电动机的启动、停止、制动信号,以控制电动机的启动、停止和制动。

扩展资料

直流无刷电机的维护

1、在拆卸前,要用压缩空气吹净电机表面灰尘,并将表面污垢擦拭干净。

2、为了进一步了解电机运行中的缺陷,有条件时可在拆卸前做一次检查试验。

3、切断电源 ,拆除电机外部接线,做好记录。

4、选用合适电压的兆欧表测试电机绝缘电阻 。为了跟上次检修时所测的绝缘电阻值相比较以判断电机绝缘变化趋势和绝缘状态,应将不同温度下测出的绝缘电阻值换算到同一温度,一般换算至75℃。

5、测试吸收比K。当吸收比大于1.33时,表明电机绝缘不曾受潮或受潮程度不严重。为了跟以前数据进行比较,同样要将任意温度下测得的吸收比换算到同一温度。

参考资料来源:百度百科-直流无刷电机


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11330944.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-15
下一篇 2023-05-15

发表评论

登录后才能评论

评论列表(0条)

保存