实现单片机和PC机进行SPI通讯方法:\x0d\1:电路设计\x0d\设计的电路,利用两片AT89C52芯片,一片做为发送模块,一片做为接收模块。分别编写发送和接收程序,实现数据的发送和接受。通过LED显示接收到的数据。通过示波器观察输出的波形。\x0d\2:编写程序\x0d\根据设计好的电路及题目要求分别编写数据发送程序和数据接收程序。①:数据发送程序#define\x0d\ucharunsignedchar\x0d\#defineuintunsignedint\x0d\\x0d\#defineulongunsignedlong\x0d\//---------------------------#include\x0d\#include\x0d\//---------------------------sbitSPICLK=P1^0;//时钟信号sbitMOSI=P1^1;//主器件数据输出,从器件数据输入sbitMISO=P1^2;//主器件数据输入,从器件数据输出\x0d\sbitSS=P1^3;//从器件使能信号\x0d\voidDat_Transmit(uchardat)//发送数据程序\x0d\{uchari,datbuf;\x0d\datbuf=dat;\x0d\SS=1;while(SS){;}for(i=0;i\x0d\#include\x0d\//---------------------------sbitSPICLK=P1^0;//时钟信号sbitMOSI=P1^1;//主器件数据输出,从器件数据输入sbitMISO=P1^2;//主器件数据输入,从器件数据输出sbitSS=P1^3;//从器件使能信号\x0d\\x0d\//---------------------------voidNop(void)\x0d\{;\x0d\}\x0d\voidDelay(uchart){while(t--){;}\x0d\}\x0d\\x0d\ucharData_Receive(void)//数据接收程序\x0d\{uchari,dat=0,temp;bit\x0d\bt;\x0d\\x0d\SPICLK=1;MISO=1;SS=0;\x0d\//选中器件\x0d\Nop();Nop();\x0d\for(i=0;i回答于 2022-12-14
///////////spih/////////////////////////////
#ifndef
SPI_H
#define
SPI_H
#include
<stc12le5a60s2h>
#include
<spih>
//sfr
P4
=
0xe8;
//STC12LE5A60S2单片机自带SPI控制器连接
//sbit
VCC1
=
P2^0;//
VCC1
NO
USE
//sbit
SON
=
P1^6
;//
MISO
//sbit
SIN
=
P1^5
;//
MOSI
//sbit
SCKN
=
P1^7
;
//
SCK
sbit
CSN
=
P1^4
;//
28J60
--
CS
//sbit
RSTN
=
P3^5
;
//RST,
no
use
//sbit
INTN
=
P3^3
;
//
INT,
no
use
void
init_spi(void);
void
WriteByte(u8_t
temp);
u8_t
ReadByte(void);
#endif
////////////////////////////////////////////////////////////////
///////////////////////////spic/////////////////////////////
#include<spih>
//STC12LE5A60S2单片机自带SPI控制器连接
void
init_spi(void)
{
//SSIG
=
1;
//忽略SS脚
//SPEN
=
1;
//允许SPI工作
//DORD
=
0;
//先传高位MSB
//MSTR
=
1;
//设置单片机为主机
SPCTL
=
0xD0;
//SPI
Control
Register
SSIG
SPEN
DORD
MSTR
CPOL
CPHA
SPR1
SPR0
0000,0100
SPSTAT
=
0xC0;
//
//IE2
|=
0x02;
//允许SPI中断控制位
}
void
WriteByte(u8_t
temp)
{
SPDAT
=
temp;
while(!(SPSTAT
&
0x80));
SPSTAT
=
0xC0;
}
u8_t
ReadByte(void)
{
idata
u8_t
temp;
//SPSTAT
=
0xC0;
SPDAT
=
0x00;
while(!(SPSTAT
&
0x80));
temp
=
SPDAT;
SPSTAT
=
0xC0;
return
temp;
}
////////////////////////////////////////////////////////////////
可以的,但SPI接口的器件有多种工作方式,如高位在前还是低位在前,空闲时时钟线高电平还是低电平
第一个跳变沿还是第二个跳变沿数据有效,程序是不同的,下面程序供参考
sbit CLK=P2^2;
sbit MOSI=P2^3; //发送方方管脚配置
sbit MISO=P2^4;
sbit BIT0=ACC^0;
sbit BIT7=ACC^7;//
void Write(uchar byte)//写数据
{
uchar i;
ACC=byte;
i=8;
while(i)
{
MOSI=BIT7;
CLK=1; // output 'uchar', MSB to MOSI
_nop_();
_nop_(); // shift next bit into MSB
_nop_();
_nop_();
ACC<<=1;
CLK=0; // Set SCK high
i--; // then set SCK low again
_nop_();
}
}
/
/函数:Read(uchar reg)
/功能:NRF24L01的读时序
//
uchar Read(void)
{
uchar i;
i=8;
sbit BIT0=ACC^0;
sbit BIT7=ACC^7;
while(i)
{
CLK=1; // output 'uchar', MSB to MOSI
_nop_();
_nop_();
_nop_();
_nop_(); // shift next bit into MSB
ACC<<=1;
BIT0=MISO ;
CLK=0; // Set SCK high
i--; // then set SCK low again
_nop_();
//led1=~led1;
}
return ACC; // return register value
}
1、SPTAT=0xc0;之后SPIF是不是等于零。如Datasheet,是的。置1清零。
2、SPDAT = SPDAT;两个形式相同,含义却不同。因为发送缓冲和接收缓冲,一个只写,一个只读。所以,没有必要安排两个寄存器分别存放。而是复用了一个地址。左边的是发送缓冲,可以被赋值,如SPDAT =0x11;表示发数据0x11。右边的是接收缓冲,如i=SPDAT;表示接收到的内容读取到i变量中。=赋值语句,是有要求的,左边和右边是不同的。比如0=i;就是不合法的。这样你能理解了为什么是SPDAT = SPDAT了吧。就是把收到的内容再写到发缓冲的意思。
懒得看了,把我的能用的发个你
//ioremap address
int address_map(void)
{
//SPI registers
r_SPCON0 = ioremap(0x59000000,4);
r_SPSTA0 = ioremap(0x59000004,4);
r_SPPIN0 = ioremap(0x59000008,4);
r_SPPRE0 = ioremap(0x5900000C,4);
r_SPTDAT0 = ioremap(0x59000010,4);
r_SPRDAT0 = ioremap(0x59000014,4);
//I/O registers
r_GPACON=ioremap(0x56000000,4);
r_GPADAT=ioremap(0x56000004,4);
r_GPECON = ioremap(0x56000040,4);
r_GPEUP = ioremap(0x56000048,4);
r_GPGCON = ioremap(0x56000060,4);
r_GPGUP = ioremap(0x56000068,4);
r_GPGDAT = ioremap(0x56000064,4);
return 0;
}
//Initialize 2410 spi
void Init_SPI(void)
{
int i;
rSPPRE0 = 0xff; //2410 SPI_BAUD;
rSPCON0 = 0x18; //polling mode is used here!
for(i = 0 ; i < 10 ; i++)
{
rSPTDAT0 = 0xff;
}
rGPECON |= 0800000;
rGPECON &= (~0x05400000);
rGPEUP |= 0x3800;
//GPA13----->CS nGCS2 can not realize
rGPACON |=0x002000;
rGPADAT |=0x002000; //Unselect the chip
//GPG14----->CS
rGPGCON |= 0x10000000;
rGPGCON &= (~0x20000000);
rGPGUP &= (~0x4000);
rGPGDAT |=0x4000; //Unselect the chip
}
//To polling when SPI transfer is not finished
void spi_poll_done(void)
{
int nCount=0;
while(!(rSPSTA0 & 0x01) )
{
nCount++;
if(nCount>=5000)
{
printk("SPI state poll failed\n");
break;
}
}
}
//Transmit data
void spi_tx_data(unsigned char data)
{
spi_poll_done();
rSPTDAT0 = data; //transmit data
spi_poll_done();
}
//Write to MCP2510 with ONE byte
void Write_2510(unsigned char W_ADD, unsigned char W_DATA)
{
enable2510();
udelay(100000);
spi_tx_data(CMD_WRITE);
spi_tx_data(W_ADD);
spi_tx_data(W_DATA);
disable2510();
}
求SPI的SSD1306在linux下的测试程序理解SPI的驱动框架,还是从最基本的三个入口点触发,platform_device,platform_bus,platform_driver。
其中内核一提供给platform_bus,platform_driver在spi_s3c24xx_gpioc和spi_s3c24xxcc中,其中spi_s3c24xx_gpioc用于IO模拟SPI (本例讨论的是IO模拟SPI),spi_s3c24xxcc用于s3c24xx的硬件SPI。因此,我们需要动手写一个platform_device。
看看spi_s3c24xx_gpioc做了些什么。
static int s3c2410_spigpio_probe(struct platform_device dev)
{
/ [cgw]: 分配一个SPI主机 /
master = spi_alloc_master(&dev->dev, sizeof(struct s3c2410_spigpio));
sp = spi_master_get_devdata(master);
platform_set_drvdata(dev, sp);
/ [cgw]: 分配与spi硬件相关的配置,如指定哪些IO为MISO,MOSI,SCLK,CS,SPI工作模式,最大时钟等等 /
/ copy in the plkatform data /
sp->info = dev->devplatform_data;
/ [cgw]: 提供实现SPI各种模式的时序的基本方法,和CS的激活方法 /
/ setup spi bitbang adaptor /
sp->bitbangmaster = spi_master_get(master);
sp->bitbangchipselect =
以上就是关于怎么实现单片机和PC机进行SPI通讯全部的内容,包括:怎么实现单片机和PC机进行SPI通讯、那位高手有STC12C5A60s2单片机的SPI调试程序 谢谢!!、用51单片机引脚实现spi功能的程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)