×
单片机 > 单片机程序设计 > 详情

实用的单片机模拟I2C总线控制EEPROM读写程序

发布时间:2020-05-30 发布时间:
|
之前写的EEPROM程序虽然能够软仿成功,但烧到单片机里的时候却不能用,无疑是时序的问题,今天修正了时序,总算硬仿成功了。对照上次的程序可以发现就是添加了头函数:,这样就可以通过“_nop_()”指令较为准确的控制时序。

上次那个问题依然没有解决:就是接收缓冲区的数据是从readbuf[6]开始的,以这个程序为例:

readbuf[6]中存放0x96

readbuf[7]中存放0x84

readbuf[8]中存放0xd5

readbuf[9]中存放0x63

readbuf[10]中存放0x7c

readbuf[11]中存放0x8c

其实我是想把收到的数据存放在readbuf[0]~[5]中的,我也不知道为什么结果会这样,有知道的麻烦指教下。

不多说了,上程序:

#include
#include
#define unit unsigned int
#define uchar unsigned char

uchar num=6;
uchar idata sendbuf[6]={0x96,0x84,0xd5,0x63,0x7c,0x8c};
uchar idata readbuf[6];

sbit scl=P2^0;          
sbit sda=P2^1;

start(void)            //start
{
  sda=1;
  _nop_();
  _nop_();
  scl=1;
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  sda=0;
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  scl=0;
}

stop(void)         //stop
{
  sda=0;
  _nop_();
  _nop_();
  scl=1;
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  sda=1;
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  scl=0;
}

answer(void)        //answer
{
  sda=0;
  _nop_();
  _nop_();
  _nop_();
  scl=1;
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  scl=0;
}

noanswer(void)     //no answer
{
  sda=1;
  _nop_();
  _nop_();
  _nop_();
  scl=1;
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  scl=0; 
}

checkanswer(void)       //check answer
{
  F0=0;
  sda=1;
  _nop_();
  _nop_();
  scl=1;
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  if(sda==1) F0=1;
  scl=0; 
}

sendabyte(uchar idata *saddress)        //send a byte
{
  uchar n=8,temp=*saddress;
  while(n--)
  {
    if((temp&0x80)==0x80) sda=1;
 else sda=0;
 _nop_();
 scl=1;
 _nop_();
 _nop_();
 _nop_();
 _nop_();
 _nop_();
 scl=0;
 temp=temp<<1;
  }
  checkanswer();
  if(F0==1) return;
}

sendnbyte(uchar n)                     //send n byte
{
  uchar idata *ps; 
  ps=&sendbuf[0];

  while(n--)
  {
   sendabyte(ps);
 ps++;
  }
  stop();
}

readabyte(uchar idata *raddress)         //read a byte
{
  uchar n=8,temp=0;
  while(n--)
  { 
    _nop_();
 _nop_();       
   scl=1;
 _nop_();
 _nop_();
 temp=temp<<1;
 if(sda==1)
   temp=temp|0x01;
 else
   temp=temp&0xfe;
 _nop_();
 _nop_();
 _nop_();
 scl=0;
 _nop_();
 _nop_();
 _nop_();
  }
  *raddress=temp;
}

readnbyte(uchar n)                 //read n byte
{
  uchar idata *pr;
  pr=&readbuf[0];
  while(n--)
  {
    readabyte(pr);
 answer();
 pr++;
  }
  noanswer();
  stop();
}

main(void)                       //MAIN
{
start();

sendabyte(0xa0);

sendabyte(0x00);

sendnbyte(num);

/*-----------------------*/
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();

start();

sendabyte(0xa0);

sendabyte(0x00);

sendabyte(0xa1);

readnbyte(num);

P1=readbuf[11];

while(1);
}



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
STM32中断向量表的位置.重定向