❶ 急求51單片機控制舵機C語言程序,舵機可以根據設定旋轉任意角度!急求啊,大神幫幫忙!非常感謝!
#include<reg52.h>typedef unsigned int uint;typedef unsigned char uchar;sbit pwm=P0^3;//輸出PWM信號uchar count=0;uint pwm_value=1500;//初值為1.5msuint value[]={1500,1000,1500,2000,1500};//void delay_ms(uint x){uint i;while(x--)for(i=0;i<125;i++);}void InitTimer(void){TMOD=0x11;//開定時器0,1TH0=-20000/256;//定時20MS,20MS為一個周期TL0=-20000%256;TH1=-1500/256;//定時1.5MS,這時舵機處於0度TL1=-1500%256;EA=1;//開總斷TR0=1;//開定時器0ET0=1;TR1=1;//開定時器1ET1=1;}void timer0(void) interrupt 1//定時器0中斷函數{pwm=1;TH0=-20000/256;TL0=-20000%256;TR1=1;count++;}void timer1(void) interrupt 3//定時器1中斷函數{pwm=0;TH1=-pwm_value/256;TL1=-pwm_value%256;TR1=0;}void main(void)//主函數{uchar i;InitTimer();pwm_value=1500;while(1){for(i=0;i<5;i++){pwm_value=value[i];//通過數組就可以改變舵機的轉角度delay_ms(1000);}}}
❷ 那位大神給段c語言控制舵機從0~180持續來回轉動的程序,不勝感激
180度舵機是一特殊的機器人專用舵機。你所說的0-180度,在專業玩家裡不這樣說的,而是說成±90度。即順時針90度,逆時針90度。
你可以自己寫一個的。這種舵機比陵告較特殊,但是只要滿足尺明明一下PWM就可以實現了:
1. 周期T=20ms(即50HZ),占空比500us-2500us。槐困
2. 500us舵機逆時針轉90度,2500us舵機順時針轉90讀。 (其中0度是1500us)
3. 即: TL+TH=20ms 改變TH的值,舵機角度隨之改變。參數參照以上1.2點。
TL TH
_____ ____
_________| |_________| | _________|
4. 電路原理很簡單,接好電源,地,信號線。
信號線接到單片機或者其他能輸出PWM的控制腳。
❸ 如何用51單片機控制舵機的單片機程序是怎麼寫的希望你也能給我發一個編寫程序和電路圖
單片機系統實現對舵機輸出轉角的控制,必須首先完成兩項任務:首先,產生基本的PWM周期信號,即產生20ms的周期信號;其次,調整脈寬,即單片機調節PWM信號的占空比。單片機能使PWM信號的脈沖寬度實現微秒級的變化,從而提高舵機的轉角精度。單片機完成控制演算法,再將PWM信號輸出到舵機。
發一個自己原來寫的簡單的。
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar count,jd;
sbit pwm=P1^0;
sbit jia=P3^2;
sbit jian=P3^3;
uchar code table[10] = {0x3f,0x06,0x5b,
0x4f,0x66,0x6d,
0x7d,0x07,0x7f,0x6f};
//延時函數
void delay(uchar x)
{
uchar i,j;
for(i=x;i>0;i--)
for(j=125;j>0;j--);
}
//定時器初始化
void Time0_init()
{
TMOD=0x01; //定時器0工作方式1
IE=0x82;
TH0=0xfe;
TL0=0x33; //11.0592MHZ晶振,0.5ms
TR0=1;
}
//定時器0中斷程序
void Time0() interrupt 1
{
TH0=0xfe;
TL0=0x33;
if(count<jd) //判斷0.5ms次數是否小於角度標識
pwm=1; //是,pwm輸出高電平
else
pwm=0; //否,輸出低電平
count=count+1;
count=count%40; //次數始終保持為40,即保持周期為20ms
}
//按鍵掃描
void keyscan()
{
if(jia==0)
{
delay(10);
if(jia==0)
{
jd++; //角度增加 1
count=0; //按鍵按下則20ms周期重新開始計時
if(jd==6)
jd=5; //已經是180度,保持
while(jia==0);
}
}
if(jian==0)
{
delay(10);
if(jian==0)
{
jd--;
count=0;
if(jd==0)
jd=1; //已經0度,保持
while(jian==0);
}
}
}
//數碼管顯示
void display()
{
uchar ,shi,ge ;
switch(jd)
{
case 1:
=0;
shi=0;
ge=0;
break;
case 2:
=0;
shi=4;
ge=5;
break;
case 3:
=0;
shi=9;
ge=0;
break;
case 4:
=1;
shi=3;
ge=5;
break;
case 5:
=1;
shi=8;
ge=0;
break;
}
P0=table[];
P2=1;
delay(5);
P0=table[shi];
P2=2;
delay(5);
P0=table[ge];
P2=3;
delay(5);
}
void main()
{
//jd=1;
count=0;
Time0_init();
while(1)
{
keyscan();
display();
}
}
電路圖很簡單的,幾個按鍵,再在單片機最小系統上接出一個信號線,再給舵機供上電就可以了。
❹ 跪求51單片機控制舵機程序(切記,單片機,不要弄個C來忽悠啊)
我現在也在做舵機控制,這是控制一個舵機的程序,可以參考!
通過按鍵,改變單片機輸出脈沖寬度1ms~2ms,使舵機在-90°~+90°間轉動
ORG 0000H
AJMP MAIN ;轉主程序
ORG 000BH
AJMP INTT0 ;轉定時中斷子程序
MAIN: MOV SP,#80H
SETB EA ;開總中斷
SETB ET0 ;允許T0中斷
CLR P3.7 ;脈沖波形起始狀態
MOV TMOD,#01H ;定時,方式0
MOV 30H,#2EH ;舵機0 位,1.5ms定時初始值,TL0值存30H
MOV 31H,#0FAH ;TH0值存31H
MOV 32H,#0B2H ;18.5ms定時初始值,TL0值存32H
MOV 33H,#0B7H ;TH0存33H
CLR F0 ;清標志位
SETB TR0 ;啟動T0
K1: JB P1.4,K2 ;右轉鍵未按下,轉K2,判左轉鍵
ACALL D10MS ;按下,延時,防抖
JNB P1.4,$ ;等待釋放
ACALL D10MS
MOV A,30H
CJNE A,#3AH,K10 ;判斷是否到90°
AJMP K2 ;到90°,不改變定時時間常數,轉K2
K10: CLR C ;未到90°,清進位位,下條指令為帶進位減,必須先清進位
SUBB A,#20 ;減小時間常數,即加大高電平脈沖寬度,每次0.02ms遞增,舵機轉動3.6°
JNC K11
DEC 31H ;借位
K11: MOV 30H,A
CLR C
MOV A,32H
ADD A,#20 ;加大時間常數,即減小低電平脈沖寬度
JNC K12
INC 33H
K12: MOV 32H,A
K2: JB P1.5,K3
ACALL D10MS
JNB P1.5,$
ACALL D10MS
MOV A,30H
CJNE A,#22H,K20
AJMP K3
K20: CLR C
ADD A,#20
JNC K21
INC 31H
K21: MOV 30H,A
CLR C
MOV A,32H
SUBB A,#20
JNC K22
DEC 33H
K22: MOV 32H,A
CLR C
K3: JB P1.6,K1 ;判斷電機回0 鍵是否按下
ACALL D10MS
JNB P1.6,$
ACALL D10MS
MOV 30H,#2EH ;舵機0 位,脈寬1.5ms
MOV 31H,#0FAH
MOV 32H,#0B2H
MOV 33H,#0B7H
AJMP K1
INTT0: CPL F0 ;中斷服務程序
CPL P3.7 ;輸出高、低電平脈沖
JB F0,HIGH1
LOW0: MOV TL0,32H ;低電平脈沖定時常數
MOV TH0,33H
RETI
HIGH1: MOV TL0,30H ;高電平脈沖定時常數
MOV TH0,31H
RETI
D10MS: MOV R2,#20
MOV R1,#250
DJNZ R1,$
DJNZ R2,$-4
RET
END
❺ 怎麼用51單片機控制舵機
操作步驟:
1 單片機,舵機,電源共地;
2 用兩個穩壓晶元進行供電,將電源分開來;
3 舵機信號端沒有直接連接單片機IO口,我串了一個10K的電阻,也就是這一步之後就可以控制舵機。
❻ 求一個PWM單片機簡單控制舵機程序
以前幫人解決的;
/**舵機控制——火柴天堂作品-20120314**/
/**50Hz舵機,0.5ms-2.5ms 對應 0-180°(-90°~90°)**/
/**51系列單片機,晶振12MHz,P1.0輸出50Hz PWM調制方波(即周期20ms)驅動舵機,方波由T0定時器產生
P11-P17,7個光電檢測,P11-130.5°,P12-108°,P13-99°,P14-90°,P15-81°,P16-72°,P17-49.5°,優先順序高-低:P14→P11/P17→P12/P16→P13/P15 **/
#include"reg52.h" //包含52系列頭文件
#define uchar unsigned char //定義 無符號字元型
#define uint unsigned int //定義 無符號整型
//#define TRUE 1 //定義 邏輯真
//#define FALSE 0 //定義 邏輯假
//最小角度4.5°,時間應該為2ms×4.5°/180°=50us,故定時器T0定時時間為 50us
#define th0 0xce //50us for Model2 at 12HMz Fosc
#define DutyDeno 40 //定義 占空比分母(舵機轉動范圍) 為:180°/4.5°=40
#define SteeringBasic 10 //舵機基準角 0.5ms, 0.5ms/50us=10
#define SteerineSigne 400 //舵機信號 20ms, 20ms/50us=400
uchar code SteeringList[8]={0,29,24,22,20,18,16,11}; //P11-P17光電檢測對應舵機轉角列表,單位4.5°,第一個元素為空
sbit PS1=P1^0; //定義 光電開關1 介面
sbit PS2=P1^1; //定義 光電開關2 介面
sbit PS3=P1^2; //定義 光電開關3 介面
sbit PS4=P1^3; //定義 光電開關4 介面
sbit PS5=P1^4; //定義 光電開關5 介面
sbit PS6=P1^5; //定義 光電開關6 介面
sbit PS7=P1^6; //定義 光電開關7 介面
sbit Steering=P1^7; //定義 舵機輸出 介面
#define PS1_Value 1 //定義 光電開關1 值
#define PS2_Value 2 //定義 光電開關2 值
#define PS3_Value 3 //定義 光電開關3 值
#define PS4_Value 4 //定義 光電開關4 值
#define PS5_Value 5 //定義 光電開關5 值
#define PS6_Value 6 //定義 光電開關6 值
#define PS7_Value 7 //定義 光電開關7 值
uchar DutyNume; //定義 占空比分子(舵機轉角) 變數,單位4.5°
void Timer0() interrupt 1 //定時器T0 中斷 函數
{
static uint ty_time=0; //定義靜態變數,作為 占空比 輸出時間的參考值(50us)
ty_time=++ty_time%SteerineSigne; //該句等效於:ty_time++;ty_time%=SteerineSigne;
if(ty_time<DutyNume+SteeringBasic) Steering=1; //若計時時間小於 占空比分子,則輸出應為 高電平
else Steering=0; //若計時時間大於 占空比分子,則輸出應為 低電平
}
void TimerInit() //定時器初始化 函數
{
TMOD=0x02; //T0 8位自重裝定時器
EA=1; //允許系統中斷
ET0=1; //允許T0中斷
TH0=th0;
TL0=th0; //50us 初值
TR0=1; //T0開始計時
}
uchar PhotoSwitchScan() //光電開關掃描 函數
{
if(!PS4) return PS4_Value; //返回光電開關對應值
if(!PS1) return PS1_Value;
if(!PS7) return PS7_Value;
if(!PS2) return PS2_Value;
if(!PS6) return PS6_Value;
if(!PS3) return PS3_Value;
if(!PS5) return PS5_Value; //返回光電開關對應值
return PS4_Value; //其它情況,均保持跟最高級別一致
}
void PhotoSwitchResp() //光電開關響應 函數
{
//uchar PS_value=PhotoSwitchScan(); //掃描光電開關
//if(PS_value)DutyNume=SteeringList[PS_value]; //占空比分子 加1,即舵機轉角加4.5°,到180°後,再加歸零
DutyNume=SteeringList[PhotoSwitchScan()];
}
void main() //主函數
{
TimerInit(); //調用 定時器初始化 函數
while(1) //循環系統
{
PhotoSwitchResp(); //調用 光電開關響應 函數
}
}
❼ 汽車如何編程
Define Class 環奇小大腳 As 舵機控制
Name = "環奇小大腳"
Procere Init()
This.COM口 = 9
This.速率 = 115200
Return DoDefault()
Endproc
Procere 定義油門曲線()
If Not DoDefault() Then
Return .F.
Endif
*-- 油門
Insert Into 油門曲線 (通道, 位置, 脈沖寬度) Values (0, -1, 1700) && 油門 - 倒車最大
Insert Into 油門曲線 (通道, 位置, 脈沖寬度) Values (0, 0, 1500) && 油門 - 中點
Insert Into 油門曲線 (通道, 位置, 脈沖寬度) Values (0, 0.05, 1450) && 油門 - 不動的
Insert Into 油門曲線 (通道, 位置, 脈沖寬度) Values (0, 1, 1350) && 油門 - 最大
*-- 方向舵
Insert Into 油門曲線 (通道, 位置, 脈沖寬度) Values (1, -1, 1450) && 方向舵 - 最左
Insert Into 油門曲線 (通道, 位置, 脈沖寬度) Values (1, 0, 1370) && 方向舵 - 中點
Insert Into 油門曲線 (通道, 位置, 脈沖寬度) Values (1, 1, 1250) && 方向舵 - 最右
Return .T.
Endproc
Enddefine
Define Class 舵機控制 As Form
Name = "舵機控制"
COM口 = 0
速率 = 115200
Procere Init()
This.定義油門曲線()
Return This.連接舵機控制板()
Endproc
Procere Destory()
*-- 釋放串口。
If Type("This.舵機控制板") = "O" Then
If This.舵機控制板.PortOpen Then
This.舵機控制板.PortOpen = .F.
Endif
Endif
Return .T.
Endproc
Procere 定義油門曲線()
*-- 創建油門曲線臨時表
Create Cursor 油門曲線 (通道 Integer, 位置 N(6, 4), 脈沖寬度 N(4))
Return .T.
Endproc
Procere 連接舵機控制板()
*-- 沒有「舵機控制板」就創建一個。
If Type("This.舵機控制板") <> "O" Then
This.AddObject("舵機控制板", "Olecontrol", "MSCommlib.MSComm")
Endif
*-- 打開串口。
If This.舵機控制板.PortOpen Then
This.舵機控制板.PortOpen = .F.
Endif
This.舵機控制板.CommPort = This.COM口
This.舵機控制板.Settings = Textmerge("<<This.速率>>,n,8,1")
If Not This.舵機控制板.PortOpen Then
This.舵機控制板.PortOpen = .T.
Endif
Return This.舵機控制板.PortOpen
Endproc
Procere 發送指令(通道, 位置)
Local 下限位置, 下限脈沖寬度, 上限位置, 上限脈沖寬度, 當前脈沖寬度, 串口指令代碼
m.下限位置 = -1
m.下限脈沖寬度 = 500
m.上限位置 = 1
m.上限脈沖寬度 = 2500
m.當前脈沖寬度 = 1500
m.串口指令代碼 = ""
*-- 1 找到當前位置最近的2個曲線值,如果找不到就取默認值 -1, 500 及 1, 2500。
*-- 2 生成指令。
*-- 3 發送給串口。
*-- 1
Select Top 1 * From 油門曲線 Where 通道 = m.通道 And 位置 = m.位置 Order By 位置 Desc Into Cursor curTemp
If Reccount("curTemp") > 0 Then
m.當前脈沖寬度 = curTemp.脈沖寬度
Else
Select Top 1 * From 油門曲線 Where 通道 = m.通道 And 位置 < m.位置 Order By 位置 Desc Into Cursor curTemp
If Reccount("curTemp") > 0 Then
m.下限位置 = curTemp.位置
m.下限脈沖寬度 = curTemp.脈沖寬度
Endif
Select Top 1 * From 油門曲線 Where 通道 = m.通道 And 位置 > m.位置 Order By 位置 Into Cursor curTemp
If Reccount("curTemp") > 0 Then
m.上限位置 = curTemp.位置
m.上限脈沖寬度 = curTemp.脈沖寬度
Endif
m.當前脈沖寬度 = Int((m.上限脈沖寬度 - m.下限脈沖寬度) / (m.上限位置 - m.下限位置) * (m.位置 - m.下限位置) + m.下限脈沖寬度)
Endif
*-- 2
m.串口指令代碼 = Textmerge("#<<m.通道>>P<<m.當前脈沖寬度>>")
Debugout m.串口指令代碼
*-- 3
This.舵機控制板.OutBufferCount = 0
This.舵機控制板.Output = 串口指令代碼 + Chr(13)
Endproc
Enddefine