找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2158|回复: 10
收起左侧

用单片机管脚输出PWM波,仿真的波形出现了明显错误的连续波,请问程序哪里出错了呢?

[复制链接]
ID:796670 发表于 2021-1-26 09:54 | 显示全部楼层 |阅读模式
本帖最后由 明日香 于 2021-1-29 10:53 编辑

用定时器0,任选一管脚P21,使其输出频率50HZ,周期20ms,输出1500us的高电平时间

具体单片机程序如下:
#include <stc12c5a.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define uchar unsigned char
#define uint  unsigned int
sbit PWM=P2^1;//P21输出PWM波   
uchar time=0;   //占空比
/**单片机晶振11.0592MHZ,时钟周期为1/11.0592us,8位定时器最大定时时间256us**/
/*11.0592MHZ除以12=921600HZ,就是1秒921600机器周期,0.1ms就是92机器周期*/
/** 输出PWM频率为50HZ,即周期20ms,分成两百份,中断200次**/
/**  定时器初值:256-92=164 **/
/*周期20ms中高电平时间为1.5ms,也就是15*0.1ms*/
void time0init()//定时器0初始化
{
   TMOD=0X02;//定时器0,工作方式2
  TH0=164;
  TL0=164;
  ET0=1;
  EA=1;
  TR0=1;//开启定时器
}
void timer0() interrupt 1
{
   TR0=0;//赋初值时关闭定时器
   TH0=164; //定时器赋初值
   TL0=164; //定时器赋初值
   TR0=1;
  time++;
  if(time == 200)//PWM周期为0.1ms*200=20ms
  {
    time=0;
    PWM=1;
  }
    if(time == 15)//占空比为15%,高电平时间为1500us
    PWM=0;
}
void main()
{
  time0init();
  while(1)
   {
   }
}
用这是proteus仿真的波形:为啥会出现连续的波形呢?这明显不对啊,请问程序哪里不对呢?
捕获1.PNG 捕获2.PNG



回复

使用道具 举报

ID:390416 发表于 2021-1-26 11:16 | 显示全部楼层
可以看看这个贴子:http://www.51hei.com/bbs/dpj-200820-1.html
回复

使用道具 举报

ID:752974 发表于 2021-1-26 16:41 | 显示全部楼层
STC各类单片机的应用文档写的还可以,各种应用例程都有,当下来看看就可以了,大学毕业就应该会学习了。

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:796670 发表于 2021-1-27 15:45 | 显示全部楼层
它为什么会出现连续的波形呢?应该是一段持续的高电平才对啊?
回复

使用道具 举报

ID:880958 发表于 2021-1-27 16:38 | 显示全部楼层
个人习惯,不管是什么单片机,设定定时后在定时中断里用一个IO口取反,然后看一下定时时间对不对

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:669393 发表于 2021-1-28 00:02 | 显示全部楼层
感觉你的思路有些混乱啊,晶振是11.0592MHZ,时钟周期不是1/11.0592us吗,怎么又在注释里写了1/12us呢?这个算错了之后的定时时间肯定是错的。照你的意思,应该是输出50HZ,周期0.02s的方波,把每个周期分为200份,其中15%输出高电平,既然是这样,高电平不应该是200*0.15=30份吗,或者说一个pwm周期20ms,其中高电平时间应该是3ms,才符合15%的占空比,程序里咋写了个1500us。。周期0.02s,分成200份,按照11.0592MHZ晶振,每一份差不多是92us,就是定时器中断一次花的时间,用定时器0模式2就够了,初值设为164,正常的波形应该是图片那样。中断里的程序应该这样写才对
  1. void timer0() interrupt 1
  2. {
  3.         TH0 = 164;
  4.         TL0 = 164;
  5.         t++;
  6.         if(t == 200)
  7.         {
  8.                 pwm =1;
  9.                 t =0;
  10.         }
  11.         if(t == 30)
  12.         pwm = 0;               
  13. }
复制代码

pwm.png

评分

参与人数 1黑币 +40 收起 理由
admin + 40 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:669393 发表于 2021-1-28 00:09 | 显示全部楼层
好像看错了,应该把30改成15,按照题目的意思占空比应该是7.5%不是15%
回复

使用道具 举报

ID:796670 发表于 2021-1-29 10:15 | 显示全部楼层
SPEAR 发表于 2021-1-28 00:02
感觉你的思路有些混乱啊,晶振是11.0592MHZ,时钟周期不是1/11.0592us吗,怎么又在注释里写了1/12us呢?这 ...

是我表述的不清楚,周期20ms其中高电平为1.5ms(也就是1500us)

老哥,请问 “周期20ms,分成两百份,按照11.0592MHZ,每份92us”
为什么92us初值是164呢?
不是按照65536-92+1=FFA5吗?
然后TH0=FF,TL0=A5,请问这种算法为什么不对呢?
回复

使用道具 举报

ID:796670 发表于 2021-1-29 10:17 | 显示全部楼层
SPEAR 发表于 2021-1-28 00:02
感觉你的思路有些混乱啊,晶振是11.0592MHZ,时钟周期不是1/11.0592us吗,怎么又在注释里写了1/12us呢?这 ...

我知道了,我用的是定时器0模式1
回复

使用道具 举报

ID:796670 发表于 2021-1-29 10:51 | 显示全部楼层
SPEAR 发表于 2021-1-28 00:02
感觉你的思路有些混乱啊,晶振是11.0592MHZ,时钟周期不是1/11.0592us吗,怎么又在注释里写了1/12us呢?这 ...

老哥,发一下你完整的程序吧,谢谢了,我改了之后仿真仍然是连续波形,多谢多谢
回复

使用道具 举报

ID:796670 发表于 2021-1-30 10:32 | 显示全部楼层
使用方式2八位自动重装模式的话,中断程序里不需要再设置初值了吧
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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