datasheet

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

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

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

推荐阅读

STM32L0xx_HAL_Driver库的使用——UART

单片机型号:STM32L051C8T6开发环境MDK5.12库版本:STM32L0xx_HAL_Driver V1.1.0主机环境:Windows XP之前一直使用的STM32F030C8T6单片机来做开发,因需求更改更换了一个新型号STM32L051C8T6,主要是用到了其低功耗特性,本以为直接把代码拷贝一下就可以使用了,结果是太天真了,STM32F030C8T6使用的库是STM32F0_StdPeriph_Lib而STM32L051C8T6使用的库是STM32L0xx_HAL_Driver两者的差别还是很大的,而且官方也推荐使用后者,没办法,重新学习一下吧。。。参考其例程磕磕绊绊的勉强可以写一个工程了,这里写一下有关UART
发表于 2019-06-15

89C52单片机通过LCD1602显示任意长度字符串

1,开发板:89C52RC开发板。2,开发环境:Keil uv4打算通过89C52在LCD1602上面显示任意长度的字符串,因为该显示屏只能显示两行,每行只能显示16个英文字符,所以打算写个函数,实现在需要显示超过16个字符的时候,能够从液晶屏右边向左边移动显示文字,网上好像没有相关资料,于是只能自力更生,调试了几个小时,终于搞定了void main(){  uchar i; P0 = 0; P1 = 0; lcd_init(); lcd_clear();  while(1) { lcd_clear(); lcd_write_string(6, 0, "123456789abcdefghijklmn
发表于 2019-06-13
89C52单片机通过LCD1602显示任意长度字符串

STM32单片机学习笔记——USART串口通信

首先,USART是什么呢?USART是一个全双工通用同步/异步串行收发模块,该接口是一个高度灵活的串行通信设备。(来自百度)这是官方解释,而我对它的通俗解释是:这是一个用于和其他设备(如电脑、单片机等)通信(交换数据、信息等)的端口,就像手机数据线那样。当然,这只是我的一种通俗看法,大家经过了深入的学习之后,一定会产生更为准确、成熟的看法。我所学习的,就是通过这个模块来实现单片机和电脑之间的通信,并以此为基础,实现利用电脑来简单地控制单片机的目的。那么,我们来简单地看一看我们这段代码由哪几部分组成:1. 用于存储相关配置的结构体。2. 变量Temp,用于存储从电脑接收到的信息。3. 配置TX、RX、时钟、串口、LED灯。4. 预先
发表于 2019-06-13

STM32单片机串口功能实现

使能串口时钟 RCC_APB2PeriphClockCmd   void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)   参数1:uint32_t RCC_APB2Periph   串口号          RCC_APB2Periph_USART1   参数2:FunctionalState NewState          ENABLE 开启使能
发表于 2019-06-12

基于stm32f10x单片机USB流程理解

主要思路:文件从main.c文件到main()函数开始:主要重点是,开启中断:USB_Interrupts_Config();STM32不像C51单片机那样可以用过interrupt关键字来定义中断响应函数,STM32的中断响应函数接口存在中断向量表中。其格式如下:在文件hw_config.c里:/* Enable the USB interrupt */NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority
发表于 2019-06-12

STC单片机用户应用程序区和ISP监控程序区的区别

用户应用程序区(AP区):是指用户自己编写的程序区ISP监控程序区:ISP区是指芯片出厂时就已经固化在单片机内部的一段程序,STC单片机可以进行ISP串行下载程序,这就是因为芯片在出厂时已经在单片机内部固化了ISP引导码,程序首次上电时先会从ISP区开始执行代码,体现在实际实验中时,就是我们在下载程序时,先要点击下载软件界面上的下载,然后再开启单片机电源,当单片机检测到上位机有下载程序的需要时,便启用ISP下载功能给单片机下载程序。若经过短暂的时间没有检测到上位机有下载程序的需求,单片机便会从用户应用程序区(AP区)开始执行代码。
发表于 2019-06-03

小广播

何立民专栏

单片机及嵌入式宝典

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

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