智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 4246|回复: 8
打印 上一主题 下一主题

怎么用51 单片机产生pwm

[复制链接]

3

主题

16

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
301
QQ
威望
244
贡献
49
兑换币
0
注册时间
2010-9-18
在线时间
4 小时
跳转到指定楼层
1#
发表于 2010-10-24 11:45:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
要做巡线小车,用51单片机通L298驱动直流电机,需要用51产生pwm?

39

主题

593

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1694
威望
989
贡献
401
兑换币
86
注册时间
2008-12-13
在线时间
152 小时
2#
发表于 2010-10-24 20:55:26 | 只看该作者
两种方法,
第一种是查询法,用一个变量保存PWM占空比数值,然后程序不停查询定时器的计数值,与之前的变量相比,相等以后就把相应的PWM引脚值置0,等定时器溢出中断时,再把引脚置1,这样调整变量就可以改变PWM占空比了。 这种方法,原理就是一般硬件PWM发生器的原理,只不过用软件来实现了。
第二种是中断法,就是先在定时器里装入一个值,等溢出中断以后,翻转PWM引脚,再装入另一个计数值,这样就可以产生PWM波,通过调节两个值的大小就可以改变PWM波的占空比和周期。不过,改变占空比时,需要计算出两个计数值。
另外,STC的51单片机有很多都有PWM模块了,可以使用那些单片机,比较方便。
回复 支持 反对

使用道具 举报

3

主题

16

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
301
QQ
威望
244
贡献
49
兑换币
0
注册时间
2010-9-18
在线时间
4 小时
3#
 楼主| 发表于 2010-10-24 21:46:34 | 只看该作者
回复 2# zouyf12


    谢谢哈
回复 支持 反对

使用道具 举报

4

主题

22

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
367
QQ
威望
278
贡献
47
兑换币
14
注册时间
2010-11-4
在线时间
21 小时
4#
发表于 2010-11-4 18:37:12 | 只看该作者
受教咯
回复 支持 反对

使用道具 举报

4

主题

57

帖子

0

精华

高级会员

Rank: 4

积分
804
威望
456
贡献
170
兑换币
0
注册时间
2012-2-10
在线时间
89 小时
5#
发表于 2012-3-25 21:58:55 | 只看该作者
谢谢
回复 支持 反对

使用道具 举报

1

主题

55

帖子

0

精华

高级会员

Rank: 4

积分
935
威望
460
贡献
249
兑换币
203
注册时间
2013-6-14
在线时间
113 小时
6#
发表于 2013-6-15 17:33:29 | 只看该作者
有用:lol
回复 支持 反对

使用道具 举报

0

主题

52

帖子

0

精华

跨届大侠

Rank: 10Rank: 10Rank: 10

积分
7237
威望
3658
贡献
2421
兑换币
1612
注册时间
2013-6-15
在线时间
579 小时
7#
发表于 2013-6-16 00:55:16 | 只看该作者
//数度值:go/back(0~200,0~200)
#include <at89x51.h>
#define uchar unsigned char
#define uint unsigned int
void motor_r_z(void);//右边电动机正转
void motor_l_z(void);//左边电动机正转
void motor_r_f(void);//右边电动机反转
void motor_l_f(void);//左边电动机反转
void back(uchar,uchar); //小车后退
void go(uchar,uchar);//小车前进
void stop(void);//小车停止
void left(void);//小车左转
void right(void);//小车右转


sbit PWM1=P2^0;
sbit PWM2=P2^2;
sbit PWM3=P2^3;
sbit PWM4=P2^5;
sbit EN1=P2^1;
sbit EN2=P2^4;

sbit left_k=P0^6;
sbit right_k=P0^7;
sbit start_k=P3^2;
sbit stop_k=P3^3;

sbit sound=P2^7;

uchar data t_0;
uchar data motor_r;
uchar data motor_l;
uchar data Value;
uchar data mid;

//**延时子程序**///
void delay_1ms(uint n)
{
        uint i,j;
        for(j=n;j>0;j--)
        for(i=20;i>0;i--);
}

void ini(void)
{
////T0初始化///
TMOD=0x01; //T0工作在方式1
TH0=0xff; //装入T0初值
TL0=0xf6;
TR0=1;//开T0中断
ET0=1;//T0允许中断
EA=1;
//////////////////////
t_0=0;
/////////////////////
P2=0;
sound=1;
}
void Sound(void)
{
///蜂鸣器响///
sound=0;
delay_1ms(30);
sound=1;
}
void start(void)
{
   uchar a;
   aa:
   while(start_k);
   for(a=0;a<50;a++)
   {
   delay_1ms(1);
   while(start_k)
   goto aa;
   }
   Sound();
   back(150,150);
}
void go(uchar left_motor,uchar right_motor)//直行(右,左)
{
Value=right_motor;
motor_r_z();
Value=left_motor;
motor_l_z();
}
void back(uchar left_motor,uchar right_motor)//直行(右,左)
{
Value=right_motor;
motor_r_f();
Value=left_motor;
motor_l_f();
}
void motor_r_z(void)//右边电动机正转
{
  motor_r=200-Value;
  PWM2=1;
  EN1=1;
}
void motor_l_z(void)//左边电动机正转
{
  motor_l=200-Value;
  PWM4=1;
  EN2=1;
}
void motor_r_f(void)//右边电动机反转
{
  motor_r=Value;
  PWM2=0;
  EN1=1;
}
void motor_l_f(void)//左边电动机反转
{
  motor_l=Value;
  PWM4=0;
  EN2=1;
}

void stop(void)
{
EN2=0;
EN1=0;
}
void time0(void) interrupt 1 using 2
{
TR0=0;
TH0=0xff;
TL0=0xf6;
++t_0;
ACC=t_0;
CY=0;
ACC-=motor_r;
if(CY==1)
{
PWM1=1;
goto PWM_2;
}
PWM1=0;
PWM_2:
ACC=t_0;
CY=0;
ACC-=motor_l;
if(CY==1)
{
PWM3=1;
goto HIGHT;
}
PWM3=0;
HIGHT:
ACC=t_0;
if(ACC!=0xc9)
goto EXIT;
ACC=0;
t_0=ACC;
EXIT:
TR0=1;
}  
void main(void)
{
uchar a;
ini();
start();
while(1)
{
         go(100,100);

}
}
回复 支持 反对

使用道具 举报

0

主题

5

帖子

0

精华

注册会员

Rank: 2

积分
41
威望
32
贡献
5
兑换币
9
注册时间
2013-7-20
在线时间
2 小时
毕业学校
高级中学校
8#
发表于 2013-7-21 19:00:40 | 只看该作者
kankan
回复 支持 反对

使用道具 举报

1

主题

39

帖子

0

精华

高级会员

Rank: 4

积分
539
威望
287
贡献
166
兑换币
184
注册时间
2012-12-11
在线时间
43 小时
9#
发表于 2013-8-31 17:01:46 | 只看该作者
第二种是中断法,就是先在定时器里装入一个值,等溢出中断以后,翻转PWM引脚,再装入另一个计数值,这样就可以产生PWM波,通过调节两个值的大小就可以改变PWM波的占空比和周期。不过,改变占空比时,需要计算出两个计数值。
另外,STC的51单片机有很多都有PWM模块了,可以使用那些单片机,比较方便。

#include<AT89X51.H>
#define Moto1 P2_0 //驱动电机信号的输出端口
#define Moto2 P2_1
#define Duoj P2_4 //舵机信号的输出端口
unsigned char D_count,D_num;
unsigned char M_count,M_num;
void main()
{
Moto1=1;
P2_2=0;
Duoj=1;
TMOD=0x11; //Timer0 和Timer1 同时配置为模式1,16 位计数模式
TH0=(65536-40)/256; //定时器初值设置
TL0=(65536-40)%256; //
TH1=(65536-2000)/256;
TL1=(65536-2000)%256;
TR0=1; //允许定时器0 计数
ET0=1; //允许定时器0 溢出中断
TR1=1;
ET1=1;
EA=1; //开启总中断
第四章 程序设计
-20-
D_num=25;
while(1)
{
}
}
void t0()interrupt 1
{
D_count++;
if(D_count==D_num)
Duoj=0;
if(D_count==250)
{
D_count=0;
Duoj=1;
}
TH0=(65536-40)/256; //重装初值
TL0=(65536-40)%256;
}
void t1()interrupt 3
{
M_count++;
if(M_count==M_num)
{
Moto2=1;
}
if(M_count==5)
{
M_count=0;
Moto2=0;
}
TH1=(65536-2000)/256;
TL1=(65536-2000)%256;
}
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关于我们|联系我们|小黑屋|智能车制作 ( 黑ICP备2022002344号

GMT+8, 2024-9-28 03:30 , Processed in 0.052082 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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