数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 3634|回复: 14

[C51] 利用两个定时器做一个固定频率可调占空比的pwm

[复制链接]
发表于 2020-6-2 10:05:11 | 显示全部楼层 |阅读模式
看到我吃灰多年的手工DIY微型钻子,发现不能调速真是硬伤,今天就花点时间来写一个简单的程序,做一个频率固定,占空比可调的PWM, 先简单接一个12V的小灯泡试试,等画pcb板时再完善,程序贴出来,大家看看还有什么地方需要修改的!


  1. #include <STC15.H>


  2. #define uchar unsigned char
  3. #define uint  unsigned char

  4. typedef unsigned char BYTE;
  5. typedef unsigned int WORD;

  6. #define PWM_OUT   P11

  7. #define K1    P12
  8. #define K2    P13
  9. #define K3    P14

  10. #define led   P33


  11. uchar fa;

  12. uint t0_v = 0x10;

  13. //初始化T0的函数,51单片机工作频率为11.0592M
  14. void initT0(void)         
  15. {


  16.        
  17.         AUXR &= 0x7F;                //定时器时钟1T模式
  18.         TMOD &= 0xF0;                //设置定时器模式
  19.         TMOD |= 0x02;                //设置定时器模式
  20. //        TL0 = t0_v;                //设置定时初值
  21. //        TH0 = t0_v;                //设置定时重载值
  22.         TF0 = 0;                //清除TF0标志
  23.         ET0 = 1;
  24. //        TR0 = 1;                //定时器0开始计时
  25. }

  26. void Timer2Init(void)                //1微秒@11.0592MHz
  27. {
  28.         AUXR |= 0x04;                //定时器时钟1T模式
  29.         T2L = 0x24;                //设置定时初值
  30.         T2H = 0xF4;                //设置定时初值
  31.         AUXR |= 0x10;                //定时器2开始计时
  32. }



  33. void delay(BYTE num)
  34. {
  35.          BYTE i;
  36.          WORD j;
  37.                 for(i=0;i<num;i++)
  38.                 {
  39.                         for(j=0;j<1085;j++);
  40.                 }
  41. }

  42. void main(){
  43.        
  44.           
  45.           P1M1 &= ~(1 << 1);  //P1.1 设置为推挽输出
  46.     P1M0 |=  (1 << 1);
  47.           led = 0;
  48.                 P3M1 &=  0xf7;
  49.           P3M0 |= 0x08;
  50.           K1 = K2 = K3=1;
  51.                 initT0();
  52.           Timer2Init();
  53.                 PWM_OUT = 0;
  54.                 //ET0=1;
  55.                 IE2 |= 0x04;
  56.                 EA =1;
  57.        
  58.           while(1)
  59.                 {

  60.                        
  61.                         if(K1==0)
  62.                         {
  63.                                 delay(5);
  64.                                 if(K1==0 && t0_v!=0xff)
  65.                                 {
  66.                                         t0_v++;
  67.                                 }
  68.                         }
  69.                         if(K2==0)
  70.                         {
  71.                                 delay(5);
  72.                                 if(K2==0 && t0_v!=0x01)
  73.                                 {
  74.                                         t0_v--;
  75.                                 }
  76.                         }
  77.                         if(K3==0)
  78.                         {
  79.                                 delay(10);
  80.                                 if(K3==0)
  81.                                 {
  82.                                         led = ~led;
  83.                                 }
  84.                         }
  85.                         if(t0_v==0xff)
  86.                         {
  87.                           led = ~led;
  88.                         }
  89.                        
  90.                         if(t0_v==0x05)
  91.                         {
  92.                           led = ~led;
  93.                         }
  94.                
  95.                 }

  96. }

  97. void timer0_int (void) interrupt 1
  98. {

  99.     TR0 = 0;
  100.                 PWM_OUT =1;
  101.           
  102. }

  103. void timer2_int (void) interrupt 12
  104. {
  105.     TR0 = 0;
  106.                 TH0 = TL0 =t0_v;
  107.           TR0 =1;
  108.           PWM_OUT = 0;
  109.    
  110. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
发表于 2020-6-2 16:49:43 | 显示全部楼层
这类应用场合一概使用NE555搭PWM电路解决,皮实好用还不用写代码,鲁棒性好
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-6-2 21:05:29 | 显示全部楼层
ne555不能做成按键形势,还不可能添加其它功能,比如添加发光二极管来指示状态,还有我展示的主要是编程的逻辑!
回复 支持 反对

使用道具 举报

发表于 2020-6-3 07:17:26 来自手机浏览器 | 显示全部楼层
为毛用两个定时器,pwm不是一个定时器就可以了么?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-6-3 08:54:11 来自手机浏览器 | 显示全部楼层
1065307738 发表于 2020-6-3 07:17
为毛用两个定时器,pwm不是一个定时器就可以了么?

你看看一个定时能不能做一个定频的pwm
回复 支持 反对

使用道具 举报

发表于 2020-6-3 17:56:33 来自手机浏览器 | 显示全部楼层
深寒刺骨 发表于 2020-6-3 08:54
你看看一个定时能不能做一个定频的pwm

可以啊,不过对分辨率和频率有一定限制,分辨率高了频率高不了,频率高了分辨率就低。
回复 支持 反对

使用道具 举报

发表于 2020-6-5 21:13:56 | 显示全部楼层
本帖最后由 fair2017 于 2020-6-6 09:34 编辑

用一个定时器应该可以了,另一个定时器还可以用作它用。
回复 支持 反对

使用道具 举报

发表于 2020-6-5 21:19:20 | 显示全部楼层
本帖最后由 fair2017 于 2020-6-6 09:38 编辑
  1. #include <reg52.h>
  2. unsigned char pwm_motor_val = 0;//占空比值 取值范围0-170,0最快
  3. unsigned char pwm_t;//周期

  4. sbit PWM = P1^0;//
  5. sbit key_s2 = P3^0;
  6. sbit key_s3 = P3^1;
  7. unsigned char fx = 1; //1表示增,0表示减

  8. void delay(unsigned int z)//毫秒级延时
  9. {
  10.         unsigned int x,y;
  11.         for(x = z; x > 0; x--)
  12.                 for(y = 114; y > 0 ; y--);
  13. }
  14. //定时器0中断
  15. void timer0() interrupt 1
  16. {
  17.         pwm_t++;
  18.         if(pwm_t == 255)
  19.                 PWM = 0;
  20.         if(pwm_motor_val == pwm_t)
  21.                 PWM = 1;                                         
  22. }
  23. void main()
  24. {
  25.         unsigned int i;
  26.         TMOD |= 0x02;//8位自动重装模块
  27.         TH0 = 220;
  28.         TL0 = 220;//11.0592M晶振下占空比最大比值是256,输出100HZ    11059200/12/36/256
  29.         TR0 = 1;//启动定时器0
  30.         ET0 = 1;//允许定时器0中断
  31.         EA        = 1;//总中断允许
  32.         
  33.         while(1)
  34.         {
  35.                 if(key_s2 == 0)         //S2按下LED变暗
  36.                 {
  37.                         delay(5);
  38.                         if(key_s2 == 0)
  39.                         {
  40.                                 if(pwm_motor_val < 250)
  41.                                 {
  42.                                         pwm_motor_val++;
  43.                                 }
  44.                         }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-6-6 11:53:10 | 显示全部楼层
这个频率太低了吧,我的至少有1Khz
回复 支持 反对

使用道具 举报

发表于 2020-6-6 12:26:44 来自手机浏览器 | 显示全部楼层
深寒刺骨 发表于 2020-6-6 11:53
这个频率太低了吧,我的至少有1Khz

改变参数就可以了,比如重载值,还有就是周期值。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-6-7 11:15:21 来自手机浏览器 | 显示全部楼层
fair2017 发表于 2020-6-6 12:26
改变参数就可以了,比如重载值,还有就是周期值。

初值设大,你可调节的档位是不是就变小了!
回复 支持 反对

使用道具 举报

发表于 2020-8-15 14:28:31 | 显示全部楼层
电路图有没有?发出来 看看...:lol::lol::lol:
回复 支持 反对

使用道具 举报

发表于 2020-8-15 16:50:23 | 显示全部楼层
一片3525或者494比这个简单吧,
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-15 19:34:53 | 显示全部楼层
还是这个简单一些吧,494和3525外围元件那么多

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
回复 支持 反对

使用道具 举报

发表于 2020-8-25 23:14:10 | 显示全部楼层
12m不香吗,干嘛用11.059,,一个定时器可以的,ZKB是占空比,PL是频率,两个想调那个调那个,
定时器0模式1,,,在中断程序里交替赋值,高低电平时长就可以了,
   
           t1=ZKB/PL;                             //高电平时长
            t0=(1/PL)-t1;                        //低电平时长
              Xt1=65536-1000000*t1;        //高电平的时长转换成的定时器16位数
              Xt0=65536-1000000*t0;;  //低电平的时长转换成的定时器16位数
              
             h1=(uchar)(Xt1>>8);     //高电平高八位保存
              l1=(uchar)Xt1;                //高电平低八位保存
               h0=(uchar)(Xt0>>8);     //低电平高八位保存
              l0=(uchar)Xt0;                //低电平低八位保存
     
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-7-16 09:48 , Processed in 0.218400 second(s), 11 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

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