用于MAX7456随屏显示器SPI

2011-04-22 16:26:53来源: 互联网

MAX7456串行接口

MAX7456单通道单色随屏显示(OSD)发生器预装了256个字符和图形,并可通过SPI接口在线编程。通过SPI兼容串行接口可以设置工作模式、显示存储器以及字符存储器。状态(STAT)寄存器、显示存储器数据输出(DMDO)寄存器和字符存储器数据输出(CMDO)寄存器都可读,可以对其进行写操作和读操作。关于MAX7456寄存器及存储器结构的详细信息请参考数据资料和应用笔记4117,"使用MAX7456存储器和评估板文件生成定制字符和图形"。

MAX7456支持高达10MHz接口时钟(SCLK)。图1为写数据时序,图2是从器件读数据的时序。

写寄存器时,拉低/CS可使能串行接口。在SCLK的上升沿从SDIN读取数据。当/CS变为高电平时,数据锁存到输入寄存器。如果传输过程中/CS变高,程序终止(即数据不写入寄存器)。/CS变低之后,器件等待从SDIN读入第一个字节,以确定正在执行的数据传输类型。

读寄存器时,如上文所述,拉低/CS。地址在SCLK的上升沿锁入SDIN。然后数据在SCLK的下降沿从SDOUT输出。

SPI命令长度为16位:最高8位(MSB)代表寄存器地址,最低8位(LSB)代表数据(图1和2)。这种格式有两个例外:

  1. 自动递增写模式,用于访问显示存储器,是一个8位操作(图3)。写数据前必须写入起始地址。对显示存储器执行自动递增写命令时,8位地址由内部产生,串口只需8位数据,如图3所示。
  2. 从显示存储器读字符数据时,若处于16位工作模式,应该是24位(8位地址+16位数据)。

执行读操作时,只需要8位地址,如图2所示。

图1. 写操作
图1. 写操作

图2. 读操作
图2. 读操作

图3. 自动递增写操作
图3. 自动递增写操作

C程序

下文给出的C程序已针对MAXQ2000微控制器进行了编译,用于MAX7456评估(EV)板。本文给出了完整的程序例程。程序是自述文档,几乎没有附加说明。C程序可从以下文件获得:spi.c和MAX7456.h。

以下程序使用了SPI协议的标准定义,MAXQ2000处理器为SPI主机,MAX7456是SPI从器件。

CS与MAX7456数据资料中的定义相同。
SDIN对应于MOSI (主机出从器件入)。
SDOUT对应于MOSI (主机入从器件出)。
SCLK对应于CK。

前缀SPI_用于全部程序。

数据结构

下文所示数据结构可直接或逐位读写数据,用于独立访问SPI端口。C++和一些较新的C编译器支持位字段联合/结构语句)。

/* 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;
}

上述代码将一个单字节赋值给PO5,这是微控制器输出端口的地址。然后将另一个字节赋值给相同的可以逐位访问的存储器地址。

因此,可用以下命令直接对该端口进行寻址:

PO5 = 0x10;

或用以下命令逐位读写:

PO5_bit.bit4 = 1;

如果该程序用于其它处理器,该结构需要重新编写。

如果采用不支持位字段宽度的老式C编译器,可用位布尔运算设置及清除位:

/* 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 0x80
example: BIT_SET(PO5,BIT0); BIT_CLR(PO5,BIT6);

以下是一个简单的编程技巧,使程序更容易移植:用宏定义控制器引脚排列,如下所示。

#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

用以上宏和数据结构可以单独置位及复位每个IO口,命令如下:

SPI_CS = 1;

改变宏时相应引脚也将改变,将上述代码用于其它设计时,如果SPI口引脚排列不同,或为了实现更理想的PCB布局而对引脚进行重新排列,上述程序非常有用。

单字节写操作程序

单字节写操作(图1)程序如下所示。如果可以保证在程序入口处的/CS和CK线状态正确,可以去掉前两条命令。

程序首先发送地址,然后发送数据。进行两次循环。采用单循环及16位数据存储可以简化程序。在MAXQ2000微控制器中执行16位“int”所占用的时间比执行8位“char”长,因此需进行权衡考虑。

/**************************************************************************************
 * 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 data

  unsigned char SPIData;                                        // Define a data structure for the SPI data

  SPI_CS = 1;                                        		// Make sure we start with active-low CS high
  SPI_CK = 0;                                        		// and CK low

  SPIData = regAddr;                                            // Preload the data to be sent with Address
  SPI_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 1
      SPI_MOSI = 1;                                             // and set the MOSI line appropriately
    else
      SPI_MOSI = 0;
    SPI_CK = 1;                                                 // Toggle the clock line
    SPI_CK = 0;
    SPIData <<= 1;                                              // Rotate to get the next bit
  }                                                             // and loop back to send the next bit
                                                        
                                                                // Repeat for the Data byte
  SPIData = regData;                                            // Preload the data to be sent with Data
  for (SPICount = 0; SPICount < 8; SPICount++)
  {
    if (SPIData & 0x80)
      SPI_MOSI = 1;
    else
      SPI_MOSI = 0;
    SPI_CK = 1;
    SPI_CK = 0;
    SPIData <<= 1;
  }          
  SPI_CS = 1;
  SPI_MOSI = 0;
}

读字节操作程序

读字节操作(图2)程序如下所示,与上述程序类似。首先发送地址,然后发送时钟从MISO读回数据。

/**************************************************************************************
 * spiReadReg
 *
 * Reads an 8-bit register with the SPI port.
 * Data is returned. 
 **************************************************************************************/

unsigned char spiReadReg (const unsigned char regAddr)
{

  unsigned char SPICount;                                       // Counter used to clock out the data
  
  unsigned char SPIData;                  
  
  SPI_CS = 1;                                                   // Make sure we start with active-low CS high
  SPI_CK = 0;                                                   // and CK low
  SPIData = regAddr;                                            // Preload the data to be sent with Address and Data

  SPI_CS = 0;                                                   // Set active-low CS low to start the SPI cycle
  for (SPICount = 0; SPICount < 8; SPICount++)                  // Prepare to clock out the Address and Data
  {
    if (SPIData & 0x80)
      SPI_MOSI = 1;
    else
      SPI_MOSI = 0;
    SPI_CK = 1;
    SPI_CK = 0;
    SPIData <<= 1;
  }                                                             // and loop back to send the next bit
  SPI_MOSI = 0;                                                 // Reset the MOSI data line
  
  SPIData = 0;
  for (SPICount = 0; SPICount < 8; SPICount++)                  // Prepare to clock in the data to be read
  {
    SPIData <<=1;                                               // Rotate the data
    SPI_CK = 1;                                                 // Raise the clock to clock the data out of the MAX7456
    SPIData += SPI_MISO;                                        // Read the data bit
    SPI_CK = 0;                                                 // Drop the clock ready for the next bit
  }                                                             // and loop back
  SPI_CS = 1;                                                   // Raise CS
                      
  return ((unsigned char)SPIData);                              // Finally return the read data
}

自动递增模式下的写字节操作程序

[1] [2] [3]

关键字:显示器

编辑:神话 引用地址:http://www.eeworld.com.cn/mndz/2011/0422/article_7492.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。
论坛活动 E手掌握
微信扫一扫加关注
论坛活动 E手掌握
芯片资讯 锐利解读
微信扫一扫加关注
芯片资讯 锐利解读
推荐阅读
全部
显示器

小广播

独家专题更多

富士通铁电随机存储器FRAM主题展馆
富士通铁电随机存储器FRAM主题展馆
馆内包含了 纵览FRAM、独立FRAM存储器专区、FRAM内置LSI专区三大部分内容。 
走,跟Molex一起去看《中国电子消费品趋势》!
走,跟Molex一起去看《中国电子消费品趋势》!
 
带你走进LED王国——Microchip LED应用专题
带你走进LED王国——Microchip LED应用专题
 
电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2016 EEWORLD.com.cn, Inc. All rights reserved