jerryqyf 发表于 2009-1-10 23:18:23

9S12C32采用I/O模拟外扩24C16(读写测试程序)【恢复】

产品EOL测试中的EEPROM测试基本程序,第一次自己用IO模拟iic读写24C16

测试程序中利用了PB1上接了一个LED作为指示器,读写过程中作为提示,完成后作为PASS/FAIL的指示。

读写过程中LED闪亮,有点儿像硬盘读写指示灯,完成后全部PASS的话,就亮,否则就灭。

根据说明书,内部写数据最大所需时间为5ms,经过测试发现不同批次的AT24C16这个时间相差很大,相同批次也有一点差别,

但用5ms应该会比较可靠,缩短的话,可能会出现有些EEPROM写不进去。



仅供有需要的弟兄参考,很久没来发帖,贴上程序,拉高下帖高





#include <hidef.h>      /* common defines and macros */

#include <mc9s12c32.h>     /* derivative information */

#pragma LINK_INFO DERIVATIVE "mc9s12c32"







/* IIC operator */

//PS2  SCL   only for out

//PS3  SDA   in and out



#define scl_out PTS_PTS2

#define sda_out PTS_PTS3

#define sda_in  PTIS_PTIS3



#define iic_out() DDRS_DDRS3=1

#define iic_in()  DDRS_DDRS3=0





/**** for eeprom test ****/

//iic delay and eeprom internal write delay

void iic_delay(void){

  uchar i;

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

}

//24C16 internal write time must more than 5mS

void ee_delay(void){

  uint i;

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

}



//start condition,SDA high to low when SCL high

void start(void){

  iic_out();

  sda_out=1;iic_delay();

  scl_out=1;iic_delay();

  sda_out=0;iic_delay();

  scl_out=0;iic_delay();

}

//stop condition,SDA low to high when SCL high

void stop(void){

  iic_out();

  sda_out=0;iic_delay();

  scl_out=1;iic_delay();

  sda_out=1;iic_delay();

}

//data shift out to eeprom,use the SCL positive edge clock

void sh_out(uchar out){

  uchar i;

  iic_out();

  for(i=0;i<8;i++){

    if(out&0x80)sda_out=1;

    else sda_out=0;

    iic_delay();

    scl_out=1;

    iic_delay();

    scl_out=0;

    iic_delay();

    out=out<<1;

  }

  //read ack from eeprom,

  iic_in();

  scl_out=1;

  iic_delay();

  while(sda_in);

  scl_out=0;  

}

//data shift in from eeprom,use the SCL negative edge clock

uchar sh_in(uchar ack_ee){

  uchar i,temp;

  temp=0;

  iic_in();

  //scl_out=0;

  for(i=0;i<8;i++){

    temp=temp<<1;

    if(sda_in)temp=temp|0x01; 

    scl_out=1;

    iic_delay();

    scl_out=0;

    iic_delay();

  }

  //ack for eeprom

  iic_out();

  if(ack_ee)sda_out=0;//ack

  else sda_out=1;//no ack

  iic_delay();

  scl_out=1;

  iic_delay();

  scl_out=0;

  return temp;

}

void write_ee_byte(uchar page,uchar addr,uchar byte_data){

  page=page<<1;

  start();

  sh_out(0xa0|page);

  sh_out(addr);

  sh_out(byte_data);

  stop();

  ee_delay();

}

uchar read_ee_byte(uchar page,uchar addr){

  uchar read_buf;

  page=page<<1;

  start();

  sh_out(0xa0|page);

  sh_out(addr);

  start();

  sh_out(0xa1|page);

  read_buf=sh_in(0);

  stop();

  return read_buf;

}

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





//=============================================================

void main(void) {

  /* put your own code here */

  //EnableInterrupts;

  uchar rdata,page;

  uint i,addr;

  

  //init reg

  DDRS_DDRS2=1;

  DDRB_BIT1=1;

  PORTB_BIT1=1;

  i=0;

  rdata=0;

  //test EEPROM,write&read.

  for(page=0;page<8;page++){

    for(addr=0;addr<256;addr++){

      write_ee_byte(page,addr,0x55);

      if(read_ee_byte(page,addr)==0x55)i++;

      if(i%8==0)PORTB_BIT1=!PORTB_BIT1;

    }

  }

  

  if(i==2048)rdata=1;

  i=0;

  for(page=0;page<8;page++){

    for(addr=0;addr<256;addr++){

      write_ee_byte(page,addr,0xaa);

      if(read_ee_byte(page,addr)==0xaa)i++;

      if(i%8==0)PORTB_BIT1=!PORTB_BIT1;

    }

  }

  if(i==2048)rdata=rdata+1;

  if(rdata==2)PORTB_BIT1=0;

  else PORTB_BIT1=1;

  



  for(;;) {} /* wait forever */

  /* please make sure that you never leave this function */

}

jerryqyf 发表于 2009-1-10 23:20:43

补上,此程序是用codewarrior V4.7 编译,没有写页写和连续读取两种操作函数
页: [1]
查看完整版本: 9S12C32采用I/O模拟外扩24C16(读写测试程序)【恢复】