标题:求助C语言大神,修改程序!!
只看楼主
C语言小黑
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2014-6-13
 问题点数:0 回复次数:1 
求助C语言大神,修改程序!!
以下是程序,基于单片机的电子万年历,在运行时好几处错误,本人小白,求助大神
#include <reg51.h>
#include <intrins.h>
#include <string.h>
#define uint unsigned int
#define uchar unsigned char

sbit IO= P1^0;         //DS1302数据线
sbit SCLK = P1^1;     //DS130时钟线
sbit RST = P1^2;     //DS1302复位线
sbit RS = P2^0;         //LCD数据/命令选择端
sbit RW = P2^1;         //LCD读/写控制
sbit EN = P2^2;          //LCD使能端
sbit K1=P3^4;        //选择
sbit K2=P3^5;        //加
sbit K3=P3^6;        //减
sbit K4=P3^7;        //确定

uchar tCount=0;
uchar MonthsDays[]={0,31,0,31,30,31,30,31,31,30,31,30,31};
uchar *WEEK[]={"SUN","MON","TUS","WEN","THU","FRI","SAT"};
uchar LCD_DSY_BUFFER1[]={"DATE 00-00-00   "};  //显示格式
uchar LCD_DSY_BUFFER2[]={"TIME 00:00:00   "};
uchar DateTime[7];     //所读取的日期时间
char Adjust_Index=-1;  //当前调节的时间对象:,,分,是,日,月,(1,2,3,4,6)
uchar Change_Flag[]= "-MHDM-Y";     //(分,时,日,月,年)(不调节秒与周)
/*---------延时程序------------------*/
void DelayMS(uint ms)
{
     uchar i;
    while(ms--){for(i=0;i<120;i++);}
}
//-----------向DS1302写入一字节------------------//
void Write_A_Byte_TO_DS1302(uchar x)
{    uchar i;
    for(i=0;i<8;i++){
         IO=x&0x01;     //每一位与1与存入IO中
        SCLK=1;SCLK=0;    //一个高脉冲将数据送入液晶控制器
        x>>=1;          //  右移
    }
}
//-----------从DS1302读取一字节------------------//
uchar Get_A_Byte_FROM_DS1302()
{    uchar i,b=0x00;
    for(i=0;i<8;i++){
         b |= _crol_((uchar)IO,i);
        SCLK=1;SCLK=0;          //每一个高脉冲读取一位数据
    }
    return b/16*10+b%16; //返回BCD码
}
//-----------从DS1302指定位置读数据------------------//
uchar Read_Data(uchar addr)
{
     uchar dat;
    RST = 0;SCLK=0;RST=1;       //RST高电平时读/写
         Write_A_Byte_TO_DS1302(addr);     //先写入地址
    dat = Get_A_Byte_FROM_DS1302();
    SCLK=1;RST=0;
    return dat;
}
//---------向DS1302某地址写入数据--------------------//
void Write_DS1302(uchar addr,uchar dat)
{    SCLK=0;RST=1;
    Write_A_Byte_TO_DS1302(addr);
    Write_A_Byte_TO_DS1302(dat);
    SCLK=0;RST=0;         //高脉冲写入数据
}
//--------------设置时间----------------//
void SET_DS1302()
{    uchar i;//写控制字,取消写保护
    Write_DS1302(0x8E,0x00);//分时日月年依次写入
    for(i=1;i<7;i++)
    {  //分的起始地址10000010(0x82),后面依次是时,日,月,周,年,写入地址每次递增2
     Write_DS1302(0x80+2*i,(DateTime[i]/10<<4)|(DateTime[i]%10));
    }  
    Write_DS1302(0x8E,0x80); //加保护
}
//----------读取当前日期时间------------//
void GetTime()
{uchar i;
    for(i=0;i<7;i++){    DateTime[i]=Read_Data(0X81+2*i);}
}
//-----------读LCD状态------------------//
uchar Read_LCD_State()
{    uchar state;
    RS=0;RW=1;EN=1;     //输出:D0~D7=状态字
    DelayMS(1);
    state=P0;          //从P0口读LCD状态
    EN = 0;DelayMS(1);
    return state;
}
 //-----------忙等待------------------//
void LCD_Busy_Wait()
{
     while((Read_LCD_State()&0x80)==0x80);
    DelayMS(5);
}   
//-----------向LCD写数据------------------//
void Write_LCD_Data(uchar dat)
{
     LCD_Busy_Wait();
    RS=1;EN=0;RW=0;         //写数据,EN为高脉冲,
    P0=dat;EN=1;DelayMS(1);EN=0;   
}
//-------------写LCD指令-------------------//
void Write_LCD_Command(uchar cmd)
{
     LCD_Busy_Wait();
    RS=0;EN=0;    RW=0; //写指令,EN高脉冲,输出:D0~D7=数据
    P0=cmd;EN=1;DelayMS(1);EN=0;   
}
//-------------LCD初始化-------------------//
void Init_LCD()
{
     Write_LCD_Command(0x38);  //设置16*2显示,5*7点阵,8位数据接口
    DelayMS(1);   
    Write_LCD_Command(0x01);  //显示清零,数据指针清零
    DelayMS(1);   
    Write_LCD_Command(0x06);  //写一个字符后地址指针自动加1
    DelayMS(1);   
    Write_LCD_Command(0x0c);   //设置开显示,不显示光标
    DelayMS(1);   
}
//------------------------------------------
//设置液晶显示位置
//------------------------------------------
void Set_LCD_POS(uchar p){
    Write_LCD_Command(p|0x80);//相当于在0x80基础上加入位置量   
}
//----在LCD上显示字符串---------//
void Display_LCD_String(uchar p,uchar *s)
{        uchar i;
    Set_LCD_POS(p);
    for(i=0;i<16;i++)
    {
        Write_LCD_Data(s[i]);  //在固定位置显示时间日期
        DelayMS(1);
    }
}
//---------日期与时间值转换为数字字符----------------//
void Format_DateTime(uchar d,uchar *a)
{
    a[0]=d/10+'0';
          a[1]=d%10+'0';
}
//判断是否为闰年
uchar isLeapYear(uint y)
{    return (y%4==0&&y%100!=0)||(y%400==0);}
//求自2000.1.1开始的任何一天是星期几
//函数没有通过,求出总天数后再求星期几
//因为求总天数可能会超出uint的范围
void RefreshWeekDay()
{    uint i,d,w=5;     //已知1999.12.31是周五
    for(i=2000;i<2000+DateTime[6];i++)
    {
        d=isLeapYear(i)?366:365;
        w=(w+d)%7;
    }
    d=0;
    for(i=1;i<DateTime[4];i++)
    {    d+=MonthsDays[i];    }
    d+=DateTime[3];
    //保存星期,0~6表示星期日,星期一,二,...,六,为了与DS1302的期格式匹配,返回值需要加
          DateTime[5=(w+d)%7+1;
      
//*****年月日时分++/--********//
void DateTime_Adjust(char x)
{        switch(Adjust_Index)
    {
        case 6:      //年00-99
            if(x==1&&DateTime[6]<99) DateTime[6]++;
            if(x==-1&&DateTime[6]>0) DateTime[6]--;
            //获取2月天数
            MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28;
            //如果年份变化后当前月份的天数大于上限则设为上限
            if(DateTime[3]>MonthsDays[DateTime[4]])
            {    DateTime[3]=MonthsDays[DateTime[4]];}
            RefreshWeekDay();  //刷新星期
            break;
        case 4:     //月01-12
            if(x==1&&DateTime[4]<12) DateTime[4]++;
            if(x==-1&&DateTime[4]>1) DateTime[4]--;
            MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28;
            if(DateTime[3]>MonthsDays[DateTime[4]])
            {    DateTime[3]=MonthsDays[DateTime[4]];}
            RefreshWeekDay();
            break;
        case 3:      //日00-28、29、30、31,调节之前首先根据年份得出该年中二月的天数
          MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28;
          //根据当前月份决定调节日期的上限
           if(x==1&&DateTime[3]<MonthsDays[DateTime[4]])DateTime[3]++;
             if(x==-1&&DateTime[3]>0) DateTime[3]--;
              RefreshWeekDay();
              break;
    case 2:       //时
              if(x==1&&DateTime[2]<23) DateTime[2]++;
              if(x==-1&&DateTime[2]>0) DateTime[2]--;
              break;
        case 1:        //分
            if(x==1&&DateTime[1]<59) DateTime[1]++;
            if(x==-1&&DateTime[1]>0) DateTime[1]--;
            break;
    }
}
//---定时器0每秒刷新LCD显示----//
void T0_INT() interrupt 1
{
    TH0=-50000/256;
    TL0=-50000%256;
    if(++tCount !=2)    return;
    tCount=0;//按指定格式生成待显示的日期时间串
    Format_DateTime(DateTime[6],LCD_DSY_BUFFER1+5);
    Format_DateTime(DateTime[4],LCD_DSY_BUFFER1+8);
    Format_DateTime(DateTime[3],LCD_DSY_BUFFER1+11);    //星期strcpy(LCD_DSY_BUFFER1+13,WEEK[DateTime[5]-1]);//时分秒
  Format_DateTime(DateTime[2],LCD_DSY_BUFFER2+5);
    Format_DateTime(DateTime[1],LCD_DSY_BUFFER2+8);
    Format_DateTime(DateTime[0],LCD_DSY_BUFFER2+11);
    //显示年月日,星期,时分秒
    Display_LCD_String(0x00,LCD_DSY_BUFFER1);
    Display_LCD_String(0x40,LCD_DSY_BUFFER2);
}
//----------键盘中断(INT0)-------------//
void EX_INT0() interrupt 0
{   
    if(K1==0)      //选择调整对象(Y M D H M)
    {
        DelayMS(10);
        if(K1==0){            
        //while(K1==0);
        if(Adjust_Index==-1||Adjust_Index==1)
        {
            Adjust_Index=7;
        }
        Adjust_Index--;
        if(Adjust_Index==5) Adjust_Index=4;
        LCD_DSY_BUFFER2[13]='[';
    LCD_DSY_BUFFER2[14]=Change_Flag[Adjust_Index]; //显示调节对象
        LCD_DSY_BUFFER2[15]=']';
        }
    }
    else if(K2==0)              //加
    {    //while(K2==0);
        DelayMS(10);
        if(K2==0)
         DateTime_Adjust(1);
    }
    else if(K3==0)             //减
    {
            DelayMS(10);//while(K3==0);
        if(K3==0)
            DateTime_Adjust(-1);
    }
    else if(K4==0)               //确定
    {
        //while(K4==0);
        DelayMS(10);
        if(K4==0){
        SET_DS1302();             //将调整后的时间写入DS1302
        LCD_DSY_BUFFER2[13]=' ';
        LCD_DSY_BUFFER2[14]=' ';
        LCD_DSY_BUFFER2[15]=' ';
        Adjust_Index=-1;
        }
    }
}
void main()
{    Init_LCD();        //液晶初始化
    IE=0x83;       //允许INT0,T0中断,EA=1,,ET0=1,EX0=1
    IP=0x01;       //设置外部中断0为高级中断
    IT0=0x01;       //外部中断0为电平触发,低电平有效
    TMOD=0x01;       //设置定时器T0工作方式为方式1,
    TH0=-50000/256;        //装入初始值,定时1秒
    TL0=-50000%256;
    TR0=1;           //启动定时器
    while(1)
    {
    //如果未执行调整操作则正常读取当前时间
        if(Adjust_Index==-1)    GetTime();
    }
}
搜索更多相关主题的帖子: 万年历 include 数据线 单片机 C语言 
2014-06-13 17:21
C语言小黑
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2014-6-13
得分:0 
求助大神,万分感谢~~
2014-06-13 17:22



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-432892-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.138592 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved