您当前的位置:五五电子网电子知识单片机-工控设备PIC单片机PIC24F之EEPROM读写中断事件处理函数要点 正文
PIC24F之EEPROM读写中断事件处理函数要点

PIC24F之EEPROM读写中断事件处理函数要点

点击数:7161 次   录入时间:03-04 11:59:12   整理:http://www.55dianzi.com   PIC单片机
*-------------------------------------------------------------------------------------------------
                        PIC24F之EEPROM读写中断事件处理函数要点及说明
注意: 这是一个通用的I2C/SMBUS通讯中断处理程序
对于EEPROM来讲,从机后面需要跟EEPROM需要读写的地址(I2CRegs.RWAddr)
对于SMBUS来说,从机后面需要跟SMBUS需要的命令(I2CRegs.RWAddr改为I2CRegs.CMD即可)
由于PIC24F的I2C不太标准,I2C1STAT被搞得很倒塌!!!一点都没I2C的"大家闺秀"的样子~~~
不过它的STOP还能激活中断确实比LPCARM/AVR好一点点~~~

为什么I2C收发都用中断呢???
这主要是为了高低速灵活变化的总线通讯所做,主要是SMBUS总线的通信.


如果为I2cExit()也配上钩子函数,那么任何错误都在手掌中~~~

这个PIC程序虽没SMBUS的PEC校验部分,但"异步"还是完美的.
当然也要注意对写保护硬件管脚的控制时机的把握,原则是关保护的时间最短就更好~~~


主要看到人们编写MCU程序太死板~~~特别是I2C程序.网上收发全中断的很少,可以说几乎没有.

随贴附老外倒塌的非中断I2C状态机读写程序i2cEmem.c~~~可以比较经典和非典的差异在何处~~~

菜农近期将整理出LPCARM和AVR的I2C/SMBUS/TWI/USI收发全中断实战例程供大家“游玩”~~~

如果精通DELPHI程序的人一定会为“事件驱动”机制而痴迷~~~为什么不在MCU上"声东击西"呢???

"有事件才处理"---这才是编程的硬道理~~~轮循的“痴迷等待”最终还是“单相思”~~~
-------------------------------------------------------------------------------------------------*/
#include "i2c.h"

_PERSISTENT volatile I2CREGS I2CRegs;
_PERSISTENT volatile I2CBITS I2CBits;

void I2cInit(void)
{
unsigned int i;
    TRIS_WP   = PORTOUTMODE;//定义WP为输出IO
    TRIS_SCL1 = PORTOUTMODE;//定义SCL为输出IO
    TRIS_SDA1 = PORTINPUTMODE;//定义SDA为输出入IO
    ODC_SCL1 = 1;//OC输出
    ODC_SDA1 = 1;//OC输出
    WP = 1;//写保护
    I2CRegs.MaxCount = 0x200;//8KByte
    I2CRegs.I2CAddr = 0xa0;//器件地址
    I2CRegs.RWAddr = 0;//EEPROM读写地址
    I2CRegs.TxCount = 0;//发送数据字节个数
    I2CRegs.RxCount = 0;//接收数据字节个数
    for (i = 0; i < 16; i ++)
    {
        I2CRegs.TxBuffer[i] = 0;//发送缓冲区清零
    }
    for (i = 0; i < 256; i ++)
    {
        I2CRegs.RxBuffer[i] = 0;//接收缓冲区清零
    }

    I2C1CON = 0;
//    I2C1CONbits.A10M = 0;//7位地址模式
    I2C1CONbits.SCLREL = 1;
    I2C1MSK = 0;
    I2C1STAT = 0;
    _MI2C1IF = 0;
    _SI2C1IF = 0;
    I2C1BRG = (FCY / (2 * I2CBAUD)) - 1;//波特率计算
/*------------------------------------------------------------------------
    定义I2C串口2中断优先级位1111)
-------------------------------------------------------------------------*/
    IPC4bits.MI2C1P0 = 1;
    IPC4bits.MI2C1P1 = 1;
    IPC4bits.MI2C1P2 = 1;

    I2C1CONbits.I2CEN = 1;//允许I2C功能
    _MI2C1IE = 1;//允许主设备中断

//    I2cStop();
}

/*------------------------------------------------------------------
    EEPROM读块函数(只能在回调函数I2CReadCallBack中得到读出的数据)
-------------------------------------------------------------------*/
void I2CReadBuffers(unsigned int E2RomAddr, unsigned int ReadSize)
{
    if (ReadSize && (ReadSize <= 256))
    {
        I2CRegs.TxCount = 0;
        I2CRegs.RxCount = ReadSize;
        I2CRegs.RWAddr = E2RomAddr;
        I2CRegs.I2CAddr |= 1;//0xa1
        I2cStart();
    }
}

void I2CReadByte(unsigned int E2RomAddr)
{
    I2CRegs.TxCount = 0;
    I2CRegs.RxCount = 1;
    I2CRegs.RWAddr = E2RomAddr;
    I2CRegs.I2CAddr |= 1;//0xa1
    I2cStart();
}

/*------------------------------------------------------------------
    EEPROM写块函数
-------------------------------------------------------------------*/
void I2CWriteBuffers(unsigned int E2RomAddr, unsigned int WriteSize)
{
    if (WriteSize && (WriteSize <= 16))
    {
        I2CRegs.TxCount = WriteSize;
        I2CRegs.RxCount = 0;
        I2CRegs.RWAddr = E2RomAddr;
        I2CRegs.I2CAddr &= 0xfe;//0xa0
        I2cStart();
    }
}

void I2CWriteByte(unsigned int E2RomAddr, unsigned char cData)
{
    I2CRegs.TxBuffer[0] = cData;
    I2CRegs.TxCount = 1;
    I2CRegs.RxCount = 0;
    I2CRegs.RWAddr = E2RomAddr;
    I2CRegs.I2CAddr &= 0xfe;//0xa0
    I2cStart();
}

/*------------------------------------------------------------------
    用户读回调函数
-------------------------------------------------------------------*/
void I2CReadCallBack(void)
{
    if ((I2CRegs.RWAddr + I2CRegs.RxCount) <= I2CRegs.MaxCount) 
    {
//        I2CRegs.RWAddr += I2CRegs.RxCount;
//        I2CReadBuffers(I2CRegs.RWAddr, I2CRegs.RxCount);//继续读
    }
}

/*------------------------------------------------------------------
    用户写回调函数
-------------------------------------------------------------------*/
void I2CWriteCallBack(void)
{
    if ((I2CRegs.RWAddr + I2CRegs.TxCount) <= I2CRegs.MaxCount) 

[1] [2] [3] [4]  下一页


本文关键字:暂无联系方式PIC单片机单片机-工控设备 - PIC单片机