板子上设置了eeprom存储器,型号为at24c02。
板子的硬件连接为:scl--->p2.4,sda--->p2.5。
直接了当,贴上程序!
========================24cxx.h文件=========================#ifndef _24cxx_h_#define _24cxx_h_#include#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测试结果采用串口输出方式,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); ... }
『本文转载自网络,九游会j9的版权归原作者所有,如有侵权请联系删除』