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

当前位置:首页 > ◆本站实例 > 详细内容
键盘+可调时钟+计算器+I2C闹钟(ADC0809扩展)
作者:月夜听风 来源:微控实验网  发布时间:2009/3/10  阅读次数:7631  字体大小: 【】 【】【

//*************************************************
//需要用到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;
    }
}

来源:微控实验网
我要评论
  • 匿名发表
  • [添加到收藏夹]
  • 发表评论:(匿名发表无需登录,已登录用户可直接发表。) 登录状态:未登录
最新评论
  • 评论人:[匿名] 时间: [2019/12/6 23:54:58] IP:[5.153.178.9*]
  • 8TD 2826cc NEW ROK Manual Lock Free Wheel Hubs Nissan GQ GU Patrol Ford Maverick Y60 Y61. .. Excellent Value for Money. The Adventure Kings 12v Accessory Panel is the best way to access your camping 12v systems battery a href=http//makemoneyonlinemoney.info/the-universal-mary-sue-litmus-test-simple-ways-to-make-moneysimple ways to make money/a
  • 评论人:[匿名] 时间: [2019/12/6 20:29:32] IP:[5.153.178.9*]
  • ately after removal of pressure, Stram.; elevated red blotches, in palms, Fluor. ac.; bright red spot on ball of right, with itching in evening, Sep.; red, hard spot on skin, Hands, fever; shaking begins (intermittent), LIGels. af Hands, formication a href=http//itchypatchesonskin.ml/organic-riot-dazzle-serum-for-even-skin-tone-perfect-skin-care-for-dry-itchydry itchy patches on skin/a
  • 评论人:[匿名] 时间: [2019/11/23 9:30:13] IP:[5.153.178.9*]
  • 1 hour ago Getting your moneys worth plan your dining Outside of meal plans and points, there are ways to save money during Judiciary rules Student Union President and Vice President violated constitution, Senate responds. a href=http//howtosavemoneyfast.cf/are-snail-creams-good-for-your-how-to-save-your-money-fast-skinhow to save your money fast/a
  • 评论人:[匿名] 时间: [2019/11/5 18:40:48] IP:[5.153.178.9*]
  • Home. There is no doubt; insects have the capability of being the creepiest Learn about different insect parts, which insects can walk on water, how ants The damage is mostly unsightly but, in the long-term, may kill the branches they feed on. EDIS is the Electronic Data Information Source of UF/IFAS Extension, a href=http//howtogetridofantsinhouse.ga/inground-how-to-get-rid-of-sugar-ants-in-the-house-liners-bloghow to get rid of sugar ants in the house/a
  • 评论人:[匿名] 时间: [2019/10/15 12:08:48] IP:[5.153.178.9*]
  • Introduction. While dental software has been around since the 1980s, few dentists can say they have a truly вpaperlessв office. Practice management systems such as Dentrix, Carestream Health, and DentiMax have seen widespread adoption, but fewer dentists use software for charting or clinical documentation. a href=http//dentures.denta.top/art/affordable-dentures/Affordable dentures/a

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

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