找回密码
 立即注册

QQ登录

只需一步,快速开始

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

请教:如何写PWM信号

  [复制链接]
跳转到指定楼层
楼主
ID:423989 发表于 2018-11-10 12:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请教:如何利用51C语言写PWM信号,P3.5一个脚位输出,100-300KHZ,要求从200KHZ减到100KHZ,
减到100KHZ又自动增加到200KHZ,另外同时又从200KHZ增到300KHZ,增到300KHZ又自动减加到200KHZ;
就是200KHZ做中点,同时增,同时减,不断循环。
谢谢!
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:94031 发表于 2018-11-10 15:41 | 只看该作者
51单片机定时器是无法产生200KHZ频率PWM信号的,200hz还差不多。
回复

使用道具 举报

板凳
ID:123289 发表于 2018-11-10 16:34 | 只看该作者
读透单片机关于PWM的部分和定时器部分,而后就会写。不是C的问题,是你对上述部分不理解。
回复

使用道具 举报

地板
ID:424187 发表于 2018-11-10 17:49 | 只看该作者
用增强型的单片机专用的pwm控制器可以做到 比如stc15系列,而且实现起来很简单
回复

使用道具 举报

5#
ID:164602 发表于 2018-11-10 18:48 | 只看该作者
以STC89C52单片机为例:12M晶振,那么,12分频后,主频为1000KHz。
要产生200KHz,好像也可以。但这时,PWM的周期只有5us,特殊一点的一条指令可能都不止运行这个时间,所以,很难啊。除非只产生PWM,不做其它的,那就没什么意义了。
当然,用高级一点的51单片机,如STC12、STC15这种不分频的1T单片机,就一定可以了。
回复

使用道具 举报

6#
ID:424213 发表于 2018-11-10 19:03 | 只看该作者
#在这里快速回复#1单片机定时器是无法产生200KHZ频率PWM信号的,200hz还差不多
回复

使用道具 举报

7#
ID:423989 发表于 2018-11-12 07:34 | 只看该作者
HC6800-ES-V2.0 发表于 2018-11-10 18:48
以STC89C52单片机为例:12M晶振,那么,12分频后,主频为1000KHz。
要产生200KHz,好像也可以。但这时,PW ...

原来的芯片是STC15F101W的,就是一个频率输出,其他不做,能提供C语言代码吗?谢谢!
回复

使用道具 举报

8#
ID:155507 发表于 2018-11-12 14:17 | 只看该作者
我给你来个试试

  1. /*---------------------------------------------------------------------*/
  2. /* --- STC MCU Limited ------------------------------------------------*/
  3. /* --- STC 1T Series MCU Demo Programme -------------------------------*/
  4. /* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序        */
  5. /*---------------------------------------------------------------------*/


  6. /*************  功能说明    **************

  7. 使用Timer0模拟6通道PWM驱动程序。

  8. 输出为 P3.0 ~ P3.5, 对应 PWM0 ~ PWM5.

  9. 定时器中断频率一般不要超过100KHZ, 留足够的时间给别的程序运行.

  10. 本例子使用11.0592MHZ时钟, 25K的中断频率, 250级PWM, 周期为10ms.

  11. 中断里处理的时间不超过6us, 占CPU时间大约为15%.

  12. ******************************************/
  13. //芯片是STC15F101W的
  14. #include    <reg52.h>

  15. #define MAIN_Fosc       11059200UL  //定义主时钟
  16. #define Timer0_Rate     25000       //中断频率


  17. typedef     unsigned char   u8;
  18. typedef     unsigned int    u16;
  19. typedef     unsigned long   u32;

  20. sfr AUXR = 0x8E;

  21. sfr P3M1 = 0xB1;    //PxM1.n,PxM0.n     =00--->Standard,    01--->push-pull
  22. sfr P3M0 = 0xB2;    //                  =10--->pure input,  11--->open drain


  23. #define Timer0_Reload   (65536UL -(MAIN_Fosc / Timer0_Rate))        //Timer 0 重装值

  24. //************** PWM8 变量和常量以及IO口定义 ***************
  25. //********************  8通道8 bit 软PWM    ********************

  26. #define     PWM_DUTY_MAX    250 // 0~255    PWM周期, 最大255
  27. #define     PWM_ON          1   // 定义占空比的电平, 1 或 0

  28. #define     PWM_OFF         (!PWM_ON)
  29. #define     PWM_ALL_ON      (0xff * PWM_ON)

  30. u8 bdata PWM_temp1;                 //影射一个RAM,可位寻址,输出时同步刷新
  31. sbit    P_PWM0  =   PWM_temp1^0;    //  定义影射RAM每位对应的IO
  32. sbit    P_PWM1  =   PWM_temp1^1;
  33. sbit    P_PWM2  =   PWM_temp1^2;
  34. sbit    P_PWM3  =   PWM_temp1^3;
  35. sbit    P_PWM4  =   PWM_temp1^4;
  36. sbit    P_PWM5  =   PWM_temp1^5;


  37. u8  pwm_duty;       //周期计数值
  38. u8  pwm[6];        //pwm0~pwm5 为0至5路PWM的宽度值

  39. bit     B_1ms;
  40. u8      cnt_1ms;
  41. u8      cnt_20ms;

  42. /**********************************************/
  43. void main(void)
  44. {
  45.     u8  i;
  46.    
  47.     P3M0 = 0x00;
  48.     P3M1 = 0x00;

  49.     AUXR |=  (1<<7);    // Timer0 set as 1T mode
  50.     TMOD &= ~(1<<2);    // Timer0 set as Timer
  51.     TMOD &= ~0x03;      // Timer0 set as 16 bits Auto Reload
  52.     TH0 = Timer0_Reload / 256;  //Timer0 Load
  53.     TL0 = Timer0_Reload % 256;
  54.     ET0 = 1;        //Timer0 Interrupt Enable
  55.     PT0 = 1;        //高优先级
  56.     TR0 = 1;        //Timer0 Run
  57.     EA = 1;         //打开总中断

  58.     cnt_1ms = Timer0_Rate / 1000;   //1ms计数
  59.     cnt_20ms = 20;
  60.    
  61.     for(i=0; i<6; i++)     pwm[i] = i * 5 + 5;   //给PWM一个初值
  62.    
  63.     while(1)
  64.     {
  65.         if(B_1ms)   //1ms到
  66.         {
  67.             B_1ms = 0;
  68.             if(--cnt_20ms == 0) //PWM 20ms改变一阶
  69.             {
  70.                 cnt_20ms = 20;
  71.                 for(i=0; i<6; i++) pwm[i]++;
  72.             }
  73.         }
  74.     }
  75. }


  76. /********************** Timer0 1ms中断函数 ************************/
  77. void timer0 (void) interrupt 1
  78. {
  79.     P3 = PWM_temp1;         //影射RAM输出到实际的PWM端口
  80.         
  81.     if(++pwm_duty == PWM_DUTY_MAX)      //PWM周期结束,重新开始新的周期
  82.     {
  83.         pwm_duty = 0;
  84.         PWM_temp1 = PWM_ALL_ON;
  85.     }
  86.     ACC = pwm_duty;
  87.     if(ACC == pwm[0])       P_PWM0  = PWM_OFF;  //判断PWM占空比是否结束
  88.     if(ACC == pwm[1])       P_PWM1  = PWM_OFF;
  89.     if(ACC == pwm[2])       P_PWM2  = PWM_OFF;
  90.     if(ACC == pwm[3])       P_PWM3  = PWM_OFF;
  91.     if(ACC == pwm[4])       P_PWM4  = PWM_OFF;
  92.     if(ACC == pwm[5])       P_PWM5  = PWM_OFF;

  93.     if(--cnt_1ms == 0)
  94.     {
  95.         cnt_1ms = Timer0_Rate / 1000;
  96.         B_1ms = 1;      // 1ms标志
  97.     }
  98. }



复制代码
回复

使用道具 举报

9#
ID:423989 发表于 2018-11-13 09:27 | 只看该作者

不对,不同时增和减
回复

使用道具 举报

10#
ID:423989 发表于 2018-11-13 09:33 | 只看该作者
示波器测的波形


pwm.rar

6.3 MB, 下载次数: 10

示波器测的波形

回复

使用道具 举报

11#
ID:425084 发表于 2018-11-13 16:55 | 只看该作者
int8u beep1pwm=0;
void beeppwm(int8u ss)
{
beep1pwm=ss;
}

void timer0() interrupt 1
{               
        TH0=(65536-15)/256;                       
        TL0=(65536-15)%256;
        tt++;

        if(tt==ALL)
                {
                        if(beep1pwm !=0)
                                pwm=1;
                        tt=0;
                }       
        if(tt==beep1pwm)
                pwm=0;               
}

beeppwm(1);          这是一个控制PWM的程序,不知道对你有帮助没
回复

使用道具 举报

12#
ID:425905 发表于 2018-11-13 19:17 | 只看该作者
用定时器
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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