找回密码
 立即注册

QQ登录

只需一步,快速开始

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

用数码管显示12C887时钟,仿真器仿真一切正常,烧到SM5964里,一按按键就死机。

[复制链接]
跳转到指定楼层
楼主
ID:86240 发表于 2015-9-11 16:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include <reg52.h>
#include<intrins.h>
#include <stdio.h>
#include <absacc.h>
#define uchar unsigned char
#define uint unsigned short int
#define aa_time 200                                //发送显示命令的时间间隔
#define clk_z 0x00                                //i2c时序线
#define clk_o 0x01
#define pass_wd 0x0000                                //设置密码
#define goto_company_timeago 2880                //距离去单位时间(min)
#define w_check_timeago 10080                        //距离周检时间(min)
#define time0_time 976

#define time_a PBYTE[0x0a]
#define time_b PBYTE[0x0b]
#define time_c PBYTE[0x0c]

uchar  save_w_check1  = 0;
uchar save_w_check0 = 0;
uchar save_a6_flag = 0;
uchar save_a2_flag = 0;

sfr T2MOD = 0xC9;
sfr SCONF = 0xBF;

sbit bell_ctrl = P0^7;
sbit JL26 = P2^6;                        //74LS373锁存器LE端
sbit A_ctrl = P0^5;                 //4052模拟开关
sbit B_ctrl = P0^4;
sbit sda  = P2^4;
sbit scl = P2^5;
sbit t2ex = P1^1;                         //计程脉冲信号
sbit kcp = P1^6;                          //车灯
sbit ZT_key = P1^4;

sbit JLIO  = P2^1;
sbit JLCLK = P2^3;
sbit JLPLS = P0^3;
sbit JLPOW = P0^6;
sbit P_4053 = P0^0;


uchar idata cReceive_data2[5]={0,0,0,0,0};
uchar idata show_data[17]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};        //KEY值显示累计信息buf--->直通显示
uchar cNumber = 0;
uchar year,month,date;
uchar hour,minute,second;
uchar hour_mao,s_pfuf = 0,s_pf,s_uf;
uchar ZT_allkey_nu = 0;
uchar zhuangtai = 0;
uint idata car_nu = 0;                        //24C64总车次  ,最大为400
uint idata car_nu_node = 0;        //24C64循环存储的车次坐标
uint idata aa = 0;

bit cFlag = 0;
bit mflag = 1;
bit pie = 0;
bit uie = 0;
bit time_flag2 = 1;
bit per_time = 0;
bit one_show_flag = 0;
bit ZT_func = 0;

uchar code table_duan[] = {
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x00,0x40,0x3f|0x80,0x06|0x80,
0x5b|0x80,0x4f|0x80,0x66|0x80,0x6d|0x80,
0x7d|0x80,0x07|0x80,0x7f|0x80,0x6f|0x80,
0x00|0x80,0x40|0x80};
void a6_handler();
void a6_key_function();
void a6_show_function();
void a6_ZT_function();
void send_A6();

void init_device();
void init_device_uart1();
void key_null();
void beep_r();
void adj_clock();
void Ls373_4052_1();
void a6_on_show();
void Send_char(unsigned char cCharacter);
void delay(uint z);
void get_time(void);
//24c64函数:
void  delay1(void) { ; ;}

void main()
{
delay(100);
init_device();                                                 //初始化串口
init_device_uart1();
Ls373_4052_1();
EA = 0;

delay(300);
zhuangtai = 0 ;
EA = 1;
delay(500);    //500ms

while(1)
{
   if((per_time) && ((s_pf) == 1))               //用一位来设冒号位
  {
    hour_mao = (hour & 0x0f) + 12;
  }else if((!per_time) && ((s_pf) == 1))
  {
    hour_mao = (hour & 0x0f);
  }
                       a6_handler();
                       a6_key_function();
                         if(ZT_func)
                        {
                             a6_ZT_function();
                        }else
                        {
                             a6_show_function();
                                    a6_on_show();
                             }
                if(aa>=aa_time)
                   send_A6();
   }
}

void a6_handler()
{
        zhuangtai &= 0xFB;
}

void a6_key_function()
{
  if(ZT_key == 0)
  { delay(5);
    if(ZT_key == 0)
    {delay(5);
    beep_r();
    aa = aa_time;
    ZT_allkey_nu++;
    one_show_flag = 1;
        ZT_func = 1;
    }
  }
}


void a6_show_function()
{
     show_data[0] = table_duan[second&0x0F];
     show_data[1] = table_duan[second>>4];
     show_data[2] = table_duan[year&0x0F];;
     show_data[3] = table_duan[year>>4];;
     show_data[4] = table_duan[date&0x0F];
     show_data[5] = table_duan[date>>4];
     show_data[6] = table_duan[month&0x0F];
     show_data[7] = table_duan[month>>4];
     show_data[8] = table_duan[minute&0x0F];
     show_data[9] = table_duan[minute>>4];
     show_data[10] = table_duan[hour_mao];
     show_data[11] = table_duan[hour>>4];
}

void a6_ZT_function()
{
if(one_show_flag)
{
    if(ZT_allkey_nu == 1)   //暂停键 调时钟、补打印、清当班、返回a6
  {
     show_data[0] = 0;     //ADJ
     show_data[1] = 0;
     show_data[2] = 0;
     show_data[3] = 0;
     show_data[4] = 0;
     show_data[5] = 0;
     show_data[6] = 0;
     show_data[7] = 0;
     show_data[8] = 0;
     show_data[9] = 0;
     show_data[10] = 0;
     show_data[11] = 0;
     show_data[12] = 0;
     show_data[13] = 0;
     show_data[14] = 0x77;
     show_data[15] = 0x5E;
     show_data[16] = 0x0E;
  }else   if(ZT_allkey_nu == 2)   //PRN
  {
     show_data[0] = 0;
     show_data[1] = 0;
     show_data[2] = 0;
     show_data[3] = 0;
     show_data[4] = 0;
     show_data[5] = 0;
     show_data[6] = 0;
     show_data[7] = 0;
     show_data[8] = 0;
     show_data[9] = 0;
     show_data[10] = 0;
     show_data[11] = 0;
     show_data[12] = 0;
     show_data[13] = 0;
     show_data[14] = 0x73;
     show_data[15] = 0x50;
     show_data[16] = 0x54;
  }else   if(ZT_allkey_nu == 3)  //CLR
  {
     show_data[0] = 0;
     show_data[1] = 0;
     show_data[2] = 0;
     show_data[3] = 0;
     show_data[4] = 0;
     show_data[5] = 0;
     show_data[6] = 0;
     show_data[7] = 0;
     show_data[8] = 0;
     show_data[9] = 0;
     show_data[10] = 0;
     show_data[11] = 0;
     show_data[12] = 0;
     show_data[13] = 0;
     show_data[14] = 0x39;
     show_data[15] = 0x38;
     show_data[16] = 0x50;
  }else if(ZT_allkey_nu>3)
  {
          key_null();
  }
  one_show_flag = 0;
}
}

void send_A6()    //直通显示
{
   TB8 = 1;
   Send_char(0xAA);
   TB8 = 0;
   Send_char(0x20);
   TB8 = 0;
   Send_char(0xA6);
   TB8 = 0;
   Send_char(show_data[12]);
   TB8 = 0;
   Send_char(show_data[13]);
   TB8 = 0;
   Send_char(show_data[14]);
   TB8 = 0;
   Send_char(show_data[15]);
   TB8 = 0;
   Send_char(show_data[16]);
   TB8 = 0;
   Send_char(show_data[0]);
   TB8 = 0;
   Send_char(show_data[1]);
   TB8 = 0;
   Send_char(show_data[2]);
   TB8 = 0;
   Send_char(show_data[3]);
   TB8 = 0;
   Send_char(show_data[4]);
   TB8 = 0;
   Send_char(show_data[5]);
   TB8 = 0;
   Send_char(show_data[6]);
   TB8 = 0;
   Send_char(show_data[7]);
   TB8 = 0;
   Send_char(0x00);
   TB8 = 0;
   Send_char(0x00);
   TB8 = 0;
   Send_char(0x00);
   TB8 = 0;
   Send_char(0x00);
   TB8 = 0;
   Send_char(0x00);
   TB8 = 0;
   Send_char(0x00);
   TB8 = 0;
   Send_char(show_data[8]);     
   TB8 = 0;
   Send_char(show_data[9]);
   TB8 = 0;
   Send_char(show_data[10]);
   TB8 = 0;
   Send_char(show_data[11]);
   TB8 = 0;
   Send_char(0x00);  
      TB8 = 0;
   Send_char(0x00);
      TB8 = 0;
   Send_char(0x00);
      TB8 = 0;
   Send_char(0x00);
      TB8 = 0;
   Send_char(0x00);
      TB8 = 0;
   Send_char(zhuangtai);
      TB8 = 0;
   Send_char(0x00);
      TB8 = 0;
   Send_char((0x86)^(zhuangtai)^(show_data[0])^(show_data[1])^(show_data[2])^(show_data[3])^(show_data[4])^(show_data[5])^(show_data[6])\
   ^(show_data[7])^(show_data[8])^(show_data[9])^(show_data[10])^(show_data[11])^(show_data[12])^(show_data[13])^(show_data[14])\
   ^(show_data[15])^(show_data[16]));
   TB8 = 1;
   Send_char(0xCC);
   delay(100);     //100ms
}

void init_device()
{
        SCONF &=0XFD;

        /*****************************************
        设置初值:分、时、日、月、年
        ******************************************/
        delay(5);
        time_a = 0x30;
        delay(5);
        time_b = 0x82;
        //   PBYTE[0x01] = 0xC0;
        PBYTE[0x02] = 0x59;
        //    PBYTE[0x03] = 0xC0;
        PBYTE[0x04] = 0x11;
        //    PBYTE[0x05] = 0xC0;
        PBYTE[0x07] = 0x11;
        PBYTE[0x08] = 0x09;
        PBYTE[0x09] = 0x10;
        PBYTE[0x32] = 0x21;
        time_a = 0x20;
        delay(5);
        time_b = 0x12;  //DM = 0  BCD格式        时钟范围00-59
        delay(5);
        time_a = 0x30;
        delay(5);
        time_a |= 0x0F;
        delay(5);
        time_b |= 0x40;
        delay(5);
        time_a &= 0xEF;

        delay(100);

        TMOD = 0x61; //TMOD:定时器0,方式1
        TH0 = (65536 - time0_time) / 256;
        TL0 = (65536 - time0_time) % 256;
        ET0 = 1;
        TR0 = 1;     //启动定时器0运行

        IT0 = 0;//INT0 触发方式: 低电平
        EX0 = 1;

        PS = 1;      //串口设置为高优先级中断源
        ES = 1;      //开串口中断
        EA = 1;      //开总中断
}

void init_device_uart1()
{
        SM0 = 1;     //SCON:SM0 = 1;SM1 = 0;工作方式2, 9-bit UART,允许串行接收位(REN=1)
        SM1 = 0;
        REN = 1;
}

void key_null()
{

         ZT_func = 0;
         ZT_allkey_nu = 0;
}

void beep_r()
{
    bell_ctrl = 1;    //开启蜂鸣器
    JL26 = 1;
    JL26 = 0;
    delay(40);      //40ms
    bell_ctrl = 0;    //关闭蜂鸣器
    JL26 = 1;
    JL26 = 0;
}

void Ls373_4052_1()
{
        bell_ctrl = 0;    //关闭蜂鸣器
        JLPLS = 1;
        P_4053 = 0;
        A_ctrl = 0;
        B_ctrl = 0;
        JL26 = 1;
        JL26 = 0;
}

void a6_on_show()
{
     show_data[12] = 0x00;
     show_data[13] = 0x00;
     show_data[14] = table_duan[0+12];
     show_data[15] = table_duan[0];
     show_data[16] = table_duan[0];
}
void Send_char(unsigned char cCharacter)
{
    SBUF = cCharacter;  //发送数据给“串口调试助手”接收窗口
    while( TI == 0 );   //等待发送完,TI置1
    TI = 0;           //清零 TI为发送中断标志
}

void delay(uint z)
{
    uint x,y;
    for( x = z;x > 0;x--)
        for(y = 119;y > 0;y--);
}

void get_time(void)
{
//if((time_a&0x80)==0)
//{
   year = PBYTE[9];
   month = PBYTE[8];
   date = PBYTE[7];
   hour = PBYTE[4];
   minute = PBYTE[2];
   second = PBYTE[0];
//}
}

void UART_Routine() interrupt 4 using 2
{
  uchar ucRecBuf;
          if(RI == 1)  //RI为接受中断标志,可能是发送产生的中断
         {
          RI = 0;      //接受中断标志软件清零
          ES = 0;      //关串口中断
          ucRecBuf = SBUF;
          if (RB8 == 1)
          {
             if (ucRecBuf == 0xaa)
             {
              cNumber = 0;
              cReceive_data2[cNumber++] = ucRecBuf;
             }
             else if (ucRecBuf == 0xcc)
             {
                 cReceive_data2[cNumber++] = ucRecBuf;
                if (cReceive_data2[0] == 0xaa) //数据校验位
                  {
                    TB8 = 1;
                    Send_char(0xBB);
                    TB8 = 0;
                    Send_char(cReceive_data2[2]);
                    TB8 = 1;
                    Send_char(0xCC);
                   cFlag = 1;
                  }
                else if(cReceive_data2[0] == 0xbb)
                  {
                   cFlag = 1;
                  }
                else{
                    TB8 = 1;
                    Send_char(0xBB);
                    TB8 = 0;
                    Send_char(0xFF);
                    TB8 = 1;
                    Send_char(0xCC);//返回出错
                  }
             }else if(ucRecBuf == 0xbb)
             {
               cNumber = 0;
               cReceive_data2[cNumber++] = ucRecBuf;
             }
          }else               //RB8 == 0
          {
              if (cNumber < sizeof(cReceive_data2))
                 cReceive_data2[cNumber++] = ucRecBuf;   //数据取出赋值
          }
           ES = 1;
         }
}


void timer0() interrupt 1 using 1
{
        TH0 = (65536 - time0_time) / 256;//FC
        TL0 = (65536 - time0_time) % 256;//18
        aa++;
}

void timer1() interrupt 0 using 3
{
        s_pfuf = ((time_c & 0x50) >> 4); //清ds12c887周期中断标识PF,清ds12c887更新中断标识UF
        s_pf = ((s_pfuf &0x04) >> 2);
        s_uf = (s_pfuf & 0x01);
        pie = ((time_b & 0x40) >> 6);  //周期性中断使能
        uie = ((time_b & 0x10) >> 4);  //更新中断使能
        if((pie)&&(s_pf))
        {
          per_time ^= 1;
          get_time();  //一秒读一次DS12C887时钟芯片
        }

}


用数码管显示12C887时钟,仿真器仿真一切正常,烧到SM5964里,一按按键就死机。
取时间和冒号显示放在12C887的周期中断(500ms)里的。
12C887作为单片机的外扩RAM :
单片机    ---  12C887
P00-P07 ---  D0-D7
WR        ---   RW
RD         ---   DS
ALEX      ---   AS
             --- CS接地

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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