51模拟IIC-页读写操作
51代码页读写IIC--模拟IIC
#include <reg52.h> #include <intrins.h> sbit SDA = P0^0; sbit SCL = P0^1; sbit LED = P2^0; unsigned char code table[] = {0x1c,0X3B,0X2C,0X2D,0X5A,0X5C,0XC5,0X5b}; void delayms(unsigned int t) { unsigned int i,j; for(i = t; i > 0; i --) for(j = 110; j > 0; j --); } void delay() { _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } void start() { SCL = 1; SDA = 1; delay(); SDA = 0; delay(); SCL = 0; } void stop() { SDA = 0; delay(); SCL = 1; delay(); SDA = 1; delay(); } void ack() { SCL = 0; delay(); while(SDA); SCL = 1; delay(); SCL = 0; } void noack() { SCL = 0; SDA = 1; SCL = 1; delay(); SCL = 0; } void writebyte(unsigned char byte) { //MSB first unsigned char i = 0; SCL = 0; for(i = 0; i < 8; i ++) { byte <<= 1; SDA = CY; delay(); SCL = 1; delay(); SCL = 0; } // SDA = 1;//waiting for ack // delay(); } unsigned char readbyte() { unsigned char i = 0,val = 0; SCL = 0; for(i = 0; i < 8 ; i ++) { val <<= 1; delay(); SCL = 1; delay(); if(SDA) { val |= 0x01; } else { val |= 0x00; } SCL = 0; } SCL = 0;//release IIC bus return val; } void write_data(unsigned char add, unsigned char byte) { start(); writebyte(0xae); ack(); writebyte(add); ack(); writebyte(byte); ack(); stop(); } unsigned char read_data(unsigned char add) { unsigned char val = 0; start(); writebyte(0xae); ack(); writebyte(add); ack(); start(); writebyte(0xaf); ack(); val = readbyte(); noack(); stop(); return val; } void pagewrite(unsigned char add) { unsigned char i; start(); writebyte(0xae); ack(); writebyte(add); ack(); for(i = 0; i < 8; i ++) { writebyte(table[i]); ack(); } stop(); } unsigned char *pageread(unsigned char add) { unsigned char value[8],i; start(); writebyte(0xae); ack(); writebyte(add); ack(); start(); writebyte(0xaf); ack(); for(i = 0; i < 8; i ++) { value[i] = readbyte(); if(i == 7) { noack(); } else { SCL = 0; //主机来应答 delay(); SDA = 0; delay(); SCL = 1; delay(); SCL = 0; delay(); SDA = 1; delay(); } delay(); } stop(); return value; } void main() { unsigned char *TMP_VAL, Tmp = 0; /** write_data(0x01,0xAC); //TEST 1 delayms(500); Tmp = read_data(0x01); delayms(5); if(Tmp == 0xac) { P2 = Tmp; } **/ /** pagewrite(0X00); //TEST2 delayms(500); Tmp = read_data(0x07); delayms(5); if(Tmp == table[7]) { P2 = Tmp; } **/ pagewrite(0X00); delayms(600); TMP_VAL = pageread(0x00); delayms(500); if(*(TMP_VAL+1) == table[1]) { P2 = *(TMP_VAL+1); } while(1); }
注意以下要点
过程中出现只能写入偶数情况,是Stop()函数的问题,在SCL上升沿时发生了SDA改变导致的,调整一下先后顺序即可;
页读操作注意ack是主机拉低SDA发出的应答,和单字节读写不同;
如何接收函数返回的数组,以及如何写这个返回数组的函数。
调试过程中有EE不拉低SDA应答的情况,后来排查是EE芯片坏了。
写完数据不能立刻读,要有稍长的延时才行。