51单片机 要求:数码管1、2位显示实际温度;4、5位显示设定温度;7、8位显示00-59秒表 每秒加1循环;

作者&投稿:法会 (若有异议请与网页底部的电邮联系)
51单片机 控制数码管轮流显示温湿度~

#include
#include
#include
#include
struct PID {
unsigned int SetPoint; // 设定目标 Desired Value
unsigned int Proportion; // 比例常数 Proportional Const
unsigned int Integral; // 积分常数 Integral Const
unsigned int Derivative; // 微分常数 Derivative Const
unsigned int LastError; // Error[-1]
unsigned int PrevError; // Error[-2]
unsigned int SumError; // Sums of Errors
};
struct PID spid; // PID Control Structure
unsigned int rout; // PID Response (Output)
unsigned int rin; // PID Feedback (Input)
sbit data1=P1^0;
sbit clk=P1^1;
sbit plus=P2^0;
sbit subs=P2^1;
sbit stop=P2^2;
sbit output=P3^4;
sbit DQ=P3^3;
unsigned char flag,flag_1=0;
unsigned char high_time,low_time,count=0;//占空比调节参数
unsigned char set_temper=35;
unsigned char temper;
unsigned char i;
unsigned char j=0;
unsigned int s;
/***********************************************************
延时子程序,延时时间以12M晶振为准,延时时间为30us×time
***********************************************************/
void delay(unsigned char time)
{
unsigned char m,n;
for(n=0;n<time;n++)
for(m=0;m<2;m++){}
}
/***********************************************************
写一位数据子程序
***********************************************************/
void write_bit(unsigned char bitval)
{
EA=0;
DQ=0; /*拉低DQ以开始一个写时序*/
if(bitval==1)
{
_nop_();
DQ=1; /*如要写1,则将总线置高*/
}
delay(5); /*延时90us供DA18B20采样*/
DQ=1; /*释放DQ总线*/
_nop_();
_nop_();
EA=1;
}
/***********************************************************
写一字节数据子程序
***********************************************************/
void write_byte(unsigned char val)
{
unsigned char i;
unsigned char temp;
EA=0; /*关中断*/
TR0=0;
for(i=0;i<8;i++) /*写一字节数据,一次写一位*/
{
temp=val>>i; /*移位操作,将本次要写的位移到最低位*/
temp=temp&1;
write_bit(temp); /*向总线写该位*/
}
delay(7); /*延时120us后*/
// TR0=1;
EA=1; /*开中断*/
}
/***********************************************************
读一位数据子程序
***********************************************************/
unsigned char read_bit()
{
unsigned char i,value_bit;
EA=0;
DQ=0; /*拉低DQ,开始读时序*/
_nop_();
_nop_();
DQ=1; /*释放总线*/
for(i=0;i<2;i++){}
value_bit=DQ;
EA=1;
return(value_bit);
}
/***********************************************************
读一字节数据子程序
***********************************************************/
unsigned char read_byte()
{
unsigned char i,value=0;
EA=0;
for(i=0;i<8;i++)
{
if(read_bit()) /*读一字节数据,一个时序中读一次,并作移位处理*/
value|=0x01<<i;
delay(4); /*延时80us以完成此次都时序,之后再读下一数据*/
}
EA=1;
return(value);
}
/***********************************************************
复位子程序
***********************************************************/
unsigned char reset()
{
unsigned char presence;
EA=0;
DQ=0; /*拉低DQ总线开始复位*/
delay(30); /*保持低电平480us*/
DQ=1; /*释放总线*/
delay(3);
presence=DQ; /*获取应答信号*/
delay(28); /*延时以完成整个时序*/
EA=1;
return(presence); /*返回应答信号,有芯片应答返回0,无芯片则返回1*/
}
/***********************************************************
获取温度子程序
***********************************************************/
void get_temper()
{
unsigned char i,j;
do
{
i=reset(); /*复位*/
}while(i!=0); /*1为无反馈信号*/
i=0xcc; /*发送设备定位命令*/
write_byte(i);
i=0x44; /*发送开始转换命令*/
write_byte(i);
delay(180); /*延时*/
do
{
i=reset(); /*复位*/
}while(i!=0);
i=0xcc; /*设备定位*/
write_byte(i);
i=0xbe; /*读出缓冲区内容*/
write_byte(i);
j=read_byte();
i=read_byte();
i=(i<<4)&0x7f;
s=(unsigned int)(j&0x0f);
s=(s*100)/16;
j=j>>4;
temper=i|j; /*获取的温度放在temper中*/
}
/*====================================================================================================
Initialize PID Structure
=====================================================================================================*/
void PIDInit (struct PID *pp)
{
memset ( pp,0,sizeof(struct PID));
}
/*====================================================================================================
PID计算部分
=====================================================================================================*/
unsigned int PIDCalc( struct PID *pp, unsigned int NextPoint )
{
unsigned int dError,Error;
Error = pp->SetPoint - NextPoint; // 偏差
pp->SumError += Error; // 积分
dError = pp->LastError - pp->PrevError; // 当前微分
pp->PrevError = pp->LastError;
pp->LastError = Error;
return (pp->Proportion * Error//比例
+ pp->Integral * pp->SumError //积分项
+ pp->Derivative * dError); // 微分项
}
/***********************************************************
温度比较处理子程序
***********************************************************/
compare_temper()
{
unsigned char i;
if(set_temper>temper)
{
if(set_temper-temper>1)
{
high_time=100;
low_time=0;
}
else
{
for(i=0;i<10;i++)
{ get_temper();
rin = s; // Read Input
rout = PIDCalc ( &spid,rin ); // Perform PID Interation
}
if (high_time<=100)
high_time=(unsigned char)(rout/800);
else
high_time=100;
low_time= (100-high_time);
}
}
else if(set_temper<=temper)
{
if(temper-set_temper>0)
{
high_time=0;
low_time=100;
}
else
{
for(i=0;i<10;i++)
{ get_temper();
rin = s; // Read Input
rout = PIDCalc ( &spid,rin ); // Perform PID Interation
}
if (high_time<100)
high_time=(unsigned char)(rout/10000);
else
high_time=0;
low_time= (100-high_time);
}
}
// else
// {}
}
/*****************************************************
T0中断服务子程序,用于控制电平的翻转 ,40us*100=4ms周期
******************************************************/
void serve_T0() interrupt 1 using 1
{
if(++count<=(high_time))
output=1;
else if(count<=100)
{
output=0;
}
else
count=0;
TH0=0x2f;
TL0=0xe0;
}
/*****************************************************
串行口中断服务程序,用于上位机通讯
******************************************************/
void serve_sio() interrupt 4 using 2
{
/* EA=0;
RI=0;
i=SBUF;
if(i==2)
{
while(RI==0){}
RI=0;
set_temper=SBUF;
SBUF=0x02;
while(TI==0){}
TI=0;
}
else if(i==3)
{
TI=0;
SBUF=temper;
while(TI==0){}
TI=0;
}
EA=1; */
}
void disp_1(unsigned char disp_num1[6])
{
unsigned char n,a,m;
for(n=0;n<6;n++)
{
// k=disp_num1[n];
for(a=0;a<8;a++)
{
clk=0;
m=(disp_num1[n]&1);
disp_num1[n]=disp_num1[n]>>1;
if(m==1)
data1=1;
else
data1=0;
_nop_();
clk=1;
_nop_();
}
}
}
/*****************************************************
显示子程序
功能:将占空比温度转化为单个字符,显示占空比和测得到的温度
******************************************************/
void display()
{
unsigned char code number[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6};
unsigned char disp_num[6];
unsigned int k,k1;
k=high_time;
k=k%1000;
k1=k/100;
if(k1==0)
disp_num[0]=0;
else
disp_num[0]=0x60;
k=k%100;
disp_num[1]=number[k/10];
disp_num[2]=number[k%10];
k=temper;
k=k%100;
disp_num[3]=number[k/10];
disp_num[4]=number[k%10]+1;
disp_num[5]=number[s/10];
disp_1(disp_num);
}
/***********************************************************
主程序
***********************************************************/
main()
{
unsigned char z;
unsigned char a,b,flag_2=1,count1=0;
unsigned char phil[]={2,0xce,0x6e,0x60,0x1c,2};
TMOD=0x21;
TH0=0x2f;
TL0=0x40;
SCON=0x50;
PCON=0x00;
TH1=0xfd;
TL1=0xfd;
PS=1;
EA=1;
EX1=0;
ET0=1;
ES=1;
TR0=1;
TR1=1;
high_time=50;
low_time=50;
PIDInit ( &spid ); // Initialize Structure
spid.Proportion = 10; // Set PID Coefficients
spid.Integral = 8;
spid.Derivative =6;
spid.SetPoint = 100; // Set PID Setpoint
while(1)
{
if(plus==0)
{
EA=0;
for(a=0;a<5;a++)
for(b=0;b<102;b++){}
if(plus==0)
{
set_temper++;
flag=0;
}
}
else if(subs==0)
{
for(a=0;a<5;a++)
for(b=0;a<102;b++){}
if(subs==0)
{
set_temper--;
flag=0;
}
}
else if(stop==0)
{
for(a=0;a<5;a++)
for(b=0;b<102;b++){}
if(stop==0)
{
flag=0;
break;
}
EA=1;
}
get_temper();
b=temper;
if(flag_2==1)
a=b;
if((abs(a-b))>5)
temper=a;
else
temper=b;
a=temper;
flag_2=0;
if(++count1>30)
{
display();
count1=0;
}
compare_temper();
}
TR0=0;
z=1;
while(1)
{
EA=0;
if(stop==0)
{
for(a=0;a<5;a++)
for(b=0;b<102;b++){}
if(stop==0)
disp_1(phil);
// break;
}
EA=1;
}
}
//DS18b20 子程序
#include
sbit DQ=P2^1; //定义端口

typedef unsigned char byte;
typedef unsigned int word;
//延时
void delay(word useconds)
{
for(;useconds>0;useconds--);
}
//复位
byte ow_reset(void)
{
byte presence;
DQ=0; //DQ低电平
delay(29); //480us
DQ=1; //DQ高电平
delay(3); //等待
presence=DQ; //presence信号
delay(25);
return(presence);
} //0允许,1禁止
//从1-wire 总线上读取一个字节
byte read_byte(viod)
{
byte i;
byte value=0;
for (i=8;i>0;i--)
{
value>>=1;
DQ=0;
DQ=1;
delay(1);

if(DQ)value|=0x80;
delay(6);
}
return(value);
}

//向1-wire总线上写一个字节
void write_byte(char val)
{
byte i;
for (i=8;i>0;i--) //一次写一个字节
{
DQ=0;
DQ=val&0x01;
delay(5);
DQ=1;
val=val/2;
}
delay(5);
}
//读取温度

char Read_Temperature(void)
{
union{
byte c[2];
int x;
}temp;

ow_reset();
write_byte(0xcc);
write_byte(0xBE);
temp.c[1]=read_byte();
temp.c[0]=read_byte();
ow_reset();
write_byte(0xCC);
write_byte(0x44);
return temp.x/2;
行不行?

你把倒数第三行改为
dsxianshi(get_temp());试试看?你现在这样不会启动18b20采集温度,全局变量temp得不到温度值。

另外,这种用全局变量传值的玩法很不好看,能不用就不要用。
另外2, 全局变量和局部变量或函数参数同名字也不是好玩法。

/****************************************************************                                               

程序名称:  DS1302+DS18B20+LCD1602显示。作者:贵阳学院物电系10级杨雄 

   

*****************************************************************/

#include <reg52.h>

#include <intrins.h>

#define uchar unsigned char

#define uint unsigned int

typedef unsigned char BYTE;

sbit LCD_RS = P2^0;     /*定义LCD控制端口*/        

sbit LCD_RW = P2^1;

sbit LCD_EN = P2^2;

sbit SCLK = P1^0;                   //DS1302时钟口P1.0

sbit IO = P1^1;                     //DS1302数据口P1.1

sbit RST = P1^2;  //DS1302片选口P1.2

sbit DS=P3^3; 

sbit P14=P1^4;//确定

sbit key1=P1^5;//加

sbit key2=P1^6;//减

sbit P17=P1^7;//下一页 

sbit alarm=P3^7;              

 //秒    分    时    日    月  星期    年

BYTE code init[] = {0x00, 0x00, 0x12, 0x24, 0x04, 0x02, 0x12};

BYTE data now[7];

uchar rbuf [13];

uchar code tab[] = {'0','1','2','3','4','5','6','7','8','9','/',' '};

uchar code Weeks[][3]={{"SUN"},{"MON"},{"TUE"},{"WED"},{"THU"},{"FRI"},{"SAT"},{"SUN"}};

uchar code STime[]={"SET  TIME"};

uchar code SDate[]={"SET  DATE"};

//uchar code S

uchar flag,flag1,A1,A2,A2t,A3,TH,TL ;

uint temp;             // variable of temperature

//void DS1302_Initial();

//void DS1302_SetTime(BYTE *p);

//void DS1302_GetTime(BYTE *p);

/*******************************************************************/

/*                                                                 */

/* 延时子程序                                                      */

/*                                                                 */

/*******************************************************************/

void delay(int ms)

{                           

   int i;

   while(ms--)

   {

     for(i = 0; i< 250; i++)

     {

      _nop_();

      _nop_();

      _nop_();

      _nop_();

     }

   }

}

/*******************************************************************/

/*                                                                 */

/*检查LCD忙状态                                                    */

/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。      */

/*                                                                 */

/*******************************************************************/

bit lcd_busy()

{                          

    bit result;

    LCD_RS = 0;

    LCD_RW = 1;

    LCD_EN = 1;

    _nop_();

    _nop_();

    _nop_();

    _nop_();

     result = (bit)(P0&0x80);

    LCD_EN = 0;

    return result; 

}

/*******************************************************************/

/*                                                                 */

/*写指令数据到LCD                                                  */

/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。                             */

/*                                                                 */

/*******************************************************************/

void lcd_wcmd(uchar cmd)

{                          

   while(lcd_busy());

    LCD_RS = 0;

    LCD_RW = 0;

    LCD_EN = 0;

    _nop_();

    _nop_(); 

    P0 = cmd;

    _nop_();

    _nop_();

    _nop_();

    _nop_();

    LCD_EN = 1;

    _nop_();

    _nop_();

    _nop_();

    _nop_();

    LCD_EN = 0;  

}

/*******************************************************************/

/*                                                                 */

/*写显示数据到LCD                                                  */

/*RS=H,RW=L,E=高脉冲,D0-D7=数据。                               */

/*                                                                 */

/*******************************************************************/

void lcd_wdat(uchar dat) 

{                          

   while(lcd_busy());

    LCD_RS = 1;

    LCD_RW = 0;

    LCD_EN = 0;

    P0 = dat;

    _nop_();

    _nop_();

    _nop_();

    _nop_();

    LCD_EN = 1;

    _nop_();

    _nop_();

    _nop_();

    _nop_();

    LCD_EN = 0; 

}

/*******************************************************************/

/*                                                                 */

/*  设定显示位置                                                   */

/*                                                                 */

/*******************************************************************/

void lcd_pos(uchar pos)

{                          

   lcd_wcmd(pos|0x80);      //数据指针=80+地址变量

}

/*******************************************************************/

/*                                                                 */

/*  LCD初始化设定                                                  */

/*                                                                 */

/*******************************************************************/

void lcd_init()

{                        

    lcd_wcmd(0x38);          //16*2显示,5*7点阵,8位数据

    delay(5);

    lcd_wcmd(0x38);         

    delay(5);

    lcd_wcmd(0x38);         

    delay(5);

    lcd_wcmd(0x0c);          //显示开,关光标

    delay(5);

    lcd_wcmd(0x06);          //移动光标

    delay(5);

    lcd_wcmd(0x01);          //清除LCD的显示内容

    delay(5);

}

/*******************************************************************/

/*                                                                 */

/*  1302子程序                                                   */

/*                                                                 */

/*******************************************************************/

BYTE DS1302_ReadByte()

{

    BYTE i;

    BYTE dat = 0;

    for (i=0; i<8; i++)             //8位计数器

    {

        SCLK = 0;                   //时钟线拉低

        _nop_();                    //延时等待

        _nop_();

        dat >>= 1;                  //数据右移一位

        if (IO) dat |= 0x80;        //读取数据

        SCLK = 1;                   //时钟线拉高

        _nop_();                    //?óê±μè′y

        _nop_();

    }

    return dat;

}

/**************************************

向DS1302写1字节数据

**************************************/

void DS1302_WriteByte(BYTE dat)

{

    char i;

    for (i=0; i<8; i++)             //8位计数器

    {

        SCLK = 0;                   //时钟线拉低

        _nop_();                    //延时等待

        _nop_();

        dat >>= 1;                  //移出数据

        IO = CY;                    //送出到端口

        SCLK = 1;                   //时钟线拉高

        _nop_();                    //延时等待

        _nop_();

    }

}

/**************************************

读DS1302某地址的的数据

**************************************/

BYTE DS1302_ReadData(BYTE addr)

{

    BYTE dat;

    RST = 0;

    _nop_();                        //延时等待

    _nop_();

    SCLK = 0;

    _nop_();                        //延时等待

    _nop_();

    RST = 1;

    _nop_();                        //延时等待

    _nop_();

    DS1302_WriteByte(addr);         //写地址

    dat = DS1302_ReadByte();        //读数据

    SCLK = 1;

    RST = 0;

    return dat;

}

/**************************************

往DS1302的某个地址写入数据

**************************************/

void DS1302_WriteData(BYTE addr, BYTE dat)

{

    RST = 0;

    _nop_();                        //延时等待

    _nop_();

    SCLK = 0;

    _nop_();                        //延时等待

    _nop_();

    RST = 1;

    _nop_();                        //延时等待

    _nop_();

    DS1302_WriteByte(addr);         //写地址

    DS1302_WriteByte(dat);          //写数据

    SCLK = 1;

    RST = 0;

}

/**************************************

写入初始时间

**************************************/

void DS1302_SetTime(BYTE *p)

{

    BYTE addr = 0x80;

    BYTE n = 7;

    DS1302_WriteData(0x8e, 0x00);   //允许写操作

    while (n--)

    {

        DS1302_WriteData(addr, *p++);

        addr += 2;

    }

    DS1302_WriteData(0x8e, 0x80);   //写保护

}

/**************************************

读取当前时间

**************************************/

void DS1302_GetTime(BYTE *p)

{

    BYTE addr = 0x81;

    BYTE n = 7;

    while (n--)

    {

        *p++ = DS1302_ReadData(addr);

        addr += 2;

    }

}

/**************************************

初始化DS1302

**************************************/

void DS1302_Initial()

{

    RST = 0;

    SCLK = 0;

    DS1302_WriteData(0x8e, 0x00);   //允许写操作

    DS1302_WriteData(0x80, 0x00);   //时钟启动

    DS1302_WriteData(0x90, 0xa6);   //一个二极管+4K电阻充电

    DS1302_WriteData(0x8e, 0x80);   //写保护

}

/**************************************************************************/

void dsreset(void)       //send reset and initialization command 18B20复位,初始化函数

{

  uint i;

  DS=0;

  i=103;

  while(i>0)i--;

  DS=1;

  i=4;

  while(i>0)i--;

}

bit tmpreadbit(void)       //read a bit  读1位数据函数

{

   uint i;

   bit dat;

   DS=0;i++;          //i++ for delay

   DS=1;i++;i++;

   dat=DS;

   i=8;while(i>0)i--;

   return (dat);

}

uchar tmpread(void)   //read a byte date   读1字节函数

{

  uchar i,j,dat;

  dat=0;

  for(i=1;i<=8;i++)

  {

    j=tmpreadbit();

    dat=(j<<7)|(dat>>1);   //读出的数据最低位在最前面,这样刚好一个字节在DAT里

  }

  return(dat);

}

void tmpwritebyte(uchar dat)   //write a byte to ds18b20  向1820写一个字节数据函数

{

  uint i;

  uchar j;

  bit testb;

  for(j=1;j<=8;j++)

  {

    testb=dat&0x01;

    dat=dat>>1;

    if(testb)     //write 1

    {

      DS=0;

      i++;i++;

      DS=1;

      i=8;while(i>0)i--;

    }

    else

    {

      DS=0;       //write 0

      i=8;while(i>0)i--;

      DS=1;

      i++;i++;

    }

  }

}

void tmpchange(void)  //DS18B20 begin change       开始获取数据并转换

{

  dsreset();

  delay(1);

  tmpwritebyte(0xcc);  // address all drivers on bus  写跳过读ROM指令

  tmpwritebyte(0x44);  //  initiates a single temperature conversion  写温度转换指令

}   

uint tmp()               //get the temperature     读取寄存器中存储的温度数据

{

  float tt;

  uchar a,b;

  dsreset();

  delay(1);

  tmpwritebyte(0xcc);

  tmpwritebyte(0xbe);

  a=tmpread();   //读低8位

  b=tmpread();   //读高8位

  temp=b;

  temp<<=8;             //two byte  compose a int variable   两个字节组合为1个字

  temp=temp|a;

  tt=temp*0.0625;   //温度在寄存器中是12位,分辨率是0.0625

  temp=tt*10;  //乘10表示小数点后只取1位,加0.5是四折五入

  temp=temp;     

A1=temp/100;

A2t=temp%100;

A2=A2t/10;

A3=A2t%10;

  return (A1,A2,A3);

}

void delay10ms()            //delay

  {

    uchar a,b;

    for(a=10;a>0;a--)

      for(b=60;b>0;b--);

   }

/**************************************************/

/*温度上下限调节,预设温度范围为0—50摄氏度   */

/**************************************************/

uchar Tchan()

 {

            uchar i,buf[]={" SET TH AND TL "};

lcd_wcmd(0x01); //清除LCD的显示内容

while(1)

{

if(key1==0)

{

TH++;

while(key1==0);

if(TH>50)

TH=0;

}

if(key2==0)

{

TL++;

while(key2==0);

if(TL>50)

TL=0;

}

lcd_pos(0);//设置显示位置为第一行的第1个字符

for(i=0;i<14;i++)

{

lcd_wdat(buf[i]);

}

_nop_();_nop_();

lcd_pos(0x40);_nop_(); _nop_();//设置显示位置为第一行的第1个字符

lcd_wdat(32);_nop_(); _nop_();

lcd_wdat(84);_nop_(); _nop_();

lcd_wdat(72);_nop_(); _nop_();

lcd_wdat(tab[TH/10]); _nop_();_nop_();

lcd_wdat(tab[TH%10]); _nop_();_nop_();

lcd_wdat(46);  _nop_();_nop_();

lcd_wdat(48);  _nop_();_nop_();

lcd_wdat(32);_nop_(); _nop_();

lcd_wdat(32);_nop_(); _nop_();

lcd_wdat(84);  _nop_();_nop_();

lcd_wdat(76);  _nop_();_nop_();

lcd_wdat(tab[TL/10]); _nop_();_nop_();

lcd_wdat(tab[TL%10]); _nop_();_nop_();

lcd_wdat(46);  _nop_();_nop_();

lcd_wdat(48); _nop_();_nop_();

    if(P14==0) 

{

flag=0;

goto loop;

}

  

}

loop:return (0);

}

void TimeS()

{

uchar i,H,M,buf[]={"SET  TIME"};

    DS1302_GetTime(now);//读取当前时间

M=now[1];H=now[2];

M=(M/16*10+M%16);H=(H/16*10+H%16);

lcd_wcmd(0x01); //清除LCD的显示内容

while(1)

{           lcd_pos(0x04);//设置显示位置为第二行的第1个字符

for(i=0;i<9;i++)

{

lcd_wdat(buf[i]);

}

       if(key1==0)

{

M++;

while(key1==0);

if(M>=60)

M=0;

}

if(key2==0)

{

H++;

while(key2==0);

if(H>=24)

H=0;

}  

lcd_pos(0x44);_nop_(); _nop_();//设置显示位置为第二行的第1个字符

lcd_wdat(tab[H/10]); _nop_();_nop_();

lcd_wdat(tab[H%10]); _nop_();_nop_();

lcd_wdat(58);  _nop_();_nop_();

lcd_wdat(tab[M/10]); _nop_();_nop_();

lcd_wdat(tab[M%10]); _nop_();_nop_();

lcd_wdat(58);  _nop_();_nop_();

lcd_wdat(48); _nop_();_nop_();

lcd_wdat(48); _nop_();_nop_();

if(P14==0)

{

M=(M/10*16+M%10);H=(H/10*16+H%10);

        DS1302_WriteData(0x8e, 0x00);   //允许写操作

 

        DS1302_WriteData(0x82, M);

        DS1302_WriteData(0x84, H);

        DS1302_WriteData(0x8e, 0x80);   //写保护

while(!P14);

flag=0;

goto loop;

}

}

loop:lcd_wcmd(0x01); //清除LCD的显示内容

}

void DateS()

{

uchar i,M,D,buf[]={"SET  DATE"},y,m,W;

    DS1302_GetTime(now);//读取当前时间

M=now[4];M=(M/16*10+M%16);D=now[3];D=(D/16*10+D%16);

lcd_wcmd(0x01); //清除LCD的显示内容

while(1)

{           lcd_pos(0x04);//设置显示位置为第二行的第1个字符

for(i=0;i<9;i++)

{

lcd_wdat(buf[i]);

}

       if(key1==0)

{

M++;

while(key1==0);

if(M>12)

M=1;

}

if(key2==0)

{

D++;

while(key2==0);

if(D>31)

D=1;

}  

lcd_pos(0x43);_nop_(); _nop_();//设置显示位置为第二行的第1个字符

lcd_wdat(50); _nop_();_nop_();//年

    lcd_wdat(48);  _nop_();_nop_(); //延时等待

    lcd_wdat(tab[now[6]/16]); 

    lcd_wdat(tab[now[6]%16]);_nop_();_nop_();

lcd_wdat(45);  _nop_();_nop_();

lcd_wdat(tab[M/10]); _nop_();_nop_();

lcd_wdat(tab[M%10]); _nop_();_nop_();

lcd_wdat(45);  _nop_();_nop_();

lcd_wdat(tab[D/10]); _nop_();_nop_();

lcd_wdat(tab[D%10]); _nop_();_nop_();

    //w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1

y=(now[6]/16*10 +now[6]%16);

if(M==1)

{

y=y-1;m=13;

}

else if(M==2)

{

y=y-1;m=14;

}

else m=M;

W=(y+y/4+26*(m+1)/10+D-36)%7;

if(P14==0)

{

M=(M/10*16+M%10);D=(D/10*16+D%10);

        DS1302_WriteData(0x8e, 0x00);   //允许写操作

 

        DS1302_WriteData(0x88, M);

        DS1302_WriteData(0x86, D);

DS1302_WriteData(0x8A, W);

        DS1302_WriteData(0x8e, 0x80);   //写保护

while(!P14);

flag=0;

goto loop;

}

}

loop:lcd_wcmd(0x01); //清除LCD的显示内容

}

uchar function()//功能设置状态函数

{

 uchar i,buf[]={" SET TH AND TL "},buf1[]={"SET  TIME"},buf2[]={"SET  DATE"};

if(P17==0)

{

    while(!P17);

flag++;//状态量

    lcd_wcmd(0x01); //清除LCD的显示内容

while(1)

{

if(P17==0)

{

while(!P17);

flag++;//状态量

if(flag>3)flag=0;

}

      

if(flag==1)

{

lcd_pos(0);//设置显示位置为第一行的第1个字符

for(i=0;i<14;i++)

{

lcd_wdat(buf[i]);

}

}

else if(flag==2)

{

lcd_pos(0x04);//设置显示位置为第一行的第1个字符

for(i=0;i<9;i++)

{

lcd_wdat(buf1[i]);

}

}

else if(flag==3)

{

lcd_pos(0x04);//设置显示位置为第一行的第1个字符

for(i=0;i<9;i++)

{

lcd_wdat(buf2[i]);

}

}

if(P14==0)

{

while(!P14);

goto loop;

}

}

}

loop:return flag;

}

void Tpalarm() //温度报警

{

if(temp/10<TL||temp/10>TH) alarm=0;

else alarm=1;

}

/*******************************************************************/

/* 主显示函数    */

/*    */

/*******************************************************************/

void display(void)

{  // now[秒    分    时    日    月  星期    年]

 uchar i;

 lcd_pos(0);//设置显示位置为第一行的第1个字符

 lcd_wdat(50); _nop_();_nop_();//年

 lcd_wdat(48);  _nop_();_nop_(); //延时等待

 lcd_wdat(tab[now[6]/16]); 

 lcd_wdat(tab[now[6]%16]);  _nop_();_nop_();

 lcd_wdat(45); //显“-”

 lcd_wdat(tab[now[4]/16]); //月

 lcd_wdat(tab[now[4]%16]);  _nop_();_nop_();

 lcd_wdat(45); //显“-”

 lcd_wdat(tab[now[3]/16]); //日

 lcd_wdat(tab[now[3]%16]);

 lcd_pos(0x0c);_nop_();_nop_();

 for(i=0;i<3;i++) lcd_wdat(Weeks[now[5]%16][i]); //星期

 lcd_pos(0x40);

 lcd_wdat(tab[now[2]/16]);//时

 lcd_wdat(tab[now[2]%16]);  _nop_();_nop_();

 lcd_wdat(58);  //显示“:”

 lcd_wdat(tab[now[1]/16]);//分

 lcd_wdat(tab[now[1]%16]);  _nop_();_nop_();

 lcd_wdat(58);

 lcd_wdat(tab[now[0]/16]);//秒

 lcd_wdat(tab[now[0]%16]);

 lcd_pos(0x4a);

 lcd_wdat(tab[A1]);

 lcd_wdat(tab[A2]); _nop_(); _nop_(); 

 lcd_wdat(46);

 lcd_wdat(tab[A3]); _nop_(); _nop_();     

 lcd_wdat(0xdf);

 lcd_wdat(67);

 delay(1);

}

main()

{

    //uchar i;

    delay(10);

    lcd_init();                        // 初始化LCD

三十分 要那么多东西啊???


雨花区19489235393: 想用51单片机编个倒计时的c程序,要求用两位数码管显示分钟的,并用一个按键 -
御舍苦碟: 你这数码管的1、2口就这么悬着或者接dp一起了真的没问题吗…… 全局变量2个用于表示个位和十位,显示的时候可以省点力不用每次计算个位十位. 然后一个全局变量代表秒 编程的话,首先是按键响应中断,控制某个全局变量flag的值,三种...

雨花区19489235393: 基于AT89C51单片机,利用定时器设计一个两位数码 管显示电路.求详细的设计过程. -
御舍苦碟: 硬件很简单,我就不画图了,简单描述一下吧.在单片机最小系统的基础上,P0口接数码管的数据端,P2.6,P2.7接数码管的控制端. 程序如下: #include #define uint unsigned int #define uchar unsigned char sbit s1=P2^6;//十位 ...

雨花区19489235393: 在51单片机中1位位数码管显示的编程怎么写啊, -
御舍苦碟: 下面这个程序是4x4距阵键盘,LED数码管显示,一共可以到0-F显示,你可以稍微改一下就可以实现你的功能了,如还有问题请发信息,希望能帮上你! #include unsigned char code Dig[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,...

雨花区19489235393: 2位显示的共阳数码管和80C51单片机 -
御舍苦碟: 单片机21 22 两个引脚分别接数码管的1 2 用p1的io口接数码管的剩余8个端口 程序可以参考一些数码管显示程序

雨花区19489235393: 写一个c51单片机程序,要求使六位数码管上第一个数码管显示2,第二个显示3,要静态显示,要怎么写. -
御舍苦碟: 你的要求是静态如果全靠单片机的IO口控制的话,IO口不够用的的你要加像595这样并行输出的行片才行

雨花区19489235393: 51单片机里用一个按键让一个两位数加一并显示在两个数码管上,但是在按着按键不放时第一个数码管总是会 -
御舍苦碟: 你的数码管显示应该是扫描方式,所以按键按下时,单片机不能直行显示扫描了,只会亮一个.你可以在定时器中显示数码管.

雨花区19489235393: 求用51单片机接两个数码管,0 - 99动态显示程序(用C语言) -
御舍苦碟: #include #define uchar unsigned char #define uint unsigned int uchar DSY_CODE[]= { 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f }; void delay(uint x) { uchar i; while(x--)for(i=0;i<120;i++); } void main() { uchar i; P0 = 0x00; P2 = 0x00; while(1)...

雨花区19489235393: 51单片机如何让2位数码管闪烁 -
御舍苦碟: “想让他最后3秒闪烁”,我猜应该是像倒计时到快结束时的警报那样的闪烁吧?这需要再添加一个计时变量.比如总共有10秒,想让它在最后3秒闪烁,可以这样: 在定时器中断(比如100ms一次) 里令一个计时变量(假设叫T)加1——加到10就是1秒,加到70就是第7秒.在进行数码管驱动的时候判断这个变量T,如果大于70再执行闪烁,小于70则不闪烁.

雨花区19489235393: 51单片机的编程 -
御舍苦碟: 51编程得看外部电路的连接情况.没有电路图,木有办法写... 数码管和单片机之间的电路有很多种,你这种就用译码器,74138就行.假设单片机p1口用作数码管输出. 滑槽电路也不清楚,假设一个电机,用的是P2^0,P2^1(顺...

雨花区19489235393: 单片机求助,用汇编语言写一个双位数码管0到99循环 -
御舍苦碟: 一个数码管显示0005~01秒,再换另一个显示,他俩轮流这么显示着(再多几个也可以),这种交替人眼看不出来的单片机求助,用汇编语言写一个双位数码管0到99循环

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网