用51单片机,输出PWM信号控制智能小车的小电机,汇编程序要怎么写?

80c51输出pwm控制直流电机的速度,汇编程序控制直流电机。
2024年11月18日 20:33
有4个网友回答
网友(1):

&& 我是用PC机控制的, 不知对你有无帮助.

*-- 舵机控制

Local 我的小大脚, 油门, 方向

油门 = 0
方向 = 1
我的小大脚 = Newobject("环奇小大脚")
*-- Inkey(4)
*-- 我的小大脚.发送指令(方向, 0)
*-- 我的小大脚.发送指令(油门, 0)
*-- Inkey(2)
*-- 我的小大脚.发送指令(油门, 0.5)
*-- Inkey(2)
*-- 我的小大脚.发送指令(油门, 0.9)
*-- Inkey(1)
*-- 我的小大脚.发送指令(方向, - 0.4)
*-- Inkey(8)
*-- 我的小大脚.发送指令(方向, 0)
*-- Inkey(2)
我的小大脚.发送指令(方向, 0)
我的小大脚.发送指令(油门, 0)

Cancel

Define Class 环奇小大脚 As 舵机控制
Name = "环奇小大脚"
Procedure Init()
This.COM口 = 9
This.速率 = 115200
Return DoDefault()
Endproc
Procedure 定义油门曲线()
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, 1200) && 方向舵 - 最右
Return .T.
Endproc
Enddefine

Define Class 舵机控制 As Form
Name = "舵机控制"
COM口 = 0
速率 = 115200
Procedure Init()
This.定义油门曲线()
Return This.连接舵机控制板()
Endproc
Procedure Destory()
*-- 释放串口。
If Type("This.舵机控制板") = "O" Then
If This.舵机控制板.PortOpen Then
This.舵机控制板.PortOpen = .F.
Endif
Endif
Return .T.
Endproc
Procedure 定义油门曲线()
*-- 创建油门曲线临时表
Create Cursor 油门曲线 (通道 Integer, 位置 N(6, 4), 脉冲宽度 N(4))
Return .T.
Endproc
Procedure 连接舵机控制板()
*-- 没有“舵机控制板”就创建一个。
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("<>,n,8,1")
If Not This.舵机控制板.PortOpen Then
This.舵机控制板.PortOpen = .T.
Endif
Return This.舵机控制板.PortOpen
Endproc
Procedure 发送指令(通道, 位置)
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("#<>P<>")
Debugout m.串口指令代码
*-- 3
This.舵机控制板.OutBufferCount = 0
This.舵机控制板.Output = 串口指令代码 + Chr(13)
Endproc
Enddefine

网友(2):

用的是那种型号的单片机呢?我用的是P89V51RD2带PWM输出的:
#include
#define uchar unsigned char
#define uint unsigned int
sbit k=P3^2;
sbit k1=P2^0;
sbit k2=P2^1;
sbit k3=P2^2;
sbit k4=P2^3;

delay1ms(uint x)
{
uchar a;
while(x--)
{
for(a=0;a<125;a++);
}
}
uchar b=0,c=50,d;
main()
{EA=1;EX0=1;
CMOD=0x04;//脉冲选择,使用T0作为PCA的计数时钟源
TMOD=0x02;//设定T0的工作方式为方式2
TH0=0x90;//设定T0初植,该值决定PWM脉冲的频率
TL0=0x90;
TR0=1;//启动定时器T0
while(1)
{
CCON=0;//关闭PCA计数器
CCAPM1=0;//关闭模块1
CCAPM3=0;//关闭模块3
CCAPM2=0x42;//开启模块2
CCAPM4=0x42;//开启模块4
CCAP2H=c;//设置占空比
CCAP4H=b;
CCON=0x40;//开启PCA计数器

}
}
key()interrupt 0
{
delay1ms(10);
if(k==0)
{
if(k1==0){b=150;P0=0;}
if(k2==0){b=100;P0=0xff;}
if(k3==0){b=50;P0=0x78;}
if(k4==0){b=10;P0=0x89;}

}
}

四按键控制4档转速,这只是一个动作

网友(3):

如果用全桥控制的话,自己搭起来的最好有一个使能控制端,像L293,L298可以从使能端输入PWM信号进行调速,剩下的可以控制正转,反转。

中午的时候试了一下用C51的定时器模拟PCA模块那样的PWM输出,即使用汇编程序返回的时间会积累。还是网上的示例参考……

还是用STC的51,12系列(STC12C5608AD)有自带PCA可以PWM输出(还有8路鸡肋的ADC),价格在5-7块之间……
最近也在搞小车~

网友(4):

控制小电机,是指控制速度???还是转向??居然还要PWM,你有用步进电机吧。那这个汇编是给哪种电机驱动的呢??每种驱动的程序不同哦。