板子上设置了EEPROM存储器,型号为AT24C02。
板子的硬件连接为:SCL--->P2.4,SDA--->P2.5。
直接了当,贴上程序!
========================24cxx.h文件=========================#ifndef _24CXX_H_#define _24CXX_H_#include <msp430x14x.h>#define WRITE_ADDR 0xA0 //A0 A1 A2均接地#define READ_ADDR 0xA1 //A0 A1 A2均接地#define SDA_BIT BIT5#define SCL_BIT BIT4#define IIC_PORT_DIR P2DIR#define IIC_PORT_DATA P2OUT#define SDA_BIT_DATA (P2IN & BIT5)#define SDA_OUT (IIC_PORT_DIR |= SDA_BIT)#define SDA_IN (IIC_PORT_DIR &= ~SDA_BIT)#define SDA_1 (IIC_PORT_DATA |= SDA_BIT)#define SDA_0 (IIC_PORT_DATA &= ~SDA_BIT)#define SCL_IN (IIC_PORT_DIR &= ~SCL_BIT)#define SCL_OUT (IIC_PORT_DIR |= SCL_BIT)#define SCL_1 (IIC_PORT_DATA |= SCL_BIT)#define SCL_0 (IIC_PORT_DATA &= ~SCL_BIT)void init_iic(void);void iic_start(void);void iic_stop(void);void iic_ack(void);void iic_no_ack(void);unsigned char iic_test_ack(void);void iic_write(unsigned char data);unsigned char iic_read(void);unsigned char iic_write_data(unsigned char StartAddress,unsigned char *date,unsigned char bytes);unsigned char iic_read_data(unsigned char StartAddress,unsigned char *date,unsigned char bytes);#endif
========================24cxx.c文件=========================#include "24cxx.h" #include "main.h" //实际上需要包含延时#define CPU_F ((double)8000000) //#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0)) //#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))/**IIC端口初始化*/void init_iic(void){ SCL_OUT; //SCL管脚为输出 SDA_IN; //SDA管脚为输入 SCL_0; iic_stop();}/**IIC起始状态*/void iic_start(void){ SDA_OUT; SDA_1; delay_us(5); SCL_1; delay_us(5); SDA_0; delay_us(5); SCL_0; delay_us(5);}/**IIC停止状态*/void iic_stop(void){ SDA_OUT; SCL_0; delay_us(5); SDA_0; delay_us(5); SCL_1; delay_us(5); SDA_1; delay_us(5);}/**IIC应答*/void iic_ack(void){ SDA_OUT; SDA_0; delay_us(5); SCL_1; delay_us(5); SCL_0; delay_us(5); SDA_1;}/**IIC无应答*/void iic_no_ack(void){ SDA_OUT; SDA_1; delay_us(5); SCL_1; delay_us(5); SCL_0; delay_us(5);}/**IIC检测回应*/unsigned char iic_test_ack(void ){ unsigned char tmp; SDA_IN; //设为输入 delay_us(5); SCL_1; delay_us(5); tmp = SDA_BIT_DATA>>4; delay_us(5); SCL_0; delay_us(5); return(tmp);}/**IIC写字节*/void iic_write(unsigned char data){ SDA_OUT; unsigned char i,temp; for(i=0; i<8; i++) { SDA_OUT; temp = data&0x80; if(temp == 0x80) SDA_1; //判断发送位,送数据到数据线上 else SDA_0; delay_us(10); SCL_1; //置时钟信号为高电平,使数据有效 delay_us(5); SCL_0; delay_us(10); data=data<<1; } SDA_IN; delay_us(5);}/**IIC读字节*/unsigned char iic_read(void){ unsigned char i,tmp; unsigned char byte = 0; SDA_IN; //置数为输入 for(i=0; i<8; i++) { SCL_1; delay_us(5); byte = byte<<1; SDA_IN; tmp = SDA_BIT_DATA; if(tmp == SDA_BIT) byte = (byte|0x01); delay_us(10); SCL_0; delay_us(10); } return(byte);}/**IIC写数据*输入:start_addr起始地址* n_bytes写入字节数* dest_date写入的数据源*输出:无*/unsigned char iic_write_data(unsigned char start_addr, unsigned char *dest_date, unsigned char n_bytes){ unsigned char i=0; iic_start(); //启动IIC iic_write(WRITE_ADDR); //写24C02地址以 if(iic_test_ack() != 0) //检测应答 return 1; iic_write(start_addr); //写对24C02操作的地址 if(iic_test_ack() != 0) return 1; for(i=0; i<n_bytes; i++) { iic_write(*dest_date); //向24C02中写数据 if(iic_test_ack() != 0) return 1; dest_date++; start_addr++; } iic_stop(); return 0;}/**IIC读数据*输入:start_addr起始地址* n_bytes读出字节数*输出:dest_date读出并保存的数据目的*/unsigned char iic_read_data(unsigned char start_addr, unsigned char *dest_date, unsigned char n_bytes){ unsigned char i; iic_start(); iic_write(WRITE_ADDR); if(iic_test_ack() != 0) return 1; iic_write(start_addr); if(iic_test_ack() != 0) return 1; iic_start(); iic_write(READ_ADDR); if(iic_test_ack() != 0) return 1; for(i=0; i<n_bytes; i++) { *dest_date = iic_read(); iic_ack(); dest_date++; } *dest_date = iic_read(); iic_no_ack(); iic_stop(); return 0;}
测试结果采用串口输出方式,main包含下面的步骤。
unsigned char iic_buf[4] = {0x11,0x22,0x33,0x44}, iic_rdbuf[4],ret = 0;init_iic();printf("24c02 iic init ok\r\n");printf("write=0x%x 0x%x 0x%x 0x%x\r\n",iic_buf[0],iic_buf[1],iic_buf[2],iic_buf[3]);ret = iic_write_data(200,iic_buf,4);printf("write:%s\r\n", ret > 0 ? "err" : "ok");ret = iic_read_data(200,iic_rdbuf,4);printf("read:%s\r\n", ret > 0 ? "err" : "ok");printf("read=0x%x 0x%x 0x%x 0x%x\r\n",iic_rdbuf[0],iic_rdbuf[1],iic_rdbuf[2],iic_rdbuf[3]);
实际测试显示:
/*页写函数,写入起始地址,数据,字节数*/unsigned char EepromPageWrite(EEPROM_ADDR_TYPE address, unsigned char *pdata, unsigned char num){ unsigned char pagestart = 0; //计算起始页 unsigned char pageend = 0; //计算结束页-1 unsigned char pageloop = 0; //页写总循环数 unsigned char pagebyte; //页剩余字节数寄存器 unsigned int pagedelay = 0; pagestart = EEPROM_PAGE_CAL(address); //at24c01,02 pageend = EEPROM_PAGE_CAL(address+num-1); //页写 for (pageloop = 0; pageloop <= (pageend-pagestart); pageloop++) { //计算本次写入的字节数 pagebyte = (address|(EEPROM_PAGE_SIZE-1)) - address + 1; if (num <= pagebyte) pagebyte = num; num -= pagebyte; //剩余字节数 I2cSendStart(); if (0 == I2cSendByte(EEPROM_WRITE)) return(0); ...}
联系客服