一乐电子

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

微信扫码登录

手机号码,快捷登录

手机号码,快捷登录

搜索
查看: 5494|回复: 3

[51单片机] STC11F02E-1T单片机延时的问题

[复制链接]
发表于 2012-3-29 10:43 | 显示全部楼层 |阅读模式
《电子制作》2012年3期《迷你温湿度计》仿制出现问题,通电以后红、绿2个数码管全部8字交替闪烁,查了好多资料不知所因,最后网友提到可能是延时的问题,1T的要快12倍,但怎样修改延时,请大侠帮我。

/*
迷你温湿度计
红色显示温度,绿色显示湿度
温度和湿度能切换显示
能设置最大值,达到最大值数码管闪烁引起提醒
*/
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
#define status1 0
#define status2 1
#define status3 2

typedef unsigned char  U8;
typedef unsigned int   U16;
typedef unsigned char BYTE;
unsigned char data dis_buf[4];//用于存数据
//U8 code table[]={//共阳数码管段码
// 0xC0,/*0*/
// 0xF9,/*1*/
// 0xA4,/*2*/
// 0xB0,/*3*/
// 0x99,/*4*/
// 0x92,/*5*/
// 0x82,/*6*/
// 0xF8,/*7*/
// 0x80,/*8*/
// 0x90,/*9*/
//};
U8 code table[]={//共阳数码管段码 (有接错,修改)
0xC0,/*0*/
0xCF,/*1*/
0x92,/*2*/
0x86,/*3*/
0x8D,/*4*/
0xA4,/*5*/
0xA0,/*6*/
0xCE,/*7*/
0x80,/*8*/
0x84,/*9*/

0x89,/*H*/
0xBF,/*一横*/
0x9C,/*度*/
0xF0,/*C*/
0xFF,/*空*/
};
sbit  DATA  = P3^7 ;//定义数据接收端口
sbit P3_2 = P3^2;/*第4个数码管*/
sbit P3_3 = P3^3;
sbit P3_4 = P3^4;
sbit P3_5 = P3^5;
//sbit key1 = P3^0;//设置按键
//sbit key2 = P3^1;//加键
U8  U8FLAG;
//U8  U8FLAG,U8temp;
//U8  shidu_shi,shidu_ge,wendu_shi,wendu_ge;
//U8  U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
//U8  U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
//U8  U8comdata;
/*******定义变量***********/
uchar num,dat0,dat1,dat2,dat3,dat4,flag_dis,returnkey,setnum,displaynum,MaxHum,MaxTem,flashcount,alarmflag1,alarmflag2;
uint countnum;//int型,用于计算时间到什么时候切换显示
/********以下两个延时函数是用单片机小精灵计算出来的*****/
void delay20ms(void)   //误差 -0.000000000001us
{
    unsigned char a,b,c;
    for(c=199;c>0;c--)
        for(b=120;b>0;b--)
            for(a=1;a>0;a--);
}

//void delay30us(void)   //误差 0us
//{
//    unsigned char a,b;
//    for(b=3;b>0;b--)
//        for(a=28;a>0;a--);
//}
void delay40us(void)   //误差 0us
{
    unsigned char a,b;
    for(b=3;b>0;b--)
        for(a=38;a>0;a--);
}
/**********************************************************/
BYTE read_byte(void)/*读取一个字节数据函数*/
{
        BYTE i,value;
        for(i = 8; i > 0; i--)
        {
                value <<= 1;
    U8FLAG=2;
                while((!DATA)&&U8FLAG++);        //等待50us
                delay40us();/*原本30us*/        
                if(DATA)
                {
                        value++;
                        while((DATA)&&U8FLAG++);        //等待高电平的结束                        
                }                                                                                       
        }
        return(value);        
}

void dht11_read()/***读取湿度和温度***/
{        
        BYTE temp = 0;
        DATA = 0;                                //主机把总线拉低
        delay20ms();                        //拉低时间大于18ms,否则DHT11不会响应
        DATA = 1;                                //主机把总线拉高
        delay40us();                        //拉高时间为20us-40us               
//        while(!DATA);                //等待DHT11响应信号(低电平)
    if(!DATA)//改为if判断
  {
   U8FLAG=2;//从2开始计算
         while((!DATA)&&U8FLAG++);                //等待DHT11拉高总线
   U8FLAG=2;
   while((DATA)&&U8FLAG++);
   
  dat0 = read_byte();//high humidity
        dat1 = read_byte();//low humidity
        dat2 = read_byte();//high temp
        dat3 = read_byte();//low temp
        dat4 = read_byte();//verification code
        
        temp = dat0 + dat1 + dat2 + dat3;
        if(temp == dat4)
  {
   if(flag_dis==0)//显示湿度
   {
    dis_buf[0]=table[10];//“H”
    dis_buf[1]=table[11];//一横
    dis_buf[2]=table[dat0/10];//湿度的十位数
    dis_buf[3]=table[dat0%10];//湿度的个位数
   }
   if(flag_dis==1)//切换时间,不显示
   {
    dis_buf[0]=table[14];// 全部为空
    dis_buf[1]=table[14];//
    dis_buf[2]=table[14];//
    dis_buf[3]=table[14];//
   }
   if(flag_dis==2)//显示温度
   {
    dis_buf[0]=table[dat2/10];//温度的十位数
    dis_buf[1]=table[dat2%10];//温度的个位数
    dis_buf[2]=table[12];//度
    dis_buf[3]=table[13];//C
   }
   if(flag_dis==3)//切换时间,不显示
   {
    dis_buf[0]=table[14];// 全部为空
    dis_buf[1]=table[14];//
    dis_buf[2]=table[14];//
    dis_buf[3]=table[14];//
   }  
  }
    }
//            return 1;
//        else
//                return 0;               
}
void inittime()//定时器初始化函数
{
TMOD=0x01;//定时器0工作方式1
TH0=(65536-5000)/256;//每5毫秒检测一个状态
TL0=(65536-5000)%256;
EA=1;
ET0=1;
TR0=1;
}
/***********************************/
void flashalarm()//闪烁提醒函数
{
/**********************************/
if(flag_dis==0)//如果现在显示的是湿度
{
if(dat0>=MaxHum)//如果湿度大于等于设定值
{
  if(alarmflag1==1)/*闪烁状态*/
  {
   if(num>=2) num=0;//只显示前两个
  }
  else {if(num>=4) num=0;}
}
else {if(num>=4) num=0;}
}
/************************************/
else if(flag_dis==2)//如果显示的是温度
{
if(dat2>=MaxTem)//如果温度大于等于设定值
{
  if(alarmflag2==1)
  {
   if(num>=4) num=2;//限制在闪烁前两个
  }
  else {if(num>=4) num=0;}
}
else {if(num>=4) num=0;}
}
else {if(num>=4) num=0;}
/*******************************/
}
/*************************************/
void display()//数码管显示函数
{
P3_2=1;
P3_3=1;
P3_4=1;
P3_5=1;//先关闭所有控制端口
P1=dis_buf[num];
/*******************************/
/**********************************/
switch(num)//思考:没有对应数值会怎么样?
{
  case 0:P3_2=1;P3_3=1;P3_4=1;P3_5=0;break;
  case 1:P3_2=1;P3_3=1;P3_4=0;P3_5=1;break;
  case 2:P3_2=1;P3_3=0;P3_4=1;P3_5=1;break;
  case 3:P3_2=0;P3_3=1;P3_4=1;P3_5=1;break;
}
num++;
// if(num>=4) num=0;
flashcount++;//计算标志
if(flashcount>=100) {alarmflag1=~alarmflag1;alarmflag2=~alarmflag2;flashcount=0;}//0.5秒闪烁一次,然后返回原来的闪烁状态
if(setnum==1) flashalarm();//加载闪烁函数,区分按键按下
if(setnum==2)//按键按下时不闪烁
{
if(num>=4) num=0;
}
}
/*****************************************************************/
uchar keyread()//读取多个按键,有返回值
{
static uchar KeyStatus=status1,Knum=0;//只声明一次
uchar keynum;
//uchar Knum=0;
uchar i=0;
keynum=(~P3)&0x03;//低两位
switch(KeyStatus)
{
  case status1:
    if(keynum) KeyStatus=status2;
    return 0;
    break;
  case status2:
    if(!keynum) KeyStatus=status1;//如果是毛刺,就返回第一状态
    else
    {
     for(i=0;i<2;i++)//查询哪个按键按下
    {
     if(keynum & 1<<i)
     {
      Knum=1+i;
      break;
     }
    }
     KeyStatus=status3;
    }
    return 0;
    break;
  case status3:
    if(!keynum)
    {KeyStatus=status1;return Knum;}
    return 0;
  default : return 0; break;
}
}
/***********************************************************/
void set_display()//设置按键按下时的显示项目
{
if(displaynum==1)//设置湿度界面
{
  dis_buf[0]=table[11];//一横
  dis_buf[1]=table[11];//一横
  dis_buf[2]=table[MaxHum/10];//湿度的十位数
  dis_buf[3]=table[MaxHum%10];//湿度的个位数   
}
/******/
if(displaynum==2)//设置温度界面
{
  dis_buf[0]=table[MaxTem/10];//温度的十位数
  dis_buf[1]=table[MaxTem%10];//温度的个位数
  dis_buf[2]=table[11];//一横
  dis_buf[3]=table[11];//一横  
}
}
/***********************************/
void main()
{
// uchar read_success;//读取成功变量
inittime();//定时器初始化
num=0;
setnum=1;//设置按键的显示项目
displaynum=0;//
MaxHum=80;//湿度默认提醒的最大值为80
MaxTem=40;//温度的默认提醒最大值为40
flag_dis=0;//初始化显示标志为0,显示湿度
alarmflag1=1;
alarmflag2=1;
while(1)
{  
//  read_success=dht11_read();
//  if(read_success)//是否返回1,读取成功
//  {
   /*Hum1=dat0/10;//湿度的十位数
   Hum2=dat1%10;//湿度的个位数
   Tem1=dat2/10;//温度的十位数
   Tem2=dat3%10;//温度的个位数 */
   /*添加标志,选择显示不同项目*/
   /*添加判断显示项目*/
//   dis_buf[0]=table[dat0/10];//湿度的十位数
//   dis_buf[1]=table[dat0%10];//湿度的个位数
//   dis_buf[2]=table[dat3/10];//温度的十位数
//   dis_buf[3]=table[dat3%10];//温度的个位数
   if(setnum==1)//区分:按键按下后不读取数值
   {
   delay20ms();
   delay20ms();
   delay20ms();
   delay20ms();
   delay20ms();
   delay20ms();
   delay20ms();
   
   dht11_read();//中断中读取数据
   }
//  }
}

}

void timer0() interrupt 1//中断函数
{
TH0=(65536-5000)/256;//重新赋值 ,5毫秒
TL0=(65536-5000)%256;
countnum++;//200次一秒
if(countnum==1300) flag_dis=1;//6.5秒
if(countnum==1430) flag_dis=2;//中间切换时间
if(countnum==2730) flag_dis=3;
if(countnum==2860) {flag_dis=0;countnum=0;}//标志为0,同时countnum清零
display();//数码管显示函数
/*******************************************************/
returnkey=keyread();
if(returnkey==1)//如果设置按键按下
{
  returnkey=0;//按键值清零 !!
  setnum++;
  if(setnum>=3)//按第二下变为1,同时标志变为0,退出设置界面
  {
  setnum=1;
  displaynum=0;
  flag_dis=0;
  countnum=0;//计算数值也要为0
  }
  if(setnum==2)/*注意!!(经验:标志的冲突问题)*/
  {
   if(flag_dis==0){displaynum=1;}//显示模式为设置湿度的界面
   if(flag_dis==2){displaynum=2;}//显示为设置温度的界面
   flag_dis=4;//同时使标志设置为4,不进入数据显示项目
  }
}
/*****/
if(setnum==2)//按下后才进入
{
  if(displaynum==1)//设置的是湿度
  {
   if(returnkey==2)//设置“加”键
   {
      returnkey=0;//按键值清零 !!
      MaxHum=MaxHum+5;//湿度步进值为5
      if(MaxHum>90) MaxHum=20;//大于90,返回到20
   }
  }
  /*******/
  if(displaynum==2)//设置的是温度
  {
   if(returnkey==2)//设置加
   {
    returnkey=0;//按键值清零 !!
    MaxTem=MaxTem+2;//温度步进值为2
    if(MaxTem>50) MaxTem=0;//返回到0
   }
  }
}
/*********/
set_display();//设置按键按下时的显示项目


DHT11.zip (3.46 KB, 下载次数: 525)
发表于 2012-3-29 12:57 | 显示全部楼层
有电路图吗?
回复

使用道具 举报

 楼主| 发表于 2012-3-29 13:10 | 显示全部楼层
回复

使用道具 举报

发表于 2012-3-29 16:47 | 显示全部楼层
去官网下载 stc-isp-15xx-v6.12.exe 里面代码生成功能
回复

使用道具 举报

本版积分规则

QQ|一淘宝店|手机版|商店|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2025-11-4 14:57 , Processed in 0.032392 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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