/*
            湖南师范大学工学院课程设计    单片机教学打铃控制器
    芯      片:AT89S52
    晶      振:频率12MHz
    按键说明:
              BellSet   P1^0//时间设置
              TimeSet   P1^1//闹铃设置
              LeftMove  P1^2//向左移动
              Add          P1^3//数据增加
              Sub        P1^4//数据减小
              RightMove P1^5//向右移动
              ESC        P1^6//取消
              Enter      P1^7//确定

*/
#include "AT89X52.H"
#include "intrins.h"

#define A24C02W 0xa0//24C02的写地址
#define A24C02R  0xa1//24C02的读地址

unsigned char TimeData[]={0,0,0};//时钟数据
unsigned char BellDataH[40];//40个闹铃点(时)
unsigned char BellDataL[40];//40个闹铃点(分)
unsigned char BellCount=0;//闹铃总数
unsigned char counter=0;
unsigned char I2cStartB=0xaa;//I2c开始标志字
unsigned char I2cEndB=0x55;//I2c结束标志字
unsigned char RayFlag1=0;//秒闪标志1
sbit RayFlag=P3^1;//秒闪
sbit RayFlag2=P3^0;//秒闪标志2
sbit AlarmSingal=P3^4;//闹铃信号
sbit SDA=P3^2;//I2C BUS数据
sbit SCL=P3^3;//I2C BUS时钟

/*
void Timer1(void)interrupt 3 using 1
unsigned char BCD_to_Text(unsigned char Data)
unsigned char GetClockBit(unsigned char ShowBit)
void Delay(unsigned char count)
void D_Scan(unsigned char *ShowAddress,unsigned char FlagBit)
unsigned char GetKey()
void I2cWait()
void I2cStart()
void I2cStop()
void I2cSend(unsigned char ByteData)
unsigned char I2cReceive()
void I2cWrite24C02(unsigned char I2c24C02Addr,unsigned char I2c24C02Data)
unsigned char I2cRead24C02(unsigned char I2c24C02Addr)
void Init24C02(void)
void Order(void)
void BellSet(void)
void TimeSet()

*/
//--------------------------定义I2C接口子程序-------------------------
/*
I2C特殊字节定义
*/
void I2cWait()//等待
{
    _nop_();
    _nop_();
}
   
void I2cStart()//开始
{   
    SDA=1;
    SCL=1;
    I2cWait();
    SDA=0;
    I2cWait();
    SCL=0;
}

void I2cStop()//停止
{
    SDA=0;
    I2cWait();
    SCL=1;
    I2cWait();
    SDA=1;
}
void I2cSend(unsigned char ByteData)//发送
{
    unsigned char i;
    for(i=0;i<8;i++)
    {
        if(ByteData&0x80)
            SDA=1;
        else
            SDA=0;
        ByteData<<=1;
        I2cWait();
        SCL=1;
        I2cWait();
        SCL=0;
        I2cWait();
    }
    SDA=1;
    I2cWait();
    SCL=1;
    I2cWait();
    SCL=0;
    I2cWait();
}

unsigned char I2cReceive()//接收
{
    unsigned char i;
    unsigned char ByteData=0;
    for(i=0;i<8;i++)
    {
        SCL=1;
        I2cWait();
        ByteData<<=1;
        if(SDA)ByteData++;
        SCL=0;
        I2cWait();
    }
    SDA=1;
    I2cWait();
    SCL=1;
    I2cWait();
    SCL=0;
    I2cWait();
    return ByteData;
}
//--------------------------声明AT24C02的读写子程序-------------------
void I2cWrite24C02(unsigned char I2c24C02Addr,unsigned char I2c24C02Data)//写
{
    I2cStart();
    I2cSend(A24C02W);
    I2cSend(I2c24C02Addr);
    I2cSend(I2c24C02Data);
    I2cStop();
}

unsigned char I2cRead24C02(unsigned char I2c24C02Addr)//读
{
    unsigned char Data;
    I2cStart();
    I2cSend(A24C02W);
    I2cSend(I2c24C02Addr);
    I2cStart();
    I2cSend(A24C02R);
    Data=I2cReceive();
    I2cStop();
    return Data;
}
//-------------------------初始化24C02-----------------------------
void Init24C02(void)
{
    unsigned char i,j;
    unsigned char StartByte=I2cRead24C02(0);
    j=1;
    if(StartByte==I2cStartB)
        for(i=0;i<40;i++)
        {
            if(I2cRead24C02(j)==I2cEndB)break;
            BellDataH[i]=I2cRead24C02(j++);
            BellDataL[i]=I2cRead24C02(j++);
            BellCount++;
        }
    else
        {
            I2cWrite24C02(0,I2cStartB);
            I2cWrite24C02(1,I2cEndB);
        }
}

//---------------------T1中断,产生时钟-------------------------------
void Timer1(void)interrupt 3 using 1
{
    TH1=0x3c;
    TL1=0xb0;
    if(counter%10==0)
    {
        RayFlag2=~RayFlag2;
        if(RayFlag1)RayFlag=0;
        else RayFlag=~RayFlag;
    }
    if(counter==20)
    {
        counter=1;
        if(TimeData[0]==59)
        {
            TimeData[0]=0;
            if(TimeData[1]==59)
            {
                TimeData[1]=0;
                if(TimeData[2]==23)
                {
                    TimeData[2]=0;
                }
                else TimeData[2]++;//时
            }
            else TimeData[1]++;//分
        }
        else TimeData[0]++;//秒
    }
    else counter++;   
}
//------------------BCD码转换成字形码的程序-----------------------------
unsigned char BCD_to_Text(unsigned char Data)
{
    switch(Data)
    {
        case 0:return 0x3f;
        case 1:return 0x06;
        case 2:return 0x5b;
        case 3:return 0x4f;
        case 4:return 0xe6;
        case 5:return 0xed;
        case 6:return 0xfd;
        case 7:return 0x07;
        case 8:return 0xff;
        case 9:return 0xef;
    }
}

//-----------------------------得到位地址的程序-------------------------
unsigned char GetClockBit(unsigned char ShowBit)
{
    switch(ShowBit)
    {
        case 0:return 0xdf;
        case 1:return 0xef;
        case 2:return 0xf7;
        case 3:return 0xfb;
        case 4:return 0xfd;
        case 5:return 0xfe;
    }
}
//---------------------延时count个ms的程序-------------------------
void Delay(unsigned char count)
{
    unsigned char i;
    while(count--)
    {
        for(i=0;i<123;i++)
        ;
    }
}
//-----------------------动态扫描的程序-------------------------------
void D_Scan(unsigned char *ShowAddress,unsigned char FlagBit)
{
    unsigned char ShowBit;
    unsigned char Show;
    for(ShowBit=0;ShowBit<6;ShowBit++)
    {
        if(FlagBit!=5)
        {
            switch(ShowBit)
            {
                case 0:Show=BCD_to_Text((*ShowAddress)%10);break;
                case 1:Show=BCD_to_Text((*ShowAddress)/10);break;
                case 2:Show=BCD_to_Text((*(ShowAddress+1))%10);break;
                case 3:Show=BCD_to_Text((*(ShowAddress+1))/10);break;
                case 4:Show=BCD_to_Text((*(ShowAddress+2))%10);break;
                case 5:Show=BCD_to_Text((*(ShowAddress+2))/10);break;
            }
        }
        P2=0xff;
        switch(FlagBit)
        {
            case 0:P0=Show;break;
            case 1://设秒闪动
                    if(RayFlag2 && (ShowBit==0||ShowBit==1))P0=0x40;
                    else P0=Show;
                    break;
            case 2://设分闪动
                    if(RayFlag2 && (ShowBit==2||ShowBit==3))P0=0x40;
                    else P0=Show;
                    break;
            case 3://设时闪动
                    if(RayFlag2 && (ShowBit==4||ShowBit==5))P0=0x40;
                    else P0=Show;
                    break;
            case 4://调闹铃时的闪动
                    if(RayFlag2)P0=0x40;
                    else P0=Show;
                    break;
            case 5://调闹铃时的显示
                    P0=*(ShowAddress+ShowBit);
                    break;
        }   
        P2=GetClockBit(ShowBit);
        Delay(1);
    }
}

//----------------得到键盘值的程序----------------------------------
unsigned char GetKey()
{
    switch(P1)
    {
        case 0xff:return 0;
        case 0xfe:return 1;
        case 0xfd:return 2;
        case 0xfb:return 3;
        case 0xf7:return 4;
        case 0xef:return 5;
        case 0xdf:return 6;
        case 0xbf:return 7;
        case 0x7f:return 8;
    }
}

//-------------------排序的程序------------------------------------
void Order(void)
{
    unsigned char i,j,t;
    for(i=0;i<BellCount;i++)
        for(j=0;j<BellCount-i-1;j++)
            {
                if(BellDataH[j]>BellDataH[j+1])
                    {
                        t=BellDataH[j];
                        BellDataH[j]=BellDataH[j+1];
                        BellDataH[j+1]=t;
                        t=BellDataL[j];
                        BellDataL[j]=BellDataL[j+1];
                        BellDataL[j+1]=t;
                    }
                else if(BellDataH[j]==BellDataH[j+1])
                        if(BellDataL[j]>BellDataL[j+1])
                            {
                                t=BellDataL[j];
                                BellDataL[j]=BellDataL[j+1];
                                BellDataL[j+1]=t;
                            }
            }   
}

//---------------------------闹铃设置--------------------------------
void BellSet(void)
{
    unsigned char Null[]={0x00,0x38,0x38,0x3e,0x37,0x00};//"Null"的字形码
    unsigned char ShowRing[3];
    unsigned char NowKey;
    unsigned char i,j=1;
    unsigned char BeforKey=0xff;
    unsigned char KeyCount=0;
    unsigned char FlagBit=3;
    unsigned char ShowBellCount=0;
    unsigned char count1=0x40;//无操作时的时间控制
    unsigned char count2=0xff;//无操作时的时间控制
    RayFlag1=1;
    ShowRing[0]=BellDataL[ShowBellCount];
    ShowRing[1]=BellDataH[ShowBellCount];
    ShowRing[2]=ShowBellCount;
    while(1)
    {
        if(BellCount==0)
            D_Scan(Null,5);
        else
            D_Scan(ShowRing,FlagBit);
        if(KeyCount==2)
        {
            KeyCount=0;
            NowKey=GetKey();
            if(NowKey!=BeforKey)
            {
                count1=0x40;
                count2=0xff;
                switch(NowKey)
                {
                    case 1://增加一个闹铃
                            if(BellCount!=40 && FlagBit==4)
                            {
                                BellDataH[BellCount]=BellDataL[BellCount]=0;   
                                ShowBellCount=BellCount++;
                            }
                            if(BellCount==0)
                            {
                                BellDataH[0]=BellDataL[0]=0;
                                BellCount++;
                            }
                            ShowRing[0]=BellDataL[ShowBellCount];
                            ShowRing[1]=BellDataH[ShowBellCount];
                            ShowRing[2]=ShowBellCount;
                            break;
                    case 2://删除一个闹铃
                            if(BellCount!=0 && FlagBit==4)
                            {
                                if(BellCount==1)
                                {
                                    BellDataH[0]=BellDataL[0]=0;
                                }
                                else
                                    {
                                        for(i=ShowBellCount;i<BellCount;i++)
                                        {
                                            BellDataH[i]=BellDataH[i+1];
                                            BellDataL[i]=BellDataL[i+1];
                                        }
                                        BellDataH[i]=BellDataL[i]=0;
                                    }
                                BellCount--;   
                                if(BellCount==ShowBellCount)
                                    ShowBellCount--;
                                ShowRing[0]=BellDataL[ShowBellCount];
                                ShowRing[1]=BellDataH[ShowBellCount];
                                ShowRing[2]=ShowBellCount;
                            }
                            break;

case 3://左移
                            if(BellCount!=0)
                            {
                                if(FlagBit==4)FlagBit=1;
                                else FlagBit++;
                            }
                            break;
                    case 4://闹铃时间增
                            switch(FlagBit)
                            {
                                case 1:
                                        if(ShowRing[0]==59)
                                            ShowRing[0]=0;
                                        else
                                            ShowRing[0]++;
                                        BellDataL[ShowBellCount]=ShowRing[0];
                                        break;
                                case 2:
                                        if(ShowRing[1]==23)
                                            ShowRing[1]=0;
                                        else
                                            ShowRing[1]++;
                                        BellDataH[ShowBellCount]=ShowRing[1];
                                        break;
                                case 3:
                                        if(ShowBellCount==BellCount-1)
                                            ShowBellCount=0;
                                        else
                                            ShowBellCount++;
                                        ShowRing[0]=BellDataL[ShowBellCount];
                                        ShowRing[1]=BellDataH[ShowBellCount];
                                        ShowRing[2]=ShowBellCount;
                                        break;
                            }
                            break;
                    case 5://闹铃时间减
                            switch(FlagBit)
                            {
                                case 1:
                                        if(ShowRing[0]==0)
                                            ShowRing[0]=59;
                                        else
                                            ShowRing[0]--;
                                        break;
                                case 2:
                                        if(ShowRing[1]==0)
                                            ShowRing[1]=23;
                                        else
                                            ShowRing[1]--;
                                        break;
                                case 3:
                                        if(ShowBellCount==0)
                                            ShowBellCount=BellCount-1;
                                        else
                                            ShowBellCount--;
                                        ShowRing[0]=BellDataL[ShowBellCount];
                                        ShowRing[1]=BellDataH[ShowBellCount];
                                        ShowRing[2]=ShowBellCount;
                                        break;
                            }
                            break;
                    case 6://右移
                            if(BellCount!=0)
                            {
                                if(FlagBit==1)FlagBit=4;
                                else FlagBit--;
                            }
                            break;
                    case 7://取消
L3:                            j=1;
                            BellCount=0;
                            EA=0;
                            for(i=0;i<40;i++)
                            {
                                if(I2cRead24C02(j)==I2cEndB)break;
                                BellDataH[i]=I2cRead24C02(j++);
                                BellDataL[i]=I2cRead24C02(j++);
                                BellCount++;
                            }
                            EA=1;
                            goto L2;
                    case 8://确定
                            j=1;
                            BellDataL[ShowBellCount]=ShowRing[0];
                            BellDataH[ShowBellCount]=ShowRing[1];
                            Order();//排序
                            for(i=0;i<BellCount;i++)
                            {
                                EA=0;
                                I2cWrite24C02(j++,BellDataH[i]);
                                EA=1;
                                D_Scan(ShowRing,FlagBit);
                                EA=0;
                                I2cWrite24C02(j++,BellDataL[i]);
                                EA=1;
                                D_Scan(ShowRing,FlagBit);
                            }
                            EA=0;
                            I2cWrite24C02(j,I2cEndB);
                            EA=1;
                            if(BellCount==0)
                                D_Scan(Null,5);
                            else
                                D_Scan(ShowRing,FlagBit);
                            goto L2;
                               
                } 
            }
            BeforKey=NowKey;
            count2--;
            if(count2==0)
            {
                count2=0x40;
                count1--;
                if(count1==0)
                    goto L3;
            }
        }
        else KeyCount++;
    }
L2:RayFlag1=0;
}

//-------------时间设置的程序--------------------------------------------
void TimeSet()
{
    unsigned char S_Flag=1;
    unsigned char M_Flag=1;
    unsigned char H_Flag=1;
    unsigned char count1=0x40;//无操作时的时间控制
    unsigned char count2=0xff;//无操作时的时间控制
    unsigned char NowKey=0xff;
    unsigned char BeforKey=0xff;
    unsigned char KeyCount=0;
    unsigned char FlagBit=1;
    unsigned char LS_TimeData[3];
    LS_TimeData[2]=TimeData[2];
    LS_TimeData[1]=TimeData[1];
    LS_TimeData[0]=TimeData[0];
    while(1)
    {
        if(S_Flag)LS_TimeData[0]=TimeData[0];
        if(M_Flag)LS_TimeData[1]=TimeData[1];
        if(H_Flag)LS_TimeData[2]=TimeData[2];
        D_Scan(LS_TimeData,FlagBit);//动态扫描显示
        if(KeyCount==2)
        {
       
            KeyCount=0;
            NowKey=GetKey();
            if(NowKey!=BeforKey)
            {
                count1=0x40;
                count2=0xff;
                switch(GetKey())
                {
                    case 3://向左移动
                            if(FlagBit==3)FlagBit=1;
                            else FlagBit++;
                            break;
                    case 4://增加
                            switch(FlagBit)
                            {
                                case 1://秒增加
                                        if(LS_TimeData[0]==59)
                                            LS_TimeData[0]=0;
                                        else LS_TimeData[0]++;   
                                        S_Flag=0;
                                        break;
                                case 2://分增加
                                        if(LS_TimeData[1]==59)
                                            LS_TimeData[1]=0;
                                        else LS_TimeData[1]++;
                                        M_Flag=0;
                                        break;
                                case 3://时增加
                                        if(LS_TimeData[2]==23)
                                            LS_TimeData[2]=0;
                                        else LS_TimeData[2]++;
                                        H_Flag=0;
                                        break;
                            }
                            break;
                    case 5://减小
                            switch(FlagBit)
                            {
                                case 1://秒减小
                                        if(LS_TimeData[0]==0)
                                            LS_TimeData[0]=59;
                                        else LS_TimeData[0]--;
                                        S_Flag=0;
                                        break;
                                case 2://分减小
                                        if(LS_TimeData[1]==0)
                                            LS_TimeData[1]=59;
                                        else LS_TimeData[1]--;
                                        M_Flag=0;
                                        break;
                                case 3://时减小
                                        if(LS_TimeData[2]==0)
                                            LS_TimeData[2]=23;
                                        else LS_TimeData[2]--;
                                        H_Flag=0;
                                        break;
                            }
                            break;
                    case 6://向右移动
                            if(FlagBit==1)FlagBit=3;
                            else FlagBit--;
                            break;
                    case 7://取消
                            goto L1;
                    case 8://确定
                            TimeData[2]=LS_TimeData[2];
                            TimeData[1]=LS_TimeData[1];
                            TimeData[0]=LS_TimeData[0];
                            goto L1;
                }
            }
            BeforKey=NowKey;
            count2--;
            if(count2==0)
            {
                count2=0x40;
                count1--;
                if(count1==0)
                    goto L1;
            }
        }
        else KeyCount++;
    }
L1:;
}

//----------------------主程序-----------------------------------------------
void main()
{
    unsigned char NowKey;
    unsigned char BeforKey=0xff;
    unsigned char KeyCount=0;
    unsigned char i=1;
    AlarmSingal=0;
    RayFlag=1;
    RayFlag2=1;
    Init24C02();//读24C02
    TMOD=0x10;//设置T1
    EA=1;
    ET1=1;
    PT1=1;
    TH1=0x3c;
    TL1=0xb0;
    TR1=1;
    while(1)
    {   
        D_Scan(TimeData,0);//动态扫描
        //闹铃监视
        for(i=0;i<BellCount;i++)
        {
            if((BellDataH[i]==TimeData[2]) && (BellDataL[i]==TimeData[1]))
            {
                AlarmSingal=1;
                break;
            }
            else AlarmSingal=0;
        }
        //按键控制
        if(KeyCount==2)
        {
       
            KeyCount=0;
            NowKey=GetKey();
            if(NowKey!=BeforKey)
            {
                switch (NowKey)
                {
                    case 1:
                            TimeSet();
                            break;
                    case 2:
                            AlarmSingal=0;
                            BellSet();   
                            break;
                    default:
                            break;
                }
            }
            BeforKey=NowKey;
        }
        else KeyCount++;
    }
}

单片机教学打铃控制器C语言相关推荐

  1. 教学打铃单片机实现(课程设计)

    单片机课程设计 一.课程设计题:单片机教学打铃控制器程序设计 二.设计要求: 1. 用LED数码管显示时.分.秒时间,尽量减少时间积累误差,具有秒闪功能. 2. 最多能设置40个打铃时间点,打铃时间点 ...

  2. c51语言单片机打铃系统设计,毕业论文单片机自动控制打铃系统及设计.doc

    毕业论文单片机自动控制打铃系统及设计 湖南工业职业技术学院 Hunan Industry Polytechnic 类别毕业设计题目单片机自动控制打铃系统设计 系名称电气工程系专业及班级机电一体化S20 ...

  3. 单片机应用技能实训(c语言) 李志京,基于应用型人才培养的单片机原理及应用教学改革探讨...

    摘要:本文根据单片机原理及应用课程的特点,从课程教学内容优化.课堂教学改革.实验教学改革等方面进行研究和尝试,目的在于提高学生分析问题和解决问题的能力,增强学生的创新能力和综合素质,并指出了如何改善现 ...

  4. c语言打铃器单片机程序,51单片机自动打铃C语言程序

    51单片机自动打铃C语言程序: #include "reg51.h" #include "intrins.h" #define uchar unsigned c ...

  5. 有温度传感器的风机控制系统C语言,毕业论文--基于单片机的工业风机控制器设计与实现.doc...

    大连东软信息学院 本科毕业设计(论文) 论文题目 论文题目:基于单片机的工业风机控制器设计与实现 系 所: 电子工程系 专 业: 电子信息工程(嵌入式系统工程方向) 学生姓名: 学生学号: 指导教师: ...

  6. 基于51单片机的霓虹灯c语言,基于单片机控制的霓虹灯控制器056

    基于单片机控制的霓虹灯控制器 摘要:本设计采用AT89S51单片机实现对霓虹灯的控制.系统由单片机控制部分和显示部分组成.显示部分的128个发光二极管成8行16列矩阵式分布.单片机I/O口输出的信号经 ...

  7. 水塔水位控制器单片机c语言,基于单片机的水塔水位控制器设计.doc

    基于单片机的水塔水位控制器设计 河南质量工程职业学院 毕业设计 题 目:水塔水位设计 系 别:机电工程系 专业班级:商检技术 班 级: 学生姓名: 指导老师: 设计时间: 2012年3月13 日 河南 ...

  8. 单片机彩灯c语言程序设计,(定稿)毕业论文基于AT89C51单片机的LED彩灯控制器设计(完整版)...

    <[毕业论文]基于AT89C51单片机的LED彩灯控制器设计.doc>由会员分享,可免费在线阅读全文,更多与<(定稿)毕业论文基于AT89C51单片机的LED彩灯控制器设计(完整版) ...

  9. c语言单片机求最小公倍数,单片机常用的14个C语言算法,要熟记在心哦!

    原标题:单片机常用的14个C语言算法,要熟记在心哦! 算法(Algorithm):计算机解题的基本思想方法和步骤. 算法的描述:是对要解决一个问题或要完成一项任务所采取的方法和步骤的描述,包括需要什么 ...

最新文章

  1. C语言 | C语言实现十六进制转八进制
  2. Python 实现批量从不同的Linux服务器下载文件
  3. 使用 Ocelot 匹配路由的方法匹配路由
  4. selenium无法定位到QQ邮箱登录页面的输入框元素和登录按钮元素-解决方法
  5. eclipse java的jvm匹配_eclipse设置jvm
  6. 容器编排技术 -- Kubernetes kubectl create service loadbalancer 命令详解
  7. 2728:摘花生(数字金子塔变形)
  8. 原生js的ajax的get怎么传参,原生js---ajax---get方法传数据
  9. SSOR-PCG FORTRAN版CSR压缩存储
  10. 液压伺服控制系统设计
  11. android转场动画的两种方式
  12. 修改PPT文档属性工具使用教程
  13. AutoCAD.Net 实现创建wipeout遮罩实体
  14. 绘图杂记【3】Python / R语言 制作峰峦图
  15. ajax请求数据成功但是success中拿不到数据。
  16. C#数据库四种执行方法(ExecuteNonQuery)
  17. 基于EasyExcel锁定指定列导出数据到excel
  18. [Nikon D80]适马微距
  19. 华为笔记本软件商店_华为要消灭流氓软件?干净的电脑应用商店来了!
  20. 哈希计划(河南省多校联盟第六次)

热门文章

  1. 测试功能点----方法
  2. Unity3D中HideFlags.DontSave使用解析
  3. git报错 Disconnected:No supported authentication methods available
  4. ROS双臂定点抓取问题记录
  5. 【计算机网络】第九章:无线网络
  6. 解读Tapestry5.1——页面渲染
  7. 博客代码总算要结束了!
  8. mysql卡库,Lemon谐音歌词_米津玄师Lemon的日语中文唱法音译
  9. JavaScript学习二
  10. 环境参数智能监测站设计(说明书篇)