找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6739|回复: 12
收起左侧

编译没有错误,但是protues仿真/显示为0且不能够实现上下值加减,什么原因啊?

  [复制链接]
ID:76963 发表于 2015-4-24 10:38 | 显示全部楼层 |阅读模式


#include <reg52.h>                
#define uchar unsigned char  
#define uint  unsigned int       
#include <intrins.h>



uchar menu_1;           //菜单设计的变量

sbit beep = P3^7;
uchar flag_200ms ;


sbit rs=P1^0;       
sbit rw=P1^1;       
sbit e =P1^2;         

unsigned char i=0,timecount=0,displayOK=0,rate=0;
unsigned int time[6]={0};
uchar rate_l=50,rate_h=120;


/***********************延时函数*****************************/
void delay_1ms(uint q)
{
        uint i,j;
        for(i=0;i<q;i++)
                for(j=0;j<110;j++);
}

void delay_uint(uint q)
{
        while(q--);
}

/********************************************************************
* 名称 : write_com(uchar com)
* 功能 : 1602命令函数
***********************************************************************/
void write_com(uchar com)
{
        e=0;
        rs=0;
        rw=0;
        P0=com;
        delay_uint(25);
        e=1;
        delay_uint(100);
        e=0;
}

/********************************************************************
* 名称 : write_data(uchar dat)
* 功能 : 1602写数据函数
***********************************************************************/
void write_data(uchar dat)
{
        e=0;
        rs=1;
        rw=0;
        P0=dat;
        delay_uint(25);
        e=1;
        delay_uint(100);
        e=0;       
}

/********************************************************************
* 名称 : write_string(uchar hang,uchar add,uchar *p)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
                  write_string(1,5,"ab cd ef;")
***********************************************************************/
void write_string(uchar hang,uchar add,uchar *p)
{
        if(hang==1)   
                write_com(0x80+add);
        else
                write_com(0x80+0x40+add);
        while(1)
        {
                if(*p == '\0')  break;
                write_data(*p);
                p++;
        }       
}

/*****************控制光标函数********************/
void write_guanbiao(uchar hang,uchar add,uchar date)
{               
        if(hang==1)   
                write_com(0x80+add);
        else
                write_com(0x80+0x40+add);
        if(date == 1)
                write_com(0x0f);     //显示光标并且闪烁       
        else
                write_com(0x0c);   //关闭光标
}       


/***********************lcd1602上显示两位十进制数************************/
void write_sfm3(uchar hang,uchar add,uint date)
{
        if(hang==1)   
                write_com(0x80+add);
        else
                write_com(0x80+0x40+add);
        write_data(0x30+date/100%10);
        write_data(0x30+date/10%10);
        write_data(0x30+date%10);       
}

/***********************lcd1602初始化设置************************/
void init_1602()
{
        write_com(0x38);       
        write_com(0x0c);
        write_com(0x06);
        delay_uint(1000);
        write_string(1,4,"000/min");       
        write_string(2,2,"H:120  L:050 ");
}

/*************定时器0初始化程序***************/
void time_init()          
{
        EA   = 1;                   //开总中断
        TMOD = 0X01;          //定时器0、定时器1工作方式1
        ET0  = 1;                  //开定时器0中断
        TR0  = 1;                  //允许定时器0定时
}


/***********外部中断0初始化程序****************/
void init_int0()          //外部中断0初始化程序
{
        EX0=1;                          //允许外部中断0中断
        EA=1;                           //开总中断
        IT0 = 1;                   //外部中断0负跳变中断
}

/********************独立按键程序*****************/
uchar key_can;         //按键值

void key()         //独立按键程序
{
        static uchar key_new;
        key_can = 20;                   //按键值还原
        P2 |= 0x78;                     //对应的按键IO口输出为1
        if((P2 & 0x78) != 0x78)                //按键按下
        {
                delay_1ms(1);                     //按键消抖动
                if(((P2 & 0x78) != 0x78) && (key_new == 1))
                {                                                //确认是按键按下
                        key_new = 0;
                        switch(P2& 0x78)
                        {
                                case 0x68:  key_can = 3;  break;         //得到按键值
                                case 0x58:  key_can = 2;  break;         //得到按键值
                                case 0x38:  key_can = 1;  break;         //得到按键值
                        }
                }                       
        }
        else
                key_new = 1;       
}

/**********************设置函数************************/
void key_with()
{
        if(key_can == 1)        //设置键
        {
                menu_1++;
                if(menu_1 > 2)    //回到正常显示
                {
                        menu_1 = 0;
                        write_guanbiao(1,2,0);         //关闭光标
                        init_1602();      //初始化液晶显示               
                }
        }
/***************设置*********************/
        if(menu_1 != 0)
        {
                if(menu_1 == 1)                  //设置上限报警
                {
                        if(key_can == 2)        //加
                        {
                            rate_h ++;
                                if(rate_h >= 255)
                                        rate_h = 0;
                        }               
                        if(key_can == 3)        //减          
                        {
                                rate_h -- ;
                                if(rate_h <= rate_l)
                                        rate_h = rate_l + 1;
                        }       
                }
                if(menu_1 == 2)                  //设置下限报警
                {
                        if(key_can == 2)        //加
                        {
                            rate_l ++;
                                if(rate_l >= rate_h)
                                        rate_l = rate_h - 1;
                        }       
                        if(key_can == 3)        //减          
                        {
                                if(rate_l == 0x00)
                                        rate_l = 1;
                                rate_l -- ;                       
                        }
                }
       
                switch(menu_1)           // 光标显示
                {
                        case 1:  write_guanbiao(2,4,1);  break;
                        case 2:  write_guanbiao(2,11,1);  break;
                }       
        }
}

/****************报警函数***************/
void clock_h_l()
{
        static uchar value;
        if(rate != 0)
        {
                if((rate <= rate_l) || (rate >= rate_h))
                {
                        value ++;  //消除实际距离在设定距离左右变化时的干扰
                        if(value >= 2)
                        {
                                beep = ~beep;           //蜂鸣器报警                       
                        }       
                }
                else
                {
                        beep = 1;        //取消报警
                }
        }else
        {
                beep = 1;   //取消报警       
        }
                       
}

/****************主函数***************/
void main()
{       
        init_1602();                    //1602初始化


        time_init();                    //初始化定时器
        init_int0();          //外部中断0初始化程序
        while(1)
        {                       
                key();                                         //按键函数
                key_with();
                if(key_can <10)
                {
                        key_with();                         //按键处理函数
                }
                if(displayOK==0)//如果显示关
                {
                         rate = 0;
                }
                else//如果显示开
                {
                        rate=60000/(time[1]/5+time[2]/5+time[3]/5+time[4]/5+time[5]/5);
                }
                write_sfm3(2,5,rate);
                flag_200ms ++;
                if(flag_200ms >= 200)        //200ms
                {
                        flag_200ms = 0;
                        write_sfm3(1,5,rate);
                        clock_h_l();    //报警函数
                }
                delay_1ms(1);

                delay_1ms(300);
        }
}

void int0() interrupt 0
{
                EX0=0;//暂时关外部中断
                if(timecount<8)   //当连续两次检测时间间隔小于8*50ms=400ms不处理
                {
                                TR0=1;//开定时器
                }
                else
                {
                        time[i]=timecount*50+TH0*0.256+TL0/1000;//算出间隔时间
                        TH0 = 0x3c;
                        TL0 = 0xb0;     // 50ms         12M
                        timecount=0;//50ms计数清零
                        i++;
                        if(i==6)//记录到超过等于6次时间
                        {
                                i=1;//计数从1开始
                                displayOK=1;    //测得5次开始显示?
                        }                                                               
                }
}

/*************定时器0中断服务程序***************/
void time0_int() interrupt 1
{       
        TH0 = 0x3c;
        TL0 = 0xb0;     // 50ms         12M
        timecount++;//每50ms一次计数
        if(timecount>25)     //当超过25*50ms=1.5s没有检测到信号停止显示
        {
                        i=0;//数据个数清零
                        timecount=0;//50ms计数清零
                        displayOK=0;//显示关
                        TR0=0;//定时器关
                        TH0 = 0x3c;
                        TL0 = 0xb0;     // 50ms         12M
        }
}


显示有错,不能通过按键实现H、L数值加减

显示有错,不能通过按键实现H、L数值加减
回复

使用道具 举报

ID:77958 发表于 2015-4-24 20:52 | 显示全部楼层
看不懂。。。。。。。。
回复

使用道具 举报

ID:78279 发表于 2015-4-27 23:21 | 显示全部楼层
楼主 我想问一下按键那一部分的程序
switch(P3 & 0xf0)
          {
            case 0xb0: key_can = 3; break;      //得到k3键值
        case 0x70: key_can = 2; break;      //得到k2键值
        case 0x30: key_can = 1; break;      //得到k4键值
         }
我是不理解 case后面那个16进制数是用来的干嘛的?别人说按键值,能具体说说干嘛用的吗?

跪求 我从别人那里拿的程序,拷到自己芯片上按键程序根本就不能运行,按键按哪个系统都没有反应

评分

参与人数 1黑币 +35 收起 理由
admin + 35 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:75782 发表于 2015-4-28 13:02 | 显示全部楼层
  switch(P2& 0x78) 这部分有问题,对应的应该是P3口才对。 然后P3.4~P3.6 。 P3|(~(0X70))

switch(P3|(0X1F))
          {
            case 0xBF: key_can = 3; break;      //得到k3键值
        case 0xDF: key_can = 2; break;      //得到k2键值
        case 0xEF: key_can = 1; break;      //得到k4键值
         }

评分

参与人数 1黑币 +35 收起 理由
admin + 35 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:76963 发表于 2015-4-28 16:03 | 显示全部楼层
jmc1001 发表于 2015-4-28 13:02
switch(P2& 0x78) 这部分有问题,对应的应该是P3口才对。 然后P3.4~P3.6 。 P3|(~(0X70))

switch(P3|( ...

想同时用P3^4端口作为按键输入和T0定时器中断是否有冲突
回复

使用道具 举报

ID:75782 发表于 2015-4-28 16:08 | 显示全部楼层
chenyahuan 发表于 2015-4-28 16:03
想同时用P3^4端口作为按键输入和T0定时器中断是否有冲突

不会,可用做定时器,产生中断。

评分

参与人数 1黑币 +35 收起 理由
admin + 35 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:76963 发表于 2015-4-28 16:16 | 显示全部楼层
大六神丸 发表于 2015-4-27 23:21
楼主 我想问一下按键那一部分的程序
switch(P3 & 0xf0)
          {

应该是用P3端口状态与0xf(11110000)按位与,出现以下case x 情况就代表是哪个按键按下,但是你这个case3的0x30(00110000)是不是错了,不然要求两键同时按下吗?嗯,你拷贝的程序调试有问题吗?

评分

参与人数 1黑币 +35 收起 理由
admin + 35 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:78366 发表于 2015-4-28 21:04 | 显示全部楼层
有时候仿真有问题

评分

参与人数 1黑币 +35 收起 理由
admin + 35 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:78646 发表于 2015-5-2 12:29 | 显示全部楼层
代码有点长
回复

使用道具 举报

ID:78659 发表于 2015-5-2 15:03 | 显示全部楼层
仿真一般是不会有问题的额你好好看看你额按键

评分

参与人数 1黑币 +35 收起 理由
admin + 35 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:78279 发表于 2015-5-10 18:53 | 显示全部楼层
chenyahuan 发表于 2015-4-28 16:16
应该是用P3端口状态与0xf(11110000)按位与,出现以下case x 情况就代表是哪个按键按下,但是你这个case3 ...

嗯,确实那个设置错了

评分

参与人数 1黑币 +35 收起 理由
admin + 35 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:79558 发表于 2015-5-10 20:03 | 显示全部楼层
学习学习
回复

使用道具 举报

ID:162036 发表于 2017-1-16 16:01 | 显示全部楼层
楼主,问题解决了吗??可否发奋源程序给我,我遇到和你一样的问题了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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