找回密码
 立即注册

QQ登录

只需一步,快速开始

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

萌新求教一个关于DA转换(PWM)的问题,求指点

[复制链接]
跳转到指定楼层
楼主
本帖最后由 明日香 于 2020-7-29 10:05 编辑

实验现象是DA模块上的小灯成呼吸效果,由亮变暗
这是完整的程序:

请问,这个程序里value是代表一个周期里的高电平,那count的作用是什么呢?为什么要判断count大于100?count每次加1的时间应该是1us吧,count加到100再清零是只为了产生100us的间隔吗?
timer1代表一个周期1ms,它肯定大于等于value吧,为什么要判断它小于value呢?
还有这个程序,value==1000则DIR=0,value==0则DIR=1,那value处于1000和0之间怎么办?
以及,这个PWM的周期timer1为什么是1000us,这个周期是自己设定的吗?


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:808700 发表于 2020-7-29 11:07 | 只看该作者
value表示高电平的时间,count的作用就是100us使其变化一次,判断value和timer的大小关系,只能为了决定PWM端口的电平,,可以改周期
回复

使用道具 举报

板凳
ID:804115 发表于 2020-7-29 13:59 | 只看该作者
上面这段代码的功能虽然实现了,但是命名真的很不规范,不易读懂,好在是我读懂了。

经过分析:各个参数的含义如下:
1. timer1:PWM的周期,为1ms;
2. DIR :呼吸灯的变化方向,如果从硬件上来说,灯是用高电平1点亮的话,那么DIR=1代表呼吸灯越来越亮,DIR=0则是变暗;反之亦然;
3. value:用于控制单个周期内高电平的持续时间。它只能设置成小于或者等于周期时间;它为0,则本周期高电平持续时间为0,占空比为0%,它为1000时,则高电平持续在整个周期内,则占空比为100%。中间的值则介于这两者之间,占空比计算:(value/10)%,具体为什么除以10,请看下面的count的介绍。
4. count :用于指定相邻两个周期的波形中高电平的增加量,或者叫相邻两周期波形占空比的增加量;判断count大于100指的是相邻两个周期的波形的增加量为:周期/100 = timer1/100 = 10us. 所以相邻两个周期的占空比变化为10us/1000us = 1%;

通过上面的分析,我们知道输出各个周期的波形的占空比依次为:
0%,1%,2%,3%,...  ,99%,100%,99%,98%,...,2%,1%
按照上面的变化规律反复进行,就形成呼吸灯了。
其中0%到100%是逐渐变亮,而100%到0%则是逐渐变暗。
由于一个波形的周期是1ms,那么一个呼吸周期就是200ms。
回复

使用道具 举报

地板
ID:796670 发表于 2020-7-30 09:46 | 只看该作者
1692483014 发表于 2020-7-29 13:59
上面这段代码的功能虽然实现了,但是命名真的很不规范,不易读懂,好在是我读懂了。

经过分析:各个参数 ...

请问为什么一个周期是1ms?这个是自己设定的吗?还是固定的?
回复

使用道具 举报

5#
ID:576088 发表于 2020-7-30 10:42 | 只看该作者
这个程序三个关键变量:1.timer1是PWM周期,周期为1000*1us,因为定时中断实现的是1us定时,每次timer1++,然后主程序82行判断是否到达1000,如果到达则完成定时1000*1us,此时要重新清零timer1,同时在这里86行控制引脚PWM=P2.1输出正负电平。2:value确实是控制占空比的变量,正如你所说的现象是呼吸灯,那么这个占空比就不是定值了,需要程序设计占空比的更改,既要有占空比大小的更改,即value值要变化,同时也有方向的控制,即一会儿占空比变大,一会儿变小,用DIR正负来控制增减。3:count是控制value变化速度的,假如我们把value的增减周期和PWM的周期都设置成1000*1us,这个时候呼吸灯就会变化得相对很慢,试想一下每次PWM周期到了,value占空比仅仅增加或者减小1就很不明显了。所以count就是把value更改的时间缩短了,换言之,这样每次PWM周期到了,value占空比更改的数值+/- 10,这样呼吸灯的效果也好看
回复

使用道具 举报

6#
ID:576088 发表于 2020-7-30 10:45 | 只看该作者
明日香 发表于 2020-7-30 09:46
请问为什么一个周期是1ms?这个是自己设定的吗?还是固定的?

这个周期是灵活规定的,200ms我觉得也可以,更改timer1判断的值就好(82行)
回复

使用道具 举报

7#
ID:804115 发表于 2020-8-1 02:26 | 只看该作者
明日香 发表于 2020-7-30 09:46
请问为什么一个周期是1ms?这个是自己设定的吗?还是固定的?

是你的代码里if(timer1>1000)那句话看出来,timer1是每1000us从0重新开始,说明就是1ms,这个1ms的周期你可以自己改,但是要注意其他值也要跟着相应调整才行,看懂我上面写的原理,你就知道咋调试了,你试着自己改一下参数,让灯呼吸的过程更加缓慢,来验证你的推断。
回复

使用道具 举报

8#
ID:213173 发表于 2020-8-1 09:28 | 只看该作者
楼主这个程序有严重错误,定时中断周期1us,执行中断函数4条指令需要8us时间,就算能勉强运行,根本就不是预期结果。代码改这样既容易理解也能实战。
  1. #include "reg52.h"

  2. typedef unsigned int u16;
  3. typedef unsigned char u8;

  4. sbit PWM=P2^1;

  5. bit  DIR;
  6. u16  count;
  7. u8   value=0;


  8. void Timer1Init()
  9. {
  10.         TMOD|=0X20;//自动重装
  11.         TH1 = 0x38;//200us
  12.         TL1 = 0x38;
  13.         ET1 = 1;
  14.         EA  = 1;
  15.         TR1 = 1;
  16. }

  17. void main()
  18. {        
  19.         Timer1Init();
  20.         while(1);               
  21. }

  22. void Timer1() interrupt 3
  23. {
  24.         count++;
  25.         if(count==100)
  26.         {
  27.                 count=0;
  28.                 if(DIR)
  29.                 {
  30.                         value++;
  31.                         if(value==100)
  32.                         {
  33.                                 DIR=0;
  34.                         }
  35.                 }
  36.                 else
  37.                 {
  38.                         value--;
  39.                         if(value==0)
  40.                         {
  41.                                 DIR=1;
  42.                         }
  43.                 }
  44.         }
  45.         if(count>=value)
  46.         {
  47.                 PWM=1;
  48.         }
  49.         else
  50.         {
  51.                 PWM=0;
  52.         }
  53. }
复制代码
回复

使用道具 举报

9#
ID:810243 发表于 2020-8-1 11:07 | 只看该作者
单片机中确实要注意指令执行周期,保证需求要求的时序
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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