SPI接口的工作原理

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

SPI接口的工作原理发布:|作者:|来源:mahuaxiao|查看:1979次|用户关注:MAX7456随屏显示(OSD)发生器具有SPI™兼容接口,本应用笔记介绍了SPI接口的工作原理,文中还包含在微控制器内逐位模拟SPI接口的控制器C程序。MAX7456串行接口MAX7456单通道单色随屏显示(OSD)发生器预装了256个字符和图形,并可通过SPI接口在线编程。通过SPI兼容串行接口可以设置工作模式、显示存储器以及字符存储器。状态(STAT)寄存器、显示存储器数据输出(DMDO)寄存器和字符存储器数据输出(CMDO)寄存器都可读,可以对其进行MAX7456随屏显示(OSD)发生器具有SPI™兼容接口,本应用笔记介绍了SPI接口的工作原理,文中还包含在微控制器内逐位模拟SPI接口的控制器C程序。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.写操作图2.读操作图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编译器支持位字段联合/结构语句)。/*Port5OutputRegister*/__no_initvolatile__iounion{unsignedcharPO5;struct{unsignedcharbit0:1;unsignedcharbit1:1;unsignedcharbit2:1;unsignedcharbit3:1;unsignedcharbit4:1;unsignedcharbit5:1;unsignedcharbit6:1;unsignedcharbit7:1;}PO5_bit;}上述代码将一个单字节赋值给PO5,这是微控制器输出端口的地址。然后将另一个字节赋值给相同的可以逐位访问的存储器地址。因此,可用以下命令直接对该端口进行寻址:PO5=0x10;或用以下命令逐位读写:PO5_bit.bit4=1;如果该程序用于其它处理器,该结构需要重新编写。如果采用不支持位字段宽度的老式C编译器,可用位布尔运算设置及清除位:/*Portablebit-setandbit-clearmacros.*/#defineBIT_SET(sfr,bitmask)sfr|=(bitmask)#defineBIT_CLR(sfr,bitmask)sfr&=~(bitmask)#defineBIT00x01#defineBIT10x02#defineBIT20x04#defineBIT30x08#defineBIT40x10#defineBIT50x20#defineBIT60x40#defineBIT70x80example:BIT_SET(PO5,BIT0);BIT_CLR(PO5,BIT6);宏以下是一个简单的编程技巧,使程序更容易移植:用宏定义控制器引脚排列,如下所示。#defineSPI_CSPO5_bit.bit4//PO5_bit.bit4=active-lowCS—chipselect#defineSPI_MOSIPO5_bit.bit5//PO5_bit.bit5=MOSI—masteroutslavein,//datatoMAX7456#defineSPI_MISOPI5_bit.bit7//PO5_bit.bit7=MISO—masterinslaveout,//datafromMAX7456#defineSPI_CKPO5_bit.bit6//PO5_bit.bit6=SCK-SPIclock用以上宏和数据结构可以单独置位及复位每个IO口,命令如下:SPI_CS=1;改变宏时相应引脚也将改变,将上述代码用于其它设计时,如果SPI口引脚排列不同,或为了实现更理想的PCB布局而对引脚进行重新排列,上述程序非常有用。单字节写操作程序单字节写操作(图1)程序如下所示。如果可以保证在程序入口处的/CS和CK线状态正确,可以去掉前两条命令。程序首先发送地址,然后发送数据。进行两次循环。采用单循环及16位数据存储可以简化程序。在MAXQ2000微控制器中执行16位“int”所占用的时间比执行8位“char”长,因此需进行权衡考虑。/**********************************************spiWriteReg**Writestoan8-bitregisterwiththeSPIport************************************************************/voidspiWriteReg(constunsignedcharregAddr,constunsignedcharregData){unsignedcharSPICount;//CounterusedtoclockoutthedataunsignedcharSPIData;//DefineadatastructurefortheSPIdataSPI_CS=1;//Makesurewestartwithactive-lowCShighSPI_CK=0;//andCKlowSPIData=regAddr;//PreloadthedatatobesentwithAddressSPI_CS=0;//Setactive-lowCSlowtostarttheSPIcycle//AlthoughSPIDatacouldbeimplementedasanint,//resultinginone//loop,theroutinesrunfasterwhentwoloops//areimplementedwith//SPIDataimplementedastwochars.for(SPICount=0;SPICount8;SPICount++)//PreparetoclockouttheAddressbyte{if(SPIData&0x80)//Checkfora1SPI_MOSI=1;//andsettheMOSIlineappropriatelyelseSPI_MOSI=0;SPI_CK=1;//ToggletheclocklineSPI_CK=0;SPIData=1;//Rotatetogetthenextbit}//andloopbacktosendthenextbit//RepeatfortheDatabyteSPIData=regData;//PreloadthedatatobesentwithDatafor(SPICount=0;SPICount8;SPICount++){if(SPIData&0x80)SPI_MOSI=1;elseSPI_MOSI=0;SPI_CK=1;SPI_CK=0;SPIData=1;}SPI_CS=1;SPI_MOSI=0;}读字节操作程序读字节操作(图2)程序如下所示,与上述程序类似。首先发送地址,然后发送时钟从MISO读回数据。/**********************************************spiReadReg**Readsan8-bitregisterwiththeSPIport.*Dataisreturned.*******************************************************/unsignedcharspiReadReg(constunsignedcharregAddr){unsignedcharSPICount;//CounterusedtoclockoutthedataunsignedcharSPIData;SPI_CS=1;//Makesurewestartwithactive-lowCShighSPI_CK=0;//andCKlowSPIData=regAddr;//PreloadthedatatobesentwithAddressandDataSPI_CS=0;//Setactive-lowCSlowtostarttheSPIcyclefor(SPICount=0;SPICount8;SPICount++)//PreparetoclockouttheAddressandData{if(SPIData&0x80)SPI_MOSI=1;elseSPI_MOSI=0;SPI_CK=1;SPI_CK=0;SPIData=1;}//andloopbacktosendthenextbitSPI_MOSI=0;//ResettheMOSIdatalineSPIData=0;for(SPICount=0;SPICount8;SPICount++)//Preparetoclockinthedatatoberead{SPIData=1;//RotatethedataSPI_CK=1;//RaisetheclocktoclockthedataoutoftheMAX7456SPIData+=SPI_MISO;//ReadthedatabitSPI_CK=0;//Droptheclockreadyforthenextbit}//andloopbackSPI_CS=1;//RaiseCSreturn((unsignedchar)SPIData);//Finallyreturnthereaddata}自动递增模式下的写字节操作程序自动递增模式下的写字节操作(图3)程序如下所示,与和上述单字节写程序类似。首先发送地址,然后发送时钟从MISO读回数据。/************************************************spiWriteRegAutoIncr**Writestoan8-bitregisterwiththeSPIportusingtheMAX7456'sautoin

1 / 7
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功