专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

用430写的IIC总线协议:24C02掉电记忆程序(数码管显示)

作者:我行天下   来源:本站原创   点击数:  更新时间:2014年03月30日   【字体:

#include <msp430x14x.h>
#define OP_READ 0xa1        // 器件地址以及读取操作  
#define OP_WRITE 0xa0       // 器件地址以及写入操作  
#define uchar unsigned char
#define uint unsigned int
 #define SDA_OUT  P1DIR|=BIT3
#define SDA_IN  P1DIR&=~BIT3
#define SCL_OUT  P1DIR|=BIT2
#define SCL_IN  P1DIR&=~BIT2
 #define SDA_H  P1OUT|=BIT3
#define SDA_L  P1OUT&=~BIT3
#define SCL_H  P1OUT|=BIT2
#define SCL_L  P1OUT&=~BIT2
#define wei_h P5OUT|= BIT5
#define wei_l P5OUT&= ~BIT5
#define duan_l   P6OUT &= ~BIT6
#define duan_h  P6OUT |= BIT6
//数码管7位段码:0--f
uchar table[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                    0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//记录显示位数的全局变量
uchar miao;
uchar write;
  //8M晶振时大约20us延时程序
void delayus(uint z)
{
    uint i,j;
    for(i = 0;i<20;i++)
      for(j=0;j<z;j++)
      {;;};
}
// 开始位  
void start() 

    SDA_OUT;
    SCL_OUT;
    SDA_H; 
    SCL_H; 
    delayus(1); //20
    SDA_L; 
    delayus(2);//40
    SCL_L; 

// 停止位
void stop()  

    SDA_OUT;
    SCL_OUT;
    SDA_L;  
  
    delayus(2);//20 
    SCL_H; 
    delayus(2);
    SDA_H; 
}   
// 从AT24Cxx移入数据到MCU  
uchar shin() 

    uchar i,read_data;
    SDA_OUT;
    SCL_OUT;
    for(i = 0; i < 8; i++) 
    { 
        SDA_H;
        delayus(1);
        SCL_H;
        SDA_IN;
        read_data <<= 1;    
        if(P1IN&BIT3)
          read_data|=0x01;
        SDA_OUT;      
        SCL_L; 
    }
    return(read_data); 

// 从MCU移出数据到AT24Cxx  
uchar shout(uint write_data) 

    uchar i; 
    uchar ack_bit;
    SDA_OUT;
    SCL_OUT;
    for(i = 0; i < 8; i++)       // 循环移入8个位  
    {      
          if(write_data&0x80)
          SDA_H;
          else
          SDA_L;
        delayus(2);//2
        SCL_H; 
        delayus(2);//2 
        SCL_L; 
        delayus(2);//2
        write_data <<= 1; 
    }
  
    SDA_H;  // 读取应答  
    delayus(2);
    SCL_H;  //注意拉高
    delayus(2);
    SDA_IN;
    if(P1IN&BIT3)
      ack_bit=1;
    else ack_bit=0;
    SCL_L; 
    return ack_bit; // 返回AT24Cxx应答位  
}    
// 在指定地址addr处写入数据write_data  
void write_byte(uchar addr, uchar write_data) 

    SDA_OUT;
    SCL_OUT;
    SDA_H; 
    SCL_H;
    start(); 
    shout(OP_WRITE); 
    shout(addr); 
    shout(write_data); 
    stop(); 
    delayus(1000);// 写入周期  
}       
// 在当前地址读取  
uint read_current() 

    uint read_data; 
    start(); 
    shout(OP_READ); 
    read_data = shin(); 
    stop(); 
    return read_data; 

 
// 在指定地址读取  
uchar read_random(uint random_addr) 

    SDA_IN;
    SCL_OUT;
    SDA_H; 
    SCL_H;
    start(); 
    shout(OP_WRITE); 
    shout(random_addr); 
    return(read_current()); 
}

void display(uchar dat)
{
  P4OUT = table[dat];//输出段选信号
  duan_h;
  duan_l;
  P4OUT = 0x00; //设置P4,P5的输出初值
  wei_h;
  wei_l;
}

void Clock(void)
{
miao++;
 if(miao==10)
   miao=0;
}

int main( void )
{
   /*下面六行程序关闭所有的IO口*/
    P1DIR = 0XFF;P1OUT = 0XFF;
    P2DIR = 0XFF;P2OUT = 0XFF;
    P3DIR = 0XFF;P3OUT = 0XFF;
    P4DIR = 0XFF;P4OUT = 0XFF;
    P5DIR = 0XFF;P5OUT = 0XFF;
    P6DIR = 0XFF;P6OUT = 0XFF;
  
  
    SDA_OUT;
    SCL_OUT;
    SDA_H; 
    SCL_H;
 
 
     WDTCTL = WDTPW + WDTHOLD;
     CCR0 = 32768 - 1;//设置定时器A的中断时间为1S
    TACTL = TASSEL_1 + MC_1; //计数时钟ACLK, 增计数模式
    CCTL0 |= CCIE; //使能CCR0比较中断
    _EINT();//打开全局中断
  
 
     miao=read_random(3) ;//从地址2中读出以前保存的数据
     if(miao>9)    miao=0; //防止首次读出错误数据
  
      while(1)
      {
          display(miao);
        if(write==1)
      {
    write=0;
                  write_byte(3,miao);
   }
      
     LPM3;//进入LPM3低功耗模式
          
      }
}

/*******************************************
函数名称:TimerA_ISR
功    能:定时器A的中断服务函数
********************************************/
#pragma vector=TIMERA0_VECTOR
__interrupt void TimerA_ISR(void)
{
    Clock();
    write=1;
   LPM3_EXIT;
}

关闭窗口

相关文章