找回密码
 立即注册

QQ登录

只需一步,快速开始

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

可以帮忙看看单片机程序哪里错了么,用独立按键控制有问题

[复制链接]
跳转到指定楼层
楼主
ID:694497 发表于 2020-2-17 22:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<reg51.h>
#include<intrins.h>

#define uchar unsigned char
#define uint unsigned int

typedef unsigned int u16;
typedef unsigned char u8;

sbit LCDEN=P2^7;
sbit LCDRS=P2^6;
sbit LCDRW=P2^5;
sbit DSIO=P3^4;
sbit RST=P3^5;         //CE
sbit SCLK=P3^6;
sbit k1=P3^1;
sbit k2=P3^0;
sbit k3=P3^2;
sbit k4=P3^3;

uchar code WRITE_RTC_ADDR[3] = {0x80, 0x82, 0x84};//写入秒分时的地址命令
uchar code READ_RTC_ADDR[3] = {0x81, 0x83, 0x85};//读秒分时日月周年的地址命令
uchar TIME[7] = {0x54, 0x57, 0x23};//秒分时日月周年的各个数据
uchar SetState,SetPlace;

void delay(uint c)   //误差 0us
{
    uchar a,b;
        for (; c>0; c--)
        {
                 for (b=199;b>0;b--)
                 {
                          for(a=1;a>0;a--);
                 }      
        }
            
}

void Write_Cmd(unsigned char C)        //写命令
{
        LCDEN=0;
        LCDRS=0;
        LCDRW=0;
        P0=C;
        delay(1);
        LCDEN=1;
        delay(5);
        LCDEN=0;
}

void Write_Data(unsigned char D)//写数据
{
        LCDEN=0;
        LCDRS=1;
        LCDRW=0;
        P0=D;
        delay(1);
        LCDEN=1;
        delay(5);
        LCDEN=0;
}

void LCD_Init()         //LCD初始化
{
        LCDRS=0;
        Write_Cmd(0x38);   //开显示
        Write_Cmd(0x0c);   //开显示不显示光标
        Write_Cmd(0x06);   //写一个指针加1
        //Write_Cmd(0x01);    //清屏
        Write_Cmd(0x80);        //设置数据指针起点
}


void Ds1302Write(uchar addr,uchar dat)           //向DS1302写地址,数据
{
        uchar n;
        RST=0;
        _nop_();
        SCLK=0;
    _nop_();
        RST=1;
        _nop_();
        for(n=0;n<8;n++)   //开始传送八位地址命令
        {
                DSIO=addr&0x01;          //数据从低位开始传送
                addr>>=1;
                SCLK=1;                 //数据在上升沿(SCLK)时,向DS1302写数据
                _nop_();
                SCLK=0;
                _nop_();
        }
        for(n=0;n<8;n++)   //写入8位数据
        {
                DSIO=dat&0x01;           //数据从低位开始传送
                dat>>=1;
                SCLK=1;          //数据在上升沿(SCLK)时,向DS1302写数据
                _nop_();
                SCLK=0;
                _nop_();
        }
}

uchar Ds1302Read(uchar addr)   //DS1302读数据
{
        uchar n,dat,dat1;
        RST=0;
        _nop_();
        SCLK=0;
    _nop_();
        RST=1;
        _nop_();
        for(n=0;n<8;n++) //读一个字节(八位)的地址
    {
                DSIO=addr&0x01;
                addr>>=1;
                SCLK=1;
                _nop_();
                SCLK=0;
                _nop_();
        }
        _nop_();
        for(n=0;n<8;n++)
        {
                dat1=DSIO;
                dat=(dat>>1)|(dat1<<7);
                SCLK=1;
                _nop_();
                SCLK=0;
                _nop_();
        }
        RST=0;
        _nop_();
        SCLK=1;
        _nop_();
        SCLK=0;
        _nop_();
        DSIO=0;
        _nop_();
        DSIO=1;
        _nop_();
        return dat;
}

void Ds1302Init()        //DS1302初始化
{
         uchar n;
         Ds1302Write(0x8E,0x00);//禁止写保护,关闭写保护功能
         for(n=0;n<3;n++)          //写入3个字节的时钟信号:分秒时
         {
                   Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);
         }
         Ds1302Write(0x8E,0x80);//打开写保护功能
}

void Ds1302Read()//读取时钟信息
{
        uchar n;
        for(n=0;n<3;n++)
        {
                TIME[n]=Ds1302Read(READ_RTC_ADDR[n]);
        }
}

void shuzu()
{
        Write_Cmd(0x80);
        Write_Data('0'+TIME[2]/16);                                //时
        Write_Data('0'+(TIME[2]&0x0f));                                 
        Write_Data('-');
        Write_Data('0'+TIME[1]/16);                                //分
        Write_Data('0'+(TIME[1]&0x0f));        
        Write_Data('-');
        Write_Data('0'+TIME[0]/16);                                //秒
        Write_Data('0'+(TIME[0]&0x0f));        
}

void INT1Timer1()  //外部中断T1的配置
{
         IT1=1;
         EX1=1;
         EA=1;
}

void main()
{
        u8 i=0;
    Ds1302Init();
    LCD_Init();
        INT1Timer1();
        while(1)
        {
                if(SetState==0)
                {
                        Ds1302Read();
                }
                else
                if(k1==0)
                {
                        delay(100);
                        if(k1==0)
                        {
                                SetPlace++;
                                if(SetPlace>3)
                                {
                                        SetPlace=0;
                                }
                        }
                }
                if(k2==0)
                {
                        delay(200);
                        if(k2==0)
                        {
                                TIME[SetPlace]++;
                                if(TIME[SetPlace]>=0x60&&(SetPlace<2))  //秒和分不能加到超过60,超过60变为0
                                {
                                        TIME[SetPlace]=0;
                                }
                                if(TIME[SetPlace]>=0x24&&(SetPlace=2))        //小时不能超过23,超过23变为0
                                {
                                        TIME[SetPlace]=0;
                                }
                        }
                        if(k3==0)
                        {
                                delay(200);
                                if(k3==0)
                                {
                                        TIME[SetPlace]--;
                                        if(TIME[SetPlace]<0&&(SetPlace<2))           //秒和分不能减至负数,小于0则变为59
                                        {
                                                TIME[SetPlace]=0x59;
                                        }
                                        if(TIME[SetPlace]<0&&(SetPlace=2))          //小时不能减至负数,小于0则变为23
                                        {
                                                TIME[SetPlace]=0x23;
                                        }
                                }
                        }
                }
                shuzu();
        }
}

void Int1() interrupt 2           //中断服务程序
{
         delay(10);
         if(k4==0)
         {
                  SetState=~SetState;
                 SetPlace=0;
                 Ds1302Init();
         }
}

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

使用道具 举报

沙发
ID:677678 发表于 2020-2-20 18:48 | 只看该作者
干嘛用中断,直接读取io口电平变化,中断里面最好不要写东西,   个人建议  
回复

使用道具 举报

板凳
ID:687423 发表于 2020-2-21 10:13 | 只看该作者
中断里的延时程序时间太长了,缩短一点。
回复

使用道具 举报

地板
ID:679425 发表于 2020-2-21 14:00 | 只看该作者
中断里的延时程序时间太长
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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