STC单片机spi通讯
时间:10-02
整理:3721RD
点击:
各位,最近在使用STC12LE5A60S2这款单片机彼此进行SPI通讯,参考各种例程,老是调试不同,特来求助,下面贴上程序...!
其中主机程序中通过UART_SendByte();发送abc是为了看程序执行到了哪里,通过串口助手发现程序无法发送c,而且更奇怪的是每次电脑向串口发送一个字符,便会收到重新收到一次ab!
使用的是26MHz的晶振,主从机都是同样的晶振。
先谢谢大家了...!
主机程序:
#include<reg52.h>
//接口定义
/* SCLK/P1.7 MOSI/P1.5 MISO/P1.6 SS/1.4*/
sbit SCLK = P1^7;
sbit MISO = P1^6;
sbit MOSI = P1^5;
sbit SS = P1^4;
//寄存器定义
sfr AUXR = 0x8E; //0000,0000 辅助寄存器
sfr SPSTAT = 0xCD; //00xx,xxxx SPI状态寄存器
sfr SPCTL = 0xCE; //0000,0100 SPI控制寄存器
sfr SPDAT = 0xCF; //0000,0000 SPI数据寄存器
sfr IE2 = 0xAF; //0000,0000 中断控制寄存器2
//变量定义
unsigned char UART_SendData=0;
unsigned char UART_RecData=0;
unsigned char SPI_RecData=0;
//函数声明
void Init_Uart(void);
void UART_SendByte(unsigned char dat);
void Init_SPI(void);
unsigned char SPI_SendByte(unsigned char SPI_SendData);
void main(void)
{
Init_Uart();
Init_SPI();
UART_SendByte('a');
while(1)
{
UART_SendByte('b');
while(!RI);
UART_SendByte('c');
RI = 0;
UART_RecData = SBUF;
UART_SendData = SPI_SendByte(UART_RecData);
UART_SendByte(UART_SendData);
}
}
//串口1 初始化函数
void Init_Uart(void)
{
PCON = 0x00; //SMOD=0,波特率不倍速
SM0 = 0; //SCON寄存器操作,REN=1,允许串行接收数据;方式1,8位UART,波特率可变
SM1 = 1;
REN = 1;
AUXR &= 0xbf; //定时器1时钟为Fosc/12,即12T
AUXR &= 0xfe; //串口1选择定时器1为波特率发生器
TMOD &= 0x0f; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xf9; //设定定时初值
TH1 = 0xf9; //设定定时器重装值
TR1 = 1; //启动定时器1
ES = 1; //开串口1中断
EA = 1; //开总中断
}
void UART_SendByte(unsigned char dat)
{
ES = 0;
SBUF = dat;
while(!TI); //等待发送完成
TI = 0; //清零发送标志位
ES = 1;
}
void Init_SPI(void)
{
SPDAT = 0; //清空SPI数据寄存器
SPSTAT = 0xc0; //清除SPI状态标志位
SPCTL = 0xfd; //CPU_CLK/16,时钟前沿为下降沿,后沿采样,主模式,最低位在前,SPI使能
}
unsigned char SPI_SendByte(unsigned char SPI_SendData)
{
SS = 0;
SPDAT = SPI_SendData; //将串口接收的数据装入SPI数据寄存器
while((SPSTAT&0x80)==0); //等待发送完毕
SPSTAT = 0xc0; //清除中断标志,和写冲突标志,注意是对应位写1才能清零
SPI_RecData = SPDAT;
SS = 1;
return SPI_RecData;
}
从机程序:
#include<reg52.h>
sbit SCLK = P1^7;
sbit MISO = P1^6;
sbit MOSI = P1^5;
sbit SS = P1^4;
sfr SPCTL = 0xce; //0000,0100 SPI控制寄存器
sfr SPSTAT = 0xcd; //00xx,xxxx SPI状态寄存器
sfr SPDAT = 0xcf; //0000,0000 SPI数据寄存器
sfr IE2 = 0xaf; //0000,0000 中断控制寄存器2
unsigned char SPI_Buffer=0;
void Init_SPI();
void main()
{
Init_SPI();
while(1);
}
void Init_SPI()
{
SPCTL = 0xed; //忽略SS,设置为从机模式;CPU_CLK/16,时钟前沿为下降沿,后沿采样,从模式,最低位在前,SPI使能
SPSTAT = 0xc0; //清除状态寄存器
SPDAT = 0;
IE2 = 0x02; //允许SPI中断
EA = 1; //开总中断
}
void SPI_Rec() interrupt 9
{
SPSTAT = 0Xc0;
SPI_Buffer = SPDAT;
SPDAT = SPI_Buffer;
P0 = SPI_Buffer;
}
其中主机程序中通过UART_SendByte();发送abc是为了看程序执行到了哪里,通过串口助手发现程序无法发送c,而且更奇怪的是每次电脑向串口发送一个字符,便会收到重新收到一次ab!
使用的是26MHz的晶振,主从机都是同样的晶振。
先谢谢大家了...!
主机程序:
#include<reg52.h>
//接口定义
/* SCLK/P1.7 MOSI/P1.5 MISO/P1.6 SS/1.4*/
sbit SCLK = P1^7;
sbit MISO = P1^6;
sbit MOSI = P1^5;
sbit SS = P1^4;
//寄存器定义
sfr AUXR = 0x8E; //0000,0000 辅助寄存器
sfr SPSTAT = 0xCD; //00xx,xxxx SPI状态寄存器
sfr SPCTL = 0xCE; //0000,0100 SPI控制寄存器
sfr SPDAT = 0xCF; //0000,0000 SPI数据寄存器
sfr IE2 = 0xAF; //0000,0000 中断控制寄存器2
//变量定义
unsigned char UART_SendData=0;
unsigned char UART_RecData=0;
unsigned char SPI_RecData=0;
//函数声明
void Init_Uart(void);
void UART_SendByte(unsigned char dat);
void Init_SPI(void);
unsigned char SPI_SendByte(unsigned char SPI_SendData);
void main(void)
{
Init_Uart();
Init_SPI();
UART_SendByte('a');
while(1)
{
UART_SendByte('b');
while(!RI);
UART_SendByte('c');
RI = 0;
UART_RecData = SBUF;
UART_SendData = SPI_SendByte(UART_RecData);
UART_SendByte(UART_SendData);
}
}
//串口1 初始化函数
void Init_Uart(void)
{
PCON = 0x00; //SMOD=0,波特率不倍速
SM0 = 0; //SCON寄存器操作,REN=1,允许串行接收数据;方式1,8位UART,波特率可变
SM1 = 1;
REN = 1;
AUXR &= 0xbf; //定时器1时钟为Fosc/12,即12T
AUXR &= 0xfe; //串口1选择定时器1为波特率发生器
TMOD &= 0x0f; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xf9; //设定定时初值
TH1 = 0xf9; //设定定时器重装值
TR1 = 1; //启动定时器1
ES = 1; //开串口1中断
EA = 1; //开总中断
}
void UART_SendByte(unsigned char dat)
{
ES = 0;
SBUF = dat;
while(!TI); //等待发送完成
TI = 0; //清零发送标志位
ES = 1;
}
void Init_SPI(void)
{
SPDAT = 0; //清空SPI数据寄存器
SPSTAT = 0xc0; //清除SPI状态标志位
SPCTL = 0xfd; //CPU_CLK/16,时钟前沿为下降沿,后沿采样,主模式,最低位在前,SPI使能
}
unsigned char SPI_SendByte(unsigned char SPI_SendData)
{
SS = 0;
SPDAT = SPI_SendData; //将串口接收的数据装入SPI数据寄存器
while((SPSTAT&0x80)==0); //等待发送完毕
SPSTAT = 0xc0; //清除中断标志,和写冲突标志,注意是对应位写1才能清零
SPI_RecData = SPDAT;
SS = 1;
return SPI_RecData;
}
从机程序:
#include<reg52.h>
sbit SCLK = P1^7;
sbit MISO = P1^6;
sbit MOSI = P1^5;
sbit SS = P1^4;
sfr SPCTL = 0xce; //0000,0100 SPI控制寄存器
sfr SPSTAT = 0xcd; //00xx,xxxx SPI状态寄存器
sfr SPDAT = 0xcf; //0000,0000 SPI数据寄存器
sfr IE2 = 0xaf; //0000,0000 中断控制寄存器2
unsigned char SPI_Buffer=0;
void Init_SPI();
void main()
{
Init_SPI();
while(1);
}
void Init_SPI()
{
SPCTL = 0xed; //忽略SS,设置为从机模式;CPU_CLK/16,时钟前沿为下降沿,后沿采样,从模式,最低位在前,SPI使能
SPSTAT = 0xc0; //清除状态寄存器
SPDAT = 0;
IE2 = 0x02; //允许SPI中断
EA = 1; //开总中断
}
void SPI_Rec() interrupt 9
{
SPSTAT = 0Xc0;
SPI_Buffer = SPDAT;
SPDAT = SPI_Buffer;
P0 = SPI_Buffer;
}