单片机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}; 展开
int sm[12]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40}; 展开
4个回答
展开全部
对于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
我截取部分程序给你看看
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
展开全部
不太清楚你是怎么个接法
给你个网址参考下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);
给你个网址参考下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);
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
不明白你为什么要用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);
}
给你写一个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);
}
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询