找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2237|回复: 5
收起左侧

51单片机PWM波的误差问题

[复制链接]
ID:553001 发表于 2019-6-2 16:29 | 显示全部楼层 |阅读模式
小组在玩51单片机的开发板的时候发现,代码上设计的PWM波为100Hz,用示波器测只有80Hz左右,出现的误差是什么造成的
  1. #include "reg52.h"                         //此文件中定义了单片机的一些特殊功能寄存器

  2. typedef unsigned int u16;          //对数据类型进行声明定义
  3. typedef unsigned char u8;

  4. //--定义使用的IO口--//
  5. sbit PWM=P2^1;
  6. bit DIR;

  7. //--定义一个全局变量--//
  8. u16 count,value,timer0;

  9. /*******************************************************************************
  10. * 函 数 名         : Timer1Init
  11. * 函数功能                   : 定时器1初始化
  12. * 输    入         : 无
  13. * 输    出         : 无
  14. *******************************************************************************/

  15. void Timer0Init(void)                //40微秒@11.0592MHz
  16. {
  17. //        AUXR &= 0x7F;                //定时器时钟12T模式
  18.         TMOD &= 0x01;                //设置定时器模式
  19.         TL0 = 0xDB;                //设置定时初值
  20.         TH0 = 0xFF;                //设置定时初值
  21.         TF0 = 0;                //清除TF0标志
  22.         TR0 = 1;                //定时器0开始计时
  23. }




  24. /*******************************************************************************
  25. * 函 数 名       : main
  26. * 函数功能                 : 主函数
  27. * 输    入       : 无
  28. * 输    出             : 无
  29. *******************************************************************************/
  30. void main()
  31. {        
  32.         Timer0Init();  //定时器0初始化
  33.         while(1)
  34.         {
  35.                 if(count>300)//多长时间变一次                                                        
  36.                 {  
  37.                         count=0;
  38.                         if(DIR==1)                                           //DIR控制增加或减小
  39.                         {
  40.                           value++;
  41.                         }                        
  42.                         if(DIR==0)
  43.                         {
  44.                           value--;
  45.                         }
  46.                                 
  47.                 }

  48.                 if(value==250)
  49.                 {
  50.                   DIR=0;
  51.                 }
  52.                 if(value==0)
  53.                 {
  54.                   DIR=1;
  55.                 }        
  56.                                 
  57.                 if(timer1>250)  //PWM周期为40*250=10ms,f=100Hz
  58.                 {
  59.                         timer1=0;
  60.                 }
  61.                 if(timer1 <value)        
  62.                 {
  63.                         PWM=1;
  64.                 }
  65.                 else
  66.                 {
  67.                         PWM=0;
  68.                 }               
  69.         }               
  70. }

  71. /*******************************************************************************
  72. * 函 数 名       : Time1
  73. * 函数功能                 : 定时器1的中断函数
  74. * 输    入       : 无
  75. * 输    出       : 无
  76. *******************************************************************************/

  77. void Time1(void) interrupt 1    //3 为定时器1的中断号  1 定时器0的中断号 0 外部中断1 2 外部中断2  4 串口中断
  78. {
  79.         TL0 = 0xDB;                //
  80.         TH0 = 0xFF;
  81.         timer1++;
  82.     count++;
  83.         
  84. }
复制代码


HC6800-ES V2.0 新版.pdf

759.71 KB, 下载次数: 7

回复

使用道具 举报

ID:213173 发表于 2019-6-4 06:53 | 显示全部楼层
楼主的程序没有打开中断,根本就无法正常运行。定时器改8位自动重装模式更合理些。
  1. #include "reg52.h"                         //此文件中定义了单片机的一些特殊功能寄存器

  2. typedef unsigned int u16;          //对数据类型进行声明定义
  3. typedef unsigned char u8;

  4. //--定义使用的IO口--//
  5. sbit PWM=P2^1;
  6. bit DIR;

  7. //--定义一个全局变量--//
  8. u16 count,value,timer1;

  9. /*******************************************************************************
  10. * 函 数 名         : Timer1Init
  11. * 函数功能                   : 定时器1初始化
  12. * 输    入         : 无
  13. * 输    出         : 无
  14. *******************************************************************************/
  15. void Timer0Init()     //40微秒@11.0592MHz
  16. {
  17.         TMOD &= 0xF0;                //设置定时器模式
  18.         TMOD |= 0x02;                //设置定时器8位自动重装模式
  19.         TL0 = 0xDB;                        //设置定时初值
  20.         TH0 = 0xDB;                        //设置定时重载值
  21.         TF0 = 0;                                //清除TF0标志
  22.         TR0 = 1;                                //定时器0开始计时
  23.         EA=1;                                        //开总中断
  24.         ET0=1;                                //开定时器0中断
  25. }
  26. /*******************************************************************************
  27. * 函 数 名       : main
  28. * 函数功能                 : 主函数
  29. * 输    入       : 无
  30. * 输    出             : 无
  31. *******************************************************************************/
  32. void main()
  33. {        
  34.         Timer0Init();  //定时器0初始化
  35.         while(1)
  36.         {
  37.                 if(count>300)//多长时间变一次                                                        
  38.                 {  
  39.                         count=0;
  40.                         if(DIR==1)                                           //DIR控制增加或减小
  41.                         {
  42.                                 value++;
  43.                         }                        
  44.                         if(DIR==0)
  45.                         {
  46.                                 value--;
  47.                         }
  48.                 }
  49.                 if(value==250)
  50.                 {
  51.                         DIR=0;
  52.                 }
  53.                 if(value==0)
  54.                 {
  55.                         DIR=1;
  56.                 }        
  57.                 if(timer1>250)  //PWM周期为40*250=10ms,f=100Hz
  58.                 {
  59.                         timer1=0;
  60.                 }
  61.                 if(timer1 <value)        
  62.                 {
  63.                         PWM=1;
  64.                 }
  65.                 else
  66.                 {
  67.                         PWM=0;
  68.                 }               
  69.         }               
  70. }

  71. /*******************************************************************************
  72. * 函 数 名       : Time1
  73. * 函数功能                 : 定时器1的中断函数
  74. * 输    入       : 无
  75. * 输    出       : 无
  76. *******************************************************************************/

  77. void Time1(void) interrupt 1    //3 为定时器1的中断号  1 定时器0的中断号 0 外部中断1 2 外部中断2  4 串口中断
  78. {
  79. //        TL0 = 0xDB;
  80. //        TH0 = 0xFF;
  81.         timer1++;
  82.         count++;        
  83. }
复制代码
回复

使用道具 举报

ID:93224 发表于 2019-6-3 13:22 | 显示全部楼层
你的定时器初始值需要考虑,还需要考虑的你的晶振是12MHz? 还是11.0592MHz的
回复

使用道具 举报

ID:323589 发表于 2019-6-2 19:59 | 显示全部楼层
你先查看一下你的晶振频率对不对  然后看一下定时进入中断时间对不对  
回复

使用道具 举报

ID:415123 发表于 2019-6-2 18:01 | 显示全部楼层
是你的count变量造成的啊,count变量就是80HZ啊。
回复

使用道具 举报

ID:94031 发表于 2019-6-2 17:55 | 显示全部楼层
调整定时器参数,修改PWM波的误差。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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