51/AVR单片机技术驿站!  <在线翻译> 淘宝店    便利工具    特色网址   打造无弹窗、无插件的绿色站点...  英才招聘   学历查询  喜欢>>收藏我站 

 首页>> 常规知识 电路图集 学习MCU 单片机文章 查器件PDF 下载中心 单片机教程 学习产品 购买联系 在线留言 RRS
当前位置:首页 > ◆本站实例 > 详细内容
键盘+可调时钟+计算器+I2C闹钟(ADC0809扩展)
作者:月夜听风 来源:微控实验网  发布时间:2009-3-10  阅读次数:3466  字体大小: 【】 【】【

//*************************************************
//需要用到ADC0809,我站XY806学习开发板例程(停产)
//原创:月夜听风Sidney QQ479780666 www.mcusy.cn(学习参考、转载须注明)
//有条件的朋友通过程序端口描述可完成电路制作,程序若发现BUG请指正
//*************************************************
#include
#include
#include

#define uchar unsigned char
#define uint unsigned int
#define IN0 XBYTE[0x1ff8]
#define IN1 XBYTE[0x1ff9]
#define PA8255 XBYTE[0x3ffc]
#define PB8255 XBYTE[0x3ffd]
#define PC8255 XBYTE[0x3ffe]           
#define COM8255 XBYTE[0x3fff]
#define CW_ADD XBYTE[0x5ffc] //写命令口
#define CR_ADD XBYTE[0x5ffd]  //读状态口
#define DW_ADD XBYTE[0x5ffe]    //写数据口       
#define DW_ADDXBYTE[0x5fff]  //读数据口
#define Busy 0x80     //忙标志,D7位为1说明忙
#define WriteDeviceAddress 0xa0 //I2C写格式
#define ReadDviceAddress 0xa1 //I2C读格式

void Keyscan(void); 
void Delay(uchar i);
void Tbz_send();
void Sbz_send();
void Jbz_send();
void Sbcd_send();
void Abz_send();
void CheckBusy( void);//读忙状态函数
void WriteIR(uchar CMD,uchar AttribC);//写入IR寄存器命令函数
void WriteDDR( char c );//写入DDR寄存器函数
void d_sendCGRAM(uchar *c);//造字。年。月。日
void LcdPos(uchar Xpos,uchar Ypos);//光标定位函数
void LcdReset( void );//初始化函数
void WriteChar(uchar Xpos,uchar Ypos,char c);//指定行列显示字符函数
void WriteString(uchar Xpos,uchar Ypos,char s[]);//显示字符串函数
void Lcdx(void);//Lcd显示函数
void Lcdclr();//
void Lcd_xian();
void Shbz_send();//闹钟设定函数

void DelayMs(uchar number);
void Start();
void Stop();
void Ack();  //应答格式
void NoAck(); //非应答格式
bit TestAck(); //检查应答的ACK
void Write8Bit(uchar input);//写一个字节
void Write24c02(uchar *Wdata,uchar RomAddress, //写入I2C程序
                          uchar number);
uchar Read8Bit();  //读一个字节
void Read24c02(uchar *RamAddress,uchar RomAddress, //读出I2C程序
                         uchar bytes) ;


bit Tbz;//调整时间启动标志
bit Jbz;//键盘输入启动标志
bit Sbz;//计算器启动标志
bit Abz;//ADC0809启动标志
bit Axbz;//Axbz=1时显示IN0 Axbz=0时显示IN1
bit Ainx;//ADC0809目前转换目标
bit Shbz;//进入闹钟设定标志
bit T05s;//0。5秒记时到标志
bit Th=1;//正在调整小时标志
bit Tm;//正在调整分钟标志
bit Yqbz=1;//操作数和被操作数选择
bit jia,jian,cheng,chu,deng,qing,xbz1,xbz2,xbz3,xbz4,xbz5,xbz6;
bit slbz=1,skbz=1;

sbit led0=P1^0;
sbit led1=P1^1;
sbit led2=P1^2;
sbit led3=P1^3;
sbit cs138=P1^6;
sbit P32=P3^2;
sbit DOG=P3^7;
sbit SCL=P1^4;
sbit SDA=P1^5;
uchar Jiukey,Key,s,m,jm=100,h,a,b,c,d,a1,b1,c1,d1,e1,f1,kk;
uchar day,month,year,shiji=20;


uchar ADCValue[2];//IN0,IN1数值存储区
uchar Adcx0[4];//IN1显示存储区
uchar Adcx1[4];//IN0显示存储区
uchar Sh[3]; //闹钟设置存储区
uint tmpp,ab,cd;//ji suan qi
uchar Xpos;  //LCD列方向地址指针
uchar Ypos;  //LCD行方向地址指针

uchar  code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
     0x77,0x7c,0x39,0x5e,0x79,0x71};//0~f

uchar  code tab1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};//0~9带小数点
     

uchar  code zm[]={0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02,
      0x0f,0x09,0x0f,0x09,0x0f,0x09,0x11,0x00,
      0x0f,0x09,0x09,0x0f,0x09,0x09,0x0f,0x00};//造字,年月日

void main(void)
{
 
 cs138=0;
 Delay(1);
 d_sendCGRAM(&zm);  //造字。年。月。日
    LcdReset();          // LCD模块初始化
    Delay(5);          //延是等待复位
 Read24c02(Sh,0x00,3);//读程序从0X00单元开始,读出3个字节
 COM8255=0X88;
 TMOD=0x11;         //定时器0工作于定时方式1,定时器1工作于定时方式1
  TH0=(65536-46080)/256;
 TL0=(65536-46080)%256; //定时时间为50MS
 TH1=(65536-9000)/256;
 TL1=(65536-9000)%256;//
 IE=0X8A;   // EA=1;ET1=1;ET0=1;
 TR0=1;           //计数器0开始运行
 TR1=1;     //计数器1开始运行

 

 while(1)
    {
 Keyscan();//键盘扫描程序
 Lcd_xian();//lcd显示程序
 if(Jiukey!=Key)
    {

       Jiukey=Key;
          if(Tbz)Tbz_send();   //启动调时间函数
       else if(Sbz)Sbz_send();  //启动计算器函数
       else if(Jbz)Jbz_send();  //启动键盘函数
       else if(Abz)Abz_send();  //启动ADC转换函数
       else if(Shbz)Shbz_send(); //启动闹钟设定程序


    }
  }
}


void Keyscan()   //键盘扫描程序***********

  uchar temph,templ,temp;
  COM8255=0X88;
  temph=PC8255;
  temph&=0xf0;
   COM8255=0x81;
   templ=PC8255;
   templ&=0x0f;
  temp=(temph|templ);

     switch(temp)
        {
       case 0xee:Key=0;break;
        case 0xde:Key=1;break;
         case 0xbe:Key=2;break;
         case 0x7e:Key=3;break;

       case 0xed:Key=4;break;
        case 0xdd:Key=5;break;
         case 0xbd:Key=6;break;
         case 0x7d:Key=7;break;

       case 0xeb:Key=8;break;
        case 0xdb:Key=9;break;
         case 0xbb:Key=10;break;
         case 0x7b:Key=11;break;

       case 0xe7:Key=12;break;
        case 0xd7:Key=13;break;
         case 0xb7:Key=14;break;
         case 0x77:Key=15;break;
     
      case 0xce:{Jbz=0;Jbz=0;Abz=0;Shbz=0;Tbz=1;}break;//0+1调整时间启动标志
      case 0x9e:{Tbz=0;Sbz=0;Abz=0;Shbz=0;Jbz=1;}break;//1+2键盘输入启动标志
      case 0x3e:{Jbz=0;Tbz=0;Abz=0;Shbz=0;Sbz=1;}break;//2+3计算器启动标志
      case 0xae:{Jbz=0;Jbz=0;Abz=0;Tbz=0;Shbz=1;}break;//0+2调整闹钟启动标志
      case 0x5e:{Tbz=0;Jbz=0;Sbz=0;Shbz=0;Abz=1;}break;//1+3ADC0809转换启动标志
      case 0x6e:{Tbz=0;Jbz=0;Abz=0;Sbz=0;Shbz=0;slbz=1;skbz=1;}break;//0+3全部清零显示时间
     
      default:Jiukey=Key=16;
      }


}

void Tbz_send()//调时间程序
{


   if(Key==0)kk++; //模式切换键
   else if(Key==1)//加一键
     {
     switch(kk)
       {
       case 0:{if(year==99)year=0;year++;}break;
          case 1:{month++; if(month>12)month=0;}break;
          case 2:{day++;if(day>30)day=0;}break;
          case 3:{h++;if(h>23)h=0;}break;
          case 4:{m++;if(m>59)m=0;}break;
       case 5:kk=0;break;
       }
      }

   else if(Key==2) //减一键
     {
     switch(kk)
       {
       case 0:{if(year==0)year=99;else {year--;}}break;
          case 1:{if(month==0)month=12;else{ month--;}}break;
          case 2:{if(day==0)day=30;else {day--;}}break;
          case 3:{if(h==0)h=23;else {h--;}}break;
          case 4:{if(m==0)m=59;else {m--;}}break;
       case 6:kk=0;break;
       }
     }

 

   else if(Key==3){Tbz=0;kk=0;}//确认并返回键  
   if(kk>5)kk=0;


}


void Jbz_send()//键盘输入程序
{
 if(Jbz)    
  {
  a=b;b=c;c=d;d=Key;
  } 
}
void Sbz_send() //计算器输入标志
{

    
 if(Key<=9)
   {
   if(Yqbz){Delay(3);ab=(ab*10);ab=(ab+Key);Sbcd_send();} //选择操作数和被操作数
   else{Delay(3);cd=(cd*10);cd=(cd+Key);Sbcd_send();}  
   }
        
 else if(Key>9)
   {
   switch(Key)
     {
     case 10:{tmpp=0;ab=cd=0;Yqbz=1;jia=jian=cheng=chu=deng=0;Sbcd_send(); }break;     
     case 12:{Yqbz=0;jia=1;}break;
     case 13:{Yqbz=0;jian=1;}break;
     case 14:{Yqbz=0;cheng=1;}break;
     case 15:{Yqbz=0;chu=1;}break; //
     case 11:{
       deng=1;Yqbz=1; 
       if(jia){tmpp=(ab+cd);}
       else if(jian){tmpp=(ab-cd);}
       else if(cheng){tmpp=(ab*cd);}
       else if(chu){tmpp=(ab/cd);}
       Sbcd_send();
       }break;
      }
    }

}
void Abz_send() //ADC0809转换启动程序
{

 while(Abz)
  {

  Keyscan();
  if(Key==0)Axbz=!Axbz; //显示IN0.IN1切换
  while(P32);
  ADCValue[0]=IN0;Sbcd_send();IN1=0;
  while(P32);
  ADCValue[1]=IN1;Sbcd_send();IN0=0;
  Delay(100);
  Lcd_xian();
  }
  
}

void Shbz_send()//闹钟设定程序

{


   if(Key==0)kk++; //模式切换键
   else if(Key==1)//加一键
     {
     switch(kk)
       {
       case 0:{if(Sh[0]>23)Sh[0]=0;Sh[0]++;}break;
          case 1:{if(Sh[1]>59)Sh[1]=0;Sh[1]++;}break;
          case 2:{if(Sh[2]>0)Sh[2]=0;Sh[2]=1;}break;
          case 3:{kk=0;}break;
       }
      }

   else if(Key==2) //减一键
     {
     switch(kk)
       {
       case 0:{if(Sh[0]==0)Sh[0]=23; Sh[0]--;}break;
          case 1:{if(Sh[1]==0)Sh[0]=59; Sh[1]--;}break;
          case 2:{if(Sh[2]==0)Sh[2]=1;Sh[2]=0;}break;
          case 3:{kk=0;}break;
       }
     }

 

   else if(Key==3){Write24c02(Sh,0x00,3);}//确认并返回键//写程序从0X00单元开始,写入3个字节  
   if(kk>3)kk=0;


}


void Sbcd_send()
{  
  uint abcd,ADCzh;   
  if(Abz)//ADC显示转换区
    {
    ADCzh=ADCValue[0];
    ADCzh=(ADCzh*196);
    ADCzh/=10;
    Adcx0[4]=ADCzh%10;
    ADCzh/=10;
    Adcx0[3]=ADCzh%10;
    ADCzh/=10;
    Adcx0[2]=ADCzh%10;
    Adcx0[1]=ADCzh/10;

    ADCzh=ADCValue[1];
    ADCzh=(ADCzh*196);
    ADCzh/=10;
    Adcx1[4]=ADCzh%10;
    ADCzh/=10;
    Adcx1[3]=ADCzh%10;
    ADCzh/=10;
    Adcx1[2]=ADCzh%10;
    Adcx1[1]=ADCzh/10;
    }
  
  else{ //计算器显示转换区
    if(deng)
     {
     f1=tmpp%10;
     tmpp/=10;
     e1=tmpp%10;
     tmpp/=10;
     d1=tmpp%10;
     tmpp/=10;
     c1=tmpp%10;
     b1=tmpp/10;
   
     }
    else if(Yqbz)
     {
     abcd=ab;
     f1=abcd%10;
     abcd/=10;
     e1=abcd%10;
     abcd/=10;
     d1=abcd%10;
     abcd/=10;
     c1=abcd%10;
     b1=abcd/10;
 
     }
    else
     {
     abcd=cd;
     f1=abcd%10;
     abcd/=10;
     e1=abcd%10;
     abcd/=10;
     d1=abcd%10;
     abcd/=10;
     c1=abcd%10;
     b1=abcd/10;

     }
   }
}

/**************************I2C操作程序////
/**************************/
/**************************/

void DelayMs(uchar number)
{
 uchar temp;
 for(;number!=0;number--,DOG=!DOG)
  {
  for(temp=112;temp!=0;temp--) {}
  }

/*******************启动I2C*/
void Start()
{
 SDA=1;
 SCL=1;
 SDA=0;
 SCL=0;
}

/*********************///停止I2C
void Stop()
{
 SCL=0;
 SDA=0;
 SCL=1;
 SDA=1;
}
/**********************/
void Ack()  //应答格式
{
 SDA=0;
 SCL=1;
 SCL=0;
 SDA=1;
}

/***********************/
void NoAck()  //应答格式
{
 SDA=1;
 SCL=1;
 SCL=0;
}

/*************************************/
bit TestAck() //检查应答的ACK
{
 bit ErrorBit;
 SDA=1;
 SCL=1;
 ErrorBit=SDA;
 SCL=0;
 return(ErrorBit);
}

/*************************************/
void Write8Bit(uchar input) //写一个字节
{
 uchar temp;
 for(temp=8;temp!=0;temp--)
  {
  if(input&0x80)SDA=1;
  else SDA=0;
  SCL=1;
  SCL=0;
  input=input<<1;
  }
}

1 2  下一页
来源:微控实验网
我要评论
  • 匿名发表
  • [添加到收藏夹]
  • 发表评论:(匿名发表无需登录,已登录用户可直接发表。) 登录状态:未登录
最新评论
    暂无已审核评论!

网站导航 管理登陆 ┊ 免责声明 问题反馈  友链说明
本站部分内容来自网络共享资源,如有冒犯您的权利请来信告之删除或纠正!
不得对本站进行复制、盗链或镜像,转载内容须获得同意或授权;欢迎友情链接、站务合作!

    我要报警 Alexa
 mcusy_cn#126.com (请把#改成@) 交流:479780666 522422171 86-0755-28650237
本站学习交流群:138..158(高级群1-)、77930286(高级群2)、61804809(群3)
Copyright© MCUSY All Rights Reserved
本站网警备案号: WZ36040002485
  ICP备案证书号:粤ICP备09034963号