单片机PWM输出控制直流电机(89c51系列、stc12c5a60s2系列)

2019-05-22来源: eefocus关键字:单片机  PWM输出  直流电机

【pwm是如何控制电机转速】

在本科学习中,学生所做的小车多数为使用lm298n或者tb6612来驱动简单的直流电机,我们需要单片机输出pwm波来控制直流电机转速。


直流电机的PWM调速原理为:通过调节驱动电压脉冲宽度的方式,并与电路中一些相应的储能元件配合,改变了输送到电枢电压的幅值,从而达到改变直流电机转速的目的。


【89C51系列单片机产生pwm波】

89c51单片机没有自带pwm发生器,如果想要使用传统的51单片机产生pwm,只能通过软件模拟的方法来产生pwm。


软件模拟可以分为软件延时和定时器两种方法。


1、软件延时输出pwm


使用延时函数产生频率为1kHz的pwm方波(@12MHz晶振)


#include

 

sbit pwm = P1^0;

 

void delay100us(unsigned int x)

{

unsigned char i;

while(--x)

{

i = 20;

while (--i);

}

}

 

int main(void)

{

while(1)

{

pwm = 1;

delay100us(6);

pwm = 0;

delay100us(4);

}

}

proteus仿真结果



使用简单的延时函数即可简单地模拟出pwm波。但是这种方法缺点很明显,就是在输出pwm时占用大量机器周期,此时若进行其他操作时会影响pwm的准确度。所以这种方法我们很少使用。


2、定时器产生pwm


使用定时器的溢出中断,在中断服务程序中改变IO口的电平高低,可以在多操作情况下输出比较准确的pwm波形。


比如我们使用定时器0。


定时器工作模式:我们设置定时器0工作模式为方式1,16位自动重载模式,这样可以获得较宽的调频范围。


定时器中断:16位自动重载模式下最多可以记65536个数,一旦超出这个数值,便会进入中断。定时器初值可以使用定时器计算器计算,方便快捷。


使用定时器0产生占空比可调,频率为100Hz的pwm波。


#include

 

sbit pwm = P1^0;

 

unsigned int PWM = 50; //pwm占空比为50%,可调占空比

unsigned char time = 0;

 

void Time0Init(void)

{

TMOD = 0X01; //定时器工作在方式1(16位定时器)

TH0 = 0XFF; //12M晶振下定时0.01ms

TL0 = 0X9c;

ET0 = 1; //开定时器1中断

EA = 1;

TR0 = 1; //开启定时器

}

 

void Timer0(void) interrupt 1

{

TH0 = 0XFF; //重装初值

TL0 = 0X9c;

time++;

}

 

void main(void)

{

Time0Init();

while(1)

{

if(time >= 100) //PWM周期为100*0.1ms

time = 0;

if(time < PWM)

pwm = 1;

else if(time >= PWM)

pwm = 0;

}

}

proteus仿真结果

由仿真结果来看,所得波形还是不算很精准,实际应用过程中还会有很多误差,但是这样已经比延时函数产生pwm的结果可靠的多。


【STC12C5A60S2系列单片机输出PWM】

我在做循迹小车时使用的是stc12c5a60s2单片机。stc12c5a60s2单片机集成了两路可编程计数器阵列(PCA)模块,可用于软件定时器、外部脉冲的捕捉、高速输出以及脉宽调制(PWM)输出。


使用stc12c5a60s2单片机的PCA模块可通过程序设定,使其工作于8位PWM模式,通过P13和P14输出。


如下图所示:


PWM输出频率取决于PCA定时器的时钟源。


 由于所有模块共用仅有的PCA定时器,所以它们的输出频率相同。各个模块的输出占空比是独立变化的,与使用的捕获寄存器[EPCnL, CCAPnL]有关。当寄存器CL的值小于[EPCnL,CCAPnL]时,输出为低;当寄存器CL的值等于或大于[EPCnL, CCAPnL]时,输出为高。当CL的值由FF变为00溢出时,[EPCnH, CCAPnH]的内容装载到[EPCnL, CCAPnL]中。这样就可实现无干扰地更新PWM。要使能PWM模式,模块CCAPMn寄存器的PWMn和ECOMn位必须置位。


 PCA时钟输入源频率由于PWM是8位的,所以


PWM频率 = PCA时钟输入源频率 / 256


PCA时钟输入源可以从以下8种中选择一种: SYSclk,   SYSclk/2,  SYSclk/4,SYSclk/6,SYSclk/8,SYSclk/12, 定时器0的溢出,ECI/P3.4输入。


当某个I/O口作为PWM使用时,该口状态:


PWM之前口的状态 PWM输出时口的状态

弱上拉/准双向 强推挽输出/强上拉输出,要加输出限流电阻1K-10K

强推挽输出/强上拉输出 强推挽输出/强上拉输出,要加输出限流电阻1K-10K

仅为输入/高阻输入 PWM无效

开漏 开漏

------


#include "stc12c5a.h"

 

void PCA_Init(void)

{

CCON = 0; //PCA初始化

CMOD = 0x00; //空闲时不计数,不产生中断,时钟源为Sysclk/12,PWM频率大约为4KHz

CL = 0x00; //PCA低8位清零

CH = 0x00; //PCA高8位清零

 

CCAPM0 = 0x42; //8位PWM模式,无中断

CCAP0H = 0xc0; //PWM0占空比(调节此处值调节PWM占空比)

CCAP0L = 0xc0; //PWM0占空比(调节此处值调节PWM占空比)

 

CCAPM1 = 0x42; //8位PWM模式,无中断

CCAP1H = 0x40; //PWM1占空比(调节此处值调节PWM占空比)

CCAP1L = 0x40; //PWM1占空比(调节此处值调节PWM占空比)

 

CR = 1; //启动PCA计数器

}

 

/*PWM占空比设置*/

void PWM_Set(unsigned char x,unsigned char y)

{

  CCAP0H = y; //设置比较值

  CCAP0L = y;

  CCAP1H = x; //设置比较值

  CCAP1L = x;

}

 

void main(void)

{

  P1M0 = 0xff; //P1口推挽输出

  P1M1 = 0x00;

  PCA_Init(); //PCA初始化

  

  PWM_Set(0x80,0x80);       //设置占空比

 

  while(1);            

}

此时产生的就是占空比为50%的PWM波。使用示波器可以在P13和P14口测得PWM输出波形。

--------------------- 

作者:小默haa 

来源:CSDN 

原文:https://blog.csdn.net/Xiaomo_haa/article/details/84189798 

版权声明:本文为博主原创文章,转载请附上博文链接!


关键字:单片机  PWM输出  直流电机 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic462583.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STC15F2K60S2设置内部时钟工作频率
下一篇:单片机按键检测笔记

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

AVR单片机测温基于DS18B20
#include<iom16v.h>#include<macros.h>#include<delay.h>#define uint unsigned int#define uchar unsigned char#define dula_set PORTA |=BIT(3) //数码管段选#define dula_clr PORTA &=~BIT(3)#define wale_set PORTA |=BIT(4)//数码管位选#define wale_clr PORTA &=~BIT(4) #define DQ_IN DDRA&=~BIT(5)#define DQ_
发表于 2019-11-20
AVR单片机控制继电器
#include "macros.h"#define uchar unsigned char#define uint  unsigned intvoid delay_ms(uchar i){uchar a,b;for(a=1;a<i;a++)   for(b=1;b<141;b++)   {;}}void main(void){DDRA=0X80;PORTA=0X80;DDRB=0XFF;PORTB=0XFF;DDRC=0X01;PORTC=0X01;DDRD=0X00;PORTD=0XFF;while(1)  {&nbs
发表于 2019-11-20
AVR单片机控制继电器
PIC16F877A单片机的PWM输出程序
//////////////////////////////////////////在PICC编译器主,调试通过,PIC16F877A的PWM信号输出#include<pic.h>#define uchar unsigned char#define uint unsigned int__CONFIG(0x1832);void delay(){uint k;for(k=0;k<5000;k++); }void main(){uchar k;T2CON=0X04;  //开定时器2CCPR1L=0X0F; //PWM匹配初值CCP1CON=0X3C;    //设置CCP1
发表于 2019-11-20
LCD1602在PIC单片机中的使用程序
#include<pic.h>__CONFIG(0x1832);        //芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡#define rs RA1#define rw RA2#define e  RA3const char web[ ]={' ','W','W','W','.','P','I','C','1','6','.','C',&#
发表于 2019-11-20
LCD1602控制要领(pic单片机)
PIC板使用LCD时需要将J401摘除LCD 4脚(RS数据/命令选择端H/L)-----RB2LCD 5脚(R/W读写选择端H/L)---------RB1LCD 6脚(E使能读H,写L->H)----------RB0控制要领:如无检忙则可在每次操作之前作适当延时即可.写命令:rs = 0;rw = 0;ep = 0->1->0;(用于初始化和在控制显示的位置)写数据:rs = 1;rw = 0;ep = 0->1->0;(用于显示内容)初始化:Write_COM(0x38);//双列16X2Write_COM(0x0C);//开显示;无不显光标;光标不闪烁Write_COM(0x06);//写入数
发表于 2019-11-20
PIC单片机在MPLAB-IDE中使用HitechC编译器
PIC单片机的C语言使用(一)在MPLAB-IDE中使用HitechC编译器 一、装入编译器:1、启动MPLAB-IDE,如下图所示选择Project-》Install Language Tool2、在弹出的安装语言工具对话框里“Language Suite”选项现在显示的是Microchip,点击后面的箭头来选择语言。 我使用的工具是HI-TECH PICCME,所以选择为“HI-TECH PICC”。3、接下来在“Tool Name”里选择编译器组件的调用路径,这里有“PICC Compiler”(C编译器)、“PICC Assembler”(汇编器)和“PICC Linker”(链接器)3项都需要设置
发表于 2019-11-20
PIC单片机在MPLAB-IDE中使用HitechC编译器
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved