单片机控制直流电机.docx
《单片机控制直流电机.docx》由会员分享,可在线阅读,更多相关《单片机控制直流电机.docx(34页珍藏版)》请在冰豆网上搜索。
单片机控制直流电机
单片机控制直流电机
[键入文档标题]
Administrator
学号:
xxx
专业:
xxx
指导老师:
xxx
组号:
第xxx组
单片机控制直流电机
摘要
随着时代的进步和科技的发展,电机调速系统在工农业生产、交通运输以及日常伤害中起着越来越重要的作用、由于直流电机剧院良好的起、制动性能,宜与在广泛范围内平滑调速。
在轧钢机、矿井卷机,挖掘机、金属切削机床、金属切削机床、造纸机高层电梯等领域中得到广泛应用。
长期以来,由于直流调速系统的性能指标优于交流调速系统。
PWM控制技术就是以该结论为理论基础,使输出端得到一系列幅值相等而宽度不相等的脉冲,用这些脉冲来代替正弦波或其他所需要的波形。
按一定的规则对各种脉冲的宽度进行调制,既可改变逆变电路输出电压大小,也可以改变输出频率。
PWM控制技术及其控制简单、灵活和动态响应好的优点而成为电子技术最广泛应用的控制方式,也是人们研究的热点。
由于必须在工作期间改变直流电机的速度,直流电机的控制是一个较困难的问题。
直流电机高效运行的最常见方法是施加一个PWM(脉宽调制)方波,其占空比对应于所需速度。
电机起到一个低通滤波器作用,将PWM信号转换为有效直流电平。
特别是对于微处理器驱动的直流电机,由于PWM信号相对容易产生,这种驱动方式使用的更为广泛。
设计要求
采用单片机设计一个控制直流电机并测量转速的装置。
单片机扩展有A/D转换芯片ADC0809和D/A转换芯片DAC0832。
(1)通过改变A/D输入端可变电阻来改变A/D的输入电压,D/A输入检测量大小,进而改变直流电机的转速。
(2)手动控制。
在键盘上设置两个按键—直流电动机加速键和直流电机减速键。
在手动状态下,每按一次键,电机的转速按照约定的速率改变。
(3)键盘列扫描(4 ⨯ 6)。
实验原理
与步进电机类似,直流电机也可精确地控制旋转速度或转矩。
直流电机是通过两个磁场的互作用产生旋转。
其结构如下页图所示,固定部分(定子)上,装设了一对直流励磁的静止的主磁极N和S,在旋转部分(转子)上装设电枢铁心。
定子与转子之间有一气隙。
在电枢铁心上放置了由A和X两根导体连成的电枢线圈,线圈的首端和末端分别连到两个圆弧形的铜片上,此铜片称为换向片。
直流电机的速度与施加的电压成正比,输出转矩则与电流成正比。
由于必须在工作期间改变直流电机的速度,直流电机的控制是一个较困难的问题。
直流电机高效运行的最常见方法是施加一个PWM(脉宽调制)方波,其占空比对应于所需速度。
电机起到一个低通滤波器作用,将PWM信号转换为有效直流电平。
特别是对于微处理器驱动的直流电机,由于PWM信号相对容易产生,这种驱动方式使用的更为广泛。
利用直流电机的速度与施加电压成正比的原理,通过滑动变阻器向ADC0809输入控制电压信号,经AD后,输入到AT89C51中,AT89C51将此信号转发给DAC0832,通过功放电路放大后,驱动直流电机。
设计方案
1.系统控制电路
采用STC89C52单片机由软件产生脉冲调制信号,来对直流电机进行控制。
2.电机控制电路
采用由三极管搭成的H型桥电路来控制电机的转动。
3.键盘电路
采用行式键盘实现电机转速的加速减速以及正反转的控制,在手动状态下,每按一次,其转速相应发生改变。
4.显示电路
采用LM016L对电机运动状态进行显示。
系统组成框图
系统总组成框图以STC89C52为主控芯片,采用桥式电路对直流电机驱动,如下所示:
硬件电路设计
1.键盘控制电路
按下DEC按钮,电机转速降低;按下INC按钮,电机转速增加。
2.单片机主控电路图
该部分电路主要由STC89C52主控芯片和晶振组成。
STC89C52芯片是低功耗8位CMOS微处理器,提供串口程序下载口。
它主要有以下几个特点:
256字节的RAM;4KB的ROM;32个通用I/O口线,为用户提供了丰富的I/O口资源;32个通用工作寄存器;2个定时器/计数器;具有6个中断源;4.0~5.5V的工作电压等。
晶振给单片机正常工作提供稳定的信号。
3.H型桥式电机驱动电路
H桥式电机驱动电路包括4个三极管和一个电机。
要使电机运转,只须导通对角线上的一对三极管。
在此设计中用到的完整的驱动电路如下:
主控程序
程序流程
总仿真电路图
程序清单
1.主程序
#include"AT89X51.h"
#include
#include
#include"led.h"
#include"uart.h"
#include"timer0.h"
#include"timer1.h"
#include"common.h"
#include"ADC0831.h"
#include"lcd1602.h"
#include"keyboard.h"
#include"ISR.h"
#include"DaType_Change.h"
#defineDcMotor_Direction_P
uChar8code*String1="DCMotorControl";
uChar8code*String2="pwm:
/100";
uChar8PWM_buff[3];
voidmain(void)
{
LCD_Init();
timer0_Init();
timer1_Init();
#ifdefDcMotor_Direction_P
Der1=0;
#elseDer1=1;
#endif
LED_Run_EN();
WrStrLCD(0,0,String1);
WrStrLCD(1,0,String2);
while
(1)
{
key_Process();//按键处理子程序
Char_To_Str(PWM_duty,&PWM_buff[0]);//液晶显示子程序
WrStrLCD(1,4,&PWM_buff[0]);
}
}
2.子程序
………………………………………………………………………………………………………………………………………………………
#include
unsignedcharvalue_converted=0x00;
unsignedcharvalue_AN6=0x00;
unsignedcharvalue_AN7=0x00;
bitend_of_convertion=0;
voidADC_Config(void)
{
ADCF=0xC0;
ADCLK=0x06;
ADCON=0x20;
EA=1;
EADC=1;
while
(1)
{
ADCON&=~0x07;
ADCON|=0x06;
ADCON&=~0x40;
ADCON|=0x08;
while(!
end_of_convertion);
end_of_convertion=0;
value_AN6=value_converted;
ADCON&=~0x07;
ADCON|=0x07;
ADCON&=~0x40;
ADCON|=0x08;
while(!
end_of_convertion);
end_of_convertion=0;
value_AN7=value_converted;
}
}
voidit_Adc(void)interrupt8
{
ADCON&=~0x10;
value_converted=ADDH;
end_of_convertion=1;
}
……………………………………………………………………………………………………………………………………………………..
#include"adc0831.h"
voidADC_CLK(void)
{
adcclk=1;
_nop_();
adcclk=0;
_nop_();
}
uChar8Read_ADC(void)
{
uChar8i;
bittemp=ADC_Val^0;
adccs=0;
ADC_CLK();
while(adcdo);
for(i=0;i<8;i++)
{
ADC_CLK();
ADC_Val=(ADC_Val<<1)|adcdo;
}
adccs=1;
return(ADC_Val);
}
voidIntToStr(uInt16t,uChar8*str,uChar8n)
{
uChar8a[5];
chari,j;
a[0]=(t/10000)%10;//取得整数值到数组
a[1]=(t/1000)%10;
a[2]=(t/100)%10;
a[3]=(t/10)%10;
a[4]=(t/1)%10;
for(i=0;i<5;i++)//转成ASCII码
a[i]=a[i]+'0';
for(i=0;a[i]=='0'&&i<=3;i++);//计算空格(0)数量
for(j=5-n;j
{*str='';str++;}
for(;i<5;i++)
{*str=a[i];str++;}//加入有效的数字
*str='\0';
}
…………………………………………………………………………………………………………………………………………………......
#include"beep.h"
sbitbeep=P1^4;
voidBeepRing(void)
{
beep=0;
DelayMS(100);
beep=1;
DelayMS(100);
}
………………………………………………………………………………………………………………………………………………………
#include"DaType_Change.h"
voidChar_To_Str(uChar8Data,uChar8*str)
{
uChar8a[4];
uChar8i,j;
a[0]=(Data/100)%10;
a[1]=(Data/10)%10;
a[2]=(Data/1)%10;
for(i=0;i<3;i++)//转成ASCII码
a[i]=a[i]+'0';
for(i=0;a[i]=='0'&&i<3;i++);
for(j=0;j
{*str='';str++;}
for(;i<3;i++)
{*str=a[i];str++;}//加入有效的数字
*str='\0';
}
………………………………………………………………………………………………………………………………………………………
#include"