十一:mini2440上面使用SPI控制器实现OLED显示

此次的SPI协议是基于mini2440开发板上SPI控制器,比较上一篇的区别就是使用了控制器,OLED的复位脚一定也要接在2440的复位脚上面,而不用定义一个复位脚给高低电平。

上一篇文章已经介绍了OLED的一些数据信息,和SPI协议的分析。
这里的区别就是控制器的使用,2440上面的SPI控制器也给出了很详细的使用说明。我们要做的事情如下所示:

1. 第一步修改GPIO的设置,上一章节是GPIO模式,因此引脚的使用是output,这里我们使用控制器,就需要将引脚设置为SPI模式,因此GPIO初始化的时候需要修改,代码贴在后面。

2. 第二步就是进行SPI控制器的初始化。初始化的流程2440的手册也写得很清楚。
*1. Set Baud Rate Prescaler Register (SPPREn).
*2. Set SPCONn to configure properly the SPI module.
*3. Write data 0xFF to SPTDATn 10 times in order to initialize MMC or SD card.
*4. Set a GPIO pin, which acts as nSS, low to activate the MMC or SD card.
*5. Tx data ¡ Check the status of Transfer Ready flag (REDY=1), and then write data to SPTDATn.
*6. Rx data(1): SPCONn’s TAGD bit disable = normal mode
*7. ¡ write 0xFF to SPTDATn, then confirm REDY to set, and then read data from Read Buffer.
*8. Rx data(2): SPCONn’s TAGD bit enable = Tx Auto Garbage Data mode
*9. ¡ confirm REDY to set, and then read data from Read Buffer (then automatically start to transfer).
*10. Set a GPIO pin, which acts as nSS, high to deactivate the MMC or SD card

首先设置波特率,那么查看OLED的手册,可以看见OLED的最小时钟是100ns,
就是最大10MHZ。在2440的波特率设置:
 *计算方法:Baud rate = PCLK / 2 / (Prescaler value + 1)
 *我们设置的PCLK=50M(1/2/4) Baud rate = 50M / 2 / (1.5 + 1)=10M
 *Prescaler value取整数2,Baud rate = PCLK / 2 / (2 + 1)=8.3MHZ

然后就是进行SPI控制器的初始化。这里说明一下,OLED接的是SPI0的引脚上面,所以要对SPCON0进行初始化。SPCON0的对应位的含义:
* [6:5] : 00, polling mode 查询模式
* [4] : 1 = enable 使能时钟
* [3] : 1 = master SPI做master
* [2] : 0 CPOL表示时钟初始电平,0为低电平,1为高电平
* [1] : 0 = format A CPHA表示相位,即第一个还是第二个时钟沿采样数据
* [0] : 0 = normal mode
* 在SPI协议中,有两个值来确定SPI的模式。 CPOL和CPHA两个确定了哪种SPI模式;
在这里插入图片描述
初始化完成后进行,读写数据函数的修改,因为现在读写数据是由控制器来控制,我们看说明,可以知道;
Tx data ¡ Check the status of Transfer Ready flag (REDY=1), and then write data to SPTDATn.
就是说要等待REDY信号为1,将要写的数据放到buffer(SPTDAT0)里面就自己完成了数据的发送。
Rx data(1): SPCONn’s TAGD bit disable = normal mode(初始化的时候已经完成)
¡ write 0xFF to SPTDATn, then confirm REDY to set, and then read data from Read Buffer.
就是说首先写0xff到SPTDAT0,然后等待REDY信号为1,就可以获取数据。

剩下的与GPIO操作完全一致,很简单的完成了SPI控制器的使用。当然,SPI控制器简化了很多时序上面的操作,所以了解并实际使用一下是很重要的。

接下来贴上所有代码。
初始化代码:

/*this is  SPI controller
 *use SPI OLED
 *
 **/

#define GPECON (*(volatile unsigned long *)0x56000040)//GPIOE控制寄存器
#define GPEDAT (*(volatile unsigned long *)0x56000044)//GPIOE数据寄存器
#define GPGCON (*(volatile unsigned long *)0x56000060)//GPIOG控制寄存器
#define GPGDAT (*(volatile unsigned long *)0x56000064)//GPIOG控制寄存器
#define GPFCON (*(volatile unsigned long *)0x56000050)//GPIOB控制寄存器
#define GPFDAT (*(volatile unsigned long *)0x56000054)//GPIOG控制寄存器


#define SPCON0  (*(volatile unsigned long *)0x59000000)//SPI0控制寄存器
#define SPCON1  (*(volatile unsigned long *)0x59000020)//SPI1控制寄存器
#define SPSTA0  (*(volatile unsigned long *)0x59000004)//SPI0状态寄存器
#define SPSTA0  (*(volatile unsigned long *)0x59000024)//SPI0状态寄存器
#define SPPIN0  (*(volatile unsigned long *)0x59000008)//SPI0片选寄存器
#define SPPIN1  (*(volatile unsigned long *)0x59000028)//SPI1片选寄存器
#define SPPRE0  (*(volatile unsigned long *)0x5900000C)//SPI0时钟寄存器
#define SPPRE1  (*(volatile unsigned long *)0x5900002C)//SPI1时钟寄存器
#define SPTDAT0 (*(volatile unsigned long *)0x59000010)//SPI0发数据寄存器
#define SPTDAT1 (*(volatile unsigned long *)0x59000030)//SPI1发数据寄存器
#define SPRDAT0 (*(volatile unsigned long *)0x59000014)//SPI0收数据寄存器
#define SPRDAT1 (*(volatile unsigned long *)0x59000034)//SPI0收数据寄存器


/*使用SPI控制器来实现SPI协议*/
static void SPI_GPIO_Init(void)
{
   
	
	/*将GPIO引脚设置为SPI功能引脚,不再是输入输出,这点要与GPIO进行区分
	 *还有就是前面做裸机的时候已经验证了,SPIMOSI引脚第26位GPIO对应的寄存器值是GPE12,而不是手册上面写的GPG6*/
	/*由原理图可以知道
	 *SPIMISO  /GPE11		OLED只输入不输出,此脚不用
	 *SPIMOSI  /GPE12		OLED的输入引脚 
	 *SPICLK   /GPE13		OLED的时钟引脚 
	 *OLED_CSn /GPG1 	 	OLED的片选信号 	   ,CPU output
	 *DC	   /GPF3 		OLED的数据/命令引脚,CPU output
	 *OLED_CSn,DC对应2440引出来的GPIO的第17,12脚
	 *2440的电源和地分别是2,3脚
	 *复位脚是第4脚,直接连接/	
 
	/* GPG1 OLED_CSn output */
    GPGCON &= ~(3<<(1*2));	//清零
    GPGCON |= (1<<(1*2));	//置位OLED_CSn
	
	 /* 
    * GPF3  OLED_DC   output
    * GPE11 SPIMISO   input
    * GPE12 SPIMOSI   output
    * GPE13 SPICLK    output
    */
    GPFCON &= ~(3<<(3*2));  //清零
    GPFCON |= (1<<(3*2));   //置位OLED_DC

    GPECON &= ~((3<<(12*2)) | (3<<(13*2))); //清零
    GPECON |=  ((2<<(12*2)) | (2<<(13*2)));	//置位为功能引脚
}	

static void SPI_CONTROLLER_Init(void)
{
   
	/*1. Set Baud Rate Prescaler Register (SPPREn).
	 *2. Set SPCONn to configure properly the SPI module.
	 *3. Write data 0xFF to SPTDATn 10 times in order to initialize MMC or SD card.
	 *4. Set a GPIO pin, which acts as nSS, low to activate the MMC or SD card.
	 *5. Tx data ¡ Check the status of Transfer Ready flag (REDY=1), and then write data to SPTDATn.
	 *6. Rx data(1): SPCONn's TAGD bit disable = normal mode
	 *7. ¡ write 0xFF to SPTDATn, then confirm REDY to set, and then read data from Read Buffer.
	 *8. Rx data(2): SPCONn's TAGD bit enable = Tx Auto Garbage Data mode
	 *9. ¡ confirm REDY to set, and then read data from Read Buffer (then automatically start to transfer).
	 *10. Set a GPIO pin, which acts as nSS, high to deactivate the MMC or SD card*/
	 
	/*1.设置波特率,OLED的最小时钟是100ns,就是最大10MHZ
	 *计算方法:Baud rate = PCLK / 2 / (Prescaler value + 1)
	 *我们设置的PCLK=50M(1/2/4) Baud rate = 50M / 2 / (1.5 + 1)=10M
	 *Prescaler value取整数2,Baud rate = PCLK / 2 / (2 + 1)=8.3MHZ*/
	SPPRE0 = 2;
	SPPRE1 = 2;
	
	/*2. 设置SPI控制寄存器
	 * [6:5] : 00, polling mode 查询模式
     * [4]   : 1 = enable 		使能时钟
     * [3]   : 1 = master 		SPI做master
     * [2]   : 0		  		CPOL表示时钟初始电平,0为低电平,1为高电平 
     * [1]   : 0 = format A		CPHA表示相位,即第一个还是第二个时钟沿采样数据
	 *	在SPI协议中,有两个值来确定SPI的模式。 CPOL和CPHA两个确定了哪种SPI模式;
	 *	CPOL	CPHA	模式	含义
	 *	0		0		 0		初始电平为低电平,在第一个时钟沿采样数据(上升沿)
	 *	0		1		 1		初始电平为低电平,在第二个时钟沿采样数据
	 *	1		0		 2		初始电平为高电平,在第一个时钟沿采样数据
	 *	1		1		 3		初始电平为高电平,在第二个时钟沿采样数据(上升沿) 
     * [0]   : 0 = normal mode
	 */
	SPCON0 &= ~
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值