查看: 5884|回复: 3

[原创] LPC1343的IIC中断模式读写24C04

[复制链接]
  • TA的每日心情

    2025-5-29 09:38
  • 签到天数: 632 天

    连续签到: 1 天

    [LV.9]以坛为家II

    94

    主题

    1639

    帖子

    2

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    4470

    热心会员

    最后登录
    2025-6-10
    发表于 2021-8-10 12:37:56 | 显示全部楼层 |阅读模式
    一般读写EEPROM,我很少用,一般用查询模式,这里的LPC1343尝试用IIC的中断模式。我们选用IIC的引脚为P0_4,P0_5:
    ZZX.png
    根据表可知,其实这个引脚仅有开漏模式,无论你配不配置成IIC引脚,这样这硬件设计时,必须加上拉电阻:
    ZZXX2.png
    IIC的状态寄存器:
    Z3.png
    根据当前不同状态,对应动作~
    废话不多说了,IIC驱动代码:
    24C04.H
    1. #ifndef __24C04_H_
    2. #define __24C04_H_

    3. #include "LPC13xx.h"


    4. #define AT24WC04   0xA0

    5. extern u8  ucI2CAdd;                  //
    6. extern u8  ucI2CRamAdd;               // RAM read and write address
    7. extern u8  ucI2CNum;                  // I2C read and write Num
    8. extern u8  *ucI2CBuf;                 // I2C work pointer
    9. extern u8  ucReadBuf[128];            // read data buf
    10. extern u8  ucWriteBuf[128];           // write data buf
    11. extern u8  ucI2CEnd;                  // end sign
    12. extern u8  ucI2CAddEn;                // work enabled sign

    13. u8 I2C_SendStr(u8 SlaveAddr, u8 WRAddr,u8 *Str,u8 number);
    14. u8 I2C_RecvStr(u8 SlaveAddr, u8 RDAddr,u8 *Str,u8 number);
    15. void AT24C04_I2C_Init(void);

    16. #endif

    复制代码


    24C04.C

    1. #include "24c04.h"

    2. u8  ucI2CAdd;                  //
    3. u8  ucI2CRamAdd;               // RAM read and write address
    4. u8  ucI2CNum;                  // I2C read and write Num
    5. u8  *ucI2CBuf;                 // I2C work pointer
    6. u8  ucReadBuf[128];            // read data buf
    7. u8  ucWriteBuf[128];           // write data buf
    8. u8  ucI2CEnd;                  // end sign
    9. u8  ucI2CAddEn;                // work enabled sign


    10. u8 I2C_SendStr(u8 SlaveAddr, u8 WRAddr,u8 *Str,u8 number)
    11. {
    12.   if(0 == number)return(0);
    13.   // setup basic parameter
    14.   ucI2CAdd = SlaveAddr;
    15.   ucI2CNum = number;
    16.   ucI2CRamAdd = WRAddr;
    17.   ucI2CBuf = Str;
    18.   ucI2CEnd = 0;
    19.   ucI2CAddEn = 2;
    20.   // set master Mode, startup bus
    21.   LPC_I2C->CONCLR = 0x2C;
    22.   LPC_I2C->CONSET = 0x60;
    23.   // wait work finish
    24.   while(0 == ucI2CEnd);
    25.   if(1 == ucI2CEnd)return(1);
    26.   else return(0);
    27. }

    28. u8 I2C_RecvStr(u8 SlaveAddr, u8 RDAddr,u8 *Str,u8 number)
    29. {
    30.   if(0 == number)return(0);
    31.   // setup basic parameter
    32.   ucI2CAdd = SlaveAddr + 1;
    33.   ucI2CNum = number;
    34.   ucI2CRamAdd = RDAddr;
    35.   ucI2CBuf = Str;
    36.   ucI2CEnd = 0;
    37.   ucI2CAddEn  = 1;
    38.   // set master Mode, startup bus
    39.   LPC_I2C->CONCLR = 0x2C;
    40.   LPC_I2C->CONSET = 0x60;
    41.   // wait work finish
    42.   while(0 == ucI2CEnd);
    43.   if(1 == ucI2CEnd) return(1);
    44.   else return(0);
    45. }

    46. void AT24C04_I2C_Init(void)
    47. {
    48.   LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 16);       //--- 使能IOCON模块的时钟源 ---
    49.   LPC_IOCON->PIO0_4 = (1 << 0);                 //--- PIO0_4为SCL功能引脚 ---
    50.   LPC_IOCON->PIO0_5 = (1 << 0);                 //--- PIO0_5为SDA功能引脚 ---
    51.   LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 5);        //--- 使能I2C模块的时钟源 ---
    52.   LPC_SYSCON->PRESETCTRL |= (1 << 1);           //--- 禁止I2C复位 ---
    53.   
    54.   LPC_I2C->SCLH = 360;
    55.   LPC_I2C->SCLL = 360;
    56.   LPC_I2C->CONCLR = 0x2C;
    57.   LPC_I2C->CONSET = 0x40;
    58.   
    59.   NVIC_EnableIRQ(I2C_IRQn);
    60. }

    61. void I2C_IRQHandler(void)
    62. {
    63.   unsigned char sta;

    64.   sta = LPC_I2C->STAT;                    // read state
    65.   switch(sta)
    66.     {
    67.       case 0x08:
    68.         if(1 == ucI2CAddEn)LPC_I2C->DAT = ucI2CAdd & 0xFE;   // send slave address + read sign
    69.         else LPC_I2C->DAT = ucI2CAdd;         // send slave address
    70.         LPC_I2C->CONCLR = 0x28;               // SI=0
    71.         break;
    72.       case 0x10:
    73.         LPC_I2C->DAT = ucI2CAdd;                // reset, send slave address
    74.         LPC_I2C->CONCLR = 0x28;               // SI=0
    75.         break;
    76.       case 0x18:
    77.         if(ucI2CAddEn == 0)
    78.           {
    79.             if(ucI2CNum > 0)
    80.               {
    81.                 LPC_I2C->DAT = *ucI2CBuf++;       // send data
    82.                 LPC_I2C->CONCLR = 0x28;
    83.                 ucI2CNum--;
    84.               }
    85.               else
    86.                 {
    87.                   LPC_I2C->CONSET = 0x10;      // send finish,
    88.                   LPC_I2C->CONCLR = 0x28;
    89.                   ucI2CEnd = 1;      // set end sign
    90.                 }
    91.             break;
    92.           }
    93.         if(ucI2CAddEn == 1)LPC_I2C->DAT = ucI2CRamAdd;       // send work address
    94.         if(ucI2CAddEn == 2)
    95.           {
    96.             LPC_I2C->DAT = ucI2CRamAdd;           // send work address
    97.             ucI2CAddEn = 0;             // clear sign
    98.           }
    99.         LPC_I2C->CONCLR = 0x28;               // SI=0 , clear interrupt sign
    100.         break;
    101.       case 0x28:
    102.         if(ucI2CAddEn == 0)
    103.           {
    104.             if(ucI2CNum>0)
    105.               {
    106.                 LPC_I2C->DAT = *ucI2CBuf++;         // send work address
    107.                 ucI2CNum--;
    108.               }
    109.             else
    110.               {
    111.                 LPC_I2C->CONSET = 0x10;         // send finish
    112.                 ucI2CEnd = 1;
    113.               }
    114.             LPC_I2C->CONCLR = 0x28;            // SI=0 , clear interrupt sign
    115.           }
    116.         if(ucI2CAddEn == 1)                             // read appoint address
    117.           {
    118.             LPC_I2C->CONSET = 0x20;
    119.             LPC_I2C->CONCLR = 0x08;
    120.             ucI2CAddEn = 0;              // appoint address dispose finish
    121.           }
    122.         break;
    123.       case 0x20:
    124.       case 0x30:
    125.       case 0x38:                  // bus error
    126.         LPC_I2C->CONCLR = 0x28;
    127.         ucI2CEnd = 0xFF;
    128.         break;
    129.       case 0x40:                  // already send sla+r and recive the ack
    130.         if(1==ucI2CNum)LPC_I2C->CONCLR = 0x2C;// send no ack when last byte
    131.         else
    132.           {                    // recive and send ack
    133.             LPC_I2C->CONSET = 0x04;
    134.             LPC_I2C->CONCLR = 0x28;
    135.           }
    136.         break;
    137.       case 0x50:
    138.         *ucI2CBuf++ = LPC_I2C->DAT;            // read data
    139.         ucI2CNum--;
    140.         if(1==ucI2CNum)LPC_I2C->CONCLR = 0x2C;
    141.         else
    142.           {
    143.             LPC_I2C->CONSET = 0x04;
    144.             LPC_I2C->CONCLR = 0x28;
    145.           }
    146.         break;
    147.       case 0x58:
    148.         *ucI2CBuf++ = LPC_I2C->DAT;            // read last byte data
    149.         LPC_I2C->CONSET = 0x10;              // bus end
    150.         LPC_I2C->CONCLR = 0x28;
    151.         ucI2CEnd = 1;
    152.         break;
    153.       case 0x48:
    154.         LPC_I2C->CONCLR = 0x28;               // bus error
    155.         ucI2CEnd = 0xFF;
    156.         break;
    157.       default:
    158.         break;
    159.     }
    160. }
    复制代码
    在main函数里面,调用读写2个函数就可以了~
    1.     AT24C04_I2C_Init();
    2.     I2C_SendStr(AT24WC04,Address,(u8*)"Hello EEPROM!\r\n",sizeof("Hello EEPROM!\r\n"));
    3.     delay_ms(500);
    4.     memset(ucReadBuf, 0, sizeof ucReadBuf);
    5.     I2C_RecvStr(AT24WC04,Address,ucReadBuf,20);
    6.     delay_ms(500);
    7.     Usart_SendString((char*)ucReadBuf);
    复制代码
    编译,下载,查看串口:
    Z2.png

    哎...今天够累的,签到来了~
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2025-8-8 16:43
  • 签到天数: 1504 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    97

    主题

    4693

    帖子

    12

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    10105
    最后登录
    2025-9-11
    发表于 2021-8-10 14:22:27 | 显示全部楼层
    我倒是觉得NXP芯片的IIC可以放心使用中断模式
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2025-5-15 09:29
  • 签到天数: 178 天

    连续签到: 1 天

    [LV.7]常住居民III

    11

    主题

    423

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    1395
    最后登录
    2025-9-9
    发表于 2021-8-10 15:18:14 | 显示全部楼层
    I2C总线会出现锁死的现象吗?
    加油加油
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2025-5-29 09:38
  • 签到天数: 632 天

    连续签到: 1 天

    [LV.9]以坛为家II

    94

    主题

    1639

    帖子

    2

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    4470

    热心会员

    最后登录
    2025-6-10
     楼主| 发表于 2021-8-10 15:19:17 | 显示全部楼层
    thinkking1985 发表于 2021-8-10 15:18
    I2C总线会出现锁死的现象吗?

    目前没发现啊~
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-9-13 00:37 , Processed in 0.095345 second(s), 23 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表