導航:首頁 > 操作系統 > 51單片機直流電機調速程序

51單片機直流電機調速程序

發布時間:2023-04-02 03:08:08

① 改一下單片機控制PWM直流電機的程序

單片機控制PWM直流電機的程序,具體如下:
PWM控制直流電機實現上來說應該不難,最主要是要求:比如加速度,需要多塊達到設定速度;
一般來講有「開環的查表法」和「閉環的採集實時速度法」;
「開環查表」:前提是知道要達到的速度是哪些,然後去增加(或減少)PWM的占空比來看速度是否和設定的一致,然後將此時的占空比放到表格中,下次需要用時,直接根據設定速度查表格就行;這種控制方法適合於「負載」不變的情況,相對簡單;
「閉環速度採集」:在硬體電路上要有速度採集系統(霍爾元件),根據反饋的速度大小來調節PWM的占空比,這種方法比較精確,適用於不同的「負載」,在控制速度的過程中要小心「超調」,也就是速度加的太快或者太慢(PWM占空比調節太快),可以通過試驗來確定調節的快慢或者引入PID演算法
控制電機:要了解可控硅的使用。

例子:
51單片機直流電機的PWM速度控製程序的代碼如下:
/* =======直流電機的PWM速度控製程序======== */
/* 晶振採用11.0592M,產生的PWM的頻率約為91Hz */
#include<reg51.h>
#include<math.h>
#define uchar unsigned char
#define uint unsigned int
sbit en1=P2^0; /* L298的Enable A */
sbit en2=P2^1; /* L298的Enable B */
sbit s1=P2^2; /* L298的Input 1 */
sbit s2=P2^3; /* L298的Input 2 */
sbit s3=P2^4; /* L298的Input 3 */
sbit s4=P2^5; /* L298的Input 4 */
uchar t=0; /* 中斷計數器 */
uchar m1=0; /* 電機1速度值 */
uchar m2=0; /* 電機2速度值 */
uchar tmp1,tmp2; /* 電機當前速度值 */

/* 電機控制函數 index-電機號(1,2); speed-電機速度(-100—100) */
void motor(uchar index, char speed)
{
if(speed>=-100 && speed<=100)
{
if(index==1) /* 電機1的處理 */
{
m1=abs(speed); /* 取速度的絕對值 */
if(speed<0) /* 速度值為負則反轉 */
{
s1=0;
s2=1;
}
else /* 不為負數則正轉 */
{
s1=1;
s2=0;
}
}
if(index==2) /* 電機2的處理 */
{
m2=abs(speed); /* 電機2的速度控制 */
if(speed<0) /* 電機2的方向控制 */
{
s3=0;
s4=1;
}
else
{
s3=1;
s4=0;
}
}
}
}

void delay(uint j) /* 簡易延時函數 */
{
for(j;j>0;j--);
}

void main()
{
char i;
TMOD=0x02; /* 設定T0的工作模式為2 */
TH0=0x9B; /* 裝入定時器的初值 */
TL0=0x9B;
EA=1; /* 開中斷 */
ET0=1; /* 定時器0允許中斷 */
TR0=1; /* 啟動定時器0 */
while(1) /* 電機實際控制演示 */
{
for(i=0;i<=100;i++) /* 正轉加速 */
{
motor(1,i);
motor(2,i);
delay(5000);
}
for(i=100;i>0;i--) /* 正轉減速 */
{
motor(1,i);
motor(2,i);
delay(5000);
}
for(i=0;i<=100;i++) /* 反轉加速 */
{
motor(1,-i);
motor(2,-i);
delay(5000);
}
for(i=100;i>0;i--) /* 反轉減速 */
{
motor(1,-i);
motor(2,-i);
delay(5000);
}
}
}

void timer0() interrupt 1 /* T0中斷服務程序 */
{
if(t==0) /* 1個PWM周期完成後才會接受新數值 */
{
tmp1=m1;
tmp2=m2;
}
if(t<tmp1) en1=1; else en1=0; /* 產生電機1的PWM信號 */
if(t<tmp2) en2=1; else en2=0; /* 產生電機2的PWM信號 */
t++;
if(t>=100) t=0; /* 1個PWM信號由100次中斷產生 */
}

② 51單片機怎麼驅動直流電機c語言

51單片機驅動直流電機程序(用的是l298n晶元):

#include<reg51.h>

#include<math.h>

#defineuintunsignedint

#defineucharunsignedchar

#defineN100

sbits1=P1^0;//電機驅動口

sbits2=P1^1;//電機驅動口

sbits3=P1^2;//電機驅動口

sbits4=P1^3;//電機驅動口

sbiten1=P1^4;//電機使能端

sbiten2=P1^5;//電機使能端

sbitLSEN=P2^0;//光電對管最左

sbitLSEN1=P2^1;//光電對管左1

sbitLSEN2=P2^2;//光電對管左2

sbitRSEN1=P2^3;//光電對管右1

sbitRSEN2=P2^4;//光電對管右2

sbitRSEN=P2^5;//光電對管最右

uintpwm1=0,pwm2=0,t=0;

voiddelay(uintxms)

{

uinta;

while(--xms)

{

for(a=123;a>0;a--);

}

}

voidmotor(ucharspeed1,ucharspeed2)

{

if(speed1>=-100&&speed1<=100)

{

pwm1=abs(speed1);

if(speed1>0)

{

s1=1;

s2=0;

}

if(speed1==0)

{

s1=1;

s2=1;

}

if(speed1<0)

{

s1=0;

s2=1;

}

}

if(speed2>=-100&&speed2<=100)

{

pwm2=abs(speed2);

if(speed2>0)

{

s3=1;

s4=0;

}

if(speed2==0)

{

s3=1;

s4=1;

}

if(speed2<0)

{

s3=0;

s4=1;

}

}

}

voidgo_forward(uintspeed)

{

s1=1;

s2=0;

s3=1;

s4=0;

pwm1=speed;

pwm2=speed;

}

voidgo_back(uintspeed)

{

s1=0;

s2=1;

s3=0;

s4=1;

pwm1=speed;

pwm2=speed;

}

voidstop()

{

s1=1;

s2=1;

s3=1;

s4=1;

pwm1=0;

pwm2=0;

}

voidturn_right(uintP1,uintP2)//右轉函數

{

s1=1;

s2=0;

s3=0;

s4=1;

pwm1=P1;

pwm2=P2;

}

voidturn_left(uintP1,uintP2)//左轉函數

{

s1=0;

s2=1;

s3=1;

s4=0;

pwm1=P1;

pwm2=P2;

}

voidtracking()

{

if((LSEN1==0)&&(LSEN2==0)&&(RSEN1==0)&&(RSEN2==0))//沒有檢測到

{

go_forward(100);

}

if((LSEN1==1)&&(LSEN2==0)&&(RSEN1==0)&&(RSEN2==0))//左一檢測到

{

turn_left(40,80);//左轉右輪》左輪

delay(N);

}

if((LSEN1==0)&&(LSEN2==1)&&(RSEN1==0)&&(RSEN2==0))//左二檢測到

{

turn_left(40,60);//左轉右輪》左輪

delay(N);

}

if((LSEN1==0)&&(LSEN2==0)&&(RSEN1==1)&&(RSEN2==0))//右一檢測到

{

turn_right(60,4);//右轉左輪》右輪

delay(N);

}

if((LSEN1==0)&&(LSEN2==0)&&(RSEN1==0)&&(RSEN2==1))//右二檢測到

{

turn_right(80,40);//右轉左輪》右輪

delay(N);

}

if((LSEN1==1)&&(LSEN2==1))

{

turn_left(0,100);

delay(1000);

}

if((RSEN1==1)&&(RSEN2==1))

{

turn_right(100,0);

delay(1000);

}

}

voidavoidance()

{

}

voidinit()

{

TMOD=0x02;//timer0同時配置為模式2,8自動重裝計數模式

TH0=156;//定時器初值設置100us中斷

TL0=156;

ET0=1;

EA=1;

TR0=1;//開啟總中斷

}

voidmain()

{

init();

while(1)

{

tracking();

}

}

voidtimer0()interrupt1//電機驅動提供PWM信號

{

if(t<pwm1)

en1=1;

else

en1=0;

if(t<pwm2)

en2=1;

else

en2=0;

t++;

if(t>100)

t=0;

}

(2)51單片機直流電機調速程序擴展閱讀

L298N是一種雙H橋電機驅動晶元,其中每個H橋可以提供2A的電流,功率部分的供電電壓范圍是2.5-48v,邏輯部分5v供電,接受5vTTL電平。一般情況下,功率部分的電壓應大於6V否則晶元可能不能正常工作。

③ 51單片機實現pwm對電機調速

可以用一個定時器實現,也可以用兩個定時器實現
一個定時器實現辦法,如定時器定時50US中斷一次,中斷100次是5ms,即PWM的周期
每次中斷,變數a加1,並且a與另一變數b比較,如果a<b,讓某一管腳輸出高電平,如果a>=b,則讓其輸出低電平,a等於100時清0,這樣占空比是b/100,改變b的值,就可以改變占空比
缺點定時器定時時間不能太短,例如10us中斷程序根本執行不完,若占空比調節精度要求較高,如要求百分之一,則a需大於100,這樣PWM波的周期就比較大,頻率比較低
兩個定時器,如一個定時器0定時100us,另外一個定時器1定時小於100us,如b
us
定時器0中斷時輸出高電平,並打開定時器1,定時器1負責置低電平
這樣,就可以產生周期100us,占空比是b/100的方波
頻率可以比用一個定時器高一些

④ 51單片機控制直流電機。(c語言控制)

有3種方案:
第一種,通過PWM脈寬調制輸出方法控制轉速,控制占空比的大小可以實現調速!
第二種,通過AD轉換的方法控制直流電機的電壓
第三種,用xtr115程式控制電流源來控制直流電機(類似第二種方法)
如果以上的驅動能力不夠的話再加上一個電壓跟隨器!
程序方面就是一個寄存器的配置問題了,你查一下單片機的技術手冊上面都有介紹的,祝你成功

⑤ 51單片機控制兩路直流電機轉速的c程序技巧

既然是技巧的話那就不提供詳細的代碼了,首先要看你這個小車是幾輪幾驅動的,首先假設你只用一個L298n驅動板的話,那麼再假設只含左右兩個輪,只對左右兩個輪進行控制的話,那麼就簡單了,首先你要知道L298N驅動板怎麼用,不同的驅動板功能都不一定相同,不過控制引腳一般來說都是4根,可以控制兩個直流電機的正反轉,同時還有兩個PWM介面,可以控制兩個電機的轉速。
假設4個控制引腳分為A1、A2和B1、B2,A1、A2控制第一個直流電機,B1、B2控制第二個直流電機,當A1和A2接不同方向的電流後直流電機會正轉或反轉,同理B1和B2也是一樣。PWM是通過控制佔有率來控制電機速度的,即控制高電平和低電平的時間的,不同,這樣在規定時間內,如果高電平的時間佔有比例越高則電機轉速越快,輸出功率越高。
知道以上內容了那麼之後的內容就更容易理解了
前進:兩個直流電機朝正方向同時轉動即可
後退:兩個直流電機朝反方向同時轉動即可
原地左轉:類似原地打轉,只需讓兩個電機一個正轉一個反轉即可,即左轉為左邊電機反轉,右邊電機正轉
原地右轉:與原地左轉相反即可
固定輪轉:固定左邊令右側輪前進即可實現固定輪轉向的目的,例如左轉的話令左邊電機停止,右側電機正向轉動即可,向右轉的話與左轉相反。
至於keil程序,這個要根據具體的硬體來寫,別人的無法通用,不過這些都不難,只要原理弄懂了,稍微花一點兒時間還是能很容易寫出來的,先從控制電機的轉向開始。別人的程序的話可能會越看越難理解,還是自己動手比較好,先不考慮調速的情況下完成了之後再去看看有關PWM調速的內容。

⑥ 51單片機直流電機調速

第一:你這個不是電機調速的,用外部中斷是測速的呀。
下面是我寫的.PID部分的代碼就不給了,想加的話,自己找可以了
#include <AT89X52.H>
#include "common.h"

#define _WHEEL_C_

#define Left_moto_pwm P1_5
#define Right_moto_pwm P1_4

#define Left_moto_go {IN1=0,IN2=1;}
#define Left_moto_back {IN1=1,IN2=0;}

#define Right_moto_go {IN3=1,IN4=0;}
#define Right_moto_back {IN3=0,IN4=1;}

sbit IN1=P1^0;
sbit IN2=P1^1;
sbit IN3=P1^2;
sbit IN4=P1^3;

unsigned char pwm_val_left=0;
unsigned char push_val_left=0;

unsigned char pwm_val_right=0;
unsigned char push_val_right=0;

float L_Count=0,R_Count=0;
unsigned int TimerNum=0,SYS_TimeNum=0;
float Save_L_Distance=0,Save_R_Distance=0,Left_Speed=0,Right_Speed=0;
unsigned char Left_point=0,Right_point=0;

unsigned char sys_1ms=0,sys_1s=0,TurnFlag=0;

//初始化PWM調速函數
void Init_Wheel()
{
TMOD = 0x01;
TH0 = 0x0FF;
TL0 = 0x0A4;
EA = 1;
ET0 = 1;
TR0 = 1;
}

void Init_WheelSpeedInter()
{
IT0=1; //INT0下降沿中斷
EX0=1; //允許INT1中斷
IT1=1; //INT1下降沿中斷
EX1=1; //允許INT1中斷
EA=1;

}

//得到上一次0.5秒的行駛距離
float GetLeftWheelMileage()
{
return Save_L_Distance;
}

//得到上一次0.25秒的行駛距離
float GetRightWheelMileage()
{
return Save_R_Distance;
}

void Inter_Left(void) interrupt 0
{
L_Count++;
}

void Inter_Right(void) interrupt 2
{
R_Count++;
}

//小車向前函數
void Wheel_Run(char left_val,char right_val)
{
push_val_left=left_val;
push_val_right=right_val;
Left_moto_go ;
Right_moto_go ;
}

//小車後退函數
void Wheel_Back(char left_val,char right_val)
{
push_val_left=left_val;
push_val_right=right_val;
Left_moto_back;
Right_moto_back;
}

//小車停止函數
void Wheel_Stop(void)
{
Wheel_Run(0,0);
}

//左輪PWM調速函數
void pwm_out_left_moto(void)
{
if(pwm_val_left>200)
{
pwm_val_left=0;
}else
{
if(pwm_val_left<=push_val_left)
{
Left_moto_pwm=1;
}
else
{
Left_moto_pwm=0;
}

}
}

//右輪調速函數
void pwm_out_right_moto(void)
{
if(pwm_val_right>200)
{
pwm_val_right=0;
}else
{
if(pwm_val_right<=push_val_right)
{
Right_moto_pwm=1;
}

else
Right_moto_pwm=0;

}
}

//PWM調速中斷(TIMER0--工作方式1)
void Wheel_Interrupt(void) interrupt 1
{
TH0 = 0x0FF;
TL0 = 0x0A4;
TimerNum++;
if(TimerNum>=2500)
{
//左右輪速度cm/s
Left_Speed=4*L_Count;
Right_Speed=4*R_Count;

//左右輪0.25秒行駛距離
Save_L_Distance+=L_Count;
Save_R_Distance+=R_Count;

//數據發送到串口圖示
DataScope_Get_Channel_Data(L_Count, 1 ); //將數據 1.0 寫入通道 1
DataScope_Get_Channel_Data(R_Count, 2 ); //將數據 2.0 寫入通道 2
Send_Count = DataScope_Data_Generate(2); //生成10個通道的 格式化幀數據,返回幀數據長度
for( DateNum = 0 ; DateNum < Send_Count; DateNum++) //循環發送,直到發送完畢
{
SendByte(DataScope_OutPut_Buffer[DateNum]);
}

TimerNum=0;
L_Count=0;
R_Count=0;

}
pwm_val_left++;
pwm_val_right++;
pwm_out_left_moto();
pwm_out_right_moto();
}

⑦ 51單片機直流電機調速問題

if(K1=0) 使用錯誤,應該是if(K1==0)

滿意請採納

閱讀全文

與51單片機直流電機調速程序相關的資料

熱點內容
程序員徵友平台 瀏覽:461
程序里添加編譯時間 瀏覽:45
BL視頻APP 瀏覽:491
蕭九作品集txt 瀏覽:360
反應剛剛解放時期諜戰片 瀏覽:970
和美女被困隧道的七天 瀏覽:801
午夜影院入口。 瀏覽:845
韓國李彩潭所有電影大全 瀏覽:446
高精定位演算法縮寫 瀏覽:855
解壓試頻 瀏覽:494
有關蛇女香港的電影 瀏覽:67
兄妹禁忌之戀 瀏覽:348
文娛小說主角姓蘇 瀏覽:211
下載軟體佔用內存大需要解壓嗎 瀏覽:269
愛戀3d未刪減版百度雲網盤 瀏覽:48
安卓邊境怎麼玩 瀏覽:204
不用下載免費網址 瀏覽:187
gl片子 瀏覽:42
台灣電影男學生女老師 瀏覽:744
推薦個能看的網址你懂的 瀏覽:150