机顶盒

wKioL1aP2oLCK79ZAABoQ6GwCqY093.jpg

版本排序说明

Ver4.0 

Ver3.0 

Ver2.0 

Ver1.0 



2016.01.18 机顶盒死机解决方案,

版本Ver4.0 

参数已经调整为线上模式:

1,死机检测主板:监测SDI盒子两个LED灯,180秒的熄灭状态,触发一个大约15秒的高电平输出然后拉低电平,推挽输出驱动能力20ma,机顶盒无条件关机15秒,然后开机

2,频道锁定:开机会有一个70秒的等待,然后进入频道设定的过程

3,发送短信:高阻模式下对应的引脚如果检测到有一个9秒的高电平输出,发出短信提示给两个管理员


详细功能,见程序注释

/*
项目名称:机顶盒死机发送短信程序
日期:2016年01月18日 20:10
版本:2.0
兼容死机监控端的3.0程序

作者:chunli
博客:http://990487026.blog.51cto.com/
邮箱:[email protected]
编码环境:GBK2312简体中文
为了代码在各编辑器美观的兼容,没有使用tab键,全用空格隔开
μVision 版本:4.72.9.0 [如果没有License 编译此程序 会报错]
代码类型:C语言
 
 
更新说明:
1,增加了一个管理员手机号,发生重启事件,把事件发送给两个管理员的手机上
2,加入开启・关闭发送短信功能
3,去除��嗦注释


硬件兼容:
单片机型号:STC12C5A60S2
晶振频率:11.0592M
谐振电容:30PF
SIM900A模块+无短信功能限制SIM卡一张


使用说明:
一、
   发送短信模块只提供以下频道的监控,单片机引脚功能的定义请看程序首部
    CCTV 5        --> 监控大板的上边左第1个模块,输出高电平长度大于crash_time数值,触发发送短信给Admin_phone_number
    CCTV 14       --> 监控大板的上边左第2个模块
    湖南卫视      --> 监控大板的上边左第3个模块
    CCTV13        --> 监控大板的上边左第4个模块
    安徽卫视      --> 监控大板的上边左第5个模块
    东方卫视      --> 监控大板的上边左第6个模块
    黑龙江卫视    --> 监控大板的上边左第7个模块
    备用频道 08   --> 监控大板的下边左第3个模块
    备用频道 09   --> 监控大板的下边左第2个模块
    备用频道 10   --> 监控大板的下边左第1个模块
二、    
   蜂鸣器一声响:提示正常,模块已经完成与SIM900A对话初始化
   蜂鸣器二声响:提示已经发送短信给Admin_phone_number1
   蜂鸣器三声响:提示已经发送短信给Admin_phone_number2
   蜂鸣器六声响:提示已经打开 或者已经关闭 发送短信功能
   蜂鸣器九声响:提示因关闭发送短信功能,发生了死机事件,无法发送短信

三、
   Grant_message手机号,发送短信内容"开启发送短信功能"到SIM900A模块的号码,就会开启因宕机事件触发的发送短信功能,并返回一条"已开启发送短信功能"的短信
   Grant_message手机号,发送短信内容"关闭发送短信功能"到SIM900A模块的号码,就会关闭因宕机事件触发的发送短信功能,并返回一条"已关闭发送短信功能"的短信
   也可以测试单片机和Sim900A模块是否在正常工作。

测试环境crash_time的数值:2,便于测试功能
线上环境crash_time的数值:9,真实环境触发条件
【前提是死机监控端的延时要精准】,死机监控端高电平持续时间足够长,必须大于crash_time的数值

编译结果:

Rebuild target 'Target 1'
compiling 死机就发送短信.c...
linking...
Program Size: data=91.0 xdata=100 code=3470
creating hex file from "机顶盒"...
"机顶盒" - 0 Error(s), 0 Warning(s).


*/
 
 
 
#include "STC12C5A60S2.H"
#include "STRING.H" 
#define cache_max 200                                                          //串口接收缓存长度,不能太短啊,要能存储一个简短的短信内容
#define crash_time 9                                                           //定义死机超时,秒
//单片机引脚定义,低电平超时crash_time 触发 发送短信
sbit channel_01 = P0^0; unsigned char channel_01_timer_ms,channel_01_timer_sec; //CCTV 5     定义宕机毫秒 ,秒计时变量
sbit channel_02 = P0^1; unsigned char channel_02_timer_ms,channel_02_timer_sec; //CCTV 14    
sbit channel_03 = P0^2; unsigned char channel_03_timer_ms,channel_03_timer_sec; //湖南卫视   
sbit channel_04 = P0^3; unsigned char channel_04_timer_ms,channel_04_timer_sec; //CCTV 13    
sbit channel_05 = P0^4; unsigned char channel_05_timer_ms,channel_05_timer_sec; //安徽卫视   
sbit channel_06 = P0^5; unsigned char channel_06_timer_ms,channel_06_timer_sec; //东方卫视   
sbit channel_07 = P0^6; unsigned char channel_07_timer_ms,channel_07_timer_sec; //黑龙江卫视  
sbit channel_08 = P0^7; unsigned char channel_08_timer_ms,channel_08_timer_sec; //备用频道 08
sbit channel_09 = P2^7; unsigned char channel_09_timer_ms,channel_09_timer_sec; //备用频道 09
sbit channel_10 = P2^6; unsigned char channel_10_timer_ms,channel_10_timer_sec; //备用频道 10
sbit       beep = P1^0;                                                         //单片机运行指示灯
sbit runing_led = P1^1;                                                         //蜂鸣器


//定义拥有开启,关闭发送短信功能的管理员手机号码+8134********
unsigned char code *Grant_message="0031003300340032003900360037003*003*003*003*";  

//管理员1的手机号码 
unsigned char code *Admin_phone_number1="AT+CMGS=\"003100330034003200390036003*0038003*003*003*\""; 
                                       
//管理员2的手机号码 
unsigned char code *Admin_phone_number2="AT+CMGS=\"003100350030003800380036003*0039003*003*003*\""; 

//CCTV5频道 正在重启,请5分钟后刷新页面。
unsigned char code *message_content_01="004300430054005600359891905300206B63572891CD542FFF0C8BF700355206949F540E523765B0987597623002";
 
//CCTV14少儿频道 正在重启,请5分钟后刷新页面。
unsigned char code *message_content_02="0043004300540056003100345C11513F9891905300206B63572891CD542FFF0C8BF700355206949F540E523765B098759762";
 
//湖南卫视频道 正在重启,请5分钟后刷新页面。
unsigned char code *message_content_03="6E565357536B89C69891905300206B63572891CD542FFF0C8BF700355206949F540E523765B0987597623002";
 
//CCTV13新闻频道 正在重启,请5分钟后刷新页面。
unsigned char code *message_content_04="00430043005400560031003365B095FB9891905300206B63572891CD542FFF0C8BF700355206949F540E523765B0987597623002";
 
//安徽卫视频道 正在重启,请5分钟后刷新页面。
unsigned char code *message_content_05="5B895FBD536B89C69891905300206B63572891CD542FFF0C8BF700355206949F540E523765B0987597623002";
 
//东方卫视频道 正在重启,请5分钟后刷新页面。
unsigned char code *message_content_06="4E1C65B9536B89C69891905300206B63572891CD542FFF0C8BF700355206949F540E523765B0987597623002";
 
//黑龙江卫视频道 正在重启,请5分钟后刷新页面。
unsigned char code *message_content_07="9ED19F996C5F536B89C69891905300206B63572891CD542FFF0C8BF700355206949F540E523765B0987597623002";
 
//备用频道08 正在重启,请5分钟后刷新页面。
unsigned char code *message_content_08="59077528989190530030003800206B63572891CD542FFF0C8BF700355206949F540E523765B0987597623002";
 
//备用频道09 正在重启,请5分钟后刷新页面。
unsigned char code *message_content_09="59077528989190530030003900206B63572891CD542FFF0C8BF700355206949F540E523765B0987597623002";
 
//备用频道10 正在重启,请5分钟后刷新页面。
unsigned char code *message_content_10="59077528989190530031003000206B63572891CD542FFF0C8BF700355206949F540E523765B0987597623002";

unsigned char code *Open_message="5F00542F";       //开启 
unsigned char code *Shut_message="517395ED";       //关闭 
unsigned char code *Send_open_message="5DF25F00542F53D1900177ED4FE1529F80FD3002";  //已开启发送短信功能。 
unsigned char code *Send_shut_message="5DF2517395ED53D1900177ED4FE1529F80FD3002";  //已开启发送短信功能。 
	
 
//xdata 把变量存在flash中,而不存在RAM中
//code 定义的数据要放在ROM里面,写入后就不能再更改
//Timer_start =Flag^0 定时器标志位  bdata 把变量定义为可拆成8位寻址
xdata unsigned char uart_cache[cache_max]; 
bdata unsigned char Flag;    
sbit Timer_start =Flag^0;     //计时器,功能开关
sbit Message_switch =Flag^1;  //打开・关闭 ,发送短信的功能

unsigned char Times=0;        //定时计数器
unsigned char First_Int = 0;  //串口数组字符“指针”
unsigned char delay=0;        //中断定时器,实际延时delay*50次
 
void SendData(unsigned char dat){   //底层驱动,发一个英文8位数据到串口SBUF
    ES=0;                  
    SBUF=dat;          
    while(TI!=1);  
    TI=0;                  
    ES=1;                  
}
     
void SendString(unsigned char *s){  //底层驱动,发英文字符到串口SBUF
    while(*s){SendData(*s++);}
}
  
void SendLR(void) {              // 发送回车换行
    SendString("\r\n");
}
  
void DELAY_MS (unsigned int a){   // 毫秒级延时・12M@1T单片机
    unsigned int i;
    while ( --a != 0 )    
    for (i=0;i<=600;i++);
}
 
void Beep_Ring(unsigned char ring_times){   //蜂鸣器提示音   
if(ring_times==1){beep=0;DELAY_MS(300); beep=1;DELAY_MS(100);}
if(ring_times==2){beep=0;DELAY_MS(150); beep=1;DELAY_MS(100);beep=0;DELAY_MS(150); beep=1;DELAY_MS(100);}
if(ring_times==3){beep=0;DELAY_MS(100); beep=1;DELAY_MS(100);beep=0;DELAY_MS(100); beep=1;DELAY_MS(100);beep=0;DELAY_MS(100); beep=1;DELAY_MS(100);}
}
 
void Uart1Init(void)   {   //定时器1,[email protected]
    PCON &= 0x7F;          //波特率不倍速
    SCON  = 0x50;          //8位数据,可变波特率
    AUXR &= 0xBF;          //定时器1时钟为Fosc/12,即12T
    AUXR &= 0xFE;          //串口1选择定时器1为波特率发生器
    TMOD &= 0x0F;          //清除定时器1模式位
    TMOD |= 0x20;          //设定定时器1为8位自动重装方式
    TL1 = 0xFD;            //设定定时初值
    TH1 = 0xFD;            //设定定时器重装值
    ET1 = 0;               //禁止定时器1中断
    TR1 = 1;               //启动定时器1
    ES=1;                  //开串口中断
}
    
void Timer0Init(void)  {   //20毫秒@11.0592MHz
    AUXR &= 0x7F;          //定时器0时钟12T模式
    TMOD &= 0xF0;          //设置定时器模式
    TMOD |= 0x01;          //设置定时器模式,16位定时器,非自动重载模式
    TL0 = 0x00;            //设置定时器初值
    TH0 = 0xB8;            //设置定时器初值
    TF0 = 0;               //清TF0标志
    TR0 = 1;               //定时器0开始计时
    ET0 = 1;               //使能定时器0中断
    EA=1;                  //开总中断
}
   
void CLR_Buf1(void){ 
    unsigned int k;
    for(k=0;k<cache_max;k++){uart_cache[k] = 0;} //将缓存内容清零
    First_Int = 0;                               //接收字符串的起始存储位置
    DELAY_MS(50);                                //摸索才发现的等待缓存串口清空生效・坑死我了,哈哈~
    //如果没有这个 DELAY_MS(50);这个缓存赋值为0,数值并不会立即生效,搞不明白,最好还是加上
}
     
void Send_Command(unsigned char *command,unsigned char *ack,unsigned char wait_time){         
    unsigned char *pointer;
    pointer = command;                     //保存字符串command的首地址到c
    CLR_Buf1();                            //清除串口缓存
    while(1) { 
        if(!strstr(uart_cache,ack))  {     //查找需要应答的字符
          if(Timer_start == 0){
           command = pointer;              //将字符串地址给b
           for (command; *command!='\0';command++){SendData(*command);}
           SendLR();  
           Times = 0;
           delay = wait_time;
           Timer_start = 1;           // 开启定时器
           }
        }else{
            Timer_start = 0;          //关闭定时器
            break; 
         }
   }
CLR_Buf1();                    //如果找到了匹配的字符串,清除串口缓存,不要干扰后面的程序
}
   
void Wait_Register(void) {     //等待模块注册成功
    unsigned char i,k;
    i = 1;                     //循环标志位,用来从内层循环直接跳出
    CLR_Buf1();                //清空串口数组缓存,免得带来干扰
    while(i) {  
        CLR_Buf1(); 
        SendString("AT+CREG?");//查询模块网络注册状态
        SendLR();
        DELAY_MS(1000);                  
        for(k=0;k<cache_max;k++) {
         if(uart_cache[k] == ':')  {
            if((uart_cache[k+4] == '1')||(uart_cache[k+4] == '5')){//表明网络注册成功
                i = 0;           //循环标志位,用来从内层循环for直接跳出到while外
                CLR_Buf1();
            }
        }
     }
  }
}
 
  
void Send_Message(unsigned char channel_number){
	if(!Message_switch){     //判断是否允许发送短信,如果不允许发送短信,9声急促提示音,结束函数
    Beep_Ring(3);
    Beep_Ring(3);
    Beep_Ring(3); 
    return;
   }

//给管理员1发送重启事件提示短信
   Send_Command("AT+CSMP=17,167,2,25","OK",3);               //设置文本模式参数   
   Send_Command("AT+CSCS=\"UCS2\"","OK",3);                  //设置字符集  
   Send_Command(Admin_phone_number1,">",3);                  //手机号码  有回车符
  switch (channel_number){
     case  1: Send_Command(message_content_01,">",3); break;    
     case  2: Send_Command(message_content_02,">",3); break;    
     case  3: Send_Command(message_content_03,">",3); break;    
     case  4: Send_Command(message_content_04,">",3); break;    
     case  5: Send_Command(message_content_05,">",3); break;    
     case  6: Send_Command(message_content_06,">",3); break;    
     case  7: Send_Command(message_content_07,">",3); break;    
     case  8: Send_Command(message_content_08,">",3); break;    
     case  9: Send_Command(message_content_09,">",3); break;    
     case 10: Send_Command(message_content_10,">",3); break;    
     default: Beep_Ring(1);Beep_Ring(1); }                //警告 连续两声长音
  SendData(0x1a);                                         // 开始发送 不跟回车符
  DELAY_MS(2000);                                         //等待SIM900A模块的响应  
  Beep_Ring(2);
		 
		 
//给管理员2发送重启事件提示短信
   Send_Command("AT+CSMP=17,167,2,25","OK",3);               
   Send_Command("AT+CSCS=\"UCS2\"","OK",3);                  
   Send_Command(Admin_phone_number2,">",3);                  
  switch (channel_number){
     case  1: Send_Command(message_content_01,">",3); break;    
     case  2: Send_Command(message_content_02,">",3); break;    
     case  3: Send_Command(message_content_03,">",3); break;    
     case  4: Send_Command(message_content_04,">",3); break;    
     case  5: Send_Command(message_content_05,">",3); break;    
     case  6: Send_Command(message_content_06,">",3); break;    
     case  7: Send_Command(message_content_07,">",3); break;    
     case  8: Send_Command(message_content_08,">",3); break;    
     case  9: Send_Command(message_content_09,">",3); break;    
     case 10: Send_Command(message_content_10,">",3); break;    
     default: Beep_Ring(3); }                             
  SendData(0x1a);                                         
  DELAY_MS(2000);                                         
  Beep_Ring(3);

}
    
void SIM900aInit(void){
    Send_Command("AT","OK",3);                  //波特率同步
//    Send_Command("AT+CLIP=1","OK",3);         //开启来电显示
    Send_Command("AT+CSCLK=0","OK",3);          //关闭SIM900A睡眠
  	Send_Command("AT+CMGD=1,4","OK",3);         //删除卡上所有短信
	  Send_Command("ATE0","OK",3);                //取消回显 
    Send_Command("AT+CNMI=3,2,0,0,0","OK",3);   //新短信直接输出
    Send_Command("AT+CMGF=1","OK",3);           //TEXT模式   
    Send_Command("AT+CPMS=\"SM\",\"SM\",\"SM\"","OK",3);    //所有操作都在SIM卡中进行
    Wait_Register();                                        //查询等待模块注册成功
    Beep_Ring(1);                                           //SIM900A初始化完成提示音,滴~
} 
 
 
void Check_status(void){        //被中断函数调用,每20毫秒执行一次该函数
  if(channel_01){               //如果channel_01引脚是低电平,进入秒计时器
  channel_01_timer_ms++;
    if(channel_01_timer_ms>50){  // [email protected]
     channel_01_timer_sec++;
      channel_01_timer_ms = 0;
    } 
  }else{channel_01_timer_ms = 0;}//如果channel_01引脚不是低电平,清空毫秒计时器
 
 
  if(channel_02){                 
    channel_02_timer_ms++;
      if(channel_02_timer_ms>50){ 
      channel_02_timer_sec++;
       channel_02_timer_ms = 0;
      } 
    }else{channel_02_timer_ms = 0;}    
  
  if(channel_03){                      
  channel_03_timer_ms++;
    if(channel_03_timer_ms>50){        
    channel_03_timer_sec++;
     channel_03_timer_ms = 0;
    } 
  }else{channel_03_timer_ms = 0;} 
                                  
  if(channel_04){                 
  channel_04_timer_ms++;          
    if(channel_04_timer_ms>50){   
    channel_04_timer_sec++;
     channel_04_timer_ms = 0;
    } 
  }else{channel_04_timer_ms = 0;} 
                                  
   if(channel_05){                
  channel_05_timer_ms++;          
    if(channel_05_timer_ms>50){   
    channel_05_timer_sec++;       
     channel_05_timer_ms = 0;     
    }                             
  }else{channel_05_timer_ms = 0;} 
                                  
   if(channel_06){                
  channel_06_timer_ms++;          
    if(channel_06_timer_ms>50){   
    channel_06_timer_sec++;       
     channel_06_timer_ms = 0;     
    }                             
  }else{channel_06_timer_ms = 0;} 
                                  
  if(channel_07){                 
  channel_07_timer_ms++;          
    if(channel_07_timer_ms>50){   
    channel_07_timer_sec++;       
     channel_07_timer_ms = 0;     
    } 
  }else{channel_07_timer_ms = 0;} 
                                  
  if(channel_08){                 
  channel_08_timer_ms++;          
    if(channel_08_timer_ms>50){   
    channel_08_timer_sec++;       
     channel_08_timer_ms = 0;
    } 
  }else{channel_08_timer_ms = 0;} 
                                  
    if(channel_09){               
  channel_09_timer_ms++;          
    if(channel_09_timer_ms>50){   
    channel_09_timer_sec++;
     channel_09_timer_ms = 0;
    } 
  }else{channel_09_timer_ms = 0;} 
                                  
   if(channel_10){                
  channel_10_timer_ms++;          
    if(channel_10_timer_ms>50){   
    channel_10_timer_sec++;
     channel_10_timer_ms = 0;
    } 
  }else{channel_10_timer_ms = 0;}   
}
  
  
void Check_Crash(void)   {                     //轮询查看是否死机 ,高电平有效
 
  if(channel_01_timer_sec > crash_time){       //检测1号频道 低电平时间
    channel_01_timer_sec=0;                    //清空死机时间长度标记
    Send_Message(1);                           //调用发送短信
  } 
 
  if(channel_02_timer_sec > crash_time){       
    channel_02_timer_sec=0;                    
    Send_Message(2);                           
  } 
 
  if(channel_03_timer_sec > crash_time){       
    channel_03_timer_sec=0;                    
    Send_Message(3);                           
  } 

  if(channel_04_timer_sec > crash_time){       
    channel_04_timer_sec=0;                    
    Send_Message(4);                           
  } 

  if(channel_05_timer_sec > crash_time){       
    channel_05_timer_sec=0;                    
    Send_Message(5);                           
  } 

  if(channel_05_timer_sec > crash_time){       
    channel_05_timer_sec=0;                    
    Send_Message(5);                           
  } 

  if(channel_06_timer_sec > crash_time){       
    channel_06_timer_sec=0;                    
    Send_Message(6);                           
  } 

  if(channel_07_timer_sec > crash_time){       
    channel_07_timer_sec=0;                    
    Send_Message(7);                           
  } 

  if(channel_08_timer_sec > crash_time){       
    channel_08_timer_sec=0;                    
    Send_Message(8);                           
  } 

  if(channel_09_timer_sec > crash_time){       
    channel_09_timer_sec=0;                    
    Send_Message(9);                           
  } 

  if(channel_10_timer_sec > crash_time){       
    channel_10_timer_sec=0;                    
    Send_Message(10);                          
  } 
} 
 
void Check_New_Message(void)   { 
    if(strstr(uart_cache,Grant_message))  {             //若缓存字符串中含有Grant_message就表示 超级管理员发短信来了
         DELAY_MS(300);                                 //等待数据全部接收完成,1T单片机执行速度太快
        if(strstr(uart_cache,Open_message)) {           //匹配开启发送短信内容
            Message_switch=1;                           //允许发送重启事件短信
  					Send_Command("AT+CSMP=17,167,2,25","OK",3); //设置文本模式参数   
            Send_Command("AT+CSCS=\"UCS2\"","OK",3);    //设置字符集  
            Send_Command(Admin_phone_number1,">",3);    //给Admin_phone_number1发送通知
            Send_Command(Send_open_message,">",3);      //已开启发送短信功能。
            SendData(0x1a);                             // 开始发送 返回OK
            DELAY_MS(3000);  
  					Beep_Ring(3);Beep_Ring(3);                  //短信发送提示音,滴~滴~滴・滴~滴~滴~
         }

				if(strstr(uart_cache,Shut_message)) {          
            Message_switch=0;                           //不允许发送重启事件短信            
            Send_Command("AT+CSMP=17,167,2,25","OK",3);
            Send_Command("AT+CSCS=\"UCS2\"","OK",3);   
            Send_Command(Admin_phone_number1,">",3);   
            Send_Command(Send_shut_message,">",3);     
            SendData(0x1a);                            
            DELAY_MS(3000);  
  					Beep_Ring(3);Beep_Ring(3);
        }
        CLR_Buf1();  // 清空SBUF缓存
    }
}
 
//主函数
void main(void){
   P0M1=0xff;       //设定P0口为高阻,用来检测高低,模拟电平
   P0M0=0x00;       //设定P0口为高阻,用来检测高低,模拟电平
   P2M1=0xff;       //设定P2口为高阻,用来检测高低,模拟电平
   P2M1=0x00;       //设定P3口为高阻,用来检测高低,模拟电平
   Timer0Init();    //初始化定时器0
   Uart1Init();     //初始化串口9600波特率
   SIM900aInit();   //初始化SIM900A模块
   Message_switch=1;//默认打开发送短信功能
	 while(1){       
    Check_Crash();        //查询各个频道的引脚状态,判断是否死机
		Check_New_Message();  //查询新的短信
   }               
}
 
//4级串口中断函数
void Uart1() interrupt 4{
    uart_cache[First_Int] = SBUF;             //将接收到的单个字符存到缓存中
    First_Int++;                              //缓存指针向后移动
    if(First_Int > cache_max){First_Int = 0;} //如果缓存满,将缓存指针指向缓存的首地址
    RI = 0;                                   //清除RI位
}
 
//1级最高级别,定时器中断函数
void Timer0() interrupt 1{              //最高级别中断服务程序 [email protected]
    static unsigned char Time_count=0;  //定时器计数器 static全局生命周期
    TR0=0;                              //关定时器
    TL0 = 0x00;                         //重设定时器初值
    TH0 = 0xB8;                         //重设定时器初值
    Time_count++;                       //每隔20毫秒进入中断,Time_count无条件自加运算            
    if(Time_count>=50){
        Time_count = 0;
        runing_led=~runing_led;         //SIM900A运行指示灯,1秒闪烁一次
       }
    if(Timer_start) Times++;  //如果收到允许定时,开始计时
    if(Times > (50*delay)){   //如果Times 到达设定时间,50*delay就是秒数
        Timer_start = 0;      //定时结束,定时功能标记Timer_start一定为0
        Times = 0;            //完成定时,清空计数器
       }
    Check_status();           //轮询监督死机函数
    TR0=1;                    //开启定时器
}





------------------------------------------------------
/*
项目名称:监控机顶盒 是否死机了
日期:2016年01月17日
版本:4.0

变更说明:
1,获取电平持续时间,判断死机状态更科学

作者:chunli
博客:990487026.blog.51cto.com
邮箱:[email protected]
编码环境:GBK2312简体中文
μVision 版本:4.72.9.0


单片机:STC15f104W
STC15F104W ,晶振设定12M
1 P3.4
2 VCC  3.8--5.5V
3 P3.5
4 GND
5 P3.0 接烧录器的TXD
6 P3.1 接烧录器的RXD
7 P3.2
8 P3.3

STC15F104W I/O 口工作类型设定
P3M1[5:0] P3M0[5:0] I/O工作模式
0         0 准双向 下拉20ma,上拉270μa
0         1 推挽模式(上拉20ma)
1         0 仅为输入(高阻状态)
1         1 开漏模式,内部上拉电阻断开
P3M1=0x00; //设定P3.3为推挽
P3M0=0x0f; //设定P3.3为推挽


线上环境的数值if(Time_sec > 180 )  3分钟的死机状态监测

*/

#include "STC15F104E.H"
#define watiting 15      //关机,输出高电平时间长度 秒  不是很精确
sbit      led1 = P3^1;  //LM393 A输出,低电平为正常,高电平为异常 ,HDMI convert SDI 1灯熄灭LM393 A会有高电平
sbit      led2 = P3^2;  //LM393 B输出,低电平为正常,高电平为异常 ,HDMI convert SDI 2灯熄灭LM393 B会有高电平
sbit   control = P3^4;  //输出高电平给机顶盒的EL817会控制重启
unsigned int Time_20ms;
unsigned int Time_sec;

void sleep_ms(unsigned int a)	{ // 毫秒级延时函数	@12M 1T单片机
    unsigned int i;
    while ( --a != 0 ) {
        for (i=0;i<=600;i++);
    }
}

void sleep_sec(unsigned char time){	 // 延时函数,秒
  unsigned char num;
  for(num=0;num<time;num++){
     sleep_ms(1000);		
  }
}

void restart(void){   //高电平 有效
  control=1;          //推挽输出高电平给机顶盒的
  sleep_sec(watiting);//关机watiting秒
  control=0;          //结束高电平,机顶盒开机
  sleep_sec(watiting);      
}

void Timer0Init(void)  {   //20毫秒@11.0592MHz
    AUXR &= 0x7F;          //定时器0时钟12T模式
    TMOD &= 0xF0;          //设置定时器模式
    TMOD |= 0x01;          //设置定时器模式,16位定时器,非自动重载模式
    TL0 = 0x00;            //设置定时器初值
    TH0 = 0xB8;            //设置定时器初值
    TF0 = 0;               //清TF0标志
    TR0 = 1;               //定时器0开始计时
    ET0 = 1;               //使能定时器0中断
    EA=1;                  //开总中断
}

void main(){
control = 0;   //监控端开机关机瞬间,不应该影响到机顶盒
P3M1=0x00;     //设定P3.4为推挽	00000(bin)
P3M0=0x10;     //设定P3.4为推挽	10000(bin)
Timer0Init();

while(1){
     if(Time_sec > 180 ){	//判断死机状态的持续时间长度,应大于电视盒子初始化时间 单位:秒
      Time_sec=0;	        //清空计数器
      restart();          //重启机顶盒
         }
     }
 }

//1级最高级别,定时器中断函数
void Timer0() interrupt 1{         //最高级别中断服务程序
    TR0=0;                         //关定时器
    TL0 = 0x00;                    //重设定时器初值
    TH0 = 0xB8;                    //重设定时器初值

    if(led1 && led2) Time_20ms ++; //只有当两个led都输出高电平,才计入死机持续时间计算
    else {						   //如果中途led1或led2电平突变为低电平,清空计数器	,复位死机时间计算
      Time_20ms=0;
      Time_sec=0;
	}

	if(Time_20ms > 50){
	  Time_20ms=0;
	  Time_sec++;
	}
    TR0=1;                     //开定时器
}

-----------------------------------------------------
/*
项目名称:机顶盒开机后,单片机固定频道(仅限用于华数机顶盒)
功能:电视盒子开机,80秒后自动锁定频道,完成后,蜂鸣器嘀的一声
日期:2016年01月15日
版本:4.0
更新说明:
1,取消right按键 ,用OK键代替


作者:chunli
博客:990487026.blog.51cto.com
邮箱:[email protected]
编码环境:GBK2312简体中文
μVision 版本:4.72.9.0


单片机型号:STC15f104W
烧录晶振选择:12M

单片机引脚说明
1 P3.4
2 VCC  3.8--5.5V
3 P3.5
4 GND
5 P3.0 接烧录器的TXD
6 P3.1 接烧录器的RXD
7 P3.2
8 P3.3

STC15F104W I/O 口工作类型设定
P3M1[5:0] P3M0[5:0] I/O工作模式
0         0 准双向 下拉20ma,上拉270μa
0         1 推挽模式(上拉20ma)
1         0 仅为输入(高阻状态)
1         1 开漏模式,内部上拉电阻断开
P3M1=0x00; //设定P3.3为推挽
P3M0=0x08; //设定P3.3为推挽

*/

#include "STC15F104E.H"
#define waiting  2000     // 按键超时时间设定,单位 毫秒

sbit    key_menu = P3^0;  //机顶盒的menu按键,发出低电平有效
sbit    key_down = P3^1;  //机顶盒的down按键,发出低电平有效
sbit      key_ok = P3^2;  //机顶盒的ok按键,发出低电平有效
sbit        beep = P3^3;  //蜂鸣器,发出低电平有效



void delay (unsigned int a)	{ // 毫秒级延时函数	@12M晶振 1T单片机
    unsigned int i;
    while ( --a != 0 ) {
        for (i=0;i<=600;i++);
    }
}

void menu(void){   //按一下menu键的操作 函数
  key_menu=0;
  delay(500);
  key_menu=1;
  delay(waiting);
}

void down(unsigned char down_number){  //按多次down键的操作 函数
  unsigned char i;
  for(i=0;i<down_number;i++){
     key_down=0;
     delay(500);
     key_down=1;
     delay(waiting);
  }
}


void ok(void){
  key_ok=0;
  delay(500); 
  key_ok=1;
  delay(waiting);
}

void change_channel(unsigned char page,unsigned char number){	 // 选择频道的函数								    
//page	     选择频道所在的 第几页	     1到21页可选
//number     选择频道所属page的number	 1到9可选  
   menu();
   down(2);
   ok();
   down(9*(page-1)+number-1);
   ok();
}

void beep_ring(void){
beep=0;
delay(500);
beep=1;
}

void initial (void){ // 开机初始化  
  unsigned char i;
  for(;i<70;i++){   // 等待机顶盒开机初始化,70秒,菜单消失,黑屏提示 无信号(无信号源时)。
      delay(1000);
   }

  change_channel(1,9); //浙江卫视,  在第1页,第9个 
//change_channel(3,3); //CCTV5 体育,在第3页,第3个 
//change_channel(9,6); //CCTV14少儿,在第9页,第6个 
//change_channel(5,4); //湖南卫视,  在第5页,第4个 
//change_channel(3,5); //CCTV13新闻,在第3页,第5个 
//change_channel(7,1); //安徽卫视,  在第7页,第1个 
//change_channel(4,7); //东方卫视,  在第4页,第7个 
//change_channel(3,8); //黑龙江卫视,在第3页,第8个 
}

void main(){	   //主函数
   initial();    //锁定频道
   beep_ring();	 //蜂鸣器提示音
   while(1){
  }
}

-----------------------------------------------------------------



3.0版本程序

/*
项目名称:机顶盒开机后,单片机固定频道(仅限用于华数机顶盒)
功能:电视盒子开机,80秒后自动锁定频道,完成后,蜂鸣器嘀的一声
日期:2016年01月15日
版本:3.0
更新说明:
1,取消right按键 ,用OK键代替


作者:chunli
博客:990487026.blog.51cto.com
邮箱:[email protected]
编码环境:GBK2312简体中文
μVision 版本:4.72.9.0


单片机型号:STC15f104W
烧录晶振选择:12M

单片机引脚说明
1 P3.4
2 VCC  3.8--5.5V
3 P3.5
4 GND
5 P3.0 接烧录器的TXD
6 P3.1 接烧录器的RXD
7 P3.2
8 P3.3

STC15F104W I/O 口工作类型设定
P3M1[5:0] P3M0[5:0] I/O工作模式
0         0 准双向 下拉20ma,上拉270μa
0         1 推挽模式(上拉20ma)
1         0 仅为输入(高阻状态)
1         1 开漏模式,内部上拉电阻断开
P3M1=0x00; //设定P3.3为推挽
P3M0=0x08; //设定P3.3为推挽

*/

#include "STC15F104E.H"
#define waiting  2000     // 按键超时时间设定,单位 毫秒

sbit    key_menu = P3^0;  //机顶盒的menu按键,发出低电平有效
sbit    key_down = P3^1;  //机顶盒的down按键,发出低电平有效
sbit      key_ok = P3^2;  //机顶盒的ok按键,发出低电平有效
sbit        beep = P3^3;  //蜂鸣器,发出低电平有效



void delay (unsigned int a)    { // 毫秒级延时函数    @12M晶振 1T单片机
    unsigned int i;
    while ( --a != 0 ) {
        for (i=0;i<=600;i++);
    }
}

void menu(void){   //按一下menu键的操作 函数
  key_menu=0;
  delay(500);
  key_menu=1;
  delay(waiting);
}

void down(unsigned char down_number){  //按多次down键的操作 函数
  unsigned char i;
  for(i=0;i<down_number;i++){
     key_down=0;
     delay(500);
     key_down=1;
     delay(waiting);
  }
}


void ok(void){
  key_ok=0;
  delay(500); 
  key_ok=1;
  delay(waiting);
}

void change_channel(unsigned char page,unsigned char number){     // 选择频道的函数                                    
//page         选择频道所在的 第几页         1到21页可选
//number     选择频道所属page的number     1到9可选  
   menu();
   down(2);
   ok();
   down(9*(page-1)+number-1);
   ok();
}

void beep_ring(void){
beep=0;
delay(500);
beep=1;
}

void initial (void){ // 开机初始化  
  unsigned char i;
  for(;i<70;i++){   // 等待机顶盒开机初始化,70秒,菜单消失,黑屏提示 无信号(无信号源时)。
      delay(1000);
   }

  change_channel(1,9); //浙江卫视,  在第1页,第9个 
//change_channel(3,3); //CCTV5 体育,在第3页,第3个 
//change_channel(9,6); //CCTV14少儿,在第9页,第6个 
//change_channel(5,4); //湖南卫视,  在第5页,第4个 
//change_channel(3,5); //CCTV13新闻,在第3页,第5个 
//change_channel(7,1); //安徽卫视,  在第7页,第1个 
//change_channel(4,7); //东方卫视,  在第4页,第7个 
//change_channel(3,8); //黑龙江卫视,在第3页,第8个 
}

void main(){     //主函数
   initial();    //锁定频道
   beep_ring();     //蜂鸣器提示音
   while(1){
  }
}




编译结果
Build target 'Target 1'
compiling 死机监控.C...
linking...
Program Size: data=13.0 xdata=0 code=209
creating hex file from "机顶盒"...
"机顶盒" - 0 Error(s), 0 Warning(s).








/*
项目名称:监控机顶盒 是否死机了
日期:2016年01月15日
版本:3.0

变更说明:
1,获取电平持续时间,判断死机状态更科学

作者:chunli
博客:990487026.blog.51cto.com
邮箱:[email protected]
编码环境:GBK2312简体中文
μVision 版本:4.72.9.0


单片机:STC15f104W
STC15F104W ,晶振设定12M
1 P3.4
2 VCC  3.8--5.5V
3 P3.5
4 GND
5 P3.0 接烧录器的TXD
6 P3.1 接烧录器的RXD
7 P3.2
8 P3.3

STC15F104W I/O 口工作类型设定
P3M1[5:0] P3M0[5:0] I/O工作模式
0         0 准双向 下拉20ma,上拉270μa
0         1 推挽模式(上拉20ma)
1         0 仅为输入(高阻状态)
1         1 开漏模式,内部上拉电阻断开
P3M1=0x00; //设定P3.3为推挽
P3M0=0x0f; //设定P3.3为推挽

*/

#include "STC15F104E.H"
#define watiting 3      //关机时间长度
sbit      led1 = P3^1;  //LM393 A输出,低电平为正常,高电平为异常 ,HDMI convert SDI 1灯熄灭LM393 A会有高电平
sbit      led2 = P3^2;  //LM393 B输出,低电平为正常,高电平为异常 ,HDMI convert SDI 2灯熄灭LM393 B会有高电平
sbit   control = P3^4;  //输出高电平给机顶盒的EL817会控制重启
unsigned int Time_20ms;
unsigned int Time_sec;

void sleep_ms(unsigned int a)    { // 毫秒级延时函数    @12M 1T单片机
    unsigned int i;
    while ( --a != 0 ) {
        for (i=0;i<=600;i++);
    }
}

void sleep_sec(unsigned char time){     // 延时函数,秒
  unsigned char num;
  for(num=0;num<time;num++){
     sleep_ms(1000);        
  }
}

void restart(void){   //高电平 有效
  control=1;          //推挽输出高电平给机顶盒的
  sleep_sec(watiting);//关机watiting秒
  control=0;          //结束高电平,机顶盒开机
  sleep_sec(watiting);      
}

void Timer0Init(void)  {   //20毫秒@11.0592MHz
    AUXR &= 0x7F;          //定时器0时钟12T模式
    TMOD &= 0xF0;          //设置定时器模式
    TMOD |= 0x01;          //设置定时器模式,16位定时器,非自动重载模式
    TL0 = 0x00;            //设置定时器初值
    TH0 = 0xB8;            //设置定时器初值
    TF0 = 0;               //清TF0标志
    TR0 = 1;               //定时器0开始计时
    ET0 = 1;               //使能定时器0中断
    EA=1;                  //开总中断
}

void main(){
control = 0;   //监控端开机关机瞬间,不应该影响到机顶盒
P3M1=0x00;     //设定P3.4为推挽    00000(bin)
P3M0=0x10;     //设定P3.4为推挽    10000(bin)
Timer0Init();

while(1){
     if(Time_sec > 3 ){        //获取高电平持续时间的长度
      Time_sec=0;            //清空计数器
      restart();            //重启机顶盒
         }
     }
 }

//1级最高级别,定时器中断函数
void Timer0() interrupt 1{         //最高级别中断服务程序
    TR0=0;                         //关定时器
    TL0 = 0x00;                    //重设定时器初值
    TH0 = 0xB8;                    //重设定时器初值

    if(led1 && led2) Time_20ms ++; //只有当两个led都输出高电平,才计入死机持续时间计算
    else {                           //如果中途led1或led2电平突变为低电平,清空计数器    ,复位死机时间计算
      Time_20ms=0;
      Time_sec=0;
    }

    if(Time_20ms > 50){
      Time_20ms=0;
      Time_sec++;
    }
    TR0=1;                     //开定时器
}



编译结果
Build target 'Target 1'
compiling 死机监控.C...
linking...
Program Size: data=13.0 xdata=0 code=209
creating hex file from "机顶盒"...
"机顶盒" - 0 Error(s), 0 Warning(s).




2.0版本程序

/*
项目名称:机顶盒开机后,单片机固定频道(仅限用于华数机顶盒)
功能:电视盒子开机,70秒后自动锁定频道,完成后,蜂鸣器嘀的一声
日期:2016年01月10日
版本:2.0
作者:chunli
博客:990487026.blog.51cto.com
邮箱:[email protected]
编码环境:GBK2312简体中文
μVision 版本:4.72.9.0


单片机:STC15f104W
STC15F104W ,晶振设定12M
1 P3.4
2 VCC  3.8--5.5V
3 P3.5
4 GND
5 P3.0 接烧录器的TXD
6 P3.1 接烧录器的RXD
7 P3.2
8 P3.3

STC15F104W I/O 口工作类型设定
P3M1[5:0] P3M0[5:0] I/O工作模式
0         0 准双向 下拉20ma,上拉270μa
0         1 推挽模式(上拉20ma)
1         0 仅为输入(高阻状态)
1         1 开漏模式,内部上拉电阻断开
P3M1=0x00; //设定P3.3为推挽
P3M0=0x08; //设定P3.3为推挽

*/

#include "reg51.h"
#define waiting  2000
sbit    key_menu = P3^0;  //机顶盒的menu按键,发出低电平有效
sbit    key_down = P3^1;  //机顶盒的down按键,发出低电平有效
sbit   key_right = P3^2;  //机顶盒的right按键,发出低电平有效
sbit      key_ok = P3^3;  //机顶盒的ok按键,发出低电平有效
sbit        beep = P3^4;  //蜂鸣器,发出低电平有效



void delay (unsigned int a)	{ // 毫秒级延时函数
    unsigned int i;
    while ( --a != 0 ) {
        for (i=0;i<=600;i++);
    }
}

void menu(void){   //按一下menu键的操作 函数
  key_menu=0;
  delay(500);
  key_menu=1;
  delay(waiting);
}

void down(unsigned char down_number){  //按一下down键的操作 函数
  unsigned char i;
  for(i=0;i<down_number;i++){
     key_down=0;
     delay(500);
     key_down=1;
     delay(waiting);
  }
}

void right(void){  //按一下rigth键的操作 函数
  key_right=0;
  delay(500);
  key_right=1;
  delay(waiting);
}


void ok(void){
  key_ok=0;
  delay(500); 
  key_ok=1;
  delay(waiting);
}

void change_channel(unsigned char page,unsigned char number){	 // 选择频道的函数								    
//page	     选择频道所在的 第几页	     1到21页可选
//number     选择频道所属page的number	 1到9可选  
   menu();
   down(2);
   right();
   down(9*(page-1)+number-1);
   ok();
}

void beep_ring(void){
beep=0;
delay(1000);
beep=1;
}

void initial (void){ // 开机初始化  
  unsigned char i;
  for(;i<70;i++){   // 等待机顶盒开机初始化,70秒,菜单消失,黑屏提示 无信号(无信号源时)。
      delay(1000);
   }

change_channel(1,9); //浙江卫视,在第1页,第9个 
//change_channel(3,5); //中央新闻,在第3页,第5个 
//change_channel(1,1); //华数剧场,在第1页,第1个 
//change_channel(1,1); //华数剧场,在第1页,第1个 
//change_channel(21,1); //求索旅行,在第21页,第2个 
}

void main(){	 //主函数
   initial(); 
	 beep_ring();
   while(1){
  }
}














/*
项目名称:监控机顶盒 是否死机了
日期:2016年01月10日
版本:2.0
作者:chunli
博客:990487026.blog.51cto.com
邮箱:[email protected]
编码环境:GBK2312简体中文
μVision 版本:4.72.9.0


单片机:STC15f104W
STC15F104W ,晶振设定12M
1 P3.4
2 VCC  3.8--5.5V
3 P3.5
4 GND
5 P3.0 接烧录器的TXD
6 P3.1 接烧录器的RXD
7 P3.2
8 P3.3

STC15F104W I/O 口工作类型设定
P3M1[5:0] P3M0[5:0] I/O工作模式
0         0 准双向 下拉20ma,上拉270μa
0         1 推挽模式(上拉20ma)
1         0 仅为输入(高阻状态)
1         1 开漏模式,内部上拉电阻断开
P3M1=0x00; //设定P3.3为推挽
P3M0=0x08; //设定P3.3为推挽

*/

#include "STC15F104E.H"
sbit      led1 = P3^5;  //HDMI convert SDI 1号灯
sbit      led2 = P3^4;  //HDMI convert SDI 2号灯
sbit   control = P3^3;  //继电器上电,机顶盒重启

void sleep_ms(unsigned int a)	{ // 毫秒级延时函数	@12M
    unsigned int i;
    while ( --a != 0 ) {
        for (i=0;i<=600;i++);
    }
}

void sleep_sec(unsigned char time){	 // 延时函数,秒
  unsigned char num;
  for(num=0;num<time;num++){
     sleep_ms(1000);
  }
}

void restart(void){   //P沟道场效应管,G极高电平,再低电平
  control=0;          //P沟道场效应管,G极高电平,机顶盒断电
  sleep_sec(10);          //机顶盒断电10秒
  control=1;          //P沟道场效应管,G极低电平,机顶盒开机
}

void main(){
   while(1){
    if(led1&&led2){	      //如果HDMI convert SDI两个灯都熄灭,LM393输出高电平
  	   sleep_sec(180);	      //3分钟再看看
	   if(led1&&led2){      //如果HDMI convert SDI两个灯还是熄灭状态,LM393输出高电平
          restart();      //重启机顶盒
         }
      }
   }
}





1.0版本程序


/*
项目名称:机顶盒开机后,单片机固定频道(仅限用于华数机顶盒)
日期:2016年01月08日
版本:1.0
作者:chunli
博客:990487026.blog.51cto.com
邮箱:[email protected]


单片机:STC15f104W
STC 15F104W ,晶振12M
1 P3.4
2 VCC  3.8--5.5V
3 P3.5
4 GND
5 P3.0 接烧录器的TXD
6 P3.1 接烧录器的RXD
7 P3.2
8 P3.3
*/

#include "reg51.h"
sbit    key_menu = P3^0;  //机顶盒的menu按键,发出低电平有效
sbit    key_down = P3^1;  //机顶盒的down按键,发出低电平有效
sbit   key_right = P3^2;  //机顶盒的right按键,发出低电平有效
sbit      key_ok = P3^3;  //机顶盒的ok按键,发出低电平有效


void delay (unsigned int a)    { // 毫秒级延时函数
    unsigned int i;
    while ( --a != 0 ) {
        for (i=0;i<=600;i++);
    }
}

void menu(void){   //按一下menu键的操作 函数
  key_menu=0;
  delay(500);
  key_menu=1;
  delay(500);
}

void down(unsigned char down_number){  //按一下down键的操作 函数
  unsigned char i;
  for(i=0;i<down_number;i++){
     key_down=0;
     delay(500);
     key_down=1;
     delay(500);
  }
}

void right(void){  //按一下rigth键的操作 函数
  key_right=0;
  delay(500);
  key_right=1;
  delay(500);
}


void ok(void){
  key_ok=0;
  delay(500); 
  key_ok=1;
  delay(500);
}

void change_channel(unsigned char page,unsigned char number){     // 选择频道的函数                                    
//page         选择频道所在的 第几页         1到21页可选
//number     选择频道所属page的number     1到9可选  
   menu();
   down(2);
   right();
   down(9*(page-1)+number-1);
   ok();
}



void initial (void){ // 开机初始化  
  unsigned char i;
  for(;i<60;i++){   // 等待机顶盒开机初始化,70秒,菜单消失,黑屏提示 无信号(无信号源时)。
      delay(1000);
   }

change_channel(1,9); //浙江卫视,在第1页,第9个 
//change_channel(3,5); //中央新闻,在第3页,第5个 
//change_channel(1,1); //华数剧场,在第1页,第1个 
//change_channel(1,1); //华数剧场,在第1页,第1个 
//change_channel(21,1); //求索旅行,在第21页,第2个 
}

void main(){     //主函数
   initial();     
   while(1){
  }
}














/*
项目名称:监控机顶盒 是否死机了
日期:2016年01月08日
版本:1.0
作者:chunli
博客:990487026.blog.51cto.com
邮箱:[email protected]

单片机:STC15f104W
STC 15F104W ,晶振12M
1 P3.4
2 VCC  3.8--5.5V
3 P3.5
4 GND
5 P3.0 接烧录器的TXD
6 P3.1 接烧录器的RXD
7 P3.2
8 P3.3
*/

#include "reg51.h"
sbit      led1 = P3^0;  //HDMI convert SDI 1号灯
sbit      led2 = P3^1;  //HDMI convert SDI 2号灯
sbit   control = P3^2;  //继电器上电,机顶盒重启

void delay (unsigned int a)    { // 毫秒级延时函数    @12M
    unsigned int i;
    while ( --a != 0 ) {
        for (i=0;i<=600;i++);
    }
}

void sleep(unsigned char time){     // 延时函数,秒
  unsigned char num;
  for(num=0;num<time;num++){
     delay(1000);
  }
}

void restart(void){   //继电器断开,再上电
  control=0;          //继电器上电,继电器松开,机顶盒断电
  sleep(10);          //机顶盒断电10秒
  control=1;          //继电器断电,继电器吸合,机顶盒开机
}

void main(){     
   while(1){
    if((led1==0)&&(led2==0)){       //如果HDMI convert SDI两个灯都熄灭
         sleep(120);                   //2分钟再看看
       if((led1==0)&&(led2==0)){   //如果HDMI convert SDI两个灯还是熄灭状态
          restart();               //重启机顶盒
         }
      }
   }
}








本文出自 “魂斗罗” 博客,谢绝转载!

你可能感兴趣的:(机顶盒)