找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 557|回复: 13
收起左侧

一个单片机PWM程序出问题

[复制链接]
shuisheng60 发表于 2021-8-5 08:30 | 显示全部楼层 |阅读模式
一个输出的PWM, 80是开起占空比,0是关闭占空比。这个器件外接一个振动开关,当有振动开关信号时(开关碰到地),有PWM输出,此时占空比 = 80,并且持续3秒钟,无PWM输出,此时占空比 = 0;1分钟内振动开关只有第一次有效 。后面循环下去。
我的写法如下:
                if(ZDK == 0)//振动开关碰到地
                        {
                                ZZ++; //碰到地计时间
                                if(ZDK == 1)CONT++;//碰到地后抬起的次数
                        }
                                if((ZZ < 1500)&&(CONT <= 1))//如果在3秒内并且只有第一次进入
                                {
                                 PWM= 80;//输出PWM
                                }
                         if((ZZ>4)&&(ZZ<54))//PWM无输出
                                {
                                        PWM = 0;        
                                }
                        if(ZZ > 54)//60
                                {
现在情况是开关在一分钟内多次有效,望友友们有好的方法

回复

使用道具 举报

yoxi 发表于 2021-8-5 11:08 | 显示全部楼层
看看,有一点难度咯
回复

使用道具 举报

lkc8210 发表于 2021-8-5 13:57 | 显示全部楼层
本帖最后由 lkc8210 于 2021-8-5 22:41 编辑
  1. uint delayms_3s = 0;
  2. uint delayms_60s = 0;
  3. void TimerX() interrupt x //定时器X中断,1ms
  4. {
  5.       if(delayms_3s)delayms_3s--;
  6.       if(delayms_60s)delayms_60s--;
  7. }
  8. void main()
  9. {
  10. if(!delayms_60s)
  11. {
  12.      if(!delayms_3s)
  13.      {
  14.          if(PWM==80)
  15.          {
  16.              delayms_60s=60000;
  17.              PWM=0;
  18.          }
  19.          if(ZDK==0 && delayms_60s!=60000)
  20.          {
  21.              delayms_3s=3000;
  22.              PWM=80;
  23.          }
  24.      }
  25. }
  26. }
复制代码


评分

参与人数 1黑币 +15 收起 理由
shuisheng60 + 15 赞一个!

查看全部评分

回复

使用道具 举报

wulin 发表于 2021-8-5 18:51 | 显示全部楼层
此代码只是表示控制PWM的逻辑关系
  1. #include <reg51.h>

  2. sbit ZDK=P3^0;

  3. bit sign=0;

  4. void InitTimer0(void)
  5. {
  6.     TMOD = 0x01;
  7.     TH0 = 0x3C;
  8.     TL0 = 0xB0;
  9.     EA = 1;
  10.     ET0 = 1;
  11.     TR0 = 0;
  12. }

  13. void main(void)
  14. {
  15.         InitTimer0();
  16.         P1=0x00;
  17.         while(1)
  18.         {
  19.             if(!ZDK && TR0==0)
  20.                 {
  21.                         TR0=1;
  22.                         P1=0x80;
  23.                 }
  24.         }
  25. }

  26. void Timer0Interrupt(void) interrupt 1
  27. {  
  28.         static unsigned int i;       
  29.         TH0 = 0x3C;
  30.         TL0 = 0xB0;
  31.         i++;
  32.         if(i<=60)//3秒
  33.                 P1=0x80;
  34.         if(i>60&&i<=1200)
  35.                 P1=0x00;
  36.         if(i>=1200)//60秒
  37.         {
  38.                 i=0;
  39.                 sign=0;
  40.                 TR0=0;
  41.         }
  42. }
复制代码
回复

使用道具 举报

 楼主| shuisheng60 发表于 2021-8-5 18:52 | 显示全部楼层

if(PWM==80)不能在这里作判断,报错咯,希望再接再厉!
回复

使用道具 举报

 楼主| shuisheng60 发表于 2021-8-5 19:12 | 显示全部楼层
wulin 发表于 2021-8-5 18:51
此代码只是表示控制PWM的逻辑关系

谢谢所提意见,可能是我说的不够清楚,我再将此功能说一下,PWM是一个恒定超声波(80单位占空比),是受外界控制器(振动开关)控制,当外界有较大振动时,振动开关动作(开关碰到地),会产生3秒恒定超声波,过后停止(0单位占空比),再待有振动再喷。而却1分钟内振动开关只有第一次有效 。
回复

使用道具 举报

 楼主| shuisheng60 发表于 2021-8-5 19:29 | 显示全部楼层

为什么要设一个分钟以内振动次数只有一次有效?是因为振动开关动作大时,会多次碰到地,导致PWM长时间输出,造成影响
回复

使用道具 举报

lkc8210 发表于 2021-8-5 22:41 | 显示全部楼层
shuisheng60 发表于 2021-8-5 18:52
if(PWM==80)不能在这里作判断,报错咯,希望再接再厉!

我给的代码是不完整的当然报错只是给你一个思路和代码写法
完整代码的效果:(亮3秒后10秒无动作)

ezgif.com-gif-maker (1).gif

评分

参与人数 1黑币 +15 收起 理由
shuisheng60 + 15 赞一个!

查看全部评分

回复

使用道具 举报

 楼主| shuisheng60 发表于 2021-8-6 08:03 | 显示全部楼层
lkc8210 发表于 2021-8-5 22:41
我给的代码是不完整的当然报错只是给你一个思路和代码写法
完整代码的效果:(亮3秒后10秒无动作)

非常感谢你的回复,你现在做出来的效果也是正确的!昨天试了好几次也没做出来,希望友友不吝分享一下代码!在此谢过!
回复

使用道具 举报

烈火 发表于 2021-8-6 08:26 | 显示全部楼层
楼主代码写的很好,点赞一下
回复

使用道具 举报

lkc8210 发表于 2021-8-6 10:39 | 显示全部楼层
shuisheng60 发表于 2021-8-6 08:03
非常感谢你的回复,你现在做出来的效果也是正确的!昨天试了好几次也没做出来,希望友友不吝分享一下代码 ...

发一下你的代码看看改成怎样
回复

使用道具 举报

jizhongbiao 发表于 2021-8-6 11:45 | 显示全部楼层
你的count没清0吧,时间长了是因为count溢出了自动为0了。
回复

使用道具 举报

 楼主| shuisheng60 发表于 2021-8-6 12:07 | 显示全部楼层
lkc8210 发表于 2021-8-6 10:39
发一下你的代码看看改成怎样

用了一个标志位,是一进到开关内就清0,结果还是一样,总是控制不了在一分钟内的噪音,还是希望友友的代码能分享一下,让我们见识见识
回复

使用道具 举报

lkc8210 发表于 2021-8-6 13:52 | 显示全部楼层
shuisheng60 发表于 2021-8-6 12:07
用了一个标志位,是一进到开关内就清0,结果还是一样,总是控制不了在一分钟内的噪音,还是希望友友的代 ...


真PWM输出就不写了,用一支脚的高低电平代替
  1. #include "reg51.h"
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. sbit PWM_EN = P2^0;
  5. sbit ZDK = P2^1;

  6. uint delayms_3s = 0;
  7. uint delayms_60s = 0;
  8. uchar PWM = 0;
  9. void Timer1Init()
  10. {
  11.     //AUXR |= 0x40;                //定时器时钟1T模式
  12.     TMOD &= 0x0F;                //设置定时器模式
  13.     TMOD |= 0x10;                //设置定时器模式
  14.                 TL1 = 0x18;                //设置定时初始值1ms@12.000MHz 12T
  15.                 TH1 = 0xFC;                //设置定时初始值1ms@12.000MHz 12T
  16.     //TL1 = 0x20;                //设置定时初始值1ms@12.000MHz 1T
  17.     //TH1 = 0xD1;                //设置定时初始值1ms@12.000MHz 1T
  18.     TF1 = 0;                //清除TF0标志
  19.     TR1 = 1;                //定时器0开始计时
  20. }
  21. void timer1_int () interrupt 3
  22. {
  23.                 TL1 = 0x18;                //设置定时初始值1ms@12.000MHz 12T
  24.                 TH1 = 0xFC;                //设置定时初始值1ms@12.000MHz 12T
  25.     //TL1 = 0x20;                //设置定时初始值1ms@12.000MHz 1T
  26.     //TH1 = 0xD1;                //设置定时初始值1ms@12.000MHz 1T
  27.                 if(delayms_3s)delayms_3s--;
  28.                 if(delayms_60s)delayms_60s--;
  29. }
  30. void Sys_Init()
  31. {
  32.     ET1 = 1;                        //Timer1 interrupt Enable
  33.     EA = 1;                                //All interrupt Enable
  34. }
  35. void main()
  36. {
  37.         Timer1Init();
  38.                 Sys_Init();
  39.         while (1)
  40.         {
  41.                 if(!delayms_60s)
  42.                 {
  43.                                  if(!delayms_3s)
  44.                                  {
  45.                                                  if(PWM==80)
  46.                                                  {
  47.                                                                  delayms_60s=10000;
  48.                                                                  PWM=0;
  49.                                                  }
  50.                                                  if(ZDK==0 && delayms_60s!=10000)
  51.                                                  {
  52.                                                                  delayms_3s=3000;
  53.                                                                  PWM=80;
  54.                                                  }
  55.                                  }
  56.                 }
  57.                 PWM_EN = (PWM == 80);
  58.         }
  59. }
复制代码



回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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