找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机控制继电器,请大家帮个忙怎样加入定时器代码?

[复制链接]
跳转到指定楼层
楼主
ID:221879 发表于 2019-1-23 07:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 xbox007 于 2019-2-19 13:14 编辑

怎样加入P3.5口是高电平时为首次通电11小时后接通5秒断开继电器,然后是通电24小时后接通5秒断开继电器,24小时一直循环,P3.5口是低电平时为首次通电11小时后接通5秒断开继电器,然后是通电48小时后接通5秒断开继电器,48小时一直循环的代码,先谢谢了。

单片机代码:
/********************************************************************/

#include<reg52.h>                 //库文件
#define uchar unsigned char//宏定义无符号字符型
#define uint unsigned int  //宏定义无符号整型
/********************************************************************
                            初始定义
*********************************************************************/
uint sec = 0; //定义计数值,每过1/10 秒,sec 加一
uint tcnt = 0; //键值判断
uchar Start_Flag = 1;//定义一个全局变量,值初始化为1,用来判断首次上电的
/********************************************************************
                            I/O定义
*********************************************************************/
sbit  OUT1=P3^3;//定义输出口为P3.3口 用以控制继电器
sbit  IN1=P3^5;        //定义输入口为P3.5口 用以输入信号

/********************************************************************
                            定时中断服务函数
*********************************************************************/
void t0(void) interrupt 1 using 0 //定时中断服务函数
{
        tcnt++; //每过250ust tcnt 加一
        if(tcnt==4000) //计满4000 次(1 秒)时
        {
                tcnt=0; //重新再计
                sec++;
                if(Start_Flag == 1)//判断为首次上电,进行11个小时的计数
                {
                        if(sec==39596)
                        {
                        OUT1=1;
                        }
                        if(sec==39600) //单位为(1秒)
                        {
                        OUT1=0;
                        sec=0;
                        Start_Flag = 0;//11小时的时间到了,清0首次上电标志,进入24小时计数
                        }
                }
                else//进入24小时计数
                {
                        if(sec==86396) //单位为(1 秒)?
                        {
                        OUT1=1;
                        }
                        if(sec==86400) //单位为(1秒)
                        {
                        OUT1=0;
                        sec=0;
                        }
                }
        }
}

/********************************************************************
                            主函数
*********************************************************************/
void main()
{
        TMOD=0x02; //定时器工作在方式2
        TH0=0x06; //对TH0 TL0 赋值
        TL0=0x06;
        TR0=1; //开始定时
        ET0=1;
        EA=1;
        sec=0;
       OUT1=0;//模块通电继电器吸合
        while(1)
        {
         if(IN1==0){OUT1=1;while(!IN1);OUT1=0;}
        }
}               

        
/********************************************************************
                              结束
*********************************************************************/

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

使用道具 举报

沙发
ID:277550 发表于 2019-1-23 10:26 | 只看该作者
比如定时器是1ms,1小时是3600秒、1秒是1000毫秒,那么11小时就是11*3600000UL,跨度大,肯定存在一些偏差的,自己细调一下。


另外,关于定时器的初始化 ,stc的下载工具中,有一个tab专门是定时器的。

评分

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

查看全部评分

回复

使用道具 举报

板凳
ID:277550 发表于 2019-1-23 10:27 | 只看该作者

补充,如果一个变量的范围不够,可以使用2个变量的。

评分

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

查看全部评分

回复

使用道具 举报

地板
ID:7485 发表于 2019-1-23 10:29 | 只看该作者
这个程序是12小时(12*60*60=43200秒),吸合5秒的吧?
11*60*60=39600秒。
24*60*60=86400秒。
上电或热复位时设置一个标志位,第一次“ if(sec==39600)......”,然后标志位取反,以后根据标志位,“ if(sec==86400)......”即可。

评分

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

查看全部评分

回复

使用道具 举报

5#
ID:213173 发表于 2019-1-23 11:04 | 只看该作者
这样程序可写得没问题,但是单片机长时间定时积累误差是很大的。

/********************************************************************
                            定时中断服务函数
*********************************************************************/
void t0(void) interrupt 1 using 0 //定时中断服务函数
{
        static long sec;                 //秒变量
        static uint count;         //计数变量
        static bit sign=0;        //首次加电标志

        if(++count>=4000)         //计满4000 次(1 秒)时
        {
                count=0; //重新再计
                sec++;
                if((sec>=39600)&&(sign==0)) //首次加电11小时
                {
                        OUT1=1;//继电器吸合
                        if(sec>=39605)
                        {
                                sec=5;//扣除继电器工作的5秒
                                OUT1=0;//继电器释放
                                sign=1;//首次加电标志置1
                        }                       
                }
                if((sec>=86400)&&(sign==1)) //非首次加电24小时
                {
                        OUT1=1;//继电器吸合
                        if(sec>=86405)
                        {
                                sec=5;//扣除继电器工作的5秒
                                OUT1=0;//继电器释放
                        }                       
                }
        }
}

评分

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

查看全部评分

回复

使用道具 举报

6#
ID:471955 发表于 2019-1-23 11:15 | 只看该作者
/********************************************************************/

#include<reg52.h>                 //库文件
#define uchar unsigned char//宏定义无符号字符型
#define uint unsigned int  //宏定义无符号整型
sfr P3M0 = 0xb2;
sfr P3M1 = 0Xb1;
/********************************************************************
                            初始定义
*********************************************************************/
uint sec = 0; //定义计数值,每过1/10 秒,sec 加一
uint tcnt = 0; //键值判断
uchar Start_Flag = 1;//定义一个全局变量,值初始化为1,用来判断首次上电的
/********************************************************************
                            I/O定义
*********************************************************************/
sbit  OUT1=P3^3;//定义输出口为P3.3口 用以控制继电器
sbit  IN1=P3^5;        //定义输入口为P3.5口 用以输入信号

/********************************************************************
                            定时中断服务函数
*********************************************************************/
void t0(void) interrupt 1 using 0 //定时中断服务函数
{
        tcnt++; //每过250ust tcnt 加一
        if(tcnt==4000) //计满4000 次(1 秒)时
        {
                tcnt=0; //重新再计
                sec++;
                if(Start_Flag == 1)//判断为首次上电,进行11个小时的计数
                {
                        if(sec==39596)
                        {
                        OUT1=1;
                        }
                        if(sec==39600) //单位为(1秒)
                        {
                        OUT1=0;
                        sec=0;
                        Start_Flag = 0;//11小时的时间到了,清0首次上电标志,进入24小时计数
                        }
                }
                else//进入24小时计数
                {
                        if(sec==86396) //单位为(1 秒)?
                        {
                        OUT1=1;
                        }
                        if(sec==86400) //单位为(1秒)
                        {
                        OUT1=0;
                        sec=0;
                        }
                }
        }
}

/********************************************************************
                            主函数
*********************************************************************/
void main()
{
        TMOD=0x02; //定时器工作在方式2
        TH0=0x06; //对TH0 TL0 赋值
        TL0=0x06;
        TR0=1; //开始定时
        ET0=1;
        EA=1;
        sec=0;
        P3M0 = 0x08;
    P3M1 = 0X00;
        OUT1=0;//模块通电继电器吸合
        while(1)
        {
         if(IN1==0){OUT1=1;while(!IN1);OUT1=0;}
        }
}               

        
/********************************************************************
                              结束
*********************************************************************/

说明下:
1.你的源程序的sec和tcnt并没有给出初始化值,会导致计数不准的
2.我不知道你的系统时钟是多少,没有办法帮你配置定时器的值,所以我就假设你的定时器溢出时间是250us
3.定时器时间是250us,但你源程序判断tcnt == 8000,也就是2秒,这个并不能够准确的计算5秒的接通时间,所以改成tcnt == 4000,就是1秒
4.下面判断sec的值也随之修改
试试吧

评分

参与人数 2黑币 +108 收起 理由
xbox007 + 8 很给力!
admin + 100 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

7#
ID:94031 发表于 2019-1-23 11:27 | 只看该作者
你把tcnt==8000改成tcnt==4000,上一个 sec==39600,下一个sec==39605,就是通电11小时后接通5秒断开继电器.

评分

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

查看全部评分

回复

使用道具 举报

8#
ID:7485 发表于 2019-1-23 15:30 | 只看该作者
楼主说的是第一次是11小时,以后是24小时........
回复

使用道具 举报

9#
ID:303383 发表于 2019-1-23 21:24 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

10#
ID:221879 发表于 2019-1-24 11:14 | 只看该作者
本帖最后由 xbox007 于 2019-2-16 20:13 编辑

精度要求不是很高的,谢谢楼上几位朋友的回复。
回复

使用道具 举报

11#
ID:221879 发表于 2019-2-16 08:28 | 只看该作者
本帖最后由 xbox007 于 2019-2-19 13:15 编辑
/********************************************************************/

#include<reg52.h>                 //库文件
#define uchar unsigned char//宏定义无符号字符型
#define uint unsigned int  //宏定义无符号整型
/********************************************************************
                            初始定义
*********************************************************************/
uint sec = 0; //定义计数值,每过1/10 秒,sec 加一
uint tcnt = 0; //键值判断
uchar Start_Flag = 1;//定义一个全局变量,值初始化为1,用来判断首次上电的
/********************************************************************
                            I/O定义
*********************************************************************/
sbit  OUT1=P3^3;//定义输出口为P3.3口 用以控制继电器
sbit  IN1=P3^5;        //定义输入口为P3.5口 用以输入信号

/********************************************************************
                            定时中断服务函数
*********************************************************************/
void t0(void) interrupt 1 using 0 //定时中断服务函数
{
        tcnt++; //每过250ust tcnt 加一
        if(tcnt==4000) //计满4000 次(1 秒)时
        {
                tcnt=0; //重新再计
                sec++;
                if(Start_Flag == 1)//判断为首次上电,进行11个小时的计数
                {
                        if(sec==39596)
                        {
                        OUT1=1;
                        }
                        if(sec==39600) //单位为(1秒)
                        {
                        OUT1=0;
                        sec=0;
                        Start_Flag = 0;//11小时的时间到了,清0首次上电标志,进入24小时计数
                        }
                }
                else//进入24小时计数
                {
                        if(sec==86396) //单位为(1 秒)?
                        {
                        OUT1=1;
                        }
                        if(sec==86400) //单位为(1秒)
                        {
                        OUT1=0;
                        sec=0;
                        }
                }
        }
}

/********************************************************************
                            主函数
*********************************************************************/
void main()
{
        TMOD=0x02; //定时器工作在方式2
        TH0=0x06; //对TH0 TL0 赋值
        TL0=0x06;
        TR0=1; //开始定时
        ET0=1;
        EA=1;
        sec=0;       OUT1=0;//模块通电继电器吸合
        while(1)
        {
         if(IN1==0){OUT1=1;while(!IN1);OUT1=0;}
        }
}               

        
/********************************************************************
                              结束
*********************************************************************/

怎样加入P3.5口是高电平时为首次通电11小时后接通5秒断开继电器,然后是通电24小时后接通5秒断开继电器,24小时一直循环,P3.5口是低电平时为首次通电11小时后接通5秒断开继电器,然后是通电48小时后接通5秒断开继电器,48小时一直循环的代码,先谢谢了。
回复

使用道具 举报

12#
ID:460466 发表于 2019-2-16 18:56 | 只看该作者
目的是首次通电11小时后接通5秒断开继电器,然后是通电24小时后接通5秒断开继电器,24小时一直循环,--------------这个过程数字电路也可以完成的呀!
回复

使用道具 举报

13#
ID:221879 发表于 2019-2-19 13:13 | 只看该作者
/********************************************************************/

#include<reg52.h>                 //库文件
#define uchar unsigned char//宏定义无符号字符型
#define uint unsigned int  //宏定义无符号整型
/********************************************************************
                            初始定义
*********************************************************************/
uint sec = 0; //定义计数值,每过1/10 秒,sec 加一
uint tcnt = 0; //键值判断
uchar Start_Flag = 1;//定义一个全局变量,值初始化为1,用来判断首次上电的
/********************************************************************
                            I/O定义
*********************************************************************/
sbit  OUT1=P3^3;//定义输出口为P3.3口 用以控制继电器
sbit  IN1=P3^5;        //定义输入口为P3.5口 用以输入信号

/********************************************************************
                            定时中断服务函数
*********************************************************************/
void t0(void) interrupt 1 using 0 //定时中断服务函数
{
        tcnt++; //每过250ust tcnt 加一
        if(tcnt==4000) //计满4000 次(1 秒)时
        {
                tcnt=0; //重新再计
                sec++;
                if(Start_Flag == 1)//判断为首次上电,进行11个小时的计数
                {
                        if(sec==39596)
                        {
                        OUT1=1;
                        }
                        if(sec==39600) //单位为(1秒)
                        {
                        OUT1=0;
                        sec=0;
                        Start_Flag = 0;//11小时的时间到了,清0首次上电标志,进入24小时计数
                        }
                }
                else//进入24小时计数
                {
                        if(sec==86396) //单位为(1 秒)?
                        {
                        OUT1=1;
                        }
                        if(sec==86400) //单位为(1秒)
                        {
                        OUT1=0;
                        sec=0;
                        }
                }
        }
}

/********************************************************************
                            主函数
*********************************************************************/
void main()
{
        TMOD=0x02; //定时器工作在方式2
        TH0=0x06; //对TH0 TL0 赋值
        TL0=0x06;
        TR0=1; //开始定时
        ET0=1;
        EA=1;
        sec=0;
        OUT1=0;//模块通电继电器吸合
        while(1)
        {
         if(IN1==0){OUT1=1;while(!IN1);OUT1=0;}
        }
}               

        
/********************************************************************
                              结束
*********************************************************************/

怎样加入P3.5口是高电平时为首次通电11小时后接通5秒断开继电器,然后是通电24小时后接通5秒断开继电器,24小时一直循环,P3.5口是低电平时为首次通电11小时后接通5秒断开继电器,然后是通电48小时后接通5秒断开继电器,48小时一直循环的代码,先谢谢了。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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