专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

51单片机软件产生PWM驱动直流电机,频率占空比可调

作者:竹园电科技   来源:本站原创   点击数:  更新时间:2014年03月18日   【字体:

 做了一个实例,以前都是用AVR直接硬件生成PWM,方便快捷,几条语句的问题,驱动能力还强,从来没仔细想过如何用51单片机软件方法做一个,现在非要用51单片机做,那就直接开始制作,首先硬件焊接,软件编程,只说程序部分,程序采用占空比可调,频率可调的思路,需要用到2个定时器,1个定时器输出占空比信号数据,另个定时器标定频率,具体的程序稍后放出,其实也不太难,问题1:如何做到定时器内的软件时间低于定时器定时中断时间 ,频率低无所谓,频率要是到了20khz,这个问题就有些困难,有些if语句进入循环后可以到20ms,这个问题解决采用51单片机特有的中断嵌套解决。
问题2 :如何做到外部中断、定时器0、定时器1中断优先级分级?解决方法就是分别在各自的服务程序中处理好中断优先级。

 



 

 视频:

 

视频演示的仅仅是占空比的变化,题目为:基于51单片机的出租车计价器设计(霍尔元件版本+减速、等待计时等功能)

=============

以下测试程序为版本V1.0的测试程序,非视频中的程序,没有加入PWM控制,只是脉冲检测部分的。

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int

sbit cs1=P1^0;
sbit cs2=P1^1;
sbit cs3=P1^2;
sbit cs4=P1^3;

sbit start=P2^1;
sbit turn=P2^0;

uint s,n=500;
uint m=500;
bit val=0;
bit flag=0;

uchar code tab[]={
 0xc0,0xf9,0xa4,0xb0,
 0x99,0x92,0x82,0xf8,
 0x80,0x90
};
uchar code tabpoint[]={
 0x40,0x79,0x24,0x30,
 0x19,0x12,0x02,0x78,
 0x00,0x10
};

void delay(uint ms)
{
 uint i,j;
 for (i=ms;i>0;i--)
    for (j=110;j>0;j--);
}

void delayus(uint us)
{
 while(--us);
}

void displayday()
{

 P0=tab[n/1000];
 cs1=0;
 delayus(20);
 cs1=1;
 P0=0xff;

 P0=tabpoint[n%1000/100];
 cs2=0;
 delayus(20);
 cs2=1;
 P0=0xff;

 P0=tab[n%100/10];
 cs3=0;
 delayus(20);
 cs3=1;
 P0=0xff;

 P0=tab[n%10];
 cs4=0;
 delayus(20);
 cs4=1;
 P0=0xff;
}

void displaynight()
{

 P0=tab[m/1000];
 cs1=0;
 delayus(20);
 cs1=1;
 P0=0xff;

 P0=tabpoint[m%1000/100];
 cs2=0;
 delayus(20);
 cs2=1;
 P0=0xff;

 P0=tab[m%100/10];
 cs3=0;
 delayus(20);
 cs3=1;
 P0=0xff;

 P0=tab[m%10];
 cs4=0;
 delayus(20);
 cs4=1;
 P0=0xff;
}
void displayoff()
{
 P0=0xff;
 cs1=cs2=cs3=cs4=0;
}

void main()
{
 TMOD=0x02;
 TH0=(256-1)/256;
 TL0=(256-1)%256;
 EA=1;
 ET0=1;
 TR0=1;
 EX0=1;
 IT0=0;
 while(1)
 {
  if (start==0&&flag==0)
  {
   displayday();
  }
  if (start==0&&flag==1)
  {
   displaynight();
  }
  if (start==1)
  {
   displayoff();
  } 
 }
}

void jisuan() interrupt 0
{
 s++;
 delay(1);
 if (val==1&&s==1000)
 {
  n=n+130;
  m=m+200;
  s=0;
  if (n==9990)
  {
   n=0;
   val=0;
  }
  if (m==9900)
  {
   m=0;
   val=0;
  }
 }
 if (s==3000)
 {
  val=1;
  s=0;
 }

}

void jiance() interrupt 1
{
 if (turn==0)
 {
  delayus(20);
  if (turn==0)
  {
   flag=!flag;
  }

 }
}

关闭窗口

相关文章