在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 關于LPC1758平臺上I2C EEPROM 調試總結

            關于LPC1758平臺上I2C EEPROM 調試總結

            作者: 時間:2016-11-21 來源:網(wǎng)絡 收藏
            硬件平臺:PLC1758

            軟件平臺 uCOS-II

            本文引用地址:http://www.biyoush.com/article/201611/319144.htm

            開發(fā)環(huán)境: IAR EWARM

            源碼如下

            #define BSP_I2C2_PINS (DEF_BIT_10|DEF_BIT_11)

            static void BSP_I2C2_Init(CPU_INT32U fi2c)
            {
            //獲取外設時鐘
            CPU_INT32U Fpclk = BSP_PM_PerClkFreqGet(BSP_PM_PER_NBR_I2C2);
            //使能該功率模塊
            BSP_PM_PerClkEn(BSP_PM_PER_NBR_I2C2);
            //配置脈沖捕捉管腳
            BSP_GPIO_Cfg(BSP_GPIO_PORT0_FAST,//P0.10引腳
            BSP_I2C2_PINS,//設置成脈沖捕捉
            BSP_GPIO_OPT_FNCT_3);//引腳輸入使能

            //設置占空比
            if(fi2c>400000)
            fi2c = 400000;
            I2C2SCLH = (Fpclk+1/fi2c ) / 2;//高電平占空比寄存器
            I2C2SCLL = (Fpclk/fi2c) / 2; //低電平占空比寄存器
            //配置成I2C主模式
            I2C2CONCLR = 0x2C; //STA|SI|AA|STO;
            I2C2CONSET = 0x40; //I2EN=1,使能主I2C

            //設置中斷源
            BSP_IntVectSet((CPU_INT08U)BSP_INT_SRC_NBR_I2C2,(CPU_FNCT_VOID)I2C2_IRQ_ISR_handler );
            BSP_IntPrioSet((CPU_INT08U)BSP_INT_SRC_NBR_I2C2,0x01);
            //使能中斷
            BSP_IntEn(BSP_INT_SRC_NBR_I2C2);
            //I2C2中斷通道號為28

            }

            問題 :一個字節(jié)的變量寫入與讀出的的結果不一致,源碼如下


            INT8U I2C_WriteNByte(INT8U sla, INT8U suba_type, INT32U suba, INT8U *s, INT32U num)
            {
            if (num > 0) // 如果讀取的個數(shù)為0,則返回錯誤
            { // 設置參數(shù)
            if (suba_type == 1)
            { // 子地址為單字節(jié)
            I2C_sla = sla; // 讀器件的從地址
            I2C_suba = suba; // 器件子地址
            I2C_suba_num = 1; // 器件子地址為1字節(jié)
            }
            else if (suba_type == 2)
            { // 子地址為2字節(jié)
            I2C_sla = sla; // 讀器件的從地址
            I2C_suba = suba; // 器件子地址
            I2C_suba_num = 2; // 器件子地址為2字節(jié)
            }
            else if (suba_type == 3)
            { // 子地址結構為8+X
            I2C_sla = sla + ((suba >> 7 )& 0x0e);// 讀器件的從地址
            I2C_suba = suba & 0x0ff; // 器件子地址
            I2C_suba_num = 1; // 器件子地址為8+X
            }

            I2C_buf = s; // 數(shù)據(jù)
            I2C_num = num; // 數(shù)據(jù)個數(shù)
            I2C_suba_en = 2; // 有子地址,寫操作
            I2C_end = 0;

            // 清除STA,SI,AA標志位
            I2C2CONCLR = (1 << 2)| // AA
            (1 << 3)| // SI
            (1 << 5); // STA

            // 置位STA,啟動I2C總線
            I2C2CONSET = (1 << 5)| // STA
            (1 << 6); // I2CEN

            // 等待I2C操作完成
            return( Wait_I2c_End(1000));

            }
            return (FALSE);
            }


            INT8U I2C_ReadNByte (INT8U sla, INT32U suba_type, INT32U suba, INT8U *s, INT32U num)
            {

            if (num > 0) // 判斷num個數(shù)的合法性
            { // 參數(shù)設置
            if (suba_type == 1)
            { // 子地址為單字節(jié)
            I2C_sla = sla + 1; // 讀器件的從地址,R=1
            I2C_suba = suba; // 器件子地址
            I2C_suba_num = 1; // 器件子地址為1字節(jié)
            }
            else if (suba_type == 2)
            { // 子地址為2字節(jié)
            I2C_sla = sla + 1; // 讀器件的從地址,R=1
            I2C_suba = suba; // 器件子地址
            I2C_suba_num = 2; // 器件子地址為2字節(jié)
            }
            else if (suba_type == 3)
            { // 子地址結構為8+X
            I2C_sla = sla + ((suba >> 7 )& 0x0e) + 1; // 讀器件的從地址,R=1
            I2C_suba = suba & 0x0ff; // 器件子地址
            I2C_suba_num = 1; // 器件子地址為8+x
            }
            I2C_buf = s; // 數(shù)據(jù)接收緩沖區(qū)指針
            I2C_num = num; // 要讀取的個數(shù)
            I2C_suba_en = 1; // 有子地址讀
            I2C_end = 0;

            // 清除STA,SI,AA標志位
            I2C2CONCLR = (1 << 2)| // AA
            (1 << 3)| // SI
            (1 << 5); // STA

            // 置位STA,啟動I2C總線
            I2C2CONSET = (1 << 5)| // STA
            (1 << 6); // I2CEN

            return( Wait_I2c_End(1000)); // 等待I2C操作完成


            }
            return (FALSE);

            }



            void I2C2_IRQ_ISR_handler(void)
            {



            switch (I2C2STAT & 0xF8)//0~6位是狀態(tài)位
            { // 根據(jù)狀態(tài)碼進行相應的處理
            case 0x08: // 已發(fā)送起始條件,主發(fā)送和主接收都有,裝入SLA+W或者SLA+R
            if(I2C_suba_en == 1)// SLA+R // 指定子地址讀
            {
            I2C2DAT = I2C_sla & 0xFE; // 先寫入地址
            }
            else // SLA+W
            {
            I2C2DAT = I2C_sla; // 否則直接發(fā)送從機地址
            }
            // 清零SI位
            I2C2CONCLR = (1 << 3)| // SI
            (1 << 5); // STA
            break;

            case 0x10: // 已發(fā)送重復起始條件 // 主發(fā)送和主接收都有
            // 裝入SLA+W或者SLA+R
            I2C2DAT = I2C_sla; // 重起總線后,重發(fā)從地址
            I2C2CONCLR = 0x28; // 清零SI,STA
            break;

            case 0x18:
            case 0x28: // 已發(fā)送I2DAT中的數(shù)據(jù),已接收ACK
            if (I2C_suba_en == 0)
            {
            if (I2C_num > 0)
            {
            I2C2DAT = *I2C_buf++;
            I2C2CONCLR = 0x28; // 清零SI,STA
            I2C_num--;
            }
            else // 沒有數(shù)據(jù)發(fā)送了
            { // 停止總線
            I2C2CONSET = (1 << 4); // STO
            I2C2CONCLR = 0x28; // 清零SI,STA
            I2C_end = 1; // 總線已經停止
            }
            }

            else if(I2C_suba_en == 1) // 若是指定地址讀,則重新啟動總線
            {
            if (I2C_suba_num == 2)
            {
            I2C2DAT = ((I2C_suba >> 8) & 0xff);
            I2C2CONCLR = 0x28; // 清零SI,STA
            I2C_suba_num--;
            break;
            }

            else if(I2C_suba_num == 1) //器件子地址為1字節(jié)
            {
            I2C2DAT = (I2C_suba & 0xff);
            I2C2CONCLR = 0x28; // 清零SI,STA
            I2C_suba_num--;
            break;
            }

            else if (I2C_suba_num == 0)
            {
            I2C2CONCLR = 0x08;
            I2C2CONSET = 0x20;
            I2C_suba_en = 0; // 子地址己處理
            break;
            }
            }
            else if (I2C_suba_en == 2) // 指定子地址寫,子地址尚未指定
            { // 則發(fā)送子地址
            if (I2C_suba_num > 0)
            {


            if (I2C_suba_num == 2)
            {
            I2C2DAT = ((I2C_suba >> 8) & 0xff);
            I2C2CONCLR = 0x28;
            I2C_suba_num--;
            break;
            }
            else if (I2C_suba_num == 1) //器件子地址為1字節(jié)
            {
            I2C2DAT = (I2C_suba & 0xff);
            I2C2CONCLR = 0x28;
            I2C_suba_num--;
            I2C_suba_en = 0;
            break;
            }
            }
            }
            break;

            case 0x40: // 已發(fā)送SLA+R,已接收ACK
            if (I2C_num <= 1) // 如果是最后一個字節(jié)
            {
            I2C2CONCLR = 1 << 2; // 下次發(fā)送非應答信號
            }
            else
            {
            I2C2CONSET = 1 << 2; // 下次發(fā)送應答信號
            }
            I2C2CONCLR = 0x28; // 清零SI,STA
            break;

            case 0x20: // 已發(fā)送SLA+W,已接收非應答
            case 0x30: // 已發(fā)送I2DAT中的數(shù)據(jù),已接收非應答
            case 0x38: // 在SLA+R/W或數(shù)據(jù)字節(jié)中丟失仲裁

            case 0x48: // 已發(fā)送SLA+R,已接收非應答
            I2C2CONCLR = 0x28;
            I2C_end = 0xFF;
            break;

            case 0x50: // 已接收數(shù)據(jù)字節(jié),已返回ACK
            *I2C_buf++ = I2C2DAT;
            I2C_num--;
            if (I2C_num == 1) // 接收最后一個字節(jié)
            {
            I2C2CONCLR = 0x2C; // STA,SI,AA = 0
            }
            else
            {
            I2C2CONSET = 0x04; // AA=1
            I2C2CONCLR = 0x28;
            }
            break;

            case 0x58: // 已接收數(shù)據(jù)字節(jié),已返回非應答
            *I2C_buf++ = I2C2DAT; // 讀取最后一字節(jié)數(shù)據(jù)
            I2C2CONSET = 0x10; // 結束總線
            I2C2CONCLR = 0x28;
            I2C_end = 1;
            break;

            default:
            break;
            }
            }

            原因:指定suba_type參數(shù)不正確,如果器件的地址位寬是一字節(jié),那么指定為1,如果地址位寬是兩字節(jié),那么指定為2。另外在讀寫操作時指定Wait_I2c_End(INT32 Dly)函數(shù)中的Dly值太小也不能操作成功,可以適當放大些。



            評論


            技術專區(qū)

            關閉