单片机spi通信的问题

物品用单片机的I/O口输出SPI接到74hc595再用来驱动数码管。我只是初步接触SPI通信,请问我用C8051F330的话,我用P0.0~P0.2输出SPI,P0.4接... 物品用单片机的I/O口输出SPI接到74hc595再用来驱动数码管。我只是初步接触SPI通信,请问我用C8051F330的话,我用P0.0~P0.2输出SPI,P0.4接74hc595的RCK,谁能告诉我怎么启动SPI传输数据的程序吗?比如我要把这个数组的数据传给出去该怎么写呢??图中的SCAN

int sm[12]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40};
展开
 我来答
lfflash
2010-08-06 · TA获得超过607个赞
知道小有建树答主
回答量:333
采纳率:0%
帮助的人:146万
展开全部
对于C8051F330而言,你需要设置好SPI的时序,极性以及空闲时的状态,一般在送完一个字节后,要等待spi中断后,在能进行第二次送数据
我截取部分程序给你看看
void SPI_INT(void) //SPI初始化
{
SPI0CFG=0x40;
SPI0CN=0x01; //0000 0001最后一位是SPI使能位 SPI工作在三线主方式
SPI0CKR=0x0f; //SPI 时钟频率设置为100kHz 0x63

IE &= 0xbf; //关闭SPI中断
}

void pio_int(void) // 端口配置
{
XBR0=0x06;
XBR1=0x40;

P0MDIN=0xff; //禁止模拟输入,0为模拟,1为数字
P0MDOUT=0x0d; //0为开漏,1为推挽(ff)
P0SKIP=0x08;

P1MDIN=0xff;
P1MDOUT=0xff; //低四位用于138
P1SKIP=0x00;

P0=0xff;
P1=0xff;

}

/***********************/
SPI0DAT = sm[i];
while(!SPIF);
SPIF=0;
//这部分就是SPI的传输指令,送一个字节后,等待中断,然后清中断
标志,然后再送
//按照你想要的东西,就可以写成
for(i=0;i<12;i++)
{
SPI0DAT = sm[i];
while(!SPIF);
SPIF=0;

CLK = 1;//这个就定义成你595的所存输出
CLK = 0;

delay(1);//像你送一个595显示的话,还要延时一下
//如有更多的,就送多次再延时
}

/************************/

我空间有个点阵驱动的程序,你可以去看看
用的就是你的这个单片机
日志名字

QQ空间247519442
C8051F330 16*16点阵(SPI 、SMBus、I2C)PCF8563
谢应宸
2010-07-30 · TA获得超过2640个赞
知道大有可为答主
回答量:2731
采纳率:66%
帮助的人:2120万
展开全部
不太清楚你是怎么个接法
给你个网址参考下http://blog.sina.com.cn/s/blog_530f95e90100fcpu.html

SPI通信可以直接根据datasheet的时序来走
根据上升和下降的规律来接受或发送数据
一个8位循环即可搞定

void SPI_TEST(void)
{
int i;
U32 k;
Uart_Printf("SPI COMMNICATION\n");
Uart_Printf("SPI0 is master ,SPI1 is slave!\n");
SPI_Init();
rGPBCON = 0x15400;
while(1)
{
for(i=0;i<19;i++)
{
rGPBDAT=0x00;
while(!(rSPSTA0&0x01));
rSPTDAT0=data[i];
delay(1000);

rGPBDAT=0xFF;
delay(1000);
}
}
Uart_Printf("\nthat's ok!\n");
}
void SPI_Init(void)
{
rGPECON=(2<<26)|(2<<24)|(2<<22);
rGPGCON=(3<<14)|(3<<12)|(3<<10)|(3<<6)|(1<<4);
rGPGUP&=0xFF13;
rGPEUP&=0xC7FF;
rSPPRE0=PCLK/2/ucSpiBaud-1;
rSPCON0=(0<<5)|(1<<4)|(1<<3)|(0<<2)|(0<<1)|(0<<0);
rSPPRE1=PCLK/2/ucSpiBaud-1;
rSPCON1=(0<<5)|(1<<4)|(0<<3)|(0<<2)|(0<<1)|(0<<0);
rSPPIN0=(0<<2)|(1<<1)|(0<<0);
rGPGDAT&=0xFFFB;

}
void delay(U32 dly)
{
U32 i;
for(;dly>0;dly--)
for(i=0;i<50000;i++);
}

同时可以把74HC595移出的数据用SPI读取

while(!(rSPSTA0&0x01));
k= rSPRDAT1;
Uart_Printf("RX %x\n",k);
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
百度网友86904c4
2010-08-04 · TA获得超过297个赞
知道小有建树答主
回答量:137
采纳率:0%
帮助的人:83.1万
展开全部
不明白你为什么要用SPI驱动595,SPI和595完全对不上关系,595只是一个数据,时钟,锁存

给你写一个595的驱动程序
#include<reg51.h>
#define data_1 P1 |= (1<<0) //P0.0为595数据信号
#define data_0 P1 &= ~(1<<0)
#define sck_1 P1 |= (1<<1) //P0.1为595时钟信号
#define sck_0 P1 &= ~(1<<1)
#define rck_1 P1 |= (1<<2) //P0.2为595锁存信号
#define rck_0 P1 &= ~(1<<2)
unsigned char sm[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40};

void Byte_Write(unsigned char date) //从595发出一个字节数据
{
unsigned char i;

rck_0;
for(i=0;i<8;i++)
{
sck_0;

if(date&0x80) data_1//数据高位在前
else data_0;

sck_1; data<<=1;
}
rck_1; //一个字节发送结束
}

void Pt_Write(*date) //发送一个数组数据
{
unsigned chae size;
size = sizeof(sm);
while(size--)
{
Byte_Write(*data++);
}
}

void main()
{
Pt_Write(sm); //直接调用数组名,数组长度不限制
while(1);
}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
做而论道
高能答主

2010-07-30 · 把复杂的事情简单说给你听
知道大有可为答主
回答量:3万
采纳率:80%
帮助的人:1.1亿
展开全部
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式