单片机控制直流电机.docx

上传人:b****8 文档编号:11404424 上传时间:2023-02-28 格式:DOCX 页数:33 大小:220.50KB
下载 相关 举报
单片机控制直流电机.docx_第1页
第1页 / 共33页
单片机控制直流电机.docx_第2页
第2页 / 共33页
单片机控制直流电机.docx_第3页
第3页 / 共33页
单片机控制直流电机.docx_第4页
第4页 / 共33页
单片机控制直流电机.docx_第5页
第5页 / 共33页
点击查看更多>>
下载资源
资源描述

单片机控制直流电机.docx

《单片机控制直流电机.docx》由会员分享,可在线阅读,更多相关《单片机控制直流电机.docx(33页珍藏版)》请在冰豆网上搜索。

单片机控制直流电机.docx

单片机控制直流电机

单片机课程设计

单片机控制直流电动机

xxx

学号:

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"delay.h"

voidDelayUS(uChar8ValUS)//精确延时,18uS+(ValUS-1)*8us

{

for(;ValUS>0;ValUS--)

{;}

}

staticvoidDelay1MS(void)

{

uChar8i=2,j=199;

do

{

while(--j);

}

while(--i);

}

voidDelayMS(uInt16ValMS)

{

uInt16uiVal;

for(uiVal=0;uiVal

{

Delay1MS();

}

}

………………………………………………………………………………………………………………………………………………………

#include"DS18B20.h"

sbitDQ=P1^0;

voidSendDS18B20(uChar8SendDat)

{

uChar8i;

for(i=0;i<8;i++)

{

DQ=0;

_nop_();_nop_();_nop_();_nop_();//延时4us

if((SendDat&0x01)==0)

DQ=0;

else

DQ=1;

SendDat=SendDat>>1;

DelayUS(5);

DQ=1;

}

}

uChar8Init_DS18B20(void)

{

uChar8i;

DQ=0;

DelayUS(61);

DQ=1;

DelayUS(8);

for(i=0;i<100;i++)

{

if(DQ)

break;

}

DQ=1;

DelayUS(11);

return0xff;

}

uChar8ReceiveDS18B20(void)

{

uChar8tmp=0;

uChar8i;

for(i=0;i<8;i++)

{

tmp=tmp>>1;

DQ=0;

_nop_();_nop_();_nop_();

_nop_();_nop_();_nop_();

DQ=1;

DelayUS

(1);

if(DQ)

tmp|=0x80;

DQ=1;

_nop_();_nop_();_nop_();

_nop_();_nop_();_nop_();

}

return(tmp);

}

uInt16ReadDS18B20(void)

{

union{

uInt16Data;

uChar8tmp[2];

}temp;

temp.tmp[1]=ReceiveDS18B20();

temp.tmp[0]=ReceiveDS18B20();

return(temp.Data);

}

uInt16GetTemper(void)

{

uInt16Temper;

DQ=1;

Init_DS18B20();

SendDS18B20(0xcc);

SendDS18B20(0xbe);

Temper=ReadDS18B20();

return(Temper);

}

……………………………………………………………………………………………………………………………………………………...

#include"ISR.h"

uInt16ms_Counter;

uChar8ucCounter;

uInt16key_l;//按键低电平计数器

uChar8key_h;//按键高电平计数器

uChar8key;

uChar8kpush;

bitUpdate_ADC_Flag=0;

voidISR_Ext0(void)interrupt0

voidISR_timer0(void)interrupt1

{

TH0=(65535-1000)/255;

TL0=(65535-1000)%255;

if(ms_Counter==PWM_duty)

{

Der2=0;

}

ms_Counter++;

if(ms_Counter==PWM_cycle)

{

ms_Counter=0;

if(PWM_duty)Der2=1;

}

}

voidISR_timer1(void)interrupt3

{

TH1=0xFB;

TL1=0x1E;

if((P0&0x0C)==0x0C){

if((key_l>30)&&(key_l<800)&&(key_h>30))//释放按键,如果之前按键的时间<1s,读出键值

{key=kpush;}

if((++key_h)>200)key_h=0;//记录高电平时间

key_l=0;

if(key>0x80)key=0;

}

else

{

kpush=P0&0x0C;

key_l++;

if((key_l>800)&&(key_h>30))

{

key=kpush|0x80;

key_h=0;

key_l=0;

}

}

}

………………………………………………………………………………………………………………………………………………………

#include"keyboard.h"

#include"ISR.h"

#include"LED.h"

uChar8PWM_duty=50;

uChar8PWM_cycle=100;#include"keyboard.h"

#include"ISR.h"

#include"LED.h"

uChar8PWM_duty=50;

uChar8PWM_cycle=100;

//4*4矩阵式键盘扫描

uChar8Key_Scan(void)

{

uChar8code_h,code_l;

P3=0xF0;

if((P3&0xF0)!

=0xF0)

{

DelayMS

(1);

if((P3&0xF0)!

=0xF0)

{

code_h=0xFE;

while((P3&0xF8)!

=0xF0)

{

P3=code_h;

if((P3&0xF0)!

=0xF0)

{

code_l=(P3&0xF0|0x0F);

return((~code_h)+(~code_l));

}

elsecode_h=(code_h<<1)|0x01;

}

}

}

return(0);

}

//4*4矩阵式键盘译码

uChar8Get_Key_Val(uChar8key_temp)

{

switch(key_temp)

{

case0x14:

return1;

case0x24:

return2;

case0x44:

return3;

case0x12:

return4;

case0x22:

return5;

case0x42:

return6;

case0x11:

return7;

case0x21:

return8;

case0x41:

return9;

default:

return0;

}

}

//按键处理函数

voidkey_Process(void)

{

switch(key)

{

case0x08:

//KB1键按下

{

if(PWM_duty==100)PWM_duty=100;

elsePWM_duty++;

break;

}

case0x88:

//KB1键按下

{

if(PWM_duty==100)PWM_duty=100;

elseif(PWM_duty<=90)PWM_duty=PWM_duty+10;

break;

}

case0x04:

//KB2键按下

{

if(PWM_duty==0x00)PWM_duty=0x00;

elsePWM_duty--;

break;

}

case0x84:

//KB2键按下

{

if(PWM_duty==0x00)PWM_duty=0x00;

elseif(PWM_duty>=10)PWM_duty=PWM_duty-10;

break;

}

default:

break;

}

key=0x1C;

}

uChar8Key_Scan(void)

{

uChar8code_h,code_l;

P3=0xF0;

if((P3&0xF0)!

=0xF0)

{

DelayMS

(1);

if((P3&0xF0)!

=0xF0)

{

code_h=0xFE;

while((P3&0xF8)!

=0xF0)

{

P3=code_h;

if((P3&0xF0)!

=0xF0)

{

code_l=(P3&0xF0|0x0F);

return((~code_h)+(~code_l));

}

elsecode_h=(code_h<<1)|0x01;

}

}

}

return(0);

}

//4*4矩阵式键盘译码

uChar8Get_Key_Val(uChar8key_temp)

{

switch(key_temp)

{

case0x14:

return1;

case0x24:

return2;

case0x44:

return3;

case0x12:

return4;

case0x22:

return5;

case0x42:

return6;

case0x11:

return7;

case0x21:

return8;

case0x41:

return9;

default:

return0;

}

}

//按键处理函数

voidkey_Process(void)

{

switch(key)

{

case0x08:

//KB1键按下

{

if(PWM_duty==100)PWM_duty=100;

elsePWM_duty++;

break;

}

case0x88:

//KB1键按下

{

if(PWM_duty==100)PWM_duty=100;

elseif(PWM_duty<=90)PWM_duty=PWM_duty+10;

break;

}

case0x04:

//KB2键按下

{

if(PWM_duty==0

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 判决书

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1