久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > 基于S5PC100裸(luo)機(ji)程序之SPI(下)

基于S5PC100裸機(ji)程(cheng)序之SPI(下(xia)) 時間:2014-08-02      ;來(lai)源:未知

3 SPI接口應用示例

這(zhe)里將介紹一種通(tong)(tong)過SPI通(tong)(tong)信的Flash,該芯片是(shi)M24PXX,如圖5所示(shi)為(wei)該芯片的原理圖,每根(gen)接線的意義已(yi)經清楚地標識出(chu)來了。


圖5 M25PXX原理圖

這一(yi)款(kuan)芯(xin)片內部集(ji)成了(le)12條指(zhi)令(ling),包括了(le)通(tong)用(yong)的讀、寫、配置等(deng)命令(ling),還有一(yi)個內置的狀(zhuang)(zhuang)態(tai)寄存器,可以通(tong)過該寄存器獲取(qu)芯(xin)片當前狀(zhuang)(zhuang)態(tai)。

如(ru)表7所示(shi)為M5DPXX芯(xin)片指令集。

表(biao)7 M25PXX芯(xin)片指令集

 Instrucion  Description  One-byle Instruction Code  Address Bytes  Dummy Bytes  Date Bytes  
 WREN  寫使能  0000 0110  06h  0  0  0
 WRDI  寫禁止  0000 0100  04h  0  0  0
 RDID  讀取ID  1001 1111  9Fh  0  0  1 to 3
 RDSR  讀狀態寄存器  0000 0101  05h  0  0  1 to ∞
 WRSR  寫狀態寄存器  0000 0001  01h  0  0  1
 READ  字節數據讀取  0000 0011  03h  3  0  1 to ∞
 FAST_READ  高速的字節讀取  0000 1011  0Bh  3  1  1 to ∞
 PP  頁編程  0000 0010  02h  3  0  1 to 256
 SE  扇區擦除  1101 1000  D8h  3  0  0
 BE  塊擦除  1100 0111  C7h  0  0  0
 DP  深度擦除  1011 1001  B9h  0  0  0
 RES  從睡眠模式喚醒以及讀出電特性  1010 1011  ABh  0  3  1 to ∞
 喚醒  0  0  0      

有了上(shang)文的知識做鋪墊,現(xian)在我(wo)們(men)先來看一(yi)下SPI控(kong)制器的基本(ben)編程模型:

(1)設置時鐘源并配置分頻值等參數。

(2)軟復(fu)位后,并(bing)設置(zhi)SPI配置(zhi)寄存器(SPI CONFIGURATION REGISTER)。

(3)設置模式寄存器。

(4)設置從機選擇寄存器。

(5)收(shou)發數據。

根據(ju)以上信(xin)息,這里(li)分成若干模塊來(lai)逐一(yi)實現。

1.相關寄存器結構體定義及宏定義。

/*SPI總線控制器寄存器定義*/
        typedef struct {
               unsigned int CHCFG;
               unsigned int CLKCFG;
               unsigned int MODECFG;
               unsigned int SLAVESEL;
               unsigned int INTEN;
               unsigned int STATUS;
               unsigned int TXDATA;
               unsigned int RXDATA; 
               unsigned int PACKETCNT;
               unsigned int PENDINGCLR;
               unsigned int SWAPCFG;
               unsigned int FBCLK;
        }spi;
        #define SPI0 ( * (volatile spi *)0XEC300000 )
        /* Flash opcodes. */
        #define    OPCODE_WREN        0x06 /*寫使能*/
        #define    OPCODE_WRDA        0x04 /*寫禁止*/
        #define    OPCODE_RDSR        0x05 /*讀狀態寄存器*/
        #define    OPCODE_WRSR        0x01 /*寫狀態寄存器*/
        #define    OPCODE_NORM_READ   0x03 /*低頻率的數據讀取*/
        #define    OPCODE_FAST_READ   0x0b /*高頻率的數據讀取*/
        #define    OPCODE_PP          0x02 /*頁編程*/
        #define    OPCODE_BE_4K       0x20 /* Erase 4KiB block */
        #define    OPCODE_BE_32K      0x52 /* Erase 32KiB block */
        #define    OPCODE_CHIP_ERASE  0xc7 /*擦除整塊芯片*/
        #define    OPCODE_SE          0xd8 /*扇區擦除*/
        #define    OPCODE_RDID        0x9f /*讀ID */
        /*狀態寄存器*/
        #define    SR_WIP             1        /*寫狀態中*/
        #define    SR_WEL               2            /*寫保護鎖*/

2.延時函數,使能芯片及禁用芯片的實現如下。

void delay(int times)
        {
                volatile int i,j;
                for (j = 0; j < times; j++){
                      for (i = 0; i < 100000; i++);
                      i = i + 1;
                }
        }
        void disable_chip(void)
        { 
                /* disable chip*/
                SPI0.SLAVESEL |= 0x1;
                delay(1);
        }
        void enable_chip(void)
        { 
                /* enable chip*/
                SPI0.SLAVESEL &= ~0x1;
                delay(1);
&nbsp;      ; }

3.軟件復位的代碼如下

void soft_reset(void)
        {
                SPI0.CHCFG |= 0x1 << 5;    
                delay(1);
                SPI0.CHCFG &= ~(0x1 << 5);
      &nbsp; }

4.接收(字節讀)的實現。

在實現讀字節功能(neng)的時(shi)候(hou),第一次發送(song)讀指令后(hou),緊接(jie)著芯片就會回送(song)數據,這時(shi)芯片會自動累加(jia)地址,因此需(xu)要(yao)人為(wei)控制所(suo)讀數據的范圍(wei),讀時(shi)序如圖6所(suo)示。


圖6 讀時序

void receive(unsigned char *buf, int len)
        {
                int i;
                SPI0.CHCFG &= ~0x1; // disable Tx  
                SPI0.CHCFG |= 0x1 << 1; // enable Rx    
                delay(1);
                for (i = 0; i < len; i++){
                      buf[i] = SPI0.RXDATA;
                       //S5PC100 SPI支持在FiFo為空時,讀緩存產生SPI時鐘,否則需要發送數據產生時鐘 
                      delay(1);
                }
                SPI0.CHCFG &= ~(0x1 << 1);
   &nbsp;    }

5.發送(寫頁面)的實現。

在發(fa)出寫指令后,要緊(jin)跟(gen)著發(fa)出第一個數據要存放的地址,這個時候再順(shun)序寫入數據,和讀的時候一樣,芯片(pian)會自動累加地址,芯片(pian)的頁(ye)面為256Bytes,寫時序如圖7所示。


圖7 寫時序

關鍵代碼如下。

void transfer(unsigned char *data, int len)
        {
                int i;
                SPI0.CHCFG &= ~(0x1 << 1);
                SPI0.CHCFG = SPI0.CHCFG | 0x1; // enable Tx and disable Rx
                delay(1);
                for (i = 0; i < len; i++){
                        SPI0.TXDATA = data[i];
                        while( !(SPI0.STATUS & (0x1 << 21)) );
                        delay(1);
                }
        SPI0.CHCFG &= ~0x1; 
      ;  }

6.擦除芯片相關操作如下。

這塊芯片提(ti)供了兩種(zhong)擦除(chu)(chu)方式,第一種(zhong)是(shi)分扇區來進行(xing)擦除(chu)(chu),重點(dian)在于選好指(zhi)定的地址,然后進行(xing)擦除(chu)(chu),結合如圖8所示的時(shi)序(xu)圖。


圖(tu)8 擦除扇區時序圖(tu)

第二種是整(zheng)片(pian)芯片(pian)擦(ca)除(chu),如圖9所(suo)示(shi)為整(zheng)片(pian)芯片(pian)的擦(ca)除(chu)時的時序(xu)情況。


圖9 整片芯片擦除(chu)時(shi)序圖

關鍵代碼如下(xia)。

/*擦除扇區*/
        void erase_sector(int addr)
        {
                unsigned char buf[4];
                buf[0] = OPCODE_SE;
                buf[1] = addr >> 16;
                buf[2] = addr >> 8;
                buf[3] = addr;
                enable_chip();
                transfer(buf, 4);
                disable_chip();
        }
        /*擦除芯片*/
        void erase_chip()
        {
                unsigned char buf[4];
                buf[0] = OPCODE_CHIP_ERASE;
                enable_chip();
                transfer(buf, 1);
                disable_chip();
        }

7.解析狀態。

判(pan)斷芯(xin)片工作是(shi)否結束,如圖10所示為狀態寄(ji)存器讀時序(xu)。


圖10 狀態(tai)寄存(cun)器(qi)讀時(shi)序

關鍵代碼如(ru)下。

void wait_till_write_finished()
        {
                unsigned char buf[1]; 
                enable_chip();
                buf[0] = OPCODE_RDSR;
                transfer(buf, 1); 
                while(1) {
                      receive(buf, 1);
                      if(buf[0] & SR_WIP) {
                              //   printf( "Write is still in progress\n" );
                      }
                      else {
                           printf( "Write is finished.\n" );
                           break;
                      }
                }
                disable_chip();
 &nbsp;      }

8.讀芯片ID。

讀ID時序如圖11所示。


圖11 讀ID時序

關鍵代碼如下。

void read_ID(void)
        { 
                unsigned char buf[3];
                int i;
                buf[0] = OPCODE_RDID;
                soft_reset();
                enable_chip();
                transfer(buf, 1);
                receive(buf, 3);
                disable_chip();
                printf("MI = %x\tMT = %x\tMC = %x\t\n", buf[0], buf[1], buf[2]);
         ;}

9.主程序

int main()
        {
                unsigned char buf[10] = "home\n";
                unsigned char data[10] = "morning\n";
                uart0_init();
                printf("aaaaa \n");
                cfg_gpio();       //配置SPI IO功能 
                set_clk();        //使能SPI控制器的時鐘 
                cfg_spi0();       //配置SPI0控制器 
                while(1)
                {
                      read_ID();               //讀出SPI Flash的ID號 
                      write_spi(buf, 4, 0);  //向目標芯片0地址寫入4個字節數據 
                      read_spi(data, 4, 0);  //從目標芯片0地址讀出4個字節數據 
                      printf("read from spi :%s", data);
                }
                return 0;
  &nbsp;     }

上一篇:關于管道使用規則的總結

下一篇:sscanf函數的用法

熱點文章推薦(jian)
華清學員(yuan)就業榜(bang)單
高薪學員(yuan)經驗(yan)分享
熱(re)點新聞推薦
前臺(tai)專線(xian):010-82525158 企業培訓洽談(tan)專線:010-82525379 院校合(he)作洽談專(zhuan)線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,,京公海網安備11010802025203號

回到頂部