找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1425|回复: 4
打印 上一主题 下一主题
收起左侧

求指教下stc89c51单片机定时器PWM占空比程序

[复制链接]
回帖奖励 15 黑币 回复本帖可获得 5 黑币奖励! 每人限 1 次(中奖概率 80%)
跳转到指定楼层
楼主
ID:336670 发表于 2022-1-15 23:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这个PWM程序是我从网上找的,备注多数是我自己备注的,请师傅们帮忙看看我备注加??问号的地方的程序是怎么意思呢
#include <reg51.h>


typedef unsigned char uint8;
typedef unsigned int  uint16;


sbit down = P3^3;                 //定义PWM增加按键
sbit  up  = P3^0;                //定义PWM减少按键
sbit  led = P2^0;                //定义PWM输出控制端口
uint8 t = 0;                         //定义一个无符号字符变量,累计定时器溢出次数
uint8 PWM_T = 0;   //占空比控制变量
/***************************************************
                                                        延时1毫秒函数
****************************************************/
void delay_1ms(uint16 t)
{
        uint16 x,y;
        for(x=t;x>0;x--)
                for(y=120;y>0;y--);
}        
/****************************************************
                  主程序
****************************************************/
void main(void)      
{


        TMOD = 0x02;  //定时器0,工作模式2,8位自动重装载定时模式
        TH0=210;             //写入预置初值(取值1-255,数越大PWM频率越高)   初值计算公式TH0=255-t*f/12;定时器计数50次溢出,每次定时计数1us;
        TL0=210;             //写入预置值 (取值1-255,数越大PWM频率越高)                                t:计数次数;f:晶振频率:11.0592M
        TR0=1;               //启动定时器
        ET0=1;               //允许定时器0中断
        EA=1;               //允许总中断
        P1=0xff;                          //初始化P1,输出端口
        PWM_T=30;                        //默认上电PWM=30%
         while(1)      
        
         {   
                   if(!up)                //检测PWM增加按键是否按下,如果按下,执行里面的判断程序
                         {
                                if(PWM_T<250)                //判断PWM控制变量是否小于250,如果小于250,则加加,如果不小于250,则无操作
                                        {
                                          PWM_T++;
                                        }
                                
                                delay_1ms(10);//延时10毫秒                ?????此处延时有什么作用?是按键消抖吗?
                        }
                 if(!down)                //检测PWM减少按键是否按下,如果按下,则执行里面的判断程序
                         {
                                if(PWM_T>0)                        //判断PWM控制变量是否大于0,  如果大于0,则减减,如果不大于0,则无操作
                                        {
                                          PWM_T--;
                                        }
                                
                                delay_1ms(10);//延时10毫秒
                        }


        
         }      
}
/****************************************************
               /定时器0中断模拟PWM
****************************************************/
timer0() interrupt 1  
{
         t++;                                    //每次定时器溢出计数变量加1,每次计数50us,累计溢出250次,累计计时12.5ms
         
        if(t==250)           //PWM周期 100个单位                                        ?????此处如何确定PWM周期就是100个单位                                                                        
         {                                                        //当定时器累计溢出250次时,清空计数变量,重新开始累计溢出次数,P1端口输出低电平,否则输出高电平
                 t=0;                                  //使t=0,开始新的PWM周期
                 led=0;                          //输出端口
         }
         
         if(PWM_T<=t)          //按照当前占空比切换输出为高电平                                       
                                                                        //???这儿的PWM_T<=t和PWM_T==t有区别吗??应该怎么样才正确,仿真两个写法都能调节占空比
         {                                            //当PWM_T检测等于定时器溢出次数时,P1端口输出高电平,否则输出低电平
                 led=1;        
         }
}


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

来自 2#
ID:213173 发表于 2022-1-17 10:12 | 只看该作者
  1. #include <reg51.h>


  2. typedef unsigned char uint8;
  3. typedef unsigned int  uint16;


  4. sbit down = P3^3;  //定义PWM增加按键
  5. sbit  up  = P3^0;  //定义PWM减少按键
  6. sbit  led = P2^0;  //定义PWM输出控制端口
  7. uint8 t = 0;       //定义一个无符号字符变量,累计定时器溢出次数
  8. uint8 PWM_T = 0;   //占空比控制变量
  9. /***************************************************
  10.   延时1毫秒函数
  11. ****************************************************/
  12. void delay_1ms(uint16 t)
  13. {
  14.         uint16 x,y;
  15.         for(x=t;x>0;x--)
  16.                 for(y=120;y>0;y--);
  17. }        
  18. /****************************************************
  19.                   主程序
  20. ****************************************************/
  21. void main(void)      
  22. {
  23.         TMOD = 0x02;  //定时器0,工作模式2,8位自动重装载定时模式
  24.         TH0=156;      //写入预置初值(取值1-255,数越大PWM频率越高)
  25.         TL0=156;      //定时周期100us
  26.         TR0=1;        //启动定时器
  27.         ET0=1;        //允许定时器0中断
  28.         EA=1;         //允许总中断
  29.         P1=0xff;      //初始化P1,输出端口
  30.         PWM_T=30;     //默认上电PWM=30%
  31.         while(1)      
  32.         {   
  33.                 if(!up)                //检测PWM增加按键是否按下,如果按下,执行里面的判断程序
  34.                 {
  35.                         delay_1ms(10);    //延时10毫秒消抖
  36.                         if(!up)                                //再次确认按下
  37.                         {
  38.                                 if(PWM_T<100)      //判断PWM控制变量是否小于100,如果小于100,则加加,如果不小于100,则无操作
  39.                                 {
  40.                                         PWM_T++;
  41.                                         while(!up);//等待松手,否则会连续++
  42.                                 }
  43.                         }
  44.                 }
  45.                 if(!down)             //检测PWM减少按键是否按下,如果按下,则执行里面的判断程序
  46.                 {
  47.                         delay_1ms(10);                //延时10毫秒消抖
  48.                         if(!down)                        //再次确认按下
  49.                         {
  50.                                 if(PWM_T>0)    //判断PWM控制变量是否大于0,  如果大于0,则减减,如果不大于0,则无操作
  51.                                 {
  52.                                         PWM_T--;
  53.                                         while(!down);//等待松手,否则会连续--
  54.                                 }
  55.                         }
  56.                 }
  57.         }      
  58. }
  59. /****************************************************
  60.         /定时器0中断模拟PWM
  61. ****************************************************/
  62. void timer0() interrupt 1  
  63. {
  64.         t++;
  65.         if(t>=100)//原来代码不能在0~100范围可调
  66.         {
  67.                 t=0;
  68.         }
  69.         if(PWM_T>t)
  70.         {
  71.                 led=0;
  72.         }
  73.         else led=1;
  74. }
复制代码
回复

使用道具 举报

板凳
ID:691185 发表于 2022-1-16 17:30 | 只看该作者
  if(t==250)           //PWM周期 100个单位                                        ?????此处如何确定PWM周期就是100个单位   
这个感觉不对吧,如果要看作一百个单位的话,前面那个  PWM_T=30;                        //默认上电PWM=30%
这个的值就改了啊。如果不改的话这250就应该改啊。不然感觉你这个输出的占空比不会是百分之30啊
回复

使用道具 举报

地板
ID:81365 发表于 2022-1-16 22:41 | 只看该作者
1. delay_1ms(10);//延时10毫秒                ????作用是按照给定时间间隔递增
2.  if(t==250)           //PWM周期 100个单位 ???前一句自加后必然结果
回复

使用道具 举报

5#
ID:336670 发表于 2022-1-18 22:33 | 只看该作者

谢谢老师,明白多了,
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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