ARM9的SPI
實驗前須知:
SPI的原理:
注:
CLK傳輸時鐘
MISO主機輸入從機輸出
MOSI主機輸出從機輸入
CS片選信號,由于SPI控制器可以外接多個SPI設備,所以這個用于選中SPI設備。
SPI的操作流程大體如下圖所示:
實驗的目的:
用s3c2440的SPI控制器操作SPI總線上的兩個設備,分別是OLED和FLASH
實驗的源程序:
07th_spi_i2c_adc_mini2440_tq2440_spi_controller.rar
實驗的問題總結:
1>我們主要分析一下s3c2440_spi.c這個文件
/*************************************s3c2440_spi.c**********************************
#include "s3c24xx.h"
/* SPI controller */
static void SPI_GPIO_Init(void)
{
/* GPG1 OLED_CSn output
* GPG10 FLASH_CSn output
*/
GPGCON &= ~((3<<(1*2)) " (3<<(10*2)));
GPGCON |= (1<<(1*2)) | (1<<(10*2));
GPGDAT |= (1<<1) | (1<<10);
/*
* GPF3 OLED_DC output
* GPE11 SPIMISO
* GPE12 SPIMOSI
* GPE13 SPICLK
*/
GPFCON &= ~(3<<(3*2));
GPFCON |= (1<<(3*2));
GPECON &= ~((3<<(11*2)) | (3<<(12*2)) | (3<<(13*2)));
GPECON |= ((2<<(11*2)) | (2<<(12*2)) | (2<<(13*2)));
}
void SPISendByte(unsigned char val)
{
while (!(SPSTA0 & 1));
SPTDAT0 = val;
}
unsigned char SPIRecvByte(void)
{
SPTDAT0 = 0xff;
while (!(SPSTA0 & 1));
return SPRDAT0;
}
static void SPIControllerInit(void)
{
/* OLED : 100ns, 10MHz
* FLASH : 104MHz
* 取10MHz
* 10 = 50 / 2 / (Prescaler value + 1)
* Prescaler value = 1.5 = 2
* Baud rate = 50/2/3=8.3MHz
*/
SPPRE0 = 2;
SPPRE1 = 2;
/* [6:5] : 00, polling mode
* [4] : 1 = enable
* [3] : 1 = master
* [2] : 0
* [1] : 0 = format A
* [0] : 0 = normal mode
*/
SPCON0 = (1<<4) | (1<<3);
SPCON1 = (1<<4) | (1<<3);
}
void SPIInit(void)
{
/* 初始化引腳 */
SPI_GPIO_Init();
SPIControllerInit();
}
***********************************s3c2440_spi.c***************************************/
在這個文件中,我們主要分析一下SPISendByte()和SPIRecvByte(),
從這兩個函數(shù)中,我們可以很清晰地知道SPI的操作是非常簡單的。這些操作就是根據(jù)上述那個流程圖來的。
由于我們的SPI總線上沒有接MMC或SD,所以步驟3,4,10都不需要。而在接收數(shù)據(jù)時,我們選擇了接收數(shù)據(jù)(1)的方式。