ARM9的SPI

来源:互联网 发布:168套优化重组2017答案 编辑:程序博客网 时间:2024/05/16 17:49
实验前须知:
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(),
从这两个函数中,我们可以很清晰地知道SPI的操作是非常简单的。这些操作就是根据上述那个流程图来的。
由于我们的SPI总线上没有接MMC或SD,所以步骤3,4,10都不需要。而在接收数据时,我们选择了接收数据(1)的方式。
0 0
原创粉丝点击