ARM9的SPI
来源:互联网 发布:168套优化重组2017答案 编辑:程序博客网 时间:2024/05/16 17:49
实验前须知:
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)的方式。
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
- ARM9的SPI
- ARM9 ADS8344 SPI驱动移植 (一)
- ARM9 ADS8344 SPI驱动移植 (二)
- ARM9 ADS8344 SPI驱动移植 (三)
- ARM9 ADS8344 SPI驱动移植 (四)
- ARM9 2440硬件SPI驱动程序-NRF24L01
- ARM7 ARM9的区别
- ARM9的存储器
- ARM9的时钟
- ARM9的存储控制器
- ARM9的中断体系结构
- ARM9的IIC
- ARM9的LCD
- ARM9的中断控制器
- 基于ARM9的逻辑运算
- ARM9
- arm7与arm9的区别
- ARM7与ARM9的区别
- ARM9的系统时钟和串口(非流控 + 非FIFO + 查询方式)
- * CPSR 和 SPSR
- POJ - 3087 Shuffle'm Up(模拟题)
- ARM9的IIC
- 在ArcGIS中发布GoogleEarth瓦片为网络地图服务(wms)
- ARM9的SPI
- ARM9的LCD
- GPIO的上拉下拉功能说明
- java中接口的定义与实现 http://blog.csdn.net/yjkwf/article/details/7238847
- Linux设备驱动之一 ---- 驱动的框架及其操作流程
- Linux设备驱动前的工作准备 ---- 内核的配置及Makefile编写
- patch命令的使用
- 任务中将某个提示语修改或去除的简便方法
- Linux设备驱动程序之二 ---- 完善上一节的驱动程序