5iMX宗旨:分享遥控模型兴趣爱好

5iMX.com 我爱模型 玩家论坛 ——专业遥控模型和无人机玩家论坛(玩模型就上我爱模型,创始于2003年)
查看: 6218|回复: 26
打印 上一主题 下一主题

简单的用单片机控制舵机的实验,给初学者做个参考(10月21日加个4通的模拟波形图)

[复制链接]
跳转到指定楼层
楼主
发表于 2012-10-12 23:21 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式
本帖最后由 铁皮 于 2012-10-21 20:05 编辑

N年没发贴了,先上程序,这是可以直接编译后写入单片机的程序,不要笑话,程序还有很大优化的余地,喜欢的自已优吧
ORG 0000H
LJMP MAIN
ORG 000BH  ;周期定时器T0中断服务程序
LJMP INTT0
ORG 001BH  ;占空比定时器T1中断服务程序
LJMP INTT1
ORG 0100H
MAIN: CLR P1.7  ;P1.7置低电平,第一个周期全低电平
MOV IE, #00H ;关所有中断
SETB PT0  ;T0中断为最高优先级
MOV TMOD, #11H ;T1为16位,T0为16位
MOV TH0, #0B1H ;T0初值45536,周期20mS
MOV TL0, #0E0H
MOV R0, #7DH ;占空值寄存器赋初值125,中间位置,R0范围:0-250
SETB EA  ;开总中断
SETB ET0  ;允许T0中断
SETB ET1  ;允许T1中断
SETB TR0  ;开启T0
BUTTON: MOV P3, #0FFH ;P3=1再读判断
JNB P3.0, BUTTON1 ;没按下P3.0则判断P3.1,按下P3.0则转+程序
JNB P3.1, BUTTON2 ;没按下P3.1继续扫描,按下P3.1时转-程序
AJMP BUTTON

;周期定时器T0中断服务程序,主要功能为将输出变高,计算T1值
INTT0: PUSH ACC
CLR TR1  ;停止T1定时器
MOV TH0, #0B1H ;T0初值45536,周期20mS
MOV TL0, #0E0H ;重装T0初值
STT1: SETB P1.7
MOV A, R0 ;T1=65536-((R0*4)+1000)=64536-R0*4
MOV B, #4H ;R0*4
MUL AB  ;R0*4
MOV  R6, A ;将低8位寄存入R6,空出A
MOV  A, #18H
SUBB A, R6 ;#18H-R6得出低8位值
MOV TL1, A ;装计算出的低8位装入T1
MOV A, #0FCH ;计算高8位
SUBB A, B ;高8位-#0FC
MOV TH1, A ;装计算出的高8位装入T1
SETB TR1  ;开启T1定时器
CLR  C
OUT0:POP ACC
RETI
;占空比定时器T1中断服务程序
INTT1: PUSH ACC
CLR P1.7  ;P1.7=0
POP ACC
RETI
;P3.0+键程序
BUTTON1:ACALL DL20MS  ;调用延时20mS程序消抖
JB P3.0, BUTTON ;没按P3.0则转回BUTTON(P3.0=1转)
CJNE R0,#0FAH,R0NO250;按+程序,先判R0=250已到最大,不转
AJMP BUTTON  ;已到最大跳回
R0NO250:INC R0  ;没到最大则R0+1
AJMP BUTTON
;P3.1-键程序
BUTTON2:ACALL DL20MS  ;调用延时20mS程序消抖
JB P3.1, BUTTON ;没按P3.1则转回BUTTON(P3.1=1转)
CJNE R0,#00H,R0NO00 ;-程序,先判R0=00不转
AJMP BUTTON  ;跳出,等待按键
R0NO00: DEC R0  ;R0-1
AJMP BUTTON
;20mS延时子程序
DL20MS: MOV R1, #0FAH ;R1赋值250
MOV R2, #28H ;R2赋值40,40*250=10000
XHR1: DJNZ R1, XHR1
MOV R1, #0FAH
DJNZ R2, XHR1
RET
END

说明:
用的是89C2051,白菜价2元一片
p1.7输出信号
P3.0按键逆时针转,p3.1按键顺时针转
T0做周期定时器,周期为20ms,时间到使p1.7输出高电平。
R0做占空比寄存器,数值通过按键控制在0至250之间,
T1做高电平时间定时器,溢出时间为1至2mS之间(要想再精确点还得减去T1启动前运行程序的时间),时间到使p1.7输出低电平,时间值由R0决定
按P3.0时R0慢慢增加,直至250,按P3.1时R0慢慢减小,直至0,通过T0中断服务程序中用R0计算得出对应T1值在1至2mS范围
用Keil uVision4调试程序、生成HEX文件,用ISIS 7 Professional模拟、看波形,用硕飞SP300写入单片机,简单搭的2051最小系统
上机实验舵机角度变化范围为90度,将T1值范围加大应该角度变化会变大
开机时R0设为125,即中间位置

开机时在中间



顺时针到底


逆时针到底


手绘简图,P1.7要直驱那个1K上拉电阻不能少

10月21日加个4通的测试波形图(CH1:0度,CH2:72度,CH3:90度,CH4:180度)4个通道的角度由4个存储器的值决定,4通的程序跟上面单通相差较大,0-180度,8位分辨率,只用了T0一个定时器,为的是留一个定时器做串行通信用,不要笑话,我还不会串口程序,8通及以下用51都没问题,而且程序变化不大


欢迎继续阅读楼主其他信息

27
发表于 2013-5-10 17:44 | 只看该作者
好贴~学习学习~
26
发表于 2013-5-10 12:17 | 只看该作者
kingM 发表于 2013-5-9 22:55
老夫前两年写过一个汇编的STC的51小系统,可以接收红外遥控,同时可以控制主电机,以及好几路PWM舵机。
...

方便给代码参考一下不?
个人感觉51的12mhz下,可以实现pwm控制,但是精度完全做不到。更别说还要处理红外的中断。

25
发表于 2013-5-9 22:55 | 只看该作者
gyro 发表于 2012-10-22 10:54
用C51,C语言写的程序,舵机玩死了也就只能做到4位步进。。。折腾死我了。。。
读取红外遥控信号,解码,然 ...

老夫前两年写过一个汇编的STC的51小系统,可以接收红外遥控,同时可以控制主电机,以及好几路PWM舵机。
关键是安排好各种时序,不能用常见的教科书式写法,
老夫的小把戏是用“载波计数式”算法来解调红外遥控信号,即设置38Khz的中断,以此中断为基准进行遥控脉宽的计数,根据计数进行红外信号的解码。
而PWM则是设置统一的短时间中断,以此中断计数,在计数的基础上可以实现多路的PWM控制。


24
发表于 2013-5-9 20:48 | 只看该作者



老师,请问为什么p1.7必须有那个电阻,什么意思,可以详细介绍下吗?

23
发表于 2013-5-7 20:46 | 只看该作者
留名回访
22
发表于 2012-10-23 11:38 | 只看该作者
又见汇编。顶强人~~~~~~~
曾经也用汇编写51程序,发现过一年回来就看不懂。所以后来换ICC来写AVR程序,移植性好多了。
2051在12M时钟下,只要安排得当,输出分辨率1uS的8通道是没问题的。
21
发表于 2012-10-23 10:47 | 只看该作者
2.5ms对于c51这种12T的芯片,真没啥可干的。。。

真是落后了。。。得换1T的芯片了
20
 楼主| 发表于 2012-10-23 10:05 | 只看该作者
gyro 发表于 2012-10-23 09:46
没错,目前我就只会循环延时法。结果11.095mhz的情况下,实际测量一个++就高达2us了。加上判断,本来1000 ...

我认为这种程序中最重要的是保证输出的脉冲宽度和周期的准确性,其它的事都可以在空闲的时候再做,所以决定宽度和周期的定时器中断为最高优先级。以4通来说,我是将20MS平分给4个通道,每个通道5MS的时间,一个通道中高电平时间最长是2.5MS,也就是说至少还有2.5MS的纯空闲时间可以干其它事,足够了。8通道时就紧张点,每个通道只得2.5MS,只能在定时器计数期间的0.5MS-2.5MS之间干其它事,应该也足够了,不够就任由中断打断也没多大影响。
19
发表于 2012-10-23 09:46 | 只看该作者
铁皮 发表于 2012-10-23 09:15
能做到4位应该就能做到8位啊,一个通道用一个存储器就是8位了,可能是C程序太臃余,不太好精确的计算时间 ...

没错,目前我就只会循环延时法。结果11.095mhz的情况下,实际测量一个++就高达2us了。加上判断,本来1000us的信号宽度,就没剩下几个。。。
计时器用在红外接收上了。

18
 楼主| 发表于 2012-10-23 09:15 | 只看该作者
gyro 发表于 2012-10-22 10:54
用C51,C语言写的程序,舵机玩死了也就只能做到4位步进。。。折腾死我了。。。
读取红外遥控信号,解码,然 ...

能做到4位应该就能做到8位啊,一个通道用一个存储器就是8位了,可能是C程序太臃余,不太好精确的计算时间吧
17
发表于 2012-10-23 00:17 | 只看该作者

可以用HC-11 433无线串口,使用方便,支持3~5V宽电压使用,自己写加密通讯协议。还可以同时使用N个组网,通讯协议和485一样
16
 楼主| 发表于 2012-10-22 10:56 | 只看该作者
谁能提供个单片机之间无线通信的好办法,最好是加密的,不会相互干扰
15
发表于 2012-10-22 10:54 | 只看该作者
用C51,C语言写的程序,舵机玩死了也就只能做到4位步进。。。折腾死我了。。。
读取红外遥控信号,解码,然后控制舵机完成一个动作。就这点,折腾死我。。唉
14
发表于 2012-10-21 23:43 | 只看该作者
不错用汇编写功底深厚啊
13
发表于 2012-10-19 19:05 | 只看该作者
这帖子要留个名备查。
12
发表于 2012-10-15 21:41 | 只看该作者
太强大了
11
发表于 2012-10-15 18:26 | 只看该作者
分辨率10微秒的
10
发表于 2012-10-15 18:23 | 只看该作者
pic单片机也可以,还可用PICBASIC PRO编程,与C一样简单:
12f509中的舵机测试程序:
INPUT GPIO.0
INPUT GPIO.1
INPUT GPIO.2
OUTPUT GPIO.5
B1 VAR BYTE
B2 VAR BYTE
B3 VAR BYTE
B1=0
B2=0
B3=150
LOW GPIO.5
MAIN:
IF GPIO.1=0 THEN B1=B1+1
IF B1=5 THEN B3=B3+1
IF B1=5 THEN B1=0
IF B3>=200 THEN B3=200
IF GPIO.2=0 THEN SUBGER
IF GPIO.0=0 THEN B3=150
PAUSE 18
PULSOUT GPIO.5,B3
GOTO MAIN
SUBGER:
IF GPIO.2=1 THEN MAIN
B2=B2+1
IF B2=5 THEN B3=B3-1
IF B2=5 THEN B2=0
IF B3<=100 THEN B3=100
PAUSE 18
PULSOUT GPIO.5,B3
GOTO SUBGER
9
发表于 2012-10-14 21:15 | 只看该作者
高手云集呀
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

关闭

【站内推荐】上一条 /1 下一条

快速回复 返回顶部 返回列表