搜索
bottom↓
回复: 166
打印 上一主题 下一主题

这是一个非常短的呼吸灯程序

  [复制链接]

出0入0汤圆

跳转到指定楼层
1
发表于 2013-3-24 15:53:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 doujiang 于 2013-3-24 16:10 编辑

呼吸灯,肯定很多人都写过,这里是一个简短的呼吸灯程序。
  1. #include <STC12C5A.H>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. #define limit 100
  5. sbit LED=P0^4;
  6. void delay(uint ms)
  7. {
  8.         uint i=0,j=0;
  9.         for(i=ms;i>0;i--)
  10.                 for(j=123;j>0;j--);
  11. }

  12. void main()
  13. {
  14.         uint t=50;
  15.         char d=1;
  16.         while(t+=d)
  17.         {
  18.                 LED=t%2;
  19.                 delay(t*(LED==1)+(limit-t)*(LED==0));//这条代码很巧妙的实现了两个状态的切换
  20.                 if(t>=95||t<=5) d=-d;
  21.         }
  22. }
复制代码

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

2
发表于 2013-3-24 22:56:09 | 只看该作者
ok,试试看

出0入0汤圆

3
发表于 2013-3-24 23:09:49 | 只看该作者
MARK 记号一下

出0入0汤圆

4
发表于 2013-3-24 23:44:58 | 只看该作者
好像挺有意思

出0入0汤圆

5
发表于 2013-3-24 23:45:13 | 只看该作者
试试,我也来呼吸一下

出0入0汤圆

6
发表于 2013-3-25 00:12:26 | 只看该作者
收下了,可以试试

出0入0汤圆

7
发表于 2013-3-25 00:23:24 | 只看该作者
刚写了一个带ADC调呼吸速度的,还没收到钱
真的没法跟这个软件比。

出0入0汤圆

8
发表于 2013-3-25 00:29:18 | 只看该作者
我看了半天,没看懂,谁给解释下。。。

出0入0汤圆

9
发表于 2013-3-25 08:59:40 | 只看该作者
好 留着

出0入0汤圆

10
发表于 2013-3-25 09:06:00 | 只看该作者
思路不错。
如果LED为1,则t有效。为0则limit-t有效。
这样调节亮和灭的占空比。
当t上升到大于等于95的时候d就d=-d。d就变负数。t+-d=t-d。t下降。下降到小于等于5时d=-d。则变正。又上升

出0入0汤圆

11
发表于 2013-3-25 22:14:32 | 只看该作者
先标记,有机会试验下

出0入0汤圆

12
 楼主| 发表于 2013-3-25 23:38:56 | 只看该作者
e315 发表于 2013-3-25 00:29
我看了半天,没看懂,谁给解释下。。。

程序有三个亮点,第一:用%2来实现LED灯的两种状态的切换。第二:用逻辑判断等实现了延时与LED灯状态的匹配。第三:边界条件的判断以及d=-d实现了呼吸灯的由灭逐渐到亮,再由亮逐渐到灭。这个可以想象成球撞击墙面的物理模型。

出0入0汤圆

13
 楼主| 发表于 2013-3-25 23:40:45 | 只看该作者
这个程序,没有考虑执行的效率,只考虑代码的简洁。

出0入0汤圆

14
发表于 2013-3-26 00:01:03 来自手机 | 只看该作者
马克   试一试

出0入0汤圆

15
发表于 2013-3-26 00:22:08 | 只看该作者
试一下。记号。

出0入4汤圆

16
发表于 2013-3-26 00:22:29 | 只看该作者
有时间也试试!

出0入0汤圆

17
发表于 2013-3-26 00:42:50 来自手机 | 只看该作者
谁能想出来同样简洁的风吹蜡烛的效果?

出0入0汤圆

18
发表于 2013-3-26 02:01:28 | 只看该作者
mark!

出0入17汤圆

19
发表于 2013-3-26 07:56:32 | 只看该作者
有机会试试

出0入0汤圆

20
发表于 2013-3-26 08:17:57 | 只看该作者
mark一下

出0入0汤圆

21
发表于 2013-3-26 08:24:10 | 只看该作者
为什么不用三元运算符实现?这个不算巧妙吧。

出0入0汤圆

22
发表于 2013-3-26 08:26:30 | 只看该作者
记下,,分享一下

出0入0汤圆

23
发表于 2013-3-26 08:57:48 | 只看该作者
简洁但效率不高

出0入0汤圆

24
发表于 2013-3-26 10:26:02 | 只看该作者
记号一下先

出0入0汤圆

25
发表于 2013-3-26 10:39:53 | 只看该作者
试下看,看来挺好玩.

出0入0汤圆

26
 楼主| 发表于 2013-3-26 12:16:44 | 只看该作者
tiancaigao7 发表于 2013-3-26 08:24
为什么不用三元运算符实现?这个不算巧妙吧。

三元运算符实际上也是if语句的缩写式,但是这个程序里的方法完全就用加法和逻辑运算代替了if语句,是一个我们不常用到的方式。

出0入0汤圆

27
发表于 2013-3-26 12:24:44 | 只看该作者
MARK,程序真够简洁的

出0入0汤圆

28
发表于 2013-3-26 12:30:29 | 只看该作者
MARK 非常短的呼吸灯程序,学习这种写法。

出0入0汤圆

29
发表于 2013-3-26 13:58:38 | 只看该作者
谢谢分享!

出0入0汤圆

30
发表于 2013-3-26 16:31:12 | 只看该作者
doujiang 发表于 2013-3-25 23:38
程序有三个亮点,第一:用%2来实现LED灯的两种状态的切换。第二:用逻辑判断等实现了延时与LED灯状态的匹 ...

谢谢你的回复,我编译了下,这个要生成这么大的代码,代码效率感觉太低了。。。
Program Size: data=11.0 xdata=0 code=183


另,while(t+=d) 这个语句,我觉得用while(1)也可以呀,可以烧下却不能运行, 是为什么呢?

出0入4汤圆

31
发表于 2013-3-27 14:31:43 | 只看该作者
效果能够实现,已经移植到定时中断里,但是亮的过程和灭的过程时间不一样。在定时中断里,就不用考虑效率了吧

出0入93汤圆

32
发表于 2013-3-27 15:29:39 | 只看该作者
本帖最后由 takashiki 于 2013-3-27 15:41 编辑
doujiang 发表于 2013-3-26 12:16
三元运算符实际上也是if语句的缩写式,但是这个程序里的方法完全就用加法和逻辑运算代替了if语句,是一个 ...


你这个还是用到了判断,而且比三元运算符更多……,LED == 0 和 LED == 1 都是判断

真要Kill掉判断,应该这样写:delay(t*LED+(limit-t)*(1 - LED));
不好意思,写成这样已经非常变态了。更变态一点,就是将括号里面展开,代替编译器进行计算,变成delay((t*2-limit) * LED + limit - t),可以少掉一次乘法,不过这样写不作注释基本上是看不懂了。

由于用到了16位的乘法,它的开销比逻辑运算要大得多,因此采用这种所谓的“技巧”根本是不可取的。

出0入0汤圆

33
 楼主| 发表于 2013-3-27 19:09:34 | 只看该作者
takashiki 发表于 2013-3-27 15:29
你这个还是用到了判断,而且比三元运算符更多……,LED == 0 和 LED == 1 都是判断

真要Kill掉判断,应 ...


这个,你只考虑到这条代码在呼吸灯里的运用,但是如果状态有三种以上呢?不用逻辑判断就不行了。这个代码只是提供给大家一个新的思路,用这种方法可以实现if,else,else....的替换,前面也提到过,只考虑了代码的简洁,没有考虑性能哈!

出0入0汤圆

34
发表于 2013-3-27 19:17:40 | 只看该作者
对应搞单片机的人来说,不该光看C的长度,还有关注下编译后的汇编长度吧

出0入0汤圆

35
发表于 2013-3-27 20:00:32 | 只看该作者
mark         

出0入0汤圆

36
发表于 2013-3-27 20:07:37 | 只看该作者
谢谢分享  谁有更好的 代码    贴出来大家互相学习啊        

出0入0汤圆

37
 楼主| 发表于 2013-3-27 20:11:21 | 只看该作者
cqsrmxxzyx 发表于 2013-3-27 19:17
对应搞单片机的人来说,不该光看C的长度,还有关注下编译后的汇编长度吧

这个没有考虑执行效率,只考虑的代码简洁程度哈,只是提供给大家一个代替if  else else......的方式,况且如果你仔细考虑后,会发现这种方法还可以用在很多其它地方,并不只是在单片机上,主要还是给大家一个另一种思路

出0入0汤圆

38
发表于 2013-3-27 20:13:10 | 只看该作者
围观一下

出0入0汤圆

39
发表于 2013-3-27 20:57:09 | 只看该作者
思路很有意思!收了!

出0入0汤圆

40
发表于 2013-3-27 21:00:34 | 只看该作者
有时间可以试试

出0入0汤圆

41
发表于 2013-3-27 22:52:39 | 只看该作者
比较巧妙  

出0入0汤圆

42
发表于 2013-3-27 23:08:53 | 只看该作者
MARK一下

出0入0汤圆

43
发表于 2013-3-27 23:11:01 | 只看该作者
MARK 非常短的呼吸灯程序,学习这种写法。

出0入0汤圆

44
发表于 2013-3-27 23:11:03 | 只看该作者
不错  从效果上来说

出0入0汤圆

45
发表于 2013-3-27 23:52:38 来自手机 | 只看该作者
没写过,看看

出0入93汤圆

46
发表于 2013-3-28 12:31:58 | 只看该作者
doujiang 发表于 2013-3-27 19:09
这个,你只考虑到这条代码在呼吸灯里的运用,但是如果状态有三种以上呢?不用逻辑判断就不行了。这个代码 ...

N多个状态一样可以用超长的表达式来解决,数学上有一种术语叫做分段函数,一般情况下我们是将它们按照自变量的取值范围分成若干段,然后组合而成,这样就有多个函数式。但也有人非得把各种分段都统一到一条语句中去,这样既长又不好理解。
用数学的观点来解决计算机的问题是不对的,数学可以用来解决计算机的问题,但是纯数学的观点只会走弯路。

下面我举一个例子,把简单问题复杂化,很复杂,一步一步的进行复杂,也是我所不推崇的

这么一个简单函数,他只完成这么个功能,计算一个Byte的十进制数有多少位:
  1. unsigned char TestFunc(unsigned char x){
  2.       return (x >= 100) ? 3                            //大于等于100的具有3位数字
  3.              : (x >= 10) ? 2                             // 10~99的具有2位
  4.              : 1;                                             // 0~9只有1位
  5. }
复制代码
现在我们将它复杂化,使用数学上的分段函数表述,这里有三个区间,分别是[0, 9], [10, 99], [100, 255],因为是离散的,我都写成闭区间了,如果是连续的(比如实数),那就必须要写成半开半闭。
首先考虑[100, 255]区间,结果是3,得到如下表达式,为了书写方便,我用y表示返回值:
[ocde] y = 3 * ((x + 156) >> 8);[/code]

x + 156在x>=100是会产生进位,而<100则不会,因此 ((x + 156) >> 8)在大于等于100时是会等于3的,上述表达式成立。

接来下,我就要计算x<100的值了,因为上述表达式在x<100时只能等于0。

继续考虑,分段的第二段,x为[10, 99]区间。
显然:
  1. y = 2 * ((x+246) >> 8)
复制代码
是会在这个区间上成立的,但是当x>=100时,它也仍然成立,因此需要去除。去除后的结果是:
  1. y = 3 * ((x + 156) >> 8) + (1 - ((x + 156) >> 8)) * ( 2 * ((x+246) >> 8));
复制代码
好了,分段2完成,以此类推,直至完成。
  1. y = 3 * ((x + 156) >> 8) + (1 - ((x + 156) >> 8)) * ( 2 * ((x+246) >> 8)) + (1 - ((x + 246) >> 8)) * 1;
复制代码
N段的一样这样完成,你看我连一个判断都没有,但是这个有什么意义呢?不写注释能看懂的都是神人。难道就是你所谓的一种方法?

出0入93汤圆

47
发表于 2013-3-28 12:58:24 | 只看该作者
如果楼主喜欢收集各种技巧,那我再给你一个技巧吧,只在51上可用,效果那是非常明显,不过看得人要骂人就是了。
P1.0在y>=x时输出高电平,y<x时输出低电平,那么可以写作:
  1. P1_0 = (ACC = x - y, CY);
复制代码
哈哈,这个如何?代码特别短,效率特别高。

出0入0汤圆

48
 楼主| 发表于 2013-3-28 13:30:18 | 只看该作者
takashiki 发表于 2013-3-28 12:58
如果楼主喜欢收集各种技巧,那我再给你一个技巧吧,只在51上可用,效果那是非常明显,不过看得人要骂人就是 ...

谢谢啦!!!

出0入0汤圆

49
发表于 2013-3-28 13:36:10 | 只看该作者
什么是呼吸灯?

出0入0汤圆

50
 楼主| 发表于 2013-3-28 15:08:45 | 只看该作者
本帖最后由 doujiang 于 2013-3-28 15:15 编辑
takashiki 发表于 2013-3-28 12:31
N多个状态一样可以用超长的表达式来解决,数学上有一种术语叫做分段函数,一般情况下我们是将它们按照自 ...


这个,只是说提供给大家一个新的方式,并不是说它有多好多好,我在这里提出来,大家看到后,可能会想:哦...原来还可以用这种方式来代替if语句,那如果我没提出来,那估计很多人都不晓得有这样的办法,现在讨论的不是说它的实际的执行效率啥的,而是说这是一个也许大家从来没见过的新的方式而已。我也深知代码短,并不代表执行效率高,就像求1000000000内素数的个数一样,往往那些在很短时间内求出个数的程序代码是非常长的,因此,这里只是提出一个新的方法哈。

出0入0汤圆

51
发表于 2013-3-28 16:51:04 | 只看该作者
程序有三个亮点,第一:用%2来实现LED灯的两种状态的切换。
%2如果编译器不做优化的话,效率很低。还不如&1,效果是一样的.
这样的程序,虽然看来简洁,但读起来难懂,执行效率也不高.在工程是不值提倡

出0入0汤圆

52
发表于 2013-3-28 19:01:42 | 只看该作者
这个可以试试啊

出0入0汤圆

53
发表于 2013-4-2 15:08:51 | 只看该作者
用硬件PWM输出是不是更简单?

出0入0汤圆

54
发表于 2013-4-2 17:35:05 | 只看该作者
效果不是太好,闪烁得厉害

出0入0汤圆

55
发表于 2013-4-2 17:47:32 | 只看该作者
学习了学习了

出0入0汤圆

56
发表于 2013-4-2 19:18:10 来自手机 | 只看该作者
mark一下,学习下

出0入0汤圆

57
发表于 2013-4-4 00:00:40 来自手机 | 只看该作者
看看怎样?

出0入4汤圆

58
发表于 2013-4-4 23:46:54 | 只看该作者
学习一下                    

出0入0汤圆

59
发表于 2013-4-17 20:45:23 | 只看该作者
看看,是不是挺美的

出70入0汤圆

60
发表于 2013-4-18 11:09:05 | 只看该作者
mark!学习了,的确很简洁!有空玩玩!

出0入0汤圆

61
发表于 2013-4-18 12:26:16 | 只看该作者
有长见识了,呼吸灯!!

出0入0汤圆

62
发表于 2013-5-7 20:56:03 | 只看该作者
最好用中断吧。。

出0入0汤圆

63
发表于 2013-5-7 21:12:18 | 只看该作者
没有见过这样的C语言语法呀,符合C标准吗?

出0入0汤圆

64
发表于 2013-5-7 21:29:36 | 只看该作者
mark 一下

出0入0汤圆

65
发表于 2013-5-7 21:30:43 | 只看该作者
要是很多灯呼吸怎么办?

出0入0汤圆

66
发表于 2013-5-8 02:04:16 | 只看该作者
非常简洁!有个语句头次见到过!

出0入0汤圆

67
发表于 2013-5-8 11:31:00 来自手机 | 只看该作者
本帖最后由 15813191501 于 2013-5-8 13:12 编辑

删了吗?看不到了?电脑上可以看到程序,手机上看不到。

出0入0汤圆

68
发表于 2013-5-8 11:39:07 来自手机 | 只看该作者
有资料吗?

出0入0汤圆

69
发表于 2013-5-8 11:41:47 | 只看该作者
很有想法啊

出0入0汤圆

70
发表于 2013-5-8 11:46:29 | 只看该作者
先记下来先

出0入137汤圆

71
发表于 2013-5-8 11:49:14 | 只看该作者
MARK 非常短的呼吸灯程序,学习这种写法。

出0入0汤圆

72
发表于 2013-5-8 12:26:33 | 只看该作者
很好,收藏了

出0入0汤圆

73
发表于 2013-5-9 10:42:03 | 只看该作者
回家再玩

出0入0汤圆

74
发表于 2013-11-16 19:47:02 | 只看该作者
刚试过  程序可行,不过延时时间有点长,一直在闪,延时改小一点 效果更好!

出0入0汤圆

75
发表于 2013-11-16 19:59:16 来自手机 | 只看该作者
inkfish321 发表于 2013-3-26 00:42  谁能想出来同样简洁的风吹蜡烛的效果?

什么叫风吹蜡烛?

出0入0汤圆

76
发表于 2013-11-16 20:05:56 来自手机 | 只看该作者
谢谢分享

出0入0汤圆

77
发表于 2013-11-16 20:59:02 | 只看该作者
mark                       

出0入0汤圆

78
发表于 2013-11-16 21:19:41 | 只看该作者
记下学习一下。

出0入0汤圆

79
发表于 2013-11-16 22:45:01 | 只看该作者
虚心学习了

出0入0汤圆

80
发表于 2013-11-16 22:57:29 | 只看该作者
有点意思,顶

出0入0汤圆

81
发表于 2013-11-16 23:00:11 | 只看该作者
好东西,先保存

出0入8汤圆

82
发表于 2013-11-17 00:15:27 | 只看该作者
呼吸灯  ~~~~~~~~~~~~~~~~~~~

出0入0汤圆

83
发表于 2013-11-17 08:09:22 | 只看该作者
自带PWM的单片机更短

出0入0汤圆

84
发表于 2013-11-17 13:07:33 | 只看该作者
厉害!!!效果非常棒!!!

出0入0汤圆

85
发表于 2013-11-17 14:27:47 | 只看该作者
思路很有意思

出0入0汤圆

86
发表于 2013-11-17 15:51:33 | 只看该作者
很巧妙。。。。。。。。。

出0入0汤圆

87
发表于 2013-11-17 21:00:42 | 只看该作者
这技巧,短小精悍!

出0入54汤圆

88
发表于 2013-11-18 08:46:26 | 只看该作者
标记下 回头试验一下

出0入0汤圆

89
发表于 2013-11-18 10:56:01 | 只看该作者
思路很巧妙   怎么想出来的

出0入0汤圆

90
发表于 2013-11-18 12:13:11 来自手机 | 只看该作者
mark
来自:amoBBS 阿莫电子论坛 Windows Phone 8 客户端

出0入0汤圆

91
发表于 2013-11-25 15:26:05 | 只看该作者
试一试。。

出0入0汤圆

92
发表于 2013-11-25 16:26:31 | 只看该作者
mark        

出0入0汤圆

93
发表于 2013-11-28 17:17:20 | 只看该作者
不错,mark

出0入0汤圆

94
发表于 2013-11-28 20:58:27 | 只看该作者
果然很简洁,试试看!

出50入0汤圆

95
发表于 2013-11-28 21:12:03 来自手机 | 只看该作者
学习了,马克

出0入0汤圆

96
发表于 2013-12-6 14:59:49 来自手机 | 只看该作者
回去试一下

出0入0汤圆

97
发表于 2013-12-6 15:00:31 来自手机 | 只看该作者
回去试一下

出0入0汤圆

98
发表于 2013-12-6 15:00:51 来自手机 | 只看该作者
回去试一下

出0入0汤圆

99
发表于 2014-4-17 14:14:26 | 只看该作者
mark,谢谢分享!

出0入0汤圆

100
发表于 2014-6-4 12:23:36 | 只看该作者
呼吸不是指数上升、下降的吗?线性升降效果也能达到那么好的效果吗?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 14:02

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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