搜索
bottom↓
回复: 5

分享:新唐的51单片机用定时器1模拟PWM

[复制链接]

出0入10汤圆

发表于 2020-7-10 10:40:27 | 显示全部楼层 |阅读模式
本帖最后由 carlsun 于 2020-7-10 18:08 编辑

  近来一个案子需要用到呼吸灯(渐亮渐暗的那种)。画板时没注意到,这组灯的IO非PWM输出口,于是用定时器1模拟了一下PWM。本身不用定时器以前也有做过用延时方式模拟。但是这个案子里呼吸灯工作还有蛮多其他事情要做,所以放到定时器中断里,以减少对其它指令的影响。
  由于本人泥腿子出身,套路,思路都是自己琢磨的。所以仅供参考。肯定有其它方便很多的方式实现这一功能。请无意中看到本文的高手勿喷。欢迎指点。旨在给学习单片机的同学参考一下而已。词不达意,不啰嗦。

void Timer1_ISR (void) interrupt 3  
{
    TR1 = 0;                 //定时器工作在0/1模式下时,一定记得:在读写TH0/TL0时一定要先清零TR0,使计时关掉后再读写;
    TH1 = th1_tmp ;       
    TL1 = tl1_tmp ;                      //加载初值
        /*================================================================
    多组呼吸灯用模拟PWM来实现,此程序用来自动变换模拟PWM的DUTY,
    参数中:hxd_duty代表呼吸的DUTY,此参数以每3MS变化一次的速度在0~100与100~0之间变化,变化一个
    周期为6秒,即按客户要求六秒呼吸一次       
        ====================================================================*/
        if(hxd_status)           //呼吸灯
        {
                hxd_time++;          //呼吸计时                 
                if(hxd_time >= 1500)   //一次0.02MS,1500次3MS,加100次,3秒,减100次3秒,一个回合6秒
                {
                        hxd_time = 0;
                        if(hxd_up)      //渐亮标志
                        {
                                hxd_duty++;     //渐亮
                                if(hxd_duty >= 100)   //亮到100,
                                {
                                    hxd_duty = 100;   
                                        hxd_up   =   0;
                                }
                                else  
                                {
                                    hxd_duty--;      //渐暗
                                        if(hxd_duty <= 1)
                                        {
                                            hxd_duty = 1;
                                                hxd_up   = 1;
                                        }
                                }
                        }
                }
                hx_tim++;      //0.02mS自增一次
                if(hx_tim >= 100){hx_tim = 0;}                 //两MS一个周期:500HZ
                if(hx_tim < hxd_pwm) {charge_led = 1;} //在周期内,时间没有到DUTY,灯亮
                else {charge_led = 0;}                 
        
        }
        TR1 = 1;                  //加载完成后继续计时
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入10汤圆

 楼主| 发表于 2020-7-10 10:49:41 | 显示全部楼层
void Timer0_ISR (void) interrupt 3    :应该是timer1

出16170入6148汤圆

发表于 2020-7-10 10:52:54 来自手机 | 显示全部楼层
打赏!

庆祝论坛“打赏”功能实施, 现在开始发技术主题,可以获得打赏
https://www.amobbs.com/thread-5735948-1-1.html

出0入10汤圆

 楼主| 发表于 2020-7-10 11:07:37 | 显示全部楼层
armok. 发表于 2020-7-10 10:52
打赏!

庆祝论坛“打赏”功能实施, 现在开始发技术主题,可以获得打赏

多谢莫大。第一个帖就收到莫大的打赏。

出0入10汤圆

 楼主| 发表于 2020-7-14 11:34:53 | 显示全部楼层
这个有问题。调试好的看下面
void Timer1_ISR (void) interrupt 3  
{
    TR1 = 0;                 //定时器工作在0/1模式下时,一定记得:在读写TH0/TL0时一定要先清零TR0,使计时关掉后再读写;
    TH1 = th1_tmp ;       
    TL1 = tl1_tmp ;                      //加载初值
        /*================================================================
    多组呼吸灯用模拟PWM来实现,此程序用来自动变换模拟PWM的DUTY,
    参数中:hxd_duty代表呼吸的DUTY,此参数以每3MS变化一次的速度在0~100与100~0之间变化,变化一个
    周期为6秒,即按客户要求六秒呼吸一次       
        ====================================================================*/
        if(hxd_status)           //呼吸灯
        {
                hxd_time++;          //呼吸计时                 
                if(hxd_time >= 1500)   //一次0.02MS,1500次3MS,加100次,3秒,减100次3秒,一个回合6秒
                {
                        hxd_time = 0;
                        if(hxd_up)      //渐亮标志
                        {
                                hxd_duty++;     //渐亮
                                if(hxd_duty >= 100)   //亮到100,
                                {
                                    hxd_duty = 100;   
                                        hxd_up   =   0;
                                }
                        }
                        else  
                        {
                                hxd_duty--;      //渐暗
                                if(hxd_duty <= 1)
                                {
                                        hxd_duty = 1;
                                        hxd_up   = 1;
                                }
                        }
                }
                hxd_tim++;      //0.02mS自增一次
                if(hxd_tim >= 100){hxd_tim = 0;}                 //两MS一个周期:500HZ
                if(hxd_tim <= hxd_duty) {charge_led = 1;} //在周期内,时间没有到DUTY,灯亮
                else {charge_led = 0;}                 
        }
       
        TR1 = 1;                  //加载完成后继续计时
}

出0入0汤圆

发表于 2020-10-30 22:06:53 来自手机 | 显示全部楼层
定个标志位
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 12:24

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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