JZ2440 裸機驅動 第12章 I2C介面

来源:http://www.cnblogs.com/sz189981/archive/2017/10/23/7716280.html
-Advertisement-
Play Games

瞭解I2C匯流排協議; 掌握S3C2410/S3C2440中I2C介面的使用方法 ...


本章目標: 瞭解I2C匯流排協議; 掌握S3C2410/S3C2440中I2C介面的使用方法; 12.1 I2C匯流排協議及硬體介紹 12.1.1 I2C匯流排協議 1 I2C匯流排的概念 2 I2C匯流排的信號類型 3 I2C匯流排的數據傳輸格式 12.1.2 S3C2410/S3C2440 I2C匯流排控制器 1. S3C2410/S3C2440 I2C匯流排控制器寄存器介紹     S3C2410/S3C2440的I2C介面有4種工作模式:主機發送、主機接收、從機發送、 從機接收。其內部結構如圖12.6所示。     從圖12.6可知,S3C2410/S3C2440提供4個寄存器來完成所有的I2C操作。SDA線上的數據 從IICDS寄存器發出,或傳入IICDS寄存器中;IICADD寄存器中保存S3C2410/S3C2440當做從 機時的地址;IICCON、IICSTAT 兩個寄存器用來控制或標識各種狀態,比如選擇工作模式,發出 S信號、P信號,決定是否發出ACK信號,檢測是否收到ACK信號。各寄存器的用法如下: (1)IICCON寄存器(Multi-master IIC-bus control)     IICCON寄存器用於控制是否發出ACK信號、設置發送器的時鐘、開啟IIC中斷,並標識中斷是 否發生。它的各位含義如下表12.2所示。      使用IICCON寄存器時,有如下註意事項:     ① 發送模式的時鐘頻率由位[6]、位[3:0]聯合決定。另外,當IICCON[6] = 0時,IICCON[3:0] 不能去0或1。     ② IIC中斷在以下3種情況下發生:         當發出地址信息或接收到一個從機地址並且吻合時;         當總線仲裁失敗時;         當發送/接收完一個位元組的數據(包括響應位)時。     ③ 基於SDA 、SCL線上時間特性的考慮,要發送數據時,先將數據寫入IICDS寄存器, 然後清除中斷。     ④ 如果IICCON[5] = 0,IICCON[4]將不能正常工作。所以即使不使用IIC中斷,也要將 IICCON[5]設為1。 (2)IICSTAT寄存器(Multi-master IIC-bus control/status)。     IICSTAT寄存器用於選擇IIC介面的工作模式,發出S信號、P信號,使能接收/發送功能, 並標識各種狀態,比如匯流排仲裁是否成功、作為從機時是否被定址、是否接收到0地址、是 否接收到ACK信號等。     IICSTAT寄存器的各位如表12.3所示: (3)IICADD寄存器(Multi-master IIC-bus address)     用到位[7:1],表示從機地址。在IICSTAT[4]為1時,才可以寫入;隨時都可以讀出。 (4)IICDS寄存器(Multi-master IIC-bus Tx/Rx data shift)     用到位[7:0],其中保存的是要發送或已經接收到的數據。在IICSTAT[4]為1時才可寫入, 隨時可以讀出。 2.S3C2410/S3C2440 I2C匯流排操作方法     啟動或複位S3C2410/S3C2440 的IIC傳輸有以下兩種方法。 (1)當IICCON[4]即中斷狀態位為0時,通過寫IICSTAT寄存器啟動IIC操作。有以下兩種 情況。     ① 在主機模式:         令IICSTAT[5:4]等於0b11,將發出S信號和IICDS寄存器的數據(定址),         令IICSTAT[5:4]等於0b01,將發出P信號。     ② 在從機模式,令IICSTAT[4]等於1,將等待其他主機發出S信號及地址信息。 (2)當IICCON[4]即中斷狀態位為1時,表示I2C操作被暫停。在這期間設置好其他寄存器 之後,向IICCON[4]寫入0即可恢復I2C操作。     所謂“設置其他寄存器”,有以下3種情況。     ① 對於主機模式,可以按照上面(1)的方法寫IICSTAT寄存器,恢復I2C操作後即可發出 S信號和IICDS寄存器的值(定址),或發出P信號。     ② 對於發送器,可以將下一個要發送的數據寫入IICDS寄存器中,恢復I2C操作後即可發 出這個數據。     ③ 對於接收器,可以從IICDS寄存器中讀出接收到的數據。最後向IICCON[4]寫入0的同時, 設置IICCON[7]以決定在接收到下一個數據後是否發出ACK信號。       通過中斷服務程式驅動I2C傳輸。 (1)當仲裁失敗時,發生中斷——本次傳輸沒有搶到匯流排,可以稍後繼續。 (2)對於主機模式,當發出S信號、地址信息並經過一個SCL周期(對應ACK信號)後,發生 中斷——主機可在此時判斷是否成功定址到從機。 (3)對於從機模式,當接收到的地址與IICADD寄存器吻合時,先發出ACK信號,然後發生 中斷——從機可在此時準備後續的傳輸。 (4)對於發送器,當發送完一個數據並經過一個SCL周期(對應ACK信號)後,發生中斷。這 時可以準備下一個要發送的數據,或發出P信號以停止傳輸。 (5)對於接收器,當接收到一個數據時,先根據IICCON[7]決定是否發出ACK信號後,然後 發生中斷。這是可以讀取IICDS寄存器得到數據,並設置IICCON[7]已決定接收到下一個數 後是否發出ACK。       對於4種工作模式,S3C2410/S3C2440數據手冊中都有它們的操作流程圖。現在以主機發 送器為例說明,它的工作流程如圖12.7所示,其他的工作模式請參考數據手冊。

    下麵結合I2C寄存器的用法,詳細講解圖12.7中各步驟的含義。 (1)配置主機發送器的各類參數     設置GPE15、GPE14引腳用於SDA、SCL,設置IICCON寄存器選擇I2C發送時鐘,最後, 設置IICSTAT[4]為1,這樣,後面才能寫IICDS寄存器。     註意:初始時IICCON[4]為0,不能將IICSTAT設為主機模式,否則就會立刻發出S信號、 發送IICDS寄存器里的值。 (2)將要定址的從機地址寫入IICDS寄存器。 (3)將0xF0寫入IICSTAT寄存器,即設為主機發送器、使能串列輸出功能、發出S信號。 (4)發出S信號後,步驟(2)中設置的IICDS寄存器值也將被髮出,它用來定址從機。 (5)在響應周期之後,發生中斷,此時IICCON[4]為1,I2C傳輸暫停。 (6)如果沒有數據要發送,則跳到步驟(10);否則跳到步驟(7)。 (7)將下一個要發送的數據寫入IICDS寄存器中。 (8)向IICCON[4]中寫入0,恢復I2C傳輸。 (9)這時,IICDS寄存器中的值將被一位一位地發送出去。當8位數據發送完畢,再經過 另一個SCL周期(對應ACK信號)後,中斷再次發生,跳到步驟(5)。     步驟(5)~(9)不斷迴圈知道發出所有數據。當要停止傳輸時,跳到步驟(10)。 (10)將0xF0寫入IICSTAT寄存器,即設為主機發送器、使能串列輸出功能、發出P信號。             註意:這時的P信號並沒有實際發出,只有清除了IICCON[4]後才會發出P信號。 (11)清除IICCON[4],P信號得以發出。 (12)等待一段時間,使得P信號完全發出。 12.2 I2C匯流排操作實例 12.2.1 I2C介面RTC晶元M41t11的操作方法     本書所用開發板中,通過I2C匯流排連接RTC(實時時鐘)晶元M4lt11,它使用電池供電, 斷電時也可以維持日期和時間。S3C2410/S3C2440作為I2C主機向M4lt11發送數據以設 置日期和時間、讀取M4lt11以獲取日期和時間。連接圖如圖12.8所示。      M4lt11中有8個寄存器,分別對應秒、分、時、天(星期幾)、日、月、年、控制寄存器, 其中的數據都是以BCD格式保存(BCD格式例子:0x15表示數值15),如表12.4所示。      除上表的8個寄存器(地址為0~7)之外,M4lt11內部還有56位元組的RAM(地址為8~63)。 訪問M4lt11前,先設置寄存器地址,以後每次讀寫操作完成後,M4lt11內部會自動將寄 存器地址加1.     所以讀寫M4lt11分以下兩個步驟:     (1)主機向M4lt11發出要操作的寄存器起始地址(0~7)。     (2)要設置M4lt11時,主機連續發出數據;讀取M4lt11時,主機連續讀取數據。     M4lt11的I2C從機地址為0xD0。 12.2.2 程式設計     本實例將在串口上輸出一個菜單,可以選擇設置時間和日期,或者將它們讀出來。將 通過本實例驗證I2C主機的發送、接收操作。 12.2.3 設置/讀取M4lt11的源碼詳解     本實例的源碼在/work/hardware/i2c目錄下。     文件i2c.c封裝了S3C2410/S3C2440作為主機發送器、主機接收器的4個操作函數: i2c_init用於初始化,i2c_write用於發起發送數據,i2c_read用於發起讀取數據, I2CIntHandle是I2C中斷服務程式,用於完成後續的數據傳輸。 1.S3C2410/S3C2440 I2C控制器初始化     i2c_init函數對應於圖12.7中的步驟(1),初始化I2C,代碼如下:
 1 行號
 2 24行/*
 3 25行 *I2C初始化
 4 26行 */
 5 27行 void i2c_init(void)
 6 28行 {
 7 29行    GPEUP |= 0xc000;        //禁止內部上拉
 8 30行    GPECON |= 0xa0000000;    //選擇引腳功能,GPE15:IICSDA,GPE14:IICSCL
 9 31行
10 32行    INTMSK &= ~(BIT_IIC);
11 33行
12 34行    /*bit[7] = 1,使能ACK
13 35行     *bit[6] = 0,IICCLK = PCLK/16
14 36行     *bit[5] = 1,使能中斷
15 37行     *bit[3:0] = 0xf,Tx clock = IICCLK/16
16 38行     *PCLK = 50MHz、IICCLK = 3.125MHz,Tx Clock = 0.195MHz
17 39行     */
18 40行    IICCON = (1 << 7) | (0 << 6) | (1 << 5) | (0xf);    //0xaf
19 41行
20 42行    IICADD  = 0x10;        //S3C24xx slave address = [7:1]
21 43行    IICSTAT = 0x10;        //I2C串列輸出使能(Rx/Tx)
22 44行 }
23 45行
i2c.c->i2c_init()     第32行在INTMSK寄存器中開啟I2C中斷,這樣,以後調用i2c_read、i2c_write啟動傳 輸時,即可觸發中斷,進而可以在中斷服務程式中進一步完成後續的傳輸。     第40行用於選擇發送時鐘,併進行一些設置:使能ACK、使能中斷。     第42行用於設置S3C2410/S3C2440作為I2C從機時的地址,本實例未用到。     第43行使能I2C串列輸出(設置IICSTAT[4]為1),這樣,在i2c_write、i2c_read 函數中就可以寫IICDS寄存器了。 2.S3C2410/S3C2440 I2C主機發送函數     初始化完成後,就可以調用i2c_read、i2c_write讀寫I2C從機了。它們的使用方法從參數 名稱就可以看出。這兩個函數只是啟動I2C傳輸,然後等待,知道數據在中斷服務程式中傳 輸完畢後再返回。     i2c_write函數的實現如下:
 1 行號
 2 46行 /* 
 3 47行  *主機發送
 4 48行  *slvAddr:從機地址,buf:數據存放的緩衝區,len:數據長度
 5 49行  */
 6 50行 void i2c_write(unsigned int slvAddr, unsigned char *buf, int len)
 7 51行 {
 8 52行    g_tS3C24xx_I2C.Mode      = WRDATA;    //寫操作
 9 53行    g_tS3C24xx_I2C.Pt        = 0;         //索引值初始化為0
10 54行    g_tS3C24xx_I2C.pDATA     = buf;       //保存緩衝區地址
11 55行    g_tS3C24xx_I2C.DataCount = len;       //傳輸長度
12 56行
13 57行    IICDS   = slvAddr;
14 58行    IICSTAT = 0xf0;        //主機發送、啟動
15 59行
16 60行    /*等待直至數據傳輸完畢*/
17 61行    while(g_tS3C24xx_I2C.DataCount != -1);
18 62行 }
19 63行
i2c.c->i2c_write()     第57行將從機地址寫入IICDS寄存器,這樣,在第58行啟動傳輸併發出S信號後,緊接 著就自動發出從機地址。     第58行設置IICSTAT寄存器,將S3C2410/S3C2440設為主機發送器,併發出S信號。 後續的傳輸工作將在中斷服務程式中完成。     第61行等待g_tS3C24xx_I2C.DataCount在中斷服務程式中被設為-1,這表明傳輸完成, 於是返回。 3.S3C2410/S3C2440 I2C主機接收函數     i2c_read函數的實現與i2c_write類似,代碼如下:
 1 行號
 2 64行 /*
 3 65行  *主機接收
 4 66行  *slvAddr:從機地址,buf:數據存放的緩衝區,len:數據長度
 5 67行  */
 6 68行 void i2c_read(unsigned int alvAddr, unsigned char *buf, int len)
 7 69行 {
 8 70行     g_tS3C24xx_I2C.Mode      = RDDATA;     //讀操作
 9 71行     g_tS3C24xx_I2C.Pt        = -1;         //索引值初始化為-1,表示第一個中斷時不接收數據(地址中斷)
10 72行     g_tS3C24xx_I2C.pData     = buf;        //保存緩衝區地址
11 73行     g_tS3C24xx_I2C.DataCount = len;        //傳輸長度
12 74行 
13 75行     IICDS   = slvAddr;
14 76行     IICSTAT = 0xb0;        //主機接收,啟動
15 77行 
16 78行     /*等待直至數據傳輸完畢*/
17 79行     while(g_tS3C24xx_I2C.DataCount != -1);
18 80行 }
19 81行 
i2c.c->i2c_read()     需要註意的是第71行將索引值設為-1,在中斷處理函數中會根據這個值決定是否從 IICDS寄存器中讀取數據。讀操作時,第1次中斷發生時表示發出了地址,這時候不能 讀取數據。
4.S3C2410/S3C2440 I2C中斷服務程式     I2C操作的主體在中斷服務程式,它分為3部分:首先在SRCPND、INTPND中清除中 斷,後面兩部分對應於寫操作和讀操作。先看清除中斷的代碼:
 1 行號
 2 82行 /*
 3 83行  *I2C中斷服務程式
 4 84行  *根據剩餘的數據長度選擇繼續傳輸或者結束
 5 85行  */
 6 86行 void I2CInitHandle(void) 
 7 87行 {
 8 88行    unsigned int iicSt, i;
 9 89行    
10 90行    //清中斷
11 91行    SRCPND = BIT_IIC;
12 92行    INTPND = BIT_IIC;
13 93行
14 94行    iicSt  = IICSTAT;
15 95行
16 96行    if(iicSt & 0x8){printf("Bus arbitration failed\n\r");}    //仲裁失敗
i2c.c->I2CInitHandle()     第91、92行用來清除I2C中斷的代碼。需要註意的是,即使清除中斷後,IICCON寄存器 中的位[4](中斷標識位)仍為1,這導致I2C傳輸暫停。     第94行讀取狀態寄存器IICSTAT,發生中斷時有可能時因為仲裁失敗,在第96行對它進行 處理。本程式忽略仲裁失敗,因為只有一個I2C主機。     接下來是一個switch語句,分別處理寫操作、讀操作。先看寫操作:
 1 行號
 2 98行  switch(g_tS3C24xx_I2C.Mode)
 3 99行  {
 4 100行    case WRDATA:
 5 101行    {
 6 102行        if((g_tS3C24xx_I2C.DataCount--) == 0)
 7 103行        {
 8 104行            //下麵兩行用於恢復I2C操作,發出P信號
 9 105行            IICSTAT = 0xd0;
10 106行            IICCON  = 0xaf;
11 107行            Delay(10000);    //等待一段時間以便P信號已經發出
12 108行            break;
13 109行        }
14 110行    
15 111行        IICDS = g_tS3C24xx_I2C.pData[g_tS3C24xx_I2C.Pt++];
16 112行
17 113行        //將數據寫入IICDS後,需要一段時間才能出現在SDA線上
18 114行        for(i = 0; i < 10; i++);
19 115行
20 116行        IICCON = 0xaf;        //恢復I2C傳輸
21 117行        break;
22 118行    }
23 119行
i2c.c->I2CInitHandle()->switch()->case WRDATA     g_tS3C24xx_I2C.DataCount表示剩餘等待傳輸的數據個數,第102行判斷數據是否已經 全部發送完畢:若是,則通過第105、106行發出P信號,停止傳輸;     第105行設置IICSTAT寄存器以便發出P信號,但是由於這時IICCON[4]仍為1,P信號還沒 有實際發出;     當第106行清除IICCON[4]後,P信號才真正發出去;     第107行等待一段時間,確保P信號已經發送完畢。     如果數據還沒有發送完畢,第111行從緩衝區中得到下一個要發送的數據,將它寫入IICDS 寄存器中。稍等之後,即可在第116行清除IICCON[4]以恢復I2C傳輸,這時,IICDS寄存器中
的數據就會發送出去,這將觸發下一個中斷。     I2C讀操作的處理與寫操作相似,代碼如下:
 1 行號
 2 120行 case RDDATA:
 3 121行 {
 4 122行     if(g_tS3C24xx_I2C.Pt == -1)
 5 123行     {
 6 124行         //這次中斷時在發送I2C設備地址後發生的,沒有數據
 7 125行         //只接收一個數據時,不要發出ACK信號
 8 126行         g_tS3C24xx_I2C.Pt = 0;
 9 127行         if(g_tS3C24xx_I2C.DataCount == 1)
10 128行             IICCON = 0x2f;    //恢復I2C傳輸,開始接收數據,接收到數據時不發出ACK
11 129行         else
12 130行             IICCON = 0xaf;    //恢復I2C傳輸,開始接收數據
13 131行         break;
14 132行     }
15 133行 
16 134行     if((g_tS3C24xx_I2C.DataCount--) == 0)
17 135行     {
18 136行         g_tS3C24xx_I2C.pData[g_tS3C24xx_I2C.Pt++] = IICDS;
19 137行 
20 138行         //下麵兩行恢復I2C操作,發出P信號
21 139行         IICSTAT = 0x90;
22 140行         IICCON  = 0xaf;
23 141行         Delay(10000);        //等待一段時間以便P信號已經發出
24 142行         break;
25 143行     }
26 144行 
27 145行     g_tS3C24xx_I2C.pData[g_tS3C24xx_I2C.Pt++] = IICDS;
28 146行 
29 147行     //接收最後一個數據時,不要發出ACK信號
30 148行     if(g_tS3C24xx_I2C.DataCount == 0)
31 149行         IICCON = 0x2f;        //恢復I2C傳輸,接收到下一個數據時無ACK
32 150行     else
33 151行         IICCON = 0xaf;        //恢復I2C傳輸,接收到下一個數據時發出ACK
34 152行     break;
35 153行  }
case RDDATA     讀操作比寫操作多一個步驟:第一次中斷發生時,表示發出了地址,這時候還不能讀取 數據。在代碼中要分辨這點。對應第122~132行:如果g_tS3C24xx_I2C.Pt等於-1,表示 這是第一次中斷,然後修改g_tS3C24xx_I2C.Pt為0,並設置IICCON寄存器恢復I2C傳輸 (第127~130行)。     當數據傳輸已經開始後,每接收到一個數據就會觸發一次中斷。後面的代碼讀取數據, 判斷所有數據是否已經完成:如果完成則發出P信號,否則繼續下一次傳輸。     第134行判斷數據是否已經發送完畢。     第19行設置IICSTAT寄存器以便發出P信號,但是由於這時IICCON[4]仍為1,P信號還沒 有實際發出。     第140行清除IICCON[4]後,P信號才真正發出。     第145~151行用來啟動下一次數據的接收。     第148~151行判斷是否只剩下最後一個數據了:若是,則通過第149行的清除IICCON[4]、 IICCON[7],這樣即可恢復IIC傳輸,並使得接收到數據後,S3C2410/S3C2440不發出ACK 信號(這樣從機即可知道數據傳輸完畢);否則在第151行中只要清除IICCON[4]以恢復IIC傳輸。     中斷服務程式中,當數據數據傳輸完畢時,g_tS3C24xx_I2C.DataCount將自減為-1,這樣, i2c_read或i2C_write函數即可跳出等待,直接返回。 5.RTC晶元M4lt11特性相關的操作     m4lt11.c文件中提供兩個函數m4lt11_set_datetime、m4lt11_get_datetime。它們都通過調 用i2c_read或i2c_write函數來完成與M4lt11的交互。     前面說過,操作M4lt11只需要兩步:發出寄存器地址,發出數據或讀取數據。 m4lt11_set_datetime函數把這兩個步驟合併為一個I2C寫操作,m4lt11_get_datetime函數先發 起一個I2C寫傳輸,再發起一個I2C讀傳輸。     m4lt11_set_datetime函數代碼如下:
 1 行號
 2 29行 /*
 3 30行  *寫m4lt11,設置日期和時間
 4 31行  */
 5 32行 int m4lt11_set_datetime(struct rtc_time *dt)
 6 33行 {
 7 34行    unsigned char leap_yr;
 8 35行    struct{
 9 36行        unsigned char addr;
10 37行        struct rtc_registers rtc;
11 38行     }__attribute__ ((packed)) addr_and_regs;
12          ... .../*設置rtc結構,即根據傳入的參數構造各寄存器的值*/
13 76行    i2c_write(0xD0, (unsigned char *)&addr_and_regs, sizeof(addr_and_regs));
14 77行
15 78行    return 0;
16 79行 }
m4lt11.c->m4lt11_set_datetime()     省略號表示的代碼用來設置addr_and_regs結構體。這個結構體分為兩部分: addr_and_regs表示M4lt11寄存器地址(它被設為0); addr_and_regs.rtc表示M4lt11的8個寄存器——秒、分、時、天(星期幾)、日、月、年、控制寄存器。     根據傳入參數填充好addr_and_regs結構體後,就可以啟動I2C寫操作了。     第38行使用“__attribute__((packed))”設置這個結構體為緊湊格式。使得它的大小 為9位元組(否則大小為12位元組):1位元組用來保存寄存器的地址,8位元組用來保存8個寄存器的值。     m4lt11_get_datetime函數的代碼與m4lt11_set_datetime函數類似,如下所示:
 1 行號
 2 81行 /*
 3 82行  *讀取m4lt11,獲取日期與時間
 4 83行  */
 5 84行 int m4lt11_get_datetime(struct rtc_time *dt)
 6 85行 {
 7 86行    unsigned char addr[1] = {0};
 8 87行    struct rtc_registers rtc;
 9 88行
10 89行    memset(&rtc, 0, sizeof(rtc));
11 90行
12 91行    i2c_write(0xD0, addr, 1);
13 92行    i2c_read(0xD0, (unsigned char *)&rtc, sizeof(rtc));
14 93行
15         ... .../*根據讀出的各寄存器的值,設置dr結構體*/
16 110行    return 0;
17 111行 }
m4lt11.c->m4lt11_get_datetime()     第91行發起一次I2C寫傳輸,設置要操作的M4lt11寄存器地址為0;     第92行發起一次I2C讀傳輸,讀出M4lt11各寄存器的值;     省略號對應的代碼根據讀出的各寄存器的值,設置dr結構。M4lt11中以BCD碼表示 日期與時間,需要轉換為程式使用的一般二進位格式。 12.2.4 I2C實例的連接腳本     本實例要用到第8章NAND Flash控制器的代碼將代碼從NAND Flash複製到SDRAM 中。由於nand代碼中用到全局變數,而全局變數要運行與可讀寫的記憶體中,為了方便, 使用連接腳本將這些初始代碼放到Steppingstone中。     連接腳本為i2c.lds,內容如下:
 1 SECTIONS{
 2     . = 0x00000000;
 3     .init : AT(0){head.o init.o nand.o}
 4     . = 0x30000000;
 5     .text : AT(4096){ *(.text)}
 6     .rodata ALIGN(4) : AT((LOADADDR(.text)+SIZEOF(.text)+3)&~(0x03)){*(.rodata*)}
 7     .data ALIGN(4) :AT((LOADADDR(.rodata)+SIZEOF(.rodata)+3)&~(0x03)){*(.data)}
 8     __bss_start = .;
 9     .bss ALIGN(4) :{ *(.bss) *(COMMON)}
10     __bss_end = .;
11 }
i2c.lds     第2~3行將head.S和nand.c對應的代碼的運行地址設為0,載入地址(存在NAND Flash 上的地址)設為0。從NAND Flash啟動時,這些代碼被覆制到Steppingstone後就可以直接運行。
    第4行設置其餘代碼的運行地址為0x3000 0000;第5行將代碼段的載入地址設為4096, 表示代碼段將存在NAND Flash地址4096處。     第6~7行的“AT(...)”設置rodata段、data段的載入地址依次位於代碼段之後。 “LOADADDR(...)”表示某段的載入地址,SIZEOF(...)表示它的大小。這兩行的前面使用 “ALIGN(4)”使得它們的運行地址為4位元組對齊。為了使各段之間載入地址的相應偏移值等於 地址的相對偏移,需要將“AT(...)”中的值也設為4位元組對齊:先加上3,然後與~(0x03)進 行與操作(將低2位清0)。 12.2.5 實例測試         本程式在main函數中通過串口輸出一個菜單,用於設置或讀取時間,步驟如下: (1)使用串口將開發板的COM0和PC的串口相連,打開PC的穿褲工具設為115200、8N1; (2)在i2c目錄下執行make,將可執行文件燒入NAND Flash中運行; (3)在PC的串口工具上,可以看到如下菜單:
#### RTC Menu ####
Data format: 'year.month.day w hour:min:sec', 'w' is week day
eg:2007.08.30 4 01:16:57
[S] Set the RTC
[R] Read the RTC
Enter your selection:
(4)要設置RTC,輸入"s"或“S”。可以看到如下字元。
Enter data&time:
    在串口工具中按照"year.month.day w hour:min:sec"格式輸入日期與時間,比如:"2007.08.30 4 01:16:57",然後按回車鍵。 註意:只能輸入2000.01.1至2099.12.31之間的日期與時間;年月日與星期必須真實存 在,否則RTC晶元無法正常工作。 (5)要可讀取RTC,輸入"r"或"R",即可看到當前日期與時間,串口上回輸出類似 下麵的結果。
*** Now is: 2007.08.30 4 01:16:57 ***
(6)斷電後重啟,輸入“R”,仍可看到正確的時間。 附:代碼: 鏈接: https://pan.baidu.com/s/1kV24a9L 密碼: tfab
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • nohup命令 起因 ssh到機器上,然後執行某個程式,再登錄發現程式早就不運行了。 原因 ssh過去之後,執行的大部分命令(守護進程不會斷開),都是ssh進程的子進程,ssh斷開,命令自然會中斷 解決辦法 命令前面加nohup就可以了,比方說: 局限性 當再次ssh過去的時候程式可能在運行,但是無 ...
  • 兩個命令df 、du結合比較直觀 df -h 查看整台伺服器的硬碟使用情況 cd / 進入根目錄 du -sh * 查看每個文件夾的大小 du -lh --max-depth=1 : 查看當前目錄下一級子文件和子目錄占用的磁碟容量。 這樣的組合可以快速定位大文件和分區滿了 ...
  • 本文目錄:1. 背景知識 1.1 java和jdk概念 1.2 jsp、servlet是什麼 1.3 web伺服器、web容器、應用程式伺服器 1.4 tomcat體繫結構2. 安裝tomcat 2.1 安裝jdk 2.2 安裝tomcat 1. 基礎背景知識 1.1 java和jdk概念 無論是何 ...
  • Vsftp服務 服務功能:文件傳輸 1.環境部署 ip=192.168.1.50 [root@localhost /]# rpm -ivh /mnt/Packages/vsftpd-2.2.2-11.el6_4.1.x86_64.rpm 2.匿名訪問 1)設置配置文件 [root@localhost ...
  • keepalived是什麼 keepalived直譯就是保持存活,在網路裡面就是保持線上了,也就是所謂的高可用或熱備,用來防止單點故障(單點故障是指一旦某一點出現故障就會導致整個系統架構的不可用)的發生,keepalived實現的基礎是vrrp,至於vrrp是什麼請直接看這裡 "vrrp" ,下麵我 ...
  • iptables的使用 基本用法: 詳細用法說明: 1)table 2)subcommand選項 1》鏈管理 2》查看: 3》規則管理: 3)鏈chain: 4)match,匹配條件 1》基本匹配條件: 2》擴展匹配條件: 1 隱式擴展 :對某一種協議的擴展 1.tcp 協議, m tcp,擴展選項 ...
  • 由於記憶力有限,把平時常用的Linux命令整理出來,以便隨時查閱。 ls (list 顯示當前目錄下文件和目錄 ls -l 詳細顯示 =ll ) ifconfig ( ifconfig ,查看本機 IP地址,子網掩碼等 ) :wq ( 保存退出 ) :q! (不保存退出) ...
  • umask 設定文件創建時的預設模式,對於文件最大值為6,對於目錄最大值為7。 系統不允許創建一個文本文件就賦予可執行許可權,而目錄對應位表示進入或可搜索許可權,故最大值為7 find -perm 八進位表示許可權值前不加橫杠表示所屬主,加了表示所有用戶 -prune 若同時指定-depth選項,則該選項 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...