#include "includes.h"
#define IICCON (*(volatile unsigned *)0x03FFF000) //IIC bus control status register #define IICBUF (*(volatile unsigned *)0x03FFF004) //IIC bus shift buffer register #define IICPS (*(volatile unsigned *)0x03FFF008) //IIC bus prescaler register
#define PAGE_SIZE 16 #define IIC_DEV_0 0xa0 // IIC device's slave address #define S_WRITE 0x00 // Write IIC data for slave #define S_READ 0x01 // Read IIC data for slave
#define BF 0x01 // Buffer flag #define IEN 0x02 // Interrupt enable #define LRB 0x04 // Last bit received/ACK not received #define ACK 0x08 // Ack enable/Generate an ACK signal at 9th SCL #define NOACK 0x00 // No more received data is required from the slave #define START 0x10 #define STOP 0x20 #define RESTART 0x30 #define BUSY 0x40 #define IICRESET 0x80 // Reset the IIC-BUS controller
U16 DrvIicInit() { U16 error = 0; // reset the ICC IICCON = IICRESET; // clock setup, ICC CLK = SysClk/(16 x (prescaker + 1) + 3), 100KHz at 50MHz IICPS = 0x0000001E; // Install Vector // SysSetInterrupt(nIIC_INT, IICisr);
// Enable the INT, Enable_Int(nTIMER1_INT); // Enable_Int(nIIC_INT); return error; }
U16 DrvIicRead(U16 addr, U16 size, U8 *pdata) //RANDOM sequential READ { // U8 block; U16 error = 0, i; // reset the ICC // DrvIicInit();
// wait for not busy while(IICCON & BUSY);
// Send Start: START | ACK IICCON = START | ACK; //置位ack每一byte后自动发一ack // send control byte (write cmd): read block 0 // block = (U8)((addr>>8) & 0xFF); // block <<= 1; // block &= 0x06; // IICBUF = IIC_DEV_0 | S_WRITE | block; IICBUF = IIC_DEV_0 | S_WRITE; //发送写命令 while(!(IICCON & BF)); // send msb address IICBUF = (U8)((addr>>8) & 0xFF); while(!(IICCON & BF));
// send lsb address IICBUF = (U8)(addr & 0xFF); while(!(IICCON & BF)); // send re-start and control byte (read cmd) IICCON = RESTART; IICCON = START | ACK; // IICBUF = IIC_DEV_0 | S_READ | block; IICBUF = IIC_DEV_0 | S_READ; //发送读命令 while(!(IICCON & BF));
// Generate ACK for multi read // IICCON = ACK; // while(!(IICCON & BF));
// Rx Data for(i=0; i<size; i++) //顺序读数 { *pdata++ = IICBUF; while(!(IICCON & BF)); }
// Send NO ACK IICCON = NOACK; //产生no ack while(!(IICCON & BF));
// Send Stop IICCON = STOP; //停止
return error; }
U16 DrvIicWrite(U16 addr, U16 size, U8 *pdata) //PAGE WRITE { U16 i; // U8 block;
// reset the ICC // DrvIicInit();
// wait for not busy while(IICCON & BUSY);
// Send Start: START | ACK IICCON = START | ACK; //自动ACK
// send control byte (write cmd): read block 0 // block = (U8)((addr>>8) & 0xFF); // block <<= 1; // block &= 0x06; // IICBUF = IIC_DEV_0 | S_WRITE | block;
IICBUF = IIC_DEV_0 | S_WRITE; //写命令 while(!(IICCON & BF));
// send msb addr IICBUF = (U8)((addr>>8) & 0xFF); while(!(IICCON & BF));
// send lsb address IICBUF = (U8)(addr & 0xFF); while(!(IICCON & BF)); // Write data for(i=0; i<size; i++) //PAGE WRITE { IICBUF = *pdata++; while(!(IICCON & BF)); }
// STOP IIC Controller IICCON = STOP; //停止 // 5 ms write cycle Delay(5); OSTimeDly(5);
return 0; }
U16 DrvEepromRead(U32 addr, U16 size, U8 *buf) { U16 error;
error = DrvIicRead(addr, size, buf);
return error; }
U16 DrvEepromWrite(U32 addr, U16 size, U8 *pdata) { U8 PageBuf[PAGE_SIZE]; U16 page, no_of_page, error=0, i, remain_byte; no_of_page = size/PAGE_SIZE; remain_byte = size % PAGE_SIZE; if (no_of_page) { for(page=0; page<no_of_page; page++) { for(i=0; i<PAGE_SIZE; i++) PageBuf = *pdata++; DrvIicWrite(addr, PAGE_SIZE, PageBuf); addr += PAGE_SIZE; } } if (remain_byte) { for(i=0; i<remain_byte; i++) PageBuf = *pdata++; DrvIicWrite(addr, remain_byte, PageBuf); }
return error; }
void test_iic(void) { U16 i; U8 a[16],b[16]; DrvIicInit();
for( i = 0; i< 16; i++){ a = 0x41; b = 0x42; } i=DrvEepromWrite(0x0,16,a); i=DrvEepromRead(0x0,16,b); for( i= 0; i < 16; i++){ bintohex_disp(b); //十六进制显示数据 } while(1); }
程序始终不对,显示全FF, 不知什么原因,请大侠帮忙。。。,谢谢
到底该如何使有FS4510的iic呢???