分享两种STC15定时器模拟PWM的方法

发布者:太白山人最新更新时间:2020-02-29 来源: 51hei关键字:STC15  定时器  模拟PWM 手机看文章 扫描二维码
随时随地手机看文章

刚刚搜了一下,发现坛里还没有这样分析PWM的帖子,然后发了一个。
手电LED控制或马达转速控制都离不开PWM,下面有两种方法可以模拟PWM的。如果不正确希望各位指教。
 

 
//用定时器装载方式模拟PWM,这种方法PWM周期短,分辩率高,1毫秒内可以做到11000格分辩率,
//缺点:高低电平会的百分之一格不受控制
#include "reg51.h"
#include
sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr P3M1 = 0xb1;
sfr P3M0 = 0xb2;
sfr AUXR      = 0x8e;//辅助寄存器
sbit P20   = P2^0; //PWM输出脚   
sbit P17   = P1^7; //按键增量
sbit P16   = P1^6; //按键减少   
unsigned int HIGHDUTY,LOWDUTY;//高低时间存放寄存器
unsigned char num;//记录分辩个数
bit flag;
void Delayms(unsigned int ms)//1mS@11.0592MHz
{unsigned char i, j;
        while(ms--)
        {        _nop_();
        _nop_();
        _nop_();
                i = 11;
        j = 190;
        do
        {
                while (--j);
        } while (--i);}
}
void main()
{  
        P0M0 = 0x00;
        P0M1 = 0x00;
        P1M0 = 0x00;
        P1M1 = 0x00;
        P2M0 = 0x00;
        P2M1 = 0x00;
        P3M0 = 0x00;
        P3M1 = 0x00;
        AUXR = 0x80;        //定时器0为1T模式
        TMOD &= 0xf0;       //设置定时器0为模式0(16位自动重装载)
        TR0 = 1;            //定时器0开始计时
        ET0 = 1;            //使能定时器0中断
        EA = 1;
        HIGHDUTY=54477+(11058/255)*num;
        LOWDUTY=54477+(11058/255)*(256-num);
    while (1)
        {
       if(!P17)
        {
        Delayms(90);          
         if(!P17)
        {
        //while(!P17);
        num++;             //按制分辩率,uchar字符型范围0~255格
        HIGHDUTY=54477+(11058/255)*num;/*求占空比高位,0xD4CD = 54477;
        程序装载初始值54477一直跑到65535共花时间1000微秒,
        65535-54477=11058,11058就是1000微秒。
        (11058再除以分辩率255)等于一格所需的时间,要点空比高位多少就剩多少 */
        LOWDUTY=54477+(11058/255)*(255-num);//求占空比高位低位
         }
       }
         if(!P16)
        {
        Delayms(90);          
         if(!P16)
        {
        //while(!P16);
        num--;                        
        HIGHDUTY=54477+(11058/255)*num;
        LOWDUTY=54477+(11058/255)*(255-num);//
         }
       }
    }
}
void tm0() interrupt 1//定时器0中断服务程序
{
   flag = !flag; 
    if (flag)//反转标志去执行高低电平的时间   
    {
        TL0 = HIGHDUTY;                //设置定时初值
        TH0 = HIGHDUTY>>8;//设置定时初值
        P20=1;//输出高电位
    }
    else
    {
        TL0 = LOWDUTY;                //设置定时初值
        TH0 = LOWDUTY>>8;        //设置定时初值
        P20=0;//输出低电位
    }
}

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

//用定时器计算方式模拟PWM,高低电平容易控制
//缺点:这种方法周期能做到1KHz以内,大多数马达或调光设置会闪烁
#include "reg51.h"
#include
sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr P3M1 = 0xb1;
sfr P3M0 = 0xb2;
sfr P4M1 = 0xb3;
sfr P4M0 = 0xb4;
sfr P5M1 = 0xC9;
sfr P5M0 = 0xCA;
sfr P6M1 = 0xCB;
sfr P6M0 = 0xCC;
sfr P7M1 = 0xE1;
sfr P7M0 = 0xE2;
sfr AUXR      = 0x8e;//辅助寄存器
sbit P20   = P2^0; //PWM输出脚   
sbit P17   = P1^7; //按键增量
sbit P16   = P1^6; //按键减少   
unsigned char num;//记录分辩个数
void Delayms(unsigned int ms)                //1mS@11.0592MHz
{unsigned char i, j;
        while(ms--)
        {        _nop_();
        _nop_();
        _nop_();
                i = 11;
        j = 190;
        do
        {
                while (--j);
        } while (--i);}
}
void main()
{   P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    AUXR = 0x80;            //定时器0为1T模式
    TMOD &= 0xf0;           //设置定时器0为模式0(16位自动重装载)
    TR0 = 1;                //定时器0开始计时
    ET0 = 1;                //使能定时器0中断
    EA = 1;
    num=10;  //给初始值
    while (1)
        {
       if(!P17)
        {
        Delayms(10);          
         if(!P17)
        {        
                num++;
         }
       }
        if(!P16)
         {
        Delayms(10);          
         if(!P16)
        {
                num--;
         }
       }
    }
}
void tm0() interrupt 1//定时器0中断服务程序
{ static unsigned char k;
        TL0 = 0xF5;        //设置定时初值 按1T时钟计算,1uS一次
        TH0 = 0xFF;        //设置定时初值 按1T时钟计算,1uS一次
        k++;
        if(k>num)P20=1;//输出高电位
        else P20=0;//输出低电位
}

关键字:STC15  定时器  模拟PWM 引用地址:分享两种STC15定时器模拟PWM的方法

上一篇:51单片机(STC15W408AS)映射printf函数 串口收发实现
下一篇:基于51单片机的PID控制的DC/DC电路仿真+程序设计

推荐阅读最新更新时间:2024-11-13 10:04

使用STM32的定时器进行输入脉冲的计数
STM32的定时器具有计数功能,在实际应用中可以用来对引脚上的输入信号进行统计。其输入信号作为计数时钟,输入引脚为ETR引脚。 本例程使用Timer 2,其ETR输入引脚为PA1,初始化是设置该引脚工作模式为输入模式,Timer2的工作模式为从模式。 为了方便测试,另外使用PC6模式输出一个时钟信号。测试时将PC6与PA1短接。(用户也可另外连接一个时钟信号到PA1引脚上。) 代码如下: int main(void) { unsigned char i_Loop; unsigned char n_Counter; #ifdef DEBUG debug(); #endif RCC_Configuration();
[单片机]
【STM32Cube_12】使用通用定时器产生PWM驱动蜂鸣器
本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的通用定时器外设,产生PWM驱动无源蜂鸣器。 1. 准备工作 硬件准备 开发板 首先需要准备一个开发板,这里我准备的是STM32L4的开发板(BearPi): 蜂鸣器 这里我直接使用扩展板上的蜂鸣器,如图: 蜂鸣器的原理图如下: 软件准备 需要安装好Keil - MDK及芯片对应的包,以便编译和下载生成的代码 2.生成MDK工程 选择芯片型号 打开STM32CubeMX,打开MCU选择器: 搜索并选中芯片STM32L431RCT6: 配置时钟源 如果选择使用外部高速时钟(HSE),则需要在System Core中配置R
[单片机]
【STM32Cube_12】使用通用<font color='red'>定时器</font>产生<font color='red'>PWM</font>驱动蜂鸣器
stm32f1按键检测使用外部中断以及定时器延时方式去抖
本来一个按键检测是很简单的功能,在大学的时候做的51单片机矩阵键盘更要复杂,但是如果要在操作系统中使用按键并且很好的去除抖动,不影响整个rtos系统的运行,保证中断不会长时间占用CPU,达到快进快出的目的。就需要另外启动一个定时器来完成计时功能(比如去抖20ms)后,产生定时器中断后再次检测按键电平。 一般51或stm32按键检测流程: #define key1 GPIOC_11 void delay(uint32_t n ) { while(n--); } void key_detected() { if (key1 == 0) { delay(20); if (ke1 == 0)
[单片机]
pic 16 定时器 012
oid init_timer1() { T1CONbits.TMR1ON=0; PIE1bits.TMR1IE=0; T1CON=0X30; //fosc/4 再8分频 1M TMR1=0xFC17; //65535-1000 定时1ms PEIE=1; //外部中断使能 GIE=1; //总中断使能 } void init_timer0() { OPTION_REG=0x04; //32分频 1ms TMR0=6; INTCON=0XA0; INTCONbits.TMR0IE=1; PEIE=1; //外部中断使能 GIE=1; //总中断使能 } void i
[单片机]
单片机定时器占空比按键调整Proteus仿真程序
仿真原理图如下 单片机源程序如下: #include reg52.h #define uchar unsigned char #define uint unsigned int uchar COUNT100,PWMCOUNT; /*LCD 端口定义*/ sbit RS=P3^7; sbit RW=P3^6; sbit E=P3^5; sbit PWM=P1^0; sbit K1=P3^0;//加1 sbit K2=P3^1;//减1 sfr LCDData=0x80;//0x80--P0,0X90--P1,0xa0--P2,0xb0--P3 /************液晶驱动程序**********
[单片机]
单片机<font color='red'>定时器</font>占空比按键调整Proteus仿真程序
STM32-通用定时器基本定时功能
1. STM32的Timer简介 STM32中一共有11个定时器,其中2个高级控制定时器,4个普通定时器和2个基本定时器,以及2个看门狗定时器和1个系统嘀嗒定时器。其中系统嘀嗒定时器是前文中所描述的SysTick,看门狗定时器以后再详细研究。今天主要是研究剩下的8个定时器。 定时器 计数器分辨率 计数器类型 预分频系数 产生DMA请求 捕获/比较通道 互补输出 TIM1 TIM8 16位 向上,向下,向上/向下 1-65536之间的任意数 可以 4 有 TIM2 TIM3 TIM4 TIM5 16位 向上,向下,向上/向下 1-65536之间的任意数 可以 4 没有 TIM6
[单片机]
STM8学习笔记---定时器 TIM1功能实现
STM8单片机的定时器1是一个16位定时器 定时器1为高级定时器,主要特性如下: 定时器1的寄存器比较多, 如果单纯的只是用定时功能的话,用不到这么多的寄存器。定时功能需要设置的寄存器主要有自动重装载寄存器ARR、预分频寄存器PSCR、控制寄存器CR、状态寄存器SR、中断使能寄存器IER。 初始化代码如下: void Timer1_Init( void ) { TIM1_ARRH = ( unsigned char )( 1000 8 ); //定时1ms TIM1_ARRL = ( unsigned char )( 1000 ); TIM1_PSCRH = ( unsigned char
[单片机]
STM8学习笔记---<font color='red'>定时器</font> TIM1功能实现
C51单片机的定时器计数器怎么用?
方法有很多的,给你一个,你可以调试一下,你可以通过不同的晶振去计算定时器初值,如果你懂定时器这部分很好调通的 #include sbit p1_0=P1^0; int i; //全局变量 void timing(void) //晶振为3.6864M { TMOD|=0x01; //定时器T0,工作方式1 TH0=0xC3; TL0=0xC7; //这两个寄存器存的是计数器的计数开始的值,这两个值累加至溢出后正好是50ms ET0=1; //使T0中断可以溢出 EA=1; //开启总中断 TF0=0; //溢出位清零 TR0=1; //开启T0 } /********定时中断
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

换一换 更多 相关热搜器件
更多往期活动

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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