51单片机模拟spi串行接口程序
- 格式:doc
- 大小:48.50 KB
- 文档页数:8
单片机模拟SPI程序单片机模拟SPI程序分类: C/C++IO口模拟SPI通信C51程序 /************************** 文件所用资源1.端口:P0.4,P0.5,P0.6,P0.72.调用delay_ms函数**************************//*************************模拟SPI接口I/O定义*************************/sbit spi_cs=P0^1;sbit spi_di=P0^2;sbit spi_clk=P0^3;sbit spi_do=P0^4;/*******************************向SPI器件写入一个字节数据*******************************/void spi_write(unsigned char spi_dat){unsigned char i;spi_cs=0;for (i=0;i<8;i++){spi_clk=0;if((spi_dat & 0x80)==0x80)spi_di=1;else spi_di=0;spi_clk=1;spi_dat=(spi_dat<<1);}spi_cs=1;}/******************************** 从SPI器件读出一个字节数据********************************/ unsigned char spi_read(){unsigned char i,spi_dat;spi_cs=0;for (i=0;i<8;i++){spi_clk=0;spi_dat=(spi_dat<<1);spi_clk=1;if(spi_do==1)spi_dat|=0x01; else spi_dat&=~0x01;}spi_cs=1;return spi_dat;}其实光模拟来说,就时序问题,读取和写入一个字节的时序。
51 单片机模拟spi 串行接口程序51 单片机模拟spi 串行接口程序,在keilc51 下编写sbit CS=P3A5;sbit CLK= P"5;sbit DataI=P1A7;sbit DataO=P1A6;#define SD_Disable() CS=1 // 片选关#define SD_Enable() CS=0 // 片选开unsigned char SPI_TransferByte(unsigned char val){unsigned char BitCounter;for(BitCounter=8; BiCounter!=0; BitCounter--){ CLK=0;DataI=0; // write if(val&0x80) DataI=1;val<<=1;CLK=1;if(DataO)val|=1; // read}CLK=0;return val;}sbit CLK= P1A5;sbit DataI=P1A7;sbit DataO=P1A6;#define SD_Disable() CS=1 // 片选关#define SD_Enable() CS=0 // 片选开unsigned char SPI_TransferByte(unsigned char val){unsigned char BitCounter;for(BitCounter=8; BiCounter!=0; BitCounter--){ CLK=0;DataI=0; // write if(val&0x80) DataI=1;val<<=1;CLK=1;if(DataO)val|=1; // read}CLK=0;return val;}sbit CLK= P1A5; sbit DataI=P1A7;sbit DataO=P1A6;#define SD_Disable() CS=1 // 片选关#define SD_Enable() CS=0 // 片选开unsigned char SPI_TransferByte(unsigned char val) { unsigned char BitCounter;for(BitCounter=8; BiCounter!=0; BitCounter--){ CLK=0;DataI=0; // writeif(val&0x80) DataI=1;val<<=1;CLK=1;if(DataO)val|=1; // read}CLK=0;return val;}sbit CLK= P1A5;sbit DataI=P1A7;sbit DataO=P1A6;#define SD_Disable() CS=1 // 片选关#define SD_Enable() CS=0 // 片选开unsigned char SPI_TransferByte(unsigned char val) { unsigned char BitCounter;for(BitCounter=8; BiCounter!=0; BitCounter--){ CLK=0;DataI=0; // writeif(val&0x80) DataI=1;val<<=1;CLK=1;if(DataO)val|=1; // read}CLK=0;return val;}sbit CLK= P1A5;sbit Datal=P1A7;sbit DataO=P1A6;#define SD_Disable() CS=1 // 片选关#define SD_Enable() CS=0 // 片选开unsigned char SPl_TransferByte(unsigned char val) unsigned char BitCounter;for(BitCounter=8; BiCounter!=0; BitCounter--){ CLK=0;DataI=0; // writeif(val&0x80) DataI=1;val<<=1;CLK=1;if(DataO)val|=1; // read}CLK=0;return val;}sbit CLK= P1A5;sbit Datal=P1A7;sbit DataO=P1A6;#define SD_Disable() CS=1 // 片选关#define SD_Enable() CS=0 // 片选开unsigned char SPl_TransferByte(unsigned char val) { unsigned char BitCounter;for(BitCounter=8; BiCounter!=0; BitCounter--){ CLK=0;DataI=0; // write if(val&0x80) DataI=1;val<<=1;CLK=1;if(DataO)val|=1; // read}CLK=0;return val;}sbit CLK= P1A5;sbit Datal=P1A7;sbit DataO=P1A6;#define SD_Disable() CS=1 // 片选关#define SD_Enable() CS=0 // 片选开unsigned char SPl_TransferByte(unsigned char val) { unsigned char BitCounter;for(BitCounter=8; BiCounter!=0; BitCounter--){ CLK=0;Datal=0; // writeif(val&0x80) Datal=1;val<<=1;CLK=1;if(DataO)val|=1; // read}CLK=0;return val;}sbit CLK= P1A5;sbit Datal=P1A7;sbit DataO=P1A6;#define SD_Disable() CS=1 // 片选关#define SD_Enable() CS=0 // 片选开unsigned char SPl_TransferByte(unsigned char val) { unsigned char BitCounter;for(BitCounter=8; BiCounter!=0; BitCounter--){ CLK=0;Datal=0; // writeif(val&0x80) Datal=1;val<<=1;CLK=1;if(DataO)val|=1; // readCLK=0;return val;}sbit CLK= P1A5;sbit Datal=P1A7;sbit DataO=P1A6;#define SD_Disable() CS=1 // 片选关#define SD_Enable() CS=0 // 片选开unsigned char SPl_TransferByte(unsigned char val) { unsigned char BitCounter;for(BitCounter=8; BiCounter!=0; BitCounter--){ CLK=0;Datal=0; // writeif(val&0x80) Datal=1;val<<=1;CLK=1;if(DataO)val|=1; // read}CLK=0;return val;。
SPI总线在51系列单片机系统中的实现(一)摘要:MCS51系列、MCS96系列等单片机由于都不带SPI串行总线接口而限制了其在SPI总线接口器件的使用。
文中介绍了SPI串行总线的特征和时序,并以串行E2PROM为例,给出了在51系列单片机上利用I/O口线实现SPI串行总线接口的方法和软件设计程序。
关键词:单片机SPI串行总线总线接口1引言SPI(SerialPeripheralInterface--串行外设接口)总线系统是一种同步串行外设接口,它可以使MCU与各种外围设备以串行方式进行通信以交换信息。
外围设置FLASHRAM、网络控制器、LCD显示驱动器、A/D转换器和MCU等。
SPI总线系统可直接与各个厂家生产的多种标准外围器件直接接口,该接口一般使用4条线:串行时钟线(SCK)、主机输入/从机输出数据线MISO、主机输出/从机输入数据线MOST和低电平有效的从机选择线SS(有的SPI接口芯片带有中断信号线INT或INT、有的SPI接口芯片没有主机输出/从机输入数据线MOSI)。
由于SPI系统总线一共只需3~4位数据线和控制即可实现与具有SPI总线接口功能的各种I/O器件进行接口,而扩展并行总线则需要8根数据线、8~16位地址线、2~3位控制线,因此,采用SPI总线接口可以简化电路设计,节省很多常规电路中的接口器件和I/O口线,提高设计的可靠性。
由此可见,在MCS51系列等不具有SPI接口的单片机组成的智能仪器和工业测控系统中,当传输速度要求不是太高时,使用SPI总线可以增加应用系统接口器件的种类,提高应用系统的性能。
2SPI总线的组成利用SPI总线可在软件的控制下构成各种系统。
如1个主MCU和几个从MCU、几个从MCU相互连接构成多主机系统(分布式系统)、1个主MCU和1个或几个从I/O设备所构成的各种系统等。
在大多数应用场合,可使用1个MCU作为控机来控制数据,并向1个或几个从外围器件传送该数据。
51模拟SPI接口在MCS51系列单片机中的实现方法对于不带SPI串行总线接口的MCS51系列单片机来说,可以使用软件来模拟SPI的操作,包括串行时钟、数据输入和数据输出。
对于不同的串行接口外围芯片,它们的时钟时序是不同的。
对于在SCK的上升沿输入(接收)数据和在下降沿输出(发送)数据的器件,一般应将其串行时钟输出口P1.1的初始状态设置为1,而在允许接口后再置P1.1为0。
这样,MCU 在输出1位SCK时钟的同时,将使接口芯片串行左移,从而输出1位数据至MCS51单片机的P1.3口(模拟MCU的MISO线),此后再置P1.1为1,使MCS51系列单片机从P1.0(模拟MCU的MOSI线)输出1位数据(先为高位)至串行接口芯片。
至此,模拟1位数据输入输出便宣告完成。
此后再置P1.1为0,模拟下1位数据的输入输出……,依此循环8次,即可完成1次通过SPI总线传输8位数据的操作。
对于在SCK的下降沿输入数据和上升沿输出数据的器件,则应取串行时钟输出的初始状态为0,即在接口芯片允许时,先置P1.1为1,以便外围接口芯片输出1位数据(MCU接收1位数据),之后再置时钟为0,使外围接口芯片接收1位数据(MCU发送1位数据),从而完成1位数据的传送。
图2所示为MCS51系列单片机与存储器X25F008(E2PROM)的硬件连接图,有关X25F008的详细资料可参考有关文献〔1〕。
图2中,P1.0模拟MCU的数据输出端(MOSI),P1.1模拟SPI的SCK输出端,P1.2模拟SPI的从机选择端,P1.3模拟SPI的数据输入端(MISO)。
下面介绍用MCS51单片机的汇编语言模拟SPI串行输入、串行输出和串行输入/输出的3个子程序。
实际上,这些子程序也适用于在串行时钟的上升沿输入和下降沿输出的其它各种串行外围接口芯片(如A/D转换芯片、网络控制器芯片、LED显示驱动芯片等)。
对于下降沿输入、上升沿输出的各种串行外围接口芯片,只要改变P1.1的输出电平顺序,即先置P1.1为低电平,之后再次置P1.1为高电平,再置P1.1为低电平……,则这些子程序也同样适用。
51单片机教程:单片机串行口通信程序设计1.串行口方式0应用编程 8051单片机串行口方式0为移位寄存器方式,外接一个串入并出的移位寄存器,就能扩展一个并行口。
单片机串行口通信程序设计硬件连接图例:用8051单片机串行口外接CD4094扩展8位并行输出口,如图所示,8位并行口的各位都接一个发光二极管,要求发光管呈流水灯状态。
串行口方式0的数据传送可采用中断方式,也可采用查询方式,无论哪种方式,都要借助于TI或RI标志。
串行发送时,能靠TI置位(发完一帧数据后)引起中断申请,在中断服务程序中发送下一帧数据,或者通过查询TI的状态,只要TI为0就继续查询,TI为1就结束查询,发送下一帧数据。
在串行接收时,则由RI引起中断或对RI查询来确定何时接收下一帧数据。
无论采用什么方式,在开始通信之前,都要先对控制寄存器SCON进行初始化。
在方式0中将,将00H送SCON就能了。
单片机串行口通信程序设计列子ORG 2000HSTART: MOV SCON,#00H ;置串行口工作方式0MOV A,#80H ;最高位灯先亮CLR P1.0 ;关闭并行输出(避象传输过程中,各LED的暗红现象) OUT0: MOV SBUF,A ;开始串行输出OUT1: JNB TI,OUT1 ;输出完否CLR TI ;完了,清TI标志,以备下次发送SETB P1.0 ;打开并行口输出ACALL DELAY ;延时一段时间RR A ;循环右移CLR P1.0 ;关闭并行输出JMP OUT0 ;循环说明:DELAY延时子程序能用前面我们讲P1口流水灯时用的延时子程序,这里就不给出了。
二、串行口异步通信org 0000HAJMP STARTORG 30HSTART:mov SP,#5fh ;mov TMOD,#20h ;T1: 工作模式2mov PCON,#80h ;SMOD=1mov TH1,#0FDH ;初始化波特率(参见表)mov SCON,#50h ;Standard UART settingsMOV R0,#0AAH ;准备送出的数SETB REN ;允许接收SETB TR1 ;T1开始工作WAIT:MOV A,R0CPL AMOV R0,AMOV SBUF,ALCALL DELAYJBC TI,WAIT1 ;如果TI等于1,则清TI并转WAIT1AJMP WAITWAIT1: JBC RI,READ ;如果RI等于1,则清RI并转READAJMP WAIT1READ:MOV A,SBUF ;将取得的数送P1口MOV P1,ALJMP WAITDELAY: ;延时子程序MOV R7,#0ffHDJNZ R7,$RETEND将程序编译通过,写入芯片,插入实验板,用通读电缆将实验板与主机的串行口相连就能实验了。
论坛新老朋友们。
祝大家新年快乐。
在新的一年开始的时候,给大家一点小小的玩意。
工程师经常碰到需要多个串口通信的时候,而低端单片机大多只有一个串行口,甚至没有串口。
这时候无论是选择高端芯片,还是更改系统设计都是比较麻烦的事。
我把以前搞的用普通I/O口模拟串行口通讯的程序拿出来,供大家参考,希望各位兄弟轻点拍砖。
基本原理:我们模拟的是串行口方式1.就是最普通的方式。
一个起始位、8个数据位、一个停止位。
模拟串行口最关键的就是要计算出每个位的时间。
以波特率9600为例,每秒发9 600个位,每个位就是1/9600秒,约104个微秒。
我们需要做一个精确的延时,延时时间+对IO口置位的时间=104微秒。
起始位是低状态,再延时一个位的时间。
停止位是高状态,也是一个位的时间。
数据位是8个位,发送时低位先发出去,接收时先接低位。
了解这些以后,做个IO模拟串口的程序,就是很容易的事。
我们开始。
先上简单原理图:就一个MAX232芯片,没什么好说的,一看就明白。
使用单片机普通I/ O口,232数据输入端使用51单片机P3.2口(外部中断1口,接到普通口上也可以,模拟中断方式的串行口会有用。
呵呵)。
数据输出为P0.4(随便哪个口都行)。
下面这个程序,您只需吧P0.4 和P3.2 当成串口直接使用即可,经过测试完全没有问题.2、底层函数代码如下:sbit TXD1 = P0^4; //定义模拟输出脚sbit RXD1 = P3^2; //定义模拟输入脚bdata unsigned char SBUF1; //定义一个位操作变量sbit SBUF1_bit0 = SBUF1^0;sbit SBUF1_bit1 = SBUF1^1;sbit SBUF1_bit2 = SBUF1^2;sbit SBUF1_bit3 = SBUF1^3;sbit SBUF1_bit4 = SBUF1^4;sbit SBUF1_bit5 = SBUF1^5;sbit SBUF1_bit6 = SBUF1^6;sbit SBUF1_bit7 = SBUF1^7;void delay_bps() {unsigned char i; for (i = 0; i < 29; i++); _nop_(); _nop_();} //波特率9600 模拟一个9600波特率unsigned char getchar2() //模拟接收一个字节数据{while (RXD1);_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); delay_bps();SBUF1_bit0 = RXD1; //0delay_bps();SBUF1_bit1 = RXD1; //1delay_bps();SBUF1_bit2 = RXD1; //2delay_bps();SBUF1_bit3 = RXD1; //3delay_bps();SBUF1_bit4 = RXD1; //4delay_bps();SBUF1_bit5 = RXD1; //5delay_bps();SBUF1_bit6 = RXD1; //6delay_bps();SBUF1_bit7 = RXD1; //7delay_bps();return(SBUF1) ; //返回读取的数据}void putchar2(unsigned char input) //模拟发送一个字节数据{SBUF1 = input;TXD1 = 0; //起始位delay_bps();TXD1 = SBUF1_bit0; //0delay_bps();TXD1 = SBUF1_bit1; //1delay_bps();TXD1 = SBUF1_bit2; //2delay_bps();TXD1 = SBUF1_bit3; //3delay_bps();TXD1 = SBUF1_bit4; //4delay_bps();TXD1 = SBUF1_bit5; //5delay_bps();TXD1 = SBUF1_bit6; //6delay_bps();TXD1 = SBUF1_bit7; //7delay_bps();TXD1 = 1; //停止位delay_bps();}3、实现串行通讯。
基于单片机I/O口模拟的SPI串行通信实现【摘要】基于单片机或ARM芯片的普通I/O口,模拟实现SPI串行通信。
模拟SPI通信需严格时钟时序,只有当主器件模拟的SPI时序与从器件的SPI时序完全一致时,才能实现SPI通信的正常数据交换。
【关键词】I/O口;SPI时序;主器件;从器件1.引言SPI(SeIial Peripheral Interfa即串行外围设备接口)总线技术是一种高效率的串行接口技术,主要用于扩展外设和进行数据交换。
在许多单片机中,已经作为一种标准配置。
但某些应用非常广泛的单片机并不带标准SPI接口,这样就限制了在这些系统中使用带SPI接口的器件。
解决该问题的方法是使用单片机的普通I/O口通过软件模拟的方式实现SPI串口通信,以满足应用需求。
此外,采用标准的SPI接口有很多局限性,在设备外围开发和扩展增加负担,而通过I/O口模拟实现SPI通信将不受这些限制,可轻松实现其外围开发和扩展,灵活性更大;通过I/O口模拟SPI通信,其通用性和可移植性强,实现简单、方便。
2.SPI总线概述SPI通信的总线形式一般采用4线制,即为使能控制线SN、始终控制线SCLK、主出从入线MOSI和主入从出线MISO。
可实现一个主控制器挂接多个从控制器,如图1所示,为SPI总线框图。
使能控制线SN完成对从控制器的片选,当需要与某个控制通信时,将SN 置于打开(高或者低,根据不同芯片分别对待)状态,使从控制器处于可通信状态,同时时钟控制线SCLK用于控制SPI通信的时序,该时序需与从控制器的SPI时序保持完全一致,这样才能保证SPI通信的实现。
主出从入线MOSI为SPI 串口通信数据输出线,主入从出线MISO为SPI串口通信数据输入线。
当主控制器MCU只与一个从控制器通信或所选从控制器无使能控制端时,使能控制线SN可不用,即3线制SPI通信,也可实现模拟SPI通信。
3.SPI通信时序控制相对于标准的SPI通信接口,通过I/O口模拟的SPI通信,其模拟时序要求很严格,即主控制器模拟的SPI时序必须与从控制器的SPI通信时序保持一致,否则会导致在通信时出现接收不到数据或是接收数据错误的情况。
单片机IO口模拟SPI四种模式的程序单片机IO口模拟SPI四种模式的程序#include "iom8535v.h"#define _CPOL 1#define _CPHA 0#define SCK_IO DDRA|=0X01#define MOSI_IO DDRA|=0X02#define MISO_IO DDRA&=0XFB#define SSEL_IO DDRA|=0X08#define SCK_D(X) (X?(PORTA|=0X01):(PORTA&=0XFE)) #define MOSI_D(X) (X?(PORTA|=0X02):(PORTA&=0XFD)) #define SSEL_D(X) (X?(PORTA|=0X08):(PORTA&=0XF7))#define MISO_I() (PINA&0X04)void delay(){unsigned char m,n;for(n=0;n<5;n++);for(m=0;m<100;m++);}/************************************************ 端口方向配置与输出初始化************************************************/ void SPI_Init(void){SCK_IO ;MOSI_IO ;MISO_IO ;SSEL_IO ;SSEL_D(1);MOSI_D(1);#if _CPOL==0SCK_D(0);#elseSCK_D(1);#endif}/**********************************************模式零写数据***********************************************/ #if _CPOL==0&&_CPHA==0 //MODE 0 0 void SPI_Send_Dat(unsigned char dat){unsigned char n;for(n=0;n<8;n++){SCK_D(0);if(dat&0x80)MOSI_D(1);else MOSI_D(0);dat<<=1;SCK_D(1);}SCK_D(0);}/********************************************* 模式零读数据*********************************************/ unsigned char SPI_Receiver_Dat(void){unsigned char n ,dat,bit_t;for(n=0;n<8;n++)SCK_D(0);dat<<=1;if(MISO_I())dat|=0x01;else dat&=0xfe;SCK_D(1);}SCK_D(0);return dat;}#endif/********************************************** 模式二写数据***********************************************/ #if _CPOL==1&&_CPHA==0 //MODE 1 0 void SPI_Send_Dat(unsigned char dat){unsigned char n;for(n=0;n<8;n++){SCK_D(1);if(dat&0x80)MOSI_D(1);else MOSI_D(0);dat<<=1;SCK_D(0);}SCK_D(1);}/********************************************* 模式二读数据*********************************************/ unsigned char SPI_Receiver_Dat(void)unsigned char n ,dat,bit_t;for(n=0;n<8;n++){SCK_D(1);dat<<=1;if(MISO_I())dat|=0x01;else dat&=0xfe;SCK_D(0);}SCK_D(1);return dat;}#endif/********************************************* 模式一写数据*********************************************/ #if _CPOL==0&&_CPHA==1 //MODE 0 1 void SPI_Send_Dat(unsigned char dat){unsigned char n;SCK_D(0);for(n=0;n<8;n++){SCK_D(1);if(dat&0x80)MOSI_D(1);else MOSI_D(0);dat<<=1;SCK_D(0);}}/********************************************* 模式一读数据*********************************************/ unsigned char SPI_Receiver_Dat(void){unsigned char n ,dat,bit_t;for(n=0;n<8;n++){SCK_D(1);dat<<=1;if(MISO_I())dat|=0x01;else dat&=0xfe;SCK_D(0);}SCK_D(0);return dat;}#endif//////////////////////////////////////////////////////////////////////////////////////////////////////////////#if _CPOL==1&&_CPHA==1 //MODE 1 1void SPI_Send_Dat(unsigned char dat){unsigned char n;SCK_D(1);for(n=0;n<8;n++){SCK_D(0);if(dat&0x80)MOSI_D(1);else MOSI_D(0);dat<<=1;SCK_D(1);}}/************************************模式三读数据************************************/unsigned char SPI_Receiver_Dat(void){unsigned char n ,dat,bit_t;SCK_D(0);for(n=0;n<8;n++){ SCK_D(0);dat<<=1;if(MISO_I())dat|=0x01;else dat&=0xfe;SCK_D(1);}SCK_D(1);return dat;}#endif/**************************************************************************/ void main() {SPI_Init();DDRB = 0XFF;//#if _CPOL//SCK_D(0);//#endifwhile(1){//SSEL_D(0);//SPI_Send_Dat(0x01);//SPI_Send_Dat(0x31);//SSEL_D(1);SSEL_D(0);SPI_Send_Dat(0x81); PORTB =SPI_Receiver_Dat(); SSEL_D(1);//delay();}}。
基于51单片机SPI器件的串口控制0 引言串行外设接口(Serial Peripheral Interface,SPI)是一种高速同步串行输入/输出端口,近年来广泛应用于移位寄存器、D/A 转换器、A/D 转换器、串行E2PROM、LED 显示驱动器等外部设备的扩展。
SPI 接口可以共享,便于组成带多个SPI 接口器件的系统。
其传送速率可编程,连接线少,具有良好的扩展性。
1 SPI 接口介绍SPI 是摩托罗拉公司推出的一种同步串行通信接口,用于微处理器、微控制器和外围扩展芯片之间的串行连接,现已发展成为一种工业标准。
目前,各半导体公司推出了大量的带有SPI 接口的具有各种各样功能的芯片,如RAM,E2PROM,FLASH ROM,A/D 转换器、D/A 转换器、LEDLCD 显示驱动器、I/0 接口芯片、实时时钟、UART 收发器等,为用户的外围扩展提供了极其灵活而价廉的选择。
由于SPI 总线接口只占用微处理器四个I/O 口线,故采用SPI 总线接口可以简化电路设计。
节省很多常规电路中的接口器件和I/O 口线,提高设计的可靠性。
目前,已有部分厂家的单片机具有SPI 接口,如Philips 的P89LPC900,Atmel 的Atmega128 等,但是,大部分单片机不支持SPI 接口。
在实际应用中,出于产品体积、成本和可扩展性等方面的考虑,设计人员往往希望使用不具备SPI 接口的单片机来控制具备SPI接口的外围器件。
现以AT89C2051 单片机模拟SPI 总线操作串行AD7390 为例,如图1 所示,介绍利用单片机的I/O 口通过软件模拟SPI 总线的实现方法。
SPI 使用的四条线是串行时钟线(SCK)、主机输入从机输出线(MISO)、主机输出从机输入线(MOSI)、低电平有效的使能信号线(CS)。
这样,仅需3~4 根数据线和控制线即可扩展具有SPI 接口的各种I/O 器件。
SPI 总线具有以下特点:(1)因连线较少,可简化电路设计。
51单片机串口通信程序(方式2)//应网要求而写//给89c2051单片机编程,用管脚控制其状态输出,即管脚1为高电平时单片机串行口输出十六进制“BBBB0000”的脉冲信号,如果是低电平时再由其他的管脚控制其输出“CCCC5555”和“AAAA1111”。
// 要求:1、单片机没隔40ms发送一组数据// 2、串行口工作是在模式2下进行输出的// 3、波特率是93.75k//此程序写2011年6月9日//特别声明,此程序还未在硬件上测试,请网友们帮忙测试,多提宝贵意见#include <reg51.h>sbit key1 = P1^0;sbit key2 = P1^1;sbit key3 = P1^2;code unsigned char senddata1[4 ]={0xBB,0xBB,0x00,0x00 };code unsigned char senddata2[4]={0xCC,0xCC,0x00,0x00 };code unsigned char senddata3[4 ]={0xAA,0xAA,0x00,0x00 };bit flagcomsend; //串口发送标志,void R_S_Byte(unsigned char R_Byte) //串发送程序{SBUF = R_Byte;while( TI == 0 );TI = 0;}void comsend(unsigned char *TxRxBuffer){unsigned char i;//ES=0;for(i=0;i<4;i++) // 只发送了实际的数据{R_S_Byte(TxRxBuffer[i]);}//ES=1;}void StartUARTT0( void ){ //波特率93.75晶振 6M 串口方式2TMOD = 0x01;SCON = 0x80; //串口方式2,不允许接收TH0 = 0xB1;// 定时器0,方式1,定时40MSTL0 = 0xE0;PCON = 0x00; //波特率不加倍ET0 = 1; PT0 = 1;TR0 = 1;EA = 1;ES = 0;}void intt0( void ) interrupt 1 using 1{ET0 = 0;TH0 = 0xB1;// 定时器0,方式1,定时40MS TL0 = 0xE0;flagcomsend=1; //串口发送标志ET0 = 1; TF0 = 0;}void main(){StartUARTT0( );TR0 = 0;while(1){key1 = 1; key2 = 1; key3 = 1;if( key1||key2||key3){TR0 = 1;}else{TR0 = 0;}if(flagcomsend){flagcomsend = 0;if( key1&&(!key2)&&(!key3)){comsend(senddata1 );}else if( key2&&(!key1)&&(!key3)) {comsend(senddata2 );}else if( key3&&(!key2)&&(!key1)) {comsend(senddata3 );}else{TR0 = 0;}}}}。
【51单片机SD卡SPI模式操作】摘要:sd卡有两种接口模式,一种是sd模式,另一种是spi模式。
在spi模式下,有六根接口线与主机相连,5V电平的51单片机通过电平转换可与3.3V电平的sd卡相连接。
51单片机没有专门的spi总线,可以用51单片机的IO口来模拟spi总结时序。
主机与sd卡的数据交换主要通过命令来实现,通过发送cmd0命令对sd卡进行复位,发送命令cmd1实现sd卡的spi模式初始化。
cmd17、cmd18命令是sd卡的读写扇区命令,对sd卡的操作是严格按照时序进行的。
关键词:sd卡;spi接口;时序sd卡以其大容量、低成本、携带方便、存储数据简单和安全可靠性高被大量应用于数码电子设备中,比如数码相机、数码摄像机、mp3、pda、电子学习机、电子图书等。
对sd卡的操作有复位、初始化、读写等,下面以本人掌握的材料对sd卡的操作进行分析。
一、sd卡的结构sd卡的外形与接口如图1,它有9个接点与主机相连,其接口端定义如表1所示。
sd卡有两种操作模式,一种是sd模式,另一种是spi模式,不同模式下端口的定义不同。
SD模式有一个时钟线、一个命令/反馈线、四根输入/输出信号线、两个电源地和一个电源,所有九根线都有定义,数据传输速率较快。
SPI模式只用到CS片选、数据输入、数据输出、时钟、电源地及电源六根线。
SPI模式较SD模式速度较慢,但很多单片机都有专用的SPI总线,可与sd卡直接相连,使用方便。
SD卡的内部结构如图2所示,主要有四部分组成,一是接口电路,共有九个接口电路,定义如表1所示。
二是接口控制电路,所有操作都由该控制电路具体去执行。
三是内部寄存器组OCR、CID、RCA等。
四是存储数据的存储单元。
接口电路通过控制电路与内部寄存器组成存储单元交换数据,其主要操作有写命令、读数据、写数据、读状态等。
二、sd卡的命令格式sd卡的命令格式固定为6个字节48个位,其格式如图3所示。
开始位固定为0,第二位固定为1,表示主机给sd卡的命令,然后是6位命令索引号,索引号的大小与索引号数字相同,比如cmd0的索引号为000000,索引号41为101001。
关于模拟SPI接口SPI:Serial Peripheral InterfaceSPI接口由四个通道组成:片选信号通道(CS),时序信号通道(SCLK),数据输入通道(Din),数据输出通道(Dout)组成。
通道名在不同器件中可能不同,且部分器件的SPI接口中会缺少Dout通道,但其实际应用依然参照SPI的基本时序。
模拟SPI接口就是模拟其工作时序,数据在SCLK上升沿被MCU写入,在下降沿被MCU读取。
其余按DATASHEET描述编写。
例子:模拟X5045 SPI写时序:/*****************************************************函数原型:void writeMemoryArrayclock_SPI(unsigned char clock)功能:模拟SPI写时序。
******************************************************void writeMemoryArrayclock_SPI(unsigned char dat){int i;for (i=8;i>0;i--) //数据循环8次{if (dat & 0x80)x5045_SI = 1;elsex5045_SI = 0; //数据锁存在SI线内nNop(5);x5045_SCK = 0;nNop(5);x5045_SCK = 1; //上升沿数据输入dat= dat << 1; //数据左移一位}x5045_SI = 0;nNop(5);x5045_SCK = 0;}例子:模拟X5045 SPI读时序/*************************************************************** 函数原型:void readMemoryArrayclock_SPI(unsigned char dat)功能:模拟SPI读时序。
基于51单片机的SPI总线基于51单片机的SPI总线单片机和其它芯片或设备之间的数据传输在单片机的使用中具有重要的地位,单片机本身的数据传输接口过去主要为8位并行数据接口或异步串行通信接口,但电子技术的迅速发展使得许多新的数据传输接口标准不断涌现,大多数的51单片机并没有在硬件中集成这些新的数据传输接口。
SPI(Serial Peripheral Interface)总线是由Motorola公司提出的一种同步串行外围接口,采用三或四根信号线。
51单片机一般并没有在硬件中集成这种新的接口,所以要用软件来进行模拟。
1 硬件设计DS1302是涓流充电时钟芯片,内含有一个实时时钟/日历和31字节静态R AM,实时时钟/日历电路提供秒、分、时、日、星期、月、年的信息,每月的天数和闰年的天数可自动调整,时钟操作可通过AM/PM指示决定采用24或12小时格式。
DS1302和单片机之间能简单地采用SPI同步串行的方式进行通信,仅需用到三根信号线:RES(复位),I/O(数据线),SCLK(同步串行时钟)。
通过16 02LCD显示日期和时间,其电路如下所示。
在桌面上双击图标,打开ISIS 7 Professional窗口(本人使用的是v7.4 SP3中文版)。
单击菜单命令“文件”→“新建设计”,选择DEFAULT模板,保存文件名为“SPI.DSN”。
在器件选择按钮中单击“P”按钮,或执行菜单命令“库”→“拾取元件/符号”,添加如下表所示的元件。
51单片机AT89C51 一片晶体CRYSTAL 12MHz 一只瓷片电容CAP 22pF 二只电解电容CAP-ELEC 10uF 一只电阻RES 10K 一只排阻 RESPAC-8 10K 一只1602液晶显示器 LM016L 一只晶体CRYSTAL 32.768KHz 一只时钟芯片DS1302 一片电池BATTERY 3V 一只若用Proteus软件进行仿真,则上图中的两只晶体、U1的复位电路和U1的31脚以及电池都可以不画,它们大都是默认的。