424

主题

3

好友

1万

积分
     

超级版主 当前离线

Rank: 8Rank: 8

UID
13663
帖子
13726
精华
6
经验
10608 点
金钱
8449 ¥
注册时间
2006-10-21

论坛版主 优秀版主 乐于助人 DIY大赛获奖

发表于 2011-11-10 10:57 | 显示全部楼层
本帖最后由 ahao 于 2011-11-10 12:07 编辑

前几年脑子一热买了一些单片机,还有相关实验板、烧写器。。。结果没学两天又没兴趣了就一直放到现在,最近又对单片机来兴致了,赶紧趁热打铁继续学下去。

正好客厅灯的分控器坏了,原来是由开关控制的,开关打开,关闭一下再开就切换一种点亮方式,共有4种模式。其实买一个也没几块钱,但是我决定要学以致用真正把学到的东西用到实处(所以想回帖说让买一个的朋友就不要回帖了)。
具体制作思路是,保留原有用开关可以切换4种点亮模式的功能,同时新增可以用家电红外遥控器切换点亮模式的功能。用AT89C2051作为控制芯片控制两个继电器产生4种点亮模式。享受动手乐趣的同时也巩固了刚学的C程序,用到了定时器、中断等。

电路如下图: 基本原理是开关打开再关闭时电路会有一个从高电平到低电平的跳变过程,这个跳变触发中断程序执行切换程序。同时当接收到有遥控信号持续800ms时也会执行切换程序,需要交代的是这个检测红外信号不是解码红外信号,因为我还没学会怎么弄。我所做的只是检测有没有接收到持续的红外脉冲,如果有持续800ms的红外脉冲就转换。
分控开关.gif

实物如下,具体制作过程略直接看成品。
01.jpg

02.jpg

03.jpg


这是烧AT89C2051用到的烧写器,这个烧写器还可以烧写AT89C5*等ATmel的单片机,如果用STC的单片机就不用这么麻烦了。
04.jpg

424

主题

3

好友

1万

积分
     

超级版主 当前离线

Rank: 8Rank: 8

UID
13663
帖子
13726
精华
6
经验
10608 点
金钱
8449 ¥
注册时间
2006-10-21

论坛版主 优秀版主 乐于助人 DIY大赛获奖

 楼主| 发表于 2011-11-10 10:59 | 显示全部楼层
本帖最后由 ahao 于 2011-11-13 15:46 编辑

C程序如下红字部分,我也是刚学C语言,所以写得很“弱智”可能还有bug。有待以后慢慢优化。。。欢迎各位师傅们积极指正,共同学习。

#include<reg52.h>                      //头文件
#define uint unsigned int   
#define uchar unsigned char         //两个宏定义


sbit deng0=P1^7;
sbit deng1=P3^7;
sbit led0=P3^0;
sbit hongwai=P3^5;                    //灯组0、灯组1、状态led、红外接口的位声明


uchar tt0,tt1,abc,biaozhi;        //定义几个unsigned char型的变量

void shuchu(uchar num1)            //状态输出子程序
{
    switch(num1)
    {
         case 0:
         deng0=0;deng1=1;break;
         case 1:
         deng0=0;deng1=0;break;
         case 2:
         deng0=1;deng1=0;break;
         case 3:
         deng0=1;deng1=1;break;
    }

}

void main()       //主程序
{
    TMOD=0x11;                         //设定定时器0、1工作模式
    TH0=(65536-10000)/256;       //定时器0装初值 10ms
    TL0=(65536-10000)%256;
    TH1=(65536-10000)/256;       //定时器1装初值 10ms
    TL1=(65536-10000)%256;

    EA=1;                                   //打开总中断
    ET0=1;                                 //打开定时器0  
    ET1=1;                                 //打开定时器1
    EX0=1;                                 //打开外部中断0    P3.2口
    IT0=1;                                  //下降沿触发方式


    abc=0;                                  //几个变量初始值
    hongwai=1;
    biaozhi=0;


    while(1)                                 //大循环
    {
        if(!hongwai)                       //如果有红外信号执行内部语句 if(!hongwai)等同于if(hongwai==0)
       {
           TR1=1;                          //启动定时器1
           tt1=0;                            //变量tt1初始值设为0
           biaozhi=1;                      //标志位  置1
       }


        if(biaozhi)                          //如果标志位为1成立执行内部语句  等同于if(biaozhi==1)
       {
           TR0=1;                          //启动定时器0
           led0=0;                          //状态led点亮
           if(tt0>=80)                     //延时800ms时间到,改变这个值可以调节按下遥控后等待切换的时间长短  {语句A}
           {
               abc++;                       //变量abc自加一次
               if(abc>3)                    //如果abc超过3就置为0
                   abc=0;
               TR0=0;                      //停止定时器0
               tt0=0;                        //变量tt0置为0
               biaozhi=0;                  //标志位  置为0
           }
       }
        else                                   //否则标志位不为1时
       {
           TR0=0;                          //停止定时器0
           tt0=0;                            //变量tt0置为0
       }


        shuchu(abc);                      //执行输出程序,将abc的值对应的状态输出
        led0=1;                             //关闭状态led
    }
}


void zhongduan0() interrupt 0     //一旦有外部中断产生就执行外部中断0服务程序
{
    biaozhi=1;                             //中断产生时让标志位置1
    tt0=100;                               //让变量tt0大于80,目的是执行 {语句A}
}

void timer0() interrupt 1             //定时器0的服务程序
{
    TH0=(65536-10000)/256;      //重装定时器0的初值10ms
    TL0=(65536-10000)%256;
    tt0++;
}

void timer1() interrupt 3             //定时器1的服务程序
{
    TH1=(65536-10000)/256;      //重装定时器1的初值10ms
    TL1=(65536-10000)%256;
    tt1++;
    if(tt1>=20)                           //如果200ms后红外信号没有持续产生,说明是红外干扰将不执行转换程序
    {
        biaozhi=0;                        //将标志位置0
        TR1=0;                            //停止定时器1
    }
}



25

主题

0

好友

1602

积分

侠之大者 当前离线

Rank: 6Rank: 6

UID
238194
帖子
1748
精华
0
经验
1602 点
金钱
1456 ¥
注册时间
2010-9-8
发表于 2011-11-10 11:26 | 显示全部楼层
C++的语法吧

424

主题

3

好友

1万

积分
     

超级版主 当前离线

Rank: 8Rank: 8

UID
13663
帖子
13726
精华
6
经验
10608 点
金钱
8449 ¥
注册时间
2006-10-21

论坛版主 优秀版主 乐于助人 DIY大赛获奖

 楼主| 发表于 2011-11-10 11:28 | 显示全部楼层
不知道,应该是C。
C++还不清楚怎么回事

83

主题

1

好友

942

积分

职业侠客 当前离线

Rank: 5Rank: 5

UID
8797
帖子
1674
精华
0
经验
942 点
金钱
643 ¥
注册时间
2006-4-21
发表于 2011-11-10 12:39 | 显示全部楼层
呵,支持版本折腾.我也刚学单片机,前阵也刚好做了个遥控开关来控制日光管.因晚上躺在床上看书懒得爬下床来关灯.红外解码我也还没有学会.思路也跟你差不多.我的是随便用一个遥控器,单片机检测到红外信号后定时一秒钟之后看看计了多少脉冲,大于设定值就执行,小于设定值就认为是干扰,将计数清零,反正是比较弱智的啦.不过也有一点不好,就是开空调或开电视也会干扰到.

3

主题

0

好友

592

积分

职业侠客 当前离线

Rank: 5Rank: 5

UID
67885
帖子
1534
精华
0
经验
592 点
金钱
574 ¥
注册时间
2008-12-10
发表于 2011-11-10 15:09 | 显示全部楼层
知识底子不到位,想学这些个东西,但看不懂,买的C语的书,还是新新的

74

主题

5

好友

1222

积分
     

侠之大者 当前离线

枭匪总教头

Rank: 6Rank: 6

UID
397774
帖子
3122
精华
0
经验
1222 点
金钱
1171 ¥
注册时间
2011-9-16
发表于 2011-11-10 15:19 | 显示全部楼层
来瞧瞧了,,以后也学学吧,,不过有难度`

19

主题

1

好友

785

积分

职业侠客 当前离线

Rank: 5Rank: 5

UID
22925
帖子
1352
精华
0
经验
785 点
金钱
700 ¥
注册时间
2007-5-22
发表于 2011-11-10 17:06 | 显示全部楼层
其实你的th0,th1,tl0,tl1直接赋值,这样省去单片机还要计算用掉的时钟,这样可以提高运算速度

9

主题

0

好友

325

积分
     

业余侠客 当前离线

Rank: 4

UID
182655
帖子
382
精华
0
经验
325 点
金钱
330 ¥
注册时间
2010-3-18
发表于 2011-11-10 17:49 | 显示全部楼层
C语言入门其实非常容易,也很简单,但写出优秀高效简洁的代码,太不容易了.
头像被屏蔽

5

主题

0

好友

109

积分

禁止发言 当前离线

UID
230986
帖子
138
精华
0
经验
109 点
金钱
109 ¥
注册时间
2010-8-18
发表于 2011-11-10 22:17 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

1

主题

0

好友

579

积分

职业侠客 当前离线

Rank: 5Rank: 5

UID
54022
帖子
1020
精华
0
经验
579 点
金钱
579 ¥
注册时间
2008-9-11
发表于 2011-11-10 22:29 | 显示全部楼层
顶起,就是我也不会

251

主题

40

好友

2万

积分

超级版主 当前在线

如果拥有金耳朵,只能花更多金钱 ¥ $去折腾.

Rank: 8Rank: 8

UID
261072
帖子
28901
精华
0
经验
24456 点
金钱
22946 ¥
注册时间
2010-11-14

社区贡献 论坛版主 乐于助人

发表于 2011-11-10 22:41 | 显示全部楼层
发射器原理图呢?

8

主题

0

好友

1568

积分
     

侠之大者 当前离线

Rank: 6Rank: 6

UID
200119
帖子
2123
精华
0
经验
1568 点
金钱
1552 ¥
注册时间
2010-5-11
发表于 2011-11-10 22:50 | 显示全部楼层
瞧瞧

31

主题

0

好友

235

积分

业余侠客 当前离线

Rank: 4

UID
407094
帖子
399
精华
0
经验
235 点
金钱
219 ¥
注册时间
2011-10-1
发表于 2011-11-10 23:39 | 显示全部楼层
非常同意9楼说法,C入门易,但要写好真的非常非常的难。断断续续学了几年,到现在也只能写些小程序。

424

主题

3

好友

1万

积分
     

超级版主 当前离线

Rank: 8Rank: 8

UID
13663
帖子
13726
精华
6
经验
10608 点
金钱
8449 ¥
注册时间
2006-10-21

论坛版主 优秀版主 乐于助人 DIY大赛获奖

 楼主| 发表于 2011-11-11 09:27 | 显示全部楼层
呵,支持版本折腾.我也刚学单片机,前阵也刚好做了个遥控开关来控制日光管.因晚上躺在床上看书懒得爬下床来关 ...
lyjsg 发表于 2011-11-10 12:39


呵呵,思路撞车了


知识底子不到位,想学这些个东西,但看不懂,买的C语的书,还是新新的
wdyinter 发表于 2011-11-10 15:09
来瞧瞧了,,以后也学学吧,,不过有难度`
409803330 发表于 2011-11-10 15:19

我觉得兴趣很重要,之前我也强迫自己来学,但是没有丝毫进展。后来有兴趣再学就很容易上手了。


其实你的th0,th1,tl0,tl1直接赋值,这样省去单片机还要计算用掉的时钟,这样可以提高运算速度
cgrrty 发表于 2011-11-10 17:06

有道理! 我原来只是感觉用算式写出来比较直观容易理解也没有往深层次考虑,看来以后的观念要改变了,多谢你的指点。
直接赋值的方法我也学了,是下面的方法不知道大家都是怎么做的。
比如使用12M晶振,要装初值50ms,先算出来预装值 65536-50000=15536 转换成16进制就是3CBO,然后把3C赋给高8位、B0赋给低8位也就是TH0=0X3C; TLO=0XB0;
未命名.GIF


发射器原理图呢?
mxwmke1 发表于 2011-11-10 22:41

木有发射器,随便找个红外遥控器就可以控制,比如电视机、空调的遥控器都可以,对着接收头持续按几百ms就可以切换了。

83

主题

1

好友

942

积分

职业侠客 当前离线

Rank: 5Rank: 5

UID
8797
帖子
1674
精华
0
经验
942 点
金钱
643 ¥
注册时间
2006-4-21
发表于 2011-11-11 10:24 | 显示全部楼层
兴趣的确是最重要的.但想成为C的高手的确是很难.毕竟没有太多的时间去折腾了,还要工作和生活.现在都是做些小东西编个小程序玩玩.高兴就好,不是靠这行吃饭.
头像被屏蔽

54

主题

4

好友

1万

积分

禁止发言 当前离线

UID
118932
帖子
14140
精华
0
经验
14228 点
金钱
14167 ¥
注册时间
2009-7-18
发表于 2011-11-11 10:38 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

5

主题

0

好友

120

积分

论坛游民 当前离线

自信小鸟

Rank: 3Rank: 3

UID
348120
帖子
102
精华
0
经验
120 点
金钱
100 ¥
注册时间
2011-6-9
发表于 2011-11-11 13:42 | 显示全部楼层
回复 4# ahao


    无线电的好点吧,我最近想做个无线电的控制器,料有了,这周课少,到时候也秀一下:

1

主题

0

好友

20

积分

注册会员 当前离线

Rank: 2

UID
587360
帖子
18
精华
0
经验
20 点
金钱
20 ¥
注册时间
2013-5-1
发表于 2013-5-2 12:20 来自手机端 | 显示全部楼层
想学单片机,看看编程就头痛,没法学

36

主题

0

好友

908

积分
     

职业侠客 当前离线

Rank: 5Rank: 5

UID
59446
帖子
2223
精华
0
经验
908 点
金钱
868 ¥
注册时间
2008-10-20
发表于 2014-10-19 17:58 | 显示全部楼层
活到老,学到老。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Powered by Discuz! X3.4

© 2001-2012 Comsenz Inc.

返回顶部