单片机控制直流电机Word格式.docx
《单片机控制直流电机Word格式.docx》由会员分享,可在线阅读,更多相关《单片机控制直流电机Word格式.docx(33页珍藏版)》请在冰点文库上搜索。
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<
intrins.h>
stdio.h>
led.h"
uart.h"
timer0.h"
timer1.h"
common.h"
ADC0831.h"
lcd1602.h"
keyboard.h"
ISR.h"
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,&
}
}
2.子程序
………………………………………………………………………………………………………………………………………………………
ADC.h>
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;
ADCON&
=~0x07;
ADCON|=0x06;
=~0x40;
ADCON|=0x08;
while(!
end_of_convertion);
end_of_convertion=0;
value_AN6=value_converted;
ADCON|=0x07;
value_AN7=value_converted;
}
voidit_Adc(void)interrupt8
ADCON&
=~0x10;
value_converted=ADDH;
end_of_convertion=1;
……………………………………………………………………………………………………………………………………………………..
adc0831.h"
voidADC_CLK(void)
{
adcclk=1;
_nop_();
adcclk=0;
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;
5;
i++)//转成ASCII码
a[i]=a[i]+'
0'
a[i]=='
&
&
=3;
i++);
//计算空格(0)数量
for(j=5-n;
j<
i;
j++)//填充空格
{*str='
'
str++;
}
for(;
i++)
{*str=a[i];
}//加入有效的数字
*str='
\0'
}
…………………………………………………………………………………………………………………………………………………......
beep.h"
sbitbeep=P1^4;
voidBeepRing(void)
beep=0;
DelayMS(100);
beep=1;
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;
3;
for(j=0;
#include"
delay.h"
voidDelayUS(uChar8ValUS)//精确延时,18uS+(ValUS-1)*8us
ValUS>
0;
ValUS--)
{;
staticvoidDelay1MS(void)
uChar8i=2,j=199;
do
while(--j);
while(--i);
voidDelayMS(uInt16ValMS)
uInt16uiVal;
for(uiVal=0;
uiVal<
ValMS;
uiVal++)
Delay1MS();
DS18B20.h"
sbitDQ=P1^0;
voidSendDS18B20(uChar8SendDat)
i<
i++)
DQ=0;
_nop_();
_nop_();
//延时4us
if((SendDat&
0x01)==0)
DQ=0;
else
DQ=1;
SendDat=SendDat>
>
1;
DelayUS(5);
DQ=1;
uChar8Init_DS18B20(void)
DQ=0;
DelayUS(61);
DQ=1;
DelayUS(8);
100;
if(DQ)
break;
DelayUS(11);
return0xff;
uChar8ReceiveDS18B20(void)
uChar8tmp=0;
tmp=tmp>
DelayUS
(1);
tmp|=0x80;
return(tmp);
uInt16ReadDS18B20(void)
union{
uInt16Data;
uChar8tmp[2];
}temp;
temp.tmp[1]=ReceiveDS18B20();
temp.tmp[0]=ReceiveDS18B20();
return(temp.Data);
uInt16GetTemper(void)
uInt16Temper;
Init_DS18B20();
SendDS18B20(0xcc);
SendDS18B20(0xbe);
Temper=ReadDS18B20();
return(Temper);
……………………………………………………………………………………………………………………………………………………...
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++;
30))
{
key=kpush|0x80;
key_h=0;
key_l=0;
}
LED.h"
uChar8PWM_duty=50;
uChar8PWM_cycle=100;
#include"
//4*4矩阵式键盘扫描
uChar8Key_Scan(void)
uChar8code_h,code_l;
P3=0xF0;
if((P3&
0xF0)!
=0xF0)
DelayMS
(1);
if((P3&
code_h=0xFE;
while((P3&
0xF8)!
{
P3=code_h;
if((P3&
{
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:
elseif(PWM_duty<
=90)PWM_duty=PWM_duty+10;
case0x04:
//KB2键按下
if(PWM_duty==0x00)PWM_duty=0x00;
elsePWM_duty--;
case0x84:
elseif(PWM_duty>
=10)PWM_duty=PWM_duty-10;
default:
break;
key=0x1C;
if(PWM_duty==0