新聞中心

EEPW首頁 > 模擬技術(shù) > 設(shè)計(jì)應(yīng)用 > 用于MAX7456隨屏顯示器SPI

用于MAX7456隨屏顯示器SPI

作者: 時(shí)間:2011-04-22 來源:網(wǎng)絡(luò) 收藏

MAX7456串行接口

MAX7456單通道單色隨屏顯示(OSD)發(fā)生器預(yù)裝了256個(gè)字符和圖形,并可通過SPI接口在線編程。通過SPI兼容串行接口可以設(shè)置工作模式、顯示存儲(chǔ)器以及字符存儲(chǔ)器。狀態(tài)(STAT)寄存器、顯示存儲(chǔ)器數(shù)據(jù)輸出(DMDO)寄存器和字符存儲(chǔ)器數(shù)據(jù)輸出(CMDO)寄存器都可讀,可以對(duì)其進(jìn)行寫操作和讀操作。關(guān)于MAX7456寄存器及存儲(chǔ)器結(jié)構(gòu)的詳細(xì)信息請(qǐng)參考數(shù)據(jù)資料和應(yīng)用筆記4117,"使用MAX7456存儲(chǔ)器和評(píng)估板文件生成定制字符和圖形"。

MAX7456支持高達(dá)10MHz接口時(shí)鐘(SCLK)。圖1為寫數(shù)據(jù)時(shí)序,圖2是從器件讀數(shù)據(jù)的時(shí)序。

寫寄存器時(shí),拉低/CS可使能串行接口。在SCLK的上升沿從SDIN讀取數(shù)據(jù)。當(dāng)/CS變?yōu)楦唠娖綍r(shí),數(shù)據(jù)鎖存到輸入寄存器。如果傳輸過程中/CS變高,程序終止(即數(shù)據(jù)不寫入寄存器)。/CS變低之后,器件等待從SDIN讀入第一個(gè)字節(jié),以確定正在執(zhí)行的數(shù)據(jù)傳輸類型。

讀寄存器時(shí),如上文所述,拉低/CS。地址在SCLK的上升沿鎖入SDIN。然后數(shù)據(jù)在SCLK的下降沿從SDOUT輸出。

SPI命令長度為16位:最高8位(MSB)代表寄存器地址,最低8位(LSB)代表數(shù)據(jù)(圖1和2)。這種格式有兩個(gè)例外:

  1. 自動(dòng)遞增寫模式,用于訪問顯示存儲(chǔ)器,是一個(gè)8位操作(圖3)。寫數(shù)據(jù)前必須寫入起始地址。對(duì)顯示存儲(chǔ)器執(zhí)行自動(dòng)遞增寫命令時(shí),8位地址由內(nèi)部產(chǎn)生,串口只需8位數(shù)據(jù),如圖3所示。
  2. 從顯示存儲(chǔ)器讀字符數(shù)據(jù)時(shí),若處于16位工作模式,應(yīng)該是24位(8位地址+16位數(shù)據(jù))。

執(zhí)行讀操作時(shí),只需要8位地址,如圖2所示。

用于MAX7456隨屏顯示器SPI
圖1. 寫操作

用于MAX7456隨屏顯示器SPI
圖2. 讀操作

用于MAX7456隨屏顯示器SPI
圖3. 自動(dòng)遞增寫操作

C程序

下文給出的C程序已針對(duì)MAXQ2000微控制器進(jìn)行了編譯,用于MAX7456評(píng)估(EV)板。本文給出了完整的程序例程。程序是自述文檔,幾乎沒有附加說明。C程序可從以下文件獲得:spi.c和MAX7456.h。

以下程序使用了SPI協(xié)議的標(biāo)準(zhǔn)定義,MAXQ2000處理器為SPI主機(jī),MAX7456是SPI從器件。

CS與MAX7456數(shù)據(jù)資料中的定義相同。
SDIN對(duì)應(yīng)于MOSI (主機(jī)出從器件入)。
SDOUT對(duì)應(yīng)于MOSI (主機(jī)入從器件出)。
SCLK對(duì)應(yīng)于CK。

前綴SPI_用于全部程序。

數(shù)據(jù)結(jié)構(gòu)

下文所示數(shù)據(jù)結(jié)構(gòu)可直接或逐位讀寫數(shù)據(jù),用于獨(dú)立訪問SPI端口。C++和一些較新的C編譯器支持位字段聯(lián)合/結(jié)構(gòu)語句)。

/* Port 5 Output Register */__no_init volatile __io union{unsigned char PO5;struct{unsigned char bit0          : 1;unsigned char bit1          : 1;unsigned char bit2          : 1;unsigned char bit3          : 1;unsigned char bit4          : 1;unsigned char bit5          : 1;unsigned char bit6          : 1;unsigned char bit7          : 1;} PO5_bit;}

上述代碼將一個(gè)單字節(jié)賦值給PO5,這是微控制器輸出端口的地址。然后將另一個(gè)字節(jié)賦值給相同的可以逐位訪問的存儲(chǔ)器地址。

因此,可用以下命令直接對(duì)該端口進(jìn)行尋址:

PO5 = 0x10;

或用以下命令逐位讀寫:

PO5_bit.bit4 = 1;

如果該程序用于其它處理器,該結(jié)構(gòu)需要重新編寫。

如果采用不支持位字段寬度的老式C編譯器,可用位布爾運(yùn)算設(shè)置及清除位:

/* Portable bit-set and bit-clear macros. */#define BIT_SET(sfr,bitmask) sfr |= (bitmask)#define BIT_CLR(sfr,bitmask) sfr =~ (bitmask)#define BIT0 0x01#define BIT1 0x02#define BIT2 0x04#define BIT3 0x08#define BIT4 0x10#define BIT5 0x20#define BIT6 0x40#define BIT7 0x80example: BIT_SET(PO5,BIT0); BIT_CLR(PO5,BIT6);

以下是一個(gè)簡單的編程技巧,使程序更容易移植:用宏定義控制器引腳排列,如下所示。

#define SPI_CS         PO5_bit.bit4                            // PO5_bit.bit4 = active-low CS—chip select#define SPI_MOSI       PO5_bit.bit5                            // PO5_bit.bit5 = MOSI—master out slave in,// data to MAX7456#define SPI_MISO       PI5_bit.bit7                            // PO5_bit.bit7 = MISO—master in slave out,// data from MAX7456#define SPI_CK         PO5_bit.bit6                            // PO5_bit.bit6 = SCK - SPI clock

用以上宏和數(shù)據(jù)結(jié)構(gòu)可以單獨(dú)置位及復(fù)位每個(gè)IO口,命令如下:

SPI_CS = 1;

改變宏時(shí)相應(yīng)引腳也將改變,將上述代碼用于其它設(shè)計(jì)時(shí),如果SPI口引腳排列不同,或?yàn)榱藢?shí)現(xiàn)更理想的PCB布局而對(duì)引腳進(jìn)行重新排列,上述程序非常有用。

單字節(jié)寫操作程序

單字節(jié)寫操作(圖1)程序如下所示。如果可以保證在程序入口處的/CS和CK線狀態(tài)正確,可以去掉前兩條命令。

程序首先發(fā)送地址,然后發(fā)送數(shù)據(jù)。進(jìn)行兩次循環(huán)。采用單循環(huán)及16位數(shù)據(jù)存儲(chǔ)可以簡化程序。在MAXQ2000微控制器中執(zhí)行16位“int”所占用的時(shí)間比執(zhí)行8位“char”長,因此需進(jìn)行權(quán)衡考慮。

/*************************************************************************************** spiWriteReg** Writes to an 8-bit register with the SPI port**************************************************************************************/void spiWriteReg(const unsigned char regAddr, const unsigned char regData){unsigned char SPICount;                                       // Counter used to clock out the dataunsigned char SPIData;                                        // Define a data structure for the SPI dataSPI_CS = 1;                                        		// Make sure we start with active-low CS highSPI_CK = 0;                                        		// and CK lowSPIData = regAddr;                                            // Preload the data to be sent with AddressSPI_CS = 0;                                                   // Set active-low CS low to start the SPI cycle // Although SPIData could be implemented as an "int", // resulting in one// loop, the routines run faster when two loops // are implemented with// SPIData implemented as two "char"s.for (SPICount = 0; SPICount  8; SPICount++)                  // Prepare to clock out the Address byte{if (SPIData  0x80)                                         // Check for a 1SPI_MOSI = 1;                                             // and set the MOSI line appropriatelyelseSPI_MOSI = 0;SPI_CK = 1;                                                 // Toggle the clock lineSPI_CK = 0;SPIData = 1;                                              // Rotate to get the next bit}                                                             // and loop back to send the next bit// Repeat for the Data byteSPIData = regData;                                            // Preload the data to be sent with Datafor (SPICount = 0; SPICount  8; SPICount++){if (SPIData  0x80)SPI_MOSI = 1;elseSPI_MOSI = 0;SPI_CK = 1;SPI_CK = 0;SPIData = 1;}          SPI_CS = 1;SPI_MOSI = 0;}

上一頁 1 2 3 4 下一頁

評(píng)論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉