打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
MSP430F149模拟IIC读写24C02程序

板子上设置了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);        ...}

 

 

 

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
学51单片机-基于PCF8591的AD采样和DA输出【实际应用篇】
ADXL345程序。 (amoBBS 阿莫电子论坛)
51单片机”光控窗帘“简易版c(带视频)
linux e2prom 驱动代码
I2C总线(主)C51源程序
IIC总线
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服