这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » ysjabcd-制作进程

共10条 1/1 1 跳转至

ysjabcd-制作进程

院士
2011-12-13 20:24:40     打赏

目录
1楼:焊接过程
3楼:速度里程计
4楼:流水灯
5楼:最简单的闪烁灯
6楼:花样流水灯
7楼:液晶显示1602
8楼:定时器的应用--秒表
9楼:数码管滚动显示
10楼:温度显示实验DS18B20



     
再来张靓照




关键词: ysjabcd-     制作     进程    

院士
2011-12-13 20:44:01     打赏
2楼
功能实现呢?

院士
2011-12-15 21:24:09     打赏
3楼
    速度里程计,带时间显示,早上起来急急忙忙上班,一直担心迟到,有时间显示,时间掌握眼中,不用频繁看手机了。
    更有单次行车里程,随时了解我们骑了多远的路了,方便测量两地之间的路程。


#include<reg52.h>
#include<intrins.h>

#define uchar unsigned char
#define uint unsigned int

#define ISP_BYTE_READ    1  //ISP字节读
#define ISP_BYTE_PROGRAM 2  //ISP直接编程
#define ISP_SECTOR_ERASE 3  //ISP扇区擦除
/*以下是配置STC单片机的寄存器*/
/*相关资料在STC89C51RC的PDF的第35页开始*/
sfr ISP_DATA  = 0xE2;
sfr ISP_ADDRH = 0xE3;
sfr ISP_ADDRL = 0xE4;
sfr ISP_CMD   = 0xE5;
sfr ISP_TRIG  = 0xE6;
sfr ISP_CONTR = 0xE7;

uchar code table[]="km/h       km";
uchar code table1[]="        km";

sbit rs=P2^4;   // 液晶
sbit rw=P2^5;   // 液晶
sbit en=P2^6;   // 液晶
uint aa,time,s1,s11;
uchar num,bb,a,b,up,down;
uchar IRCOM[7];//红外数组
unsigned long int quan,s2,s21;     //

sbit ACC0 = ACC^0;    //1302
sbit ACC7 = ACC^7;    //1302
sbit IRIN = P3^2;         //红外接收器数据线
sbit T_CLK = P3^6; /*实时时钟时钟线引脚 */
sbit T_IO = P3^4; /*实时时钟数据线引脚 */
sbit T_RST = P3^5; /*实时时钟复位线引脚 */
uchar flag;
uchar sec, min, hour;

void Write_DS1302Init(void);
void display();
void delayhw(uchar x);  //x*0.14MS 红外延时
void delay(uint z);//液晶延时

/********************************************************************
* 功能 : EEPROM的扇区擦除
* 输入 : Address(擦除扇区的地址)
***********************************************************************/
void ISP_ERASE(Address)
{
 ISP_ADDRL = Address;
 ISP_ADDRH = Address >> 8;
 ISP_CONTR = 0x81;    
 ISP_CMD = ISP_SECTOR_ERASE; 
 ISP_TRIG = 0x46; //PDF手册中说先像 ISP_TRIG 中写入 0x46, 然后写入 0xb9
 ISP_TRIG = 0xb9;
 _nop_();
 _nop_(); 
}

/********************************************************************
* 输入 : Address(想要读取EEPROM的地址)
*********************************************************************/
uint ISP_READ(Address)
{
 uchar Read_Data;
 ISP_ADDRL = Address;
 ISP_ADDRH = Address >> 8;
// EA = 0; 
 ISP_CONTR = 0x81;
 ISP_CMD = ISP_BYTE_READ;
 ISP_TRIG = 0x46;
 ISP_TRIG = 0xb9;
 _nop_();
 _nop_();
 Read_Data = ISP_DATA;
 return Read_Data; 
}

/********************************************************************
* 输入 : Address为编程的地址,Data_temp为想要编程的值
***********************************************************************/
void ISP_PROGRAM(Address, Data_temp)
{
 ISP_DATA = Data_temp;
 ISP_ADDRL = Address;
 ISP_ADDRH = Address >> 8;
 ISP_CONTR = 0x81;
 ISP_CMD = ISP_BYTE_PROGRAM;
 ISP_TRIG = 0x46;
 ISP_TRIG = 0xb9;
 _nop_();
 _nop_();  
}

void delay(uint z) //液晶延时
{
 uint x,y;
 for(x=110;x>0;x--)
  for(y=z;y>0;y--); 
}

void write_com(uchar com) //液晶写命令
{
 rs=0;
 P0=com;
 delay(1);
 en=1;
 delay(1);
 en=0; 
}
void write_data(uchar date) //液晶写数据
{
 rs=1;
 P0=date;
 delay(1);
 en=1;
 delay(1);
 en=0;
}

void init()
{
 quan=0;
 en=0;
 rw=0;
 aa=0;
 up=0;
 down=0;
 flag=0;
 write_com(0x38);
 write_com(0x0c);
 write_com(0x06);

 EA=1;    //开总中断
 EX0=1;    //开外部中断0
 IT0=1;    //外部中断设为下降沿触发
 ET0=1;     // 开定时器0中断
 TMOD=0x11;//定时器0设定为定时器模式
 TH0=(65536-5000)/256;
 TL0=(65536-5000)%256; //定时器0装初值5ms
 TR0=1;//启动定时器0 

 EX1=1;  //开外部中断1
 IT1=1;               //外部中断1设为下降沿触发
 flag=0;
}

void v_RTInputByte(uchar ucDa)  //往DS1302写入1Byte数据
{
 uchar i;
 ACC = ucDa;
 T_RST = 1;
 for(i=8; i>0; i--)
 {
  T_IO = ACC0;
  T_CLK = 1;
  T_CLK = 0;
  ACC = ACC >> 1;
 }
}
uchar uc_RTOutputByte(void)  //读取1byte数据
{
 uchar i;
 T_RST = 1;
 for(i=8; i>0; i--)
 {
  ACC = ACC >>1;
//  T_IO=1;
  ACC7 = T_IO;
  T_CLK = 1;
  T_CLK = 0;
 }
 return(ACC);
}
void v_W1302(uchar ucAddr, uchar ucDa) //输入   :   ucAddr: DS1302地址, ucDa: 要写的数据
{
 T_RST = 0;
 T_CLK = 0;
 T_RST = 1;
 v_RTInputByte(ucAddr);   // 写地址
 _nop_();
 _nop_();
 v_RTInputByte(ucDa);     // 写1Byte数据
 T_CLK = 1;
 T_RST = 0;
}
uchar uc_R1302(uchar ucAddr)  // 读取DS1302某地址的数据
{
 uchar ucDa;
 T_RST = 0;
 T_CLK = 0;
 T_RST = 1;
 v_RTInputByte(ucAddr);    //写地址,命令
 _nop_();
 _nop_();
 ucDa = uc_RTOutputByte(); //读1Byte数据
 T_CLK = 1;
 T_RST = 0;
 return(ucDa);
}
void keyscan()      //设置时钟的键盘扫描程序
{
 if(flag!=0)
 {
  while(flag)
  {
   if(flag==1)
   {
    write_com(0x80+0x47);
    write_com(0x0f);
   }
   if(flag==2)
   {
    write_com(0x80+0x44);
   }
   if(flag==3)
   {
    write_com(0x80+0x41);
   }       //
    if(up==1)
    {
     if(flag==1)
     {
      sec++;
      if(sec==60)
       sec=0;
     }
     if(flag==2)
     {
      min++;
      if(min==60)
       min=0;
     }
     if(flag==3)
     {
      hour++;
      if(hour==24)
      hour=0;
     }
     up=0;
     display();
    }
 
    if(down==1)
    {
     if(flag==1)
     {
      sec--;
      if(sec==255)
       sec=59;
     }
     if(flag==2)
     {
      min--;
      if(min==255)
       min=59;
     }
     if(flag==3)
     {
      hour--;
      if(hour==255)
      hour=23;
     }
     down=0;
     display();
    }
//      display();
  }
 Write_DS1302Init();   
 }
}
uchar dectobcd(uchar dec)//  DEC码转换为BCD码
{
 uchar bcd;
 bcd = 0;
 while(dec >= 10)
 {             
  dec -= 10;                        
  bcd++;
 }
 bcd <<= 4;
 bcd |= dec;
 return bcd;
}
uchar bcdtodec(uchar bcd)  // BCD码转换为DEC码
{
 uchar data1;
 data1 = bcd & 0x0f;     //取BCD低4位
 bcd = bcd & 0x70;       //剔除BCD的最高位和低4位。
 data1 += bcd >> 1;
 data1 += bcd >> 3;      //用位移代替乘法运算
 return data1;
}
void Write_DS1302Init(void)
{
 sec=dectobcd(sec);
 min=dectobcd(min);
 hour=dectobcd(hour);
 v_W1302(0x8e,0);
 v_W1302(0x80,sec); //写入秒;
 v_W1302(0x82,min); //写入分
 v_W1302(0x84,hour); //写入小时
}

void display()    //1302显示
{
 uchar hourshi,hourge,minshi,minge,secshi,secge;
 hourshi=hour/10;
 hourge=hour%10;
 minshi=min/10;
 minge=min%10;
 secshi=sec/10;
 secge=sec%10;
 write_com(0x80+0x40);
 write_data(0x30+hourshi);
 write_data(0x30+hourge);
 write_data(0x3a);
 write_data(0x30+minshi);
 write_data(0x30+minge);
 write_data(0x3a);
 write_data(0x30+secshi);
 write_data(0x30+secge);  
}

void Run_DS1302(void)   // 读出DS1302中的数据,并在液晶上进行显示
{ uchar dd;
    for(dd=10;dd>0;dd--)   //加入循环,防止速度变化太快,不方便度数
 {
   sec = bcdtodec(uc_R1302(0x81));    //读出DS1302中的秒;
   min = bcdtodec(uc_R1302(0x83));    //读出DS1302中的分
   hour = bcdtodec(uc_R1302(0x85));   //读出DS1302中的小时
   if(hour==0)         //时间校准,每天0:30:30减少15s
   {          
    if(min==30)
    {
     if(sec==45)
     {
       while(sec)
      {
      sec = bcdtodec(uc_R1302(0x81));
      }
      sec=46;
      Write_DS1302Init();
     }
    }
   }
   display();
   keyscan();
   }
}

void write_su(uint dat)//速度显示
{
 uchar shi,ge;
 shi=dat%100/10;
 ge=dat%10;
 write_com(0x80);
 write_data(0x20);
 write_com(0x81);
 write_data(0x30+shi);
 write_data(0x30+ge);
}

void write_s1(uint s1)//一次里程显示
{
 uchar bai,shi,ge,dian;
// wan=s1/10000;     //s1为一次路程,一般不会超过几百km,故无万千位
// qian=s1%10000/1000; 
 bai=s1%10000/1000;
 shi=s1%1000/100;
 ge=s1%100/10;
 dian=s1%10;
 write_com(0x89);
 write_data(0x30+bai);      
 write_data(0x30+shi);
 write_data(0x30+ge);
 write_data(0x2e);
 write_data(0x30+dian);
}

void write_s2(uint s2)//总里程显示
{
 uchar wan,qian,bai,shi,ge,dian;
 wan=s2%1000000/100000;
 qian=s2%100000/10000;
 bai=s2%10000/1000;
 shi=s2%1000/100;
 ge=s2%100/10;
 dian=s2%10;
 write_com(0x80+0x49);
 write_data(0x30+wan);
 write_data(0x30+qian);
 write_data(0x30+bai);
 write_data(0x30+shi);
 write_data(0x30+ge);
 write_data(0x2e);
 write_data(0x30+dian);
}

void main()
{
 init();
 write_com(0x83);
 for(num=0;num<13;num++)    //先显示固定的km/h       km
 {
  write_data(table[num]);
  delay(2);
 }
 write_com(0x80+0x46);
 for(num=0;num<10;num++)       //先显示固定的km
 {
  write_data(table1[num]);
  delay(2);
 }
//   ISP_ERASE(0x2000);     //
//   ISP_PROGRAM(0x2000, 0x05);
//   ISP_ERASE(0x2c01);
//   ISP_PROGRAM(0x2c01, 0x40);
 a=ISP_READ(0x2003);
 delay(20);
 b=ISP_READ(0x2207);  
 s21=a*256+b;   //读出的两个八位合成一个十六位
// s21=248;   //要改,用来清空第一次写入eeprom的数据
 write_s2(s21); //显示开机总里程
 while(1)
 {
  s1=quan*0.65;   //s1为一次路程 这里一圈按0.65m算
  if(s11!=s1)        //如果s1发生了变化
  {
   s2=s21+s1;     //s2为总里程 ,s21为开机读出的里程
   a=s2/256;     //s2为16位,把其分为两个八位分别写入存储器
   b=s2%256;
   ISP_ERASE(0x2003);     // 扇区擦除。无字节擦除
   ISP_PROGRAM(0x2003, a);
   delay(20);
   ISP_ERASE(0x2207);
   ISP_PROGRAM(0x2207, b);  // 将两组数据写向不同扇区
   write_s2(s2);
  }
  s11=s1;
  write_s1(s1);  // 一次路程显示
  delay(100);
  write_com(0x81); //换行
  write_su(bb);   //速度显示
  bb=0;
  Run_DS1302();

 }
}

void timer0() interrupt 1

 TH0=(65536-5000)/256;
 TL0=(65536-5000)%256; //定时器0装初值5ms
 aa++;
}

void exter1() interrupt 2
{
 if(aa>=200)//即车轮转一圈时间超过1秒,认为速度为零
  bb=0;
 if(aa<200)
 {
  time=aa*5;//定时器为5ms,为避免带小数点,此乃为正常时间的1000倍
  bb=65*36/time;//65为车圈周长的100倍,单位为米,bb为整型变量,舍掉速度小数点
 }
 aa=0;
 quan++;   
}
void exter0() interrupt 0
{
     unsigned char j,k,N=0;
     EX1 = 0;  
  delayhw(15);
  if (IRIN==1)
     { EX1 =1;
    return;
   }
                           //确认IR信号出现
  while (!IRIN)            //等IR变为高电平,跳过9ms的前导低电平信号。
    {delayhw(1);}

 for (j=0;j<4;j++)         //收集四组数据
 {
  for (k=0;k<8;k++)        //每组数据有8位
  {
   while (IRIN)            //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
     {delayhw(1);}
    while (!IRIN)          //等 IR 变为高电平
     {delayhw(1);}
     while (IRIN)           //计算IR高电平时长
      {
    delayhw(1);
    N++;          
    if (N>=30)
  { EX1=1;
  return;}                  //0.14ms计数过长自动离开。
      }                        //高电平计数完毕               
     IRCOM[j]=IRCOM[j] >> 1;                  //数据最高位补“0”
     if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;}  //数据最高位补“1”
     N=0;
  }//end for k
 }//end for j
  
   if (IRCOM[2]!=~IRCOM[3])
   { EX1=1;
     return; }

   IRCOM[5]=IRCOM[2] & 0x0F;     //取键码的低四位
   IRCOM[6]=IRCOM[2] >> 4;       //右移4次,高四位变为低四位

   if(IRCOM[5]>9)
    { IRCOM[5]=IRCOM[5]+0x37;}
   else
   IRCOM[5]=IRCOM[5]+0x30;

   if(IRCOM[6]>9)
    { IRCOM[6]=IRCOM[6]+0x37;}
   else
   IRCOM[6]=IRCOM[6]+0x30;   

 if(IRCOM[6]==0x34)
  {
    if(IRCOM[5]==0x35)
   {
     flag=flag+1;
     if(flag==4)
     {
     write_com(0x0c);
      flag=0;
      }
   }
  }
 if(IRCOM[6]==0x34)
  {
    if(IRCOM[5]==0x34)
   {
    down=1;
   }
  } 
 if(IRCOM[6]==0x34)
  {
    if(IRCOM[5]==0x30)
   {
     up=1;
   }
  }
     EX1 = 1;
  return;

}
void delayhw(unsigned char x)    //x*0.14MS  红外延时
{
 unsigned char i;
  while(x--)
 {
  for (i = 0; i<13; i++) {}
 }
}#include<reg52.h>
#include<intrins.h>

#define uchar unsigned char
#define uint unsigned int

#define ISP_BYTE_READ    1  //ISP字节读
#define ISP_BYTE_PROGRAM 2  //ISP直接编程
#define ISP_SECTOR_ERASE 3  //ISP扇区擦除
/*以下是配置STC单片机的寄存器*/
/*相关资料在STC89C51RC的PDF的第35页开始*/
sfr ISP_DATA  = 0xE2;
sfr ISP_ADDRH = 0xE3;
sfr ISP_ADDRL = 0xE4;
sfr ISP_CMD   = 0xE5;
sfr ISP_TRIG  = 0xE6;
sfr ISP_CONTR = 0xE7;

uchar code table[]="km/h       km";
uchar code table1[]="        km";

sbit rs=P2^4;   // 液晶
sbit rw=P2^5;   // 液晶
sbit en=P2^6;   // 液晶
uint aa,time,s1,s11;
uchar num,bb,a,b,up,down;
uchar IRCOM[7];//红外数组
unsigned long int quan,s2,s21;     //

sbit ACC0 = ACC^0;    //1302
sbit ACC7 = ACC^7;    //1302
sbit IRIN = P3^2;         //红外接收器数据线
sbit T_CLK = P3^6; /*实时时钟时钟线引脚 */
sbit T_IO = P3^4; /*实时时钟数据线引脚 */
sbit T_RST = P3^5; /*实时时钟复位线引脚 */
uchar flag;
uchar sec, min, hour;

void Write_DS1302Init(void);
void display();
void delayhw(uchar x);  //x*0.14MS 红外延时
void delay(uint z);//液晶延时

/********************************************************************
* 功能 : EEPROM的扇区擦除
* 输入 : Address(擦除扇区的地址)
***********************************************************************/
void ISP_ERASE(Address)
{
 ISP_ADDRL = Address;
 ISP_ADDRH = Address >> 8;
 ISP_CONTR = 0x81;    
 ISP_CMD = ISP_SECTOR_ERASE; 
 ISP_TRIG = 0x46; //PDF手册中说先像 ISP_TRIG 中写入 0x46, 然后写入 0xb9
 ISP_TRIG = 0xb9;
 _nop_();
 _nop_(); 
}

/********************************************************************
* 输入 : Address(想要读取EEPROM的地址)
*********************************************************************/
uint ISP_READ(Address)
{
 uchar Read_Data;
 ISP_ADDRL = Address;
 ISP_ADDRH = Address >> 8;
// EA = 0; 
 ISP_CONTR = 0x81;
 ISP_CMD = ISP_BYTE_READ;
 ISP_TRIG = 0x46;
 ISP_TRIG = 0xb9;
 _nop_();
 _nop_();
 Read_Data = ISP_DATA;
 return Read_Data; 
}

/********************************************************************
* 输入 : Address为编程的地址,Data_temp为想要编程的值
***********************************************************************/
void ISP_PROGRAM(Address, Data_temp)
{
 ISP_DATA = Data_temp;
 ISP_ADDRL = Address;
 ISP_ADDRH = Address >> 8;
 ISP_CONTR = 0x81;
 ISP_CMD = ISP_BYTE_PROGRAM;
 ISP_TRIG = 0x46;
 ISP_TRIG = 0xb9;
 _nop_();
 _nop_();  
}

void delay(uint z) //液晶延时
{
 uint x,y;
 for(x=110;x>0;x--)
  for(y=z;y>0;y--); 
}

void write_com(uchar com) //液晶写命令
{
 rs=0;
 P0=com;
 delay(1);
 en=1;
 delay(1);
 en=0; 
}
void write_data(uchar date) //液晶写数据
{
 rs=1;
 P0=date;
 delay(1);
 en=1;
 delay(1);
 en=0;
}

void init()
{
 quan=0;
 en=0;
 rw=0;
 aa=0;
 up=0;
 down=0;
 flag=0;
 write_com(0x38);
 write_com(0x0c);
 write_com(0x06);

 EA=1;    //开总中断
 EX0=1;    //开外部中断0
 IT0=1;    //外部中断设为下降沿触发
 ET0=1;     // 开定时器0中断
 TMOD=0x11;//定时器0设定为定时器模式
 TH0=(65536-5000)/256;
 TL0=(65536-5000)%256; //定时器0装初值5ms
 TR0=1;//启动定时器0 

 EX1=1;  //开外部中断1
 IT1=1;               //外部中断1设为下降沿触发
 flag=0;
}

void v_RTInputByte(uchar ucDa)  //往DS1302写入1Byte数据
{
 uchar i;
 ACC = ucDa;
 T_RST = 1;
 for(i=8; i>0; i--)
 {
  T_IO = ACC0;
  T_CLK = 1;
  T_CLK = 0;
  ACC = ACC >> 1;
 }
}
uchar uc_RTOutputByte(void)  //读取1byte数据
{
 uchar i;
 T_RST = 1;
 for(i=8; i>0; i--)
 {
  ACC = ACC >>1;
//  T_IO=1;
  ACC7 = T_IO;
  T_CLK = 1;
  T_CLK = 0;
 }
 return(ACC);
}
void v_W1302(uchar ucAddr, uchar ucDa) //输入   :   ucAddr: DS1302地址, ucDa: 要写的数据
{
 T_RST = 0;
 T_CLK = 0;
 T_RST = 1;
 v_RTInputByte(ucAddr);   // 写地址
 _nop_();
 _nop_();
 v_RTInputByte(ucDa);     // 写1Byte数据
 T_CLK = 1;
 T_RST = 0;
}
uchar uc_R1302(uchar ucAddr)  // 读取DS1302某地址的数据
{
 uchar ucDa;
 T_RST = 0;
 T_CLK = 0;
 T_RST = 1;
 v_RTInputByte(ucAddr);    //写地址,命令
 _nop_();
 _nop_();
 ucDa = uc_RTOutputByte(); //读1Byte数据
 T_CLK = 1;
 T_RST = 0;
 return(ucDa);
}
void keyscan()      //设置时钟的键盘扫描程序
{
 if(flag!=0)
 {
  while(flag)
  {
   if(flag==1)
   {
    write_com(0x80+0x47);
    write_com(0x0f);
   }
   if(flag==2)
   {
    write_com(0x80+0x44);
   }
   if(flag==3)
   {
    write_com(0x80+0x41);
   }       //
    if(up==1)
    {
     if(flag==1)
     {
      sec++;
      if(sec==60)
       sec=0;
     }
     if(flag==2)
     {
      min++;
      if(min==60)
       min=0;
     }
     if(flag==3)
     {
      hour++;
      if(hour==24)
      hour=0;
     }
     up=0;
     display();
    }
 
    if(down==1)
    {
     if(flag==1)
     {
      sec--;
      if(sec==255)
       sec=59;
     }
     if(flag==2)
     {
      min--;
      if(min==255)
       min=59;
     }
     if(flag==3)
     {
      hour--;
      if(hour==255)
      hour=23;
     }
     down=0;
     display();
    }
//      display();
  }
 Write_DS1302Init();   
 }
}
uchar dectobcd(uchar dec)//  DEC码转换为BCD码
{
 uchar bcd;
 bcd = 0;
 while(dec >= 10)
 {             
  dec -= 10;                        
  bcd++;
 }
 bcd <<= 4;
 bcd |= dec;
 return bcd;
}
uchar bcdtodec(uchar bcd)  // BCD码转换为DEC码
{
 uchar data1;
 data1 = bcd & 0x0f;     //取BCD低4位
 bcd = bcd & 0x70;       //剔除BCD的最高位和低4位。
 data1 += bcd >> 1;
 data1 += bcd >> 3;      //用位移代替乘法运算
 return data1;
}
void Write_DS1302Init(void)
{
 sec=dectobcd(sec);
 min=dectobcd(min);
 hour=dectobcd(hour);
 v_W1302(0x8e,0);
 v_W1302(0x80,sec); //写入秒;
 v_W1302(0x82,min); //写入分
 v_W1302(0x84,hour); //写入小时
}

void display()    //1302显示
{
 uchar hourshi,hourge,minshi,minge,secshi,secge;
 hourshi=hour/10;
 hourge=hour%10;
 minshi=min/10;
 minge=min%10;
 secshi=sec/10;
 secge=sec%10;
 write_com(0x80+0x40);
 write_data(0x30+hourshi);
 write_data(0x30+hourge);
 write_data(0x3a);
 write_data(0x30+minshi);
 write_data(0x30+minge);
 write_data(0x3a);
 write_data(0x30+secshi);
 write_data(0x30+secge);  
}

void Run_DS1302(void)   // 读出DS1302中的数据,并在液晶上进行显示
{ uchar dd;
    for(dd=10;dd>0;dd--)   //加入循环,防止速度变化太快,不方便度数
 {
   sec = bcdtodec(uc_R1302(0x81));    //读出DS1302中的秒;
   min = bcdtodec(uc_R1302(0x83));    //读出DS1302中的分
   hour = bcdtodec(uc_R1302(0x85));   //读出DS1302中的小时
   if(hour==0)         //时间校准,每天0:30:30减少15s
   {          
    if(min==30)
    {
     if(sec==45)
     {
       while(sec)
      {
      sec = bcdtodec(uc_R1302(0x81));
      }
      sec=46;
      Write_DS1302Init();
     }
    }
   }
   display();
   keyscan();
   }
}


void write_su(uint dat)//速度显示
{
 uchar shi,ge;
 shi=dat%100/10;
 ge=dat%10;
 write_com(0x80);
 write_data(0x20);
 write_com(0x81);
 write_data(0x30+shi);
 write_data(0x30+ge);
}

void write_s1(uint s1)//一次里程显示
{
 uchar bai,shi,ge,dian;
// wan=s1/10000;     //s1为一次路程,一般不会超过几百km,故无万千位
// qian=s1%10000/1000; 
 bai=s1%10000/1000;
 shi=s1%1000/100;
 ge=s1%100/10;
 dian=s1%10;
 write_com(0x89);
 write_data(0x30+bai);      
 write_data(0x30+shi);
 write_data(0x30+ge);
 write_data(0x2e);
 write_data(0x30+dian);
}

void write_s2(uint s2)//总里程显示
{
 uchar wan,qian,bai,shi,ge,dian;
 wan=s2%1000000/100000;
 qian=s2%100000/10000;
 bai=s2%10000/1000;
 shi=s2%1000/100;
 ge=s2%100/10;
 dian=s2%10;
 write_com(0x80+0x49);
 write_data(0x30+wan);
 write_data(0x30+qian);
 write_data(0x30+bai);
 write_data(0x30+shi);
 write_data(0x30+ge);
 write_data(0x2e);
 write_data(0x30+dian);
}

void main()
{
 init();
 write_com(0x83);
 for(num=0;num<13;num++)    //先显示固定的km/h       km
 {
  write_data(table[num]);
  delay(2);
 }
 write_com(0x80+0x46);
 for(num=0;num<10;num++)       //先显示固定的km
 {
  write_data(table1[num]);
  delay(2);
 }
//   ISP_ERASE(0x2000);     //
//   ISP_PROGRAM(0x2000, 0x05);
//   ISP_ERASE(0x2c01);
//   ISP_PROGRAM(0x2c01, 0x40);
 a=ISP_READ(0x2003);
 delay(20);
 b=ISP_READ(0x2207);  
 s21=a*256+b;   //读出的两个八位合成一个十六位
// s21=248;   //要改,用来清空第一次写入eeprom的数据
 write_s2(s21); //显示开机总里程
 while(1)
 {
  s1=quan*0.65;   //s1为一次路程 这里一圈按0.65m算
  if(s11!=s1)        //如果s1发生了变化
  {
   s2=s21+s1;     //s2为总里程 ,s21为开机读出的里程
   a=s2/256;     //s2为16位,把其分为两个八位分别写入存储器
   b=s2%256;
   ISP_ERASE(0x2003);     // 扇区擦除。无字节擦除
   ISP_PROGRAM(0x2003, a);
   delay(20);
   ISP_ERASE(0x2207);
   ISP_PROGRAM(0x2207, b);  // 将两组数据写向不同扇区
   write_s2(s2);
  }
  s11=s1;
  write_s1(s1);  // 一次路程显示
  delay(100);
  write_com(0x81); //换行
  write_su(bb);   //速度显示
  bb=0;
  Run_DS1302();

 }
}

void timer0() interrupt 1

 TH0=(65536-5000)/256;
 TL0=(65536-5000)%256; //定时器0装初值5ms
 aa++;
}

void exter1() interrupt 2
{
 if(aa>=200)//即车轮转一圈时间超过1秒,认为速度为零
  bb=0;
 if(aa<200)
 {
  time=aa*5;//定时器为5ms,为避免带小数点,此乃为正常时间的1000倍
  bb=65*36/time;//65为车圈周长的100倍,单位为米,bb为整型变量,舍掉速度小数点
 }
 aa=0;
 quan++;   
}
void exter0() interrupt 0
{
     unsigned char j,k,N=0;
     EX1 = 0;  
  delayhw(15);
  if (IRIN==1)
     { EX1 =1;
    return;
   }
                           //确认IR信号出现
  while (!IRIN)            //等IR变为高电平,跳过9ms的前导低电平信号。
    {delayhw(1);}

 for (j=0;j<4;j++)         //收集四组数据
 {
  for (k=0;k<8;k++)        //每组数据有8位
  {
   while (IRIN)            //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
     {delayhw(1);}
    while (!IRIN)          //等 IR 变为高电平
     {delayhw(1);}
     while (IRIN)           //计算IR高电平时长
      {
    delayhw(1);
    N++;          
    if (N>=30)
  { EX1=1;
  return;}                  //0.14ms计数过长自动离开。
      }                        //高电平计数完毕               
     IRCOM[j]=IRCOM[j] >> 1;                  //数据最高位补“0”
     if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;}  //数据最高位补“1”
     N=0;
  }//end for k
 }//end for j
  
   if (IRCOM[2]!=~IRCOM[3])
   { EX1=1;
     return; }

   IRCOM[5]=IRCOM[2] & 0x0F;     //取键码的低四位
   IRCOM[6]=IRCOM[2] >> 4;       //右移4次,高四位变为低四位

   if(IRCOM[5]>9)
    { IRCOM[5]=IRCOM[5]+0x37;}
   else
   IRCOM[5]=IRCOM[5]+0x30;

   if(IRCOM[6]>9)
    { IRCOM[6]=IRCOM[6]+0x37;}
   else
   IRCOM[6]=IRCOM[6]+0x30;   

 if(IRCOM[6]==0x34)
  {
    if(IRCOM[5]==0x35)
   {
     flag=flag+1;
     if(flag==4)
     {
     write_com(0x0c);
      flag=0;
      }
   }
  }
 if(IRCOM[6]==0x34)
  {
    if(IRCOM[5]==0x34)
   {
    down=1;
   }
  } 
 if(IRCOM[6]==0x34)
  {
    if(IRCOM[5]==0x30)
   {
     up=1;
   }
  }
     EX1 = 1;
  return;

}
void delayhw(unsigned char x)    //x*0.14MS  红外延时
{
 unsigned char i;
  while(x--)
 {
  for (i = 0; i<13; i++) {}
 }
}


院士
2011-12-25 23:02:21     打赏
4楼

流水灯实验

视频地址:http://www.tudou.com/v/nA_PvywUGN8/&rpid=104556293/v.swf

/********************************************************************
* 文件名  : 流水灯.c
* 描述    :  该程序实现LED的流水灯显示。
    该程序用于学习 LED流水灯 的控制方法。
    本例中是调用的 intrins.h 中的函数实现的循环移位。  
***********************************************************************/
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint  unsigned int

/********************************************************************
* 名称 : Delay()
* 功能 : 延时,延时时间为 10ms * del
* 输入 : del
* 输出 : 无
***********************************************************************/
void Delay(uint del)
{
 uint i,j;
 for(i=0; i<del; i++)
 for(j=0; j<1827; j++)  
 ;
}

/********************************************************************
* 名称 : Main()
* 功能 : 实现灯的闪烁
* 输入 : 无
* 输出 : 无
* 说明 :也可以使用例1的的方法来关闭数码管
***********************************************************************/
void Main(void)
{
 uchar i;
 P1 = 0x00;
 while(1)
 {
  P1 = 0x7f;     //P1.7亮
  for(i=0; i<7; i++)   //移位7次
  {
   P1 = _cror_(P1, 1);  //_crol_()这个函数在intrins.h中定义了,用于循环右移
   Delay(25);
  }
  P1 = 0xfe;
  for(i=0; i<7; i++)
  {
   P1 = _crol_(P1, 1);     //用于循环左移
   Delay(25);
  }

 }  
}


院士
2011-12-25 23:06:43     打赏
5楼

 

最简单的闪烁灯

/***********************************************************************/
#include<reg52.h>
#define uchar unsigned char   //这里用"uchar"代替"unsigned char","uchar"用来定义无符号字符型数。
#define uint  unsigned int   //"uint"用来定义无符号整型数。
sbit Show_LED = P1^0;    //用来声明P0.0口为程序所要控制的端口,"sbit"是KEIL专门用来声明某位IO口            

/********************************************************************
* 名称 : Delay()
* 功能 : 延时,延时时间为 10ms * del。这是通过软件延时,有一定误差。
* 输入 : del
* 输出 : 无
***********************************************************************/
void Delay(uint del)
{
 uint i,j;
 for(i=0; i<del; i++)
 for(j=0; j<1827; j++)     //这个是通过软件仿真得出的数 
 ;
}

/********************************************************************
* 名称 : Main()
* 功能 : 实现灯的闪烁
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Main(void)
{
 P0 = 0xff;     //用于关闭数码管
 while(1)
 {
  Show_LED = 0;
  Delay(20);  //Delay(del)中的数为延时的时间参数,延时时间为 10ms * del.
  Show_LED = 1;
  Delay(20);
 }
}


院士
2012-01-08 19:05:20     打赏
6楼

花样流水灯

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

void Delay(uint del)
{
 uint i,j;
 for(i=0; i<del; i++)
 for(j=0; j<1827; j++)   
 ;
}

void Main(void)
{
 P0 = 0xff;
 P2 = 0x00;
 while(1)
 {
  /*下面四行用于控制LED每隔一个亮*/
  P1 = 0xaa;  
  Delay(50);
  P1 = 0x55; 
  Delay(50);

  /*下面四行用于控制LED每隔一个亮*/
  P1 = 0xcc;
  Delay(50);
  P1 = 0x33;
  Delay(50);

  /*下面四行用于控制LED 高四位 或者 低四位亮*/
  P1 = 0x0f;
  Delay(50);
  P1 = 0xf0;
  Delay(50);

  /*下面八行用于控制LED的两次全亮 全灭*/
  P1 = 0x00;
  Delay(25);
  P1 = 0xff;
  Delay(25);
  P1 = 0x00;
  Delay(25);
  P1 = 0xff;
  Delay(25);

  Delay(200);  //延时两秒
 }
}


院士
2012-01-08 19:31:20     打赏
7楼

1602显示实验

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

//这三个引脚参考资料
sbit E=P2^6;  //1602使能引脚
sbit RW=P2^5;  //1602读写引脚 
sbit RS=P2^4;  //1602数据/命令选择引脚


void delay()
{
 int i,j;
 for(i=0; i<=10; i++)
 for(j=0; j<=2; j++)
;
}

/*uchar Convert(uchar In_Date)
{
    uchar i, Out_Date = 0, temp = 0;
    for(i=0; i<8; i++)
    {
        temp = (In_Date >> i) & 0x01;
        Out_Date |= (temp << (7 - i));
    }
    return Out_Date;
}    */

void enable(uchar del)
{
 P0 = del;
 RS = 0;
 RW = 0;
 E = 0;
 delay();
 E = 1;
 delay();
}

void write(uchar del)
{
 P0 = del;
 RS = 1;
 RW = 0;
 E = 0;
 delay();
 E = 1;
 delay();
}

void L1602_init(void)
{
 enable(0x01);
 enable(0x38);
 enable(0x0c);
 enable(0x06);
 enable(0xd0);
}

void L1602_char(uchar hang,uchar lie,char sign)
{
 uchar a;
 if(hang == 1) a = 0x80;
 if(hang == 2) a = 0xc0;
 a = a + lie - 1;
 enable(a);
 write(sign);
}

void L1602_string(uchar hang,uchar lie,uchar *p)
{
 uchar a;
 if(hang == 1) a = 0x80;
 if(hang == 2) a = 0xc0;
 a = a + lie - 1;
 enable(a);
 while(1)
 {
  if(*p == '\0') break;
  write(*p);
  p++;
 }
}

void Main()
{
 uchar i = 48;
 L1602_init();
 L1602_char(1,5,'b');
 L1602_string(1,1," EEPW EEPW EEPW   ");
 L1602_string(2,1,"    YSJABCD   ");
 while(1); 
}


院士
2012-01-08 19:48:37     打赏
8楼

定时器应用--秒表


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

uchar Count = 0;
uchar code table[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar code LED_W[8] = {0,4,2,6,1,5,3,7};

void Time0_Init()
{
 TMOD = 0x01;
 IE   = 0x82;
 TH0  = 0x4c;
 TL0  = 0x00; 
 TR0 = 1;  
}
           

void Time0_Int() interrupt 1
{
 TH0 = 0x4c;
 TL0 = 0x00;
 Count++;   //长度加1
}


void main()
{
 uchar i = 0;
 Time0_Init();
 while(1)
 {
  P0 = table[i % 10];   //取 i 的个位
  P2 = LED_W[0];
  while(1)
  {
   if(Count == 20)   //当Count为 20 时,i 自加一次,20 * 50MS = 1S
   {
    Count = 0;
    i++;
    break;
   }
  }
 }
}


院士
2012-01-08 19:54:37     打赏
9楼

数码管滚动显示


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

uchar code table[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar code LED_W[8] = {0,1,2,3,4,5,6,7};
uchar Time_temp = 0, LED_temp = 0;


void Delay(uint i)
{
 uchar x,j;
 for(j=0;j<i;j++)
 for(x=0;x<=148;x++); 
}

void Time0_Init()
{
 TMOD = 0x01;
 IE   = 0x82;
 TH0  = 0x4c;
 TL0  = 0x00; 
 TR0 = 1;  
}

void Time0_Int() interrupt 1
{
 TH0 = 0x4c;
 TL0 = 0x00;
 Time_temp++;
 if(Time_temp == 4)   //定时器溢出时间50毫秒,隔0.2秒,数码管的数据改变一次
 {
  LED_temp++;
  Time_temp = 0;
 }    
}


void Main(void)
{
 uchar i = 0,j = 0;
 Time0_Init();
 while(1)
 {
  P0 = table[(i + LED_temp) % 8];     //数码管段值
  P2 = LED_W[j];                  //点亮某一位数码管
  Delay(2);
  j++;
  i++;
  if(j == 8)                   //每个数码管都点亮了一次。
  {
   j = 0;
   i = 0;
  }
 }
}


院士
2012-01-08 19:57:48     打赏
10楼

温度显示实验--ds18b20


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

#define jump_ROM 0xCC
#define start 0x44
#define read_EEROM 0xBE

sbit DQ = P1^3;            //DS18B20数据口

unsigned char TMPH,TMPL;

uchar code table[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

void delay_1()
{
 int i,j;
 for(i=0; i<=10; i++)
 for(j=0; j<=2; j++)
;
}


void delay(uint N)
{
 int i;
 for(i=0; i<N; i++)
 ;
}


void Delay_1ms(uint i)//1ms延时
{
 uchar x,j;
 for(j=0;j<i;j++)
 for(x=0;x<=148;x++); 
}

uchar Reset(void)
{
 uchar deceive_ready;
 DQ = 0;
 delay(29);
 DQ = 1;
 delay(3);
 deceive_ready = DQ;
 delay(25);
 return(deceive_ready);
}


uchar read_bit(void)
{
 uchar i;
 DQ = 0;
 DQ = 1;
 for(i=0; i<3; i++);
 return(DQ);
}


void write_bit(uchar bitval)
{
DQ=0;if(bitval==1)
DQ=1;
delay(5);
DQ=1;
}


uchar read_byte(void)
{
 uchar i,m,receive_data;
 m = 1;
 receive_data = 0;
 for(i=0; i<8; i++)
 {
  if(read_bit())
  {
   receive_data = receive_data + (m << i);
  }
  delay(6);
 }
 return(receive_data);
}


void write_byte(uchar val)
{
 uchar i,temp;
 for(i=0; i<8; i++)
 {
  temp = val >> i;
  temp = temp & 0x01;
  write_bit(temp);
  delay(5);
 }
}


void main()
{
 float tt;
 uint temp;
 P2 = 0x00;
 while(1)
 {
  Reset();
  write_byte(jump_ROM);
  write_byte(start);
  Reset();
  write_byte(jump_ROM);
  write_byte(read_EEROM);
  TMPL = read_byte();
  TMPH = read_byte();
  temp = TMPL / 16 + TMPH * 16;
  P0 = table[temp/10%10];
  P2 = 6;
  Delay_1ms(5);
  P0 = table[temp%10];
  P2 = 7;
  Delay_1ms(5);
 }
}


共10条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]