STC单片机spi通讯

2019-07-16 00:07发布

各位,最近在使用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;
}




友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。