本文包含原理图、PCB、源代码、封装库、中英文PDF等资源
您需要 登录 才可以下载或查看,没有账号?注册会员
×
求助:我照搬的《增强型8051单片机实用开发技术》207页的C代码,STC12C5A60S2单片机,只将串口波特率改成了9600/11.0592MHZ晶振,单主单从,忽略SS,从机接收完全正确,但从机发给主机的数据好像滞后了(下图第3个波形),主机采样有时正确,有时错误,比如我一直发送55到串口,返回可能是55,也可能是D5,我搞了一个星期都没搞出来。
据手册介绍:CPHA=1时,数据在SCK的前沿驱动到SPI口线,SPI模块在时钟后沿采样。像下图这样的话,采样时刻正对准了返回信号跳变的边沿,是不是主要问题在这里,如何解决?
完整源代码如下:
#include "stc12c5a.h" //包含STC12C5A60S2寄存器定义文件
#define MASTER 1 //作为从机程序时,将该行注释掉,其余都不用修改。
bit SPI_Receive; //SPI 端口收到数据标志位
unsigned char idata SPI_buffer _at_ 0x30; //保存SPI端口收到的数据
void main(void)
{
unsigned char tmpdata,SPI_status;
#ifdef MASTER
//初始化串口 //9600bps@11.0592MHz
PCON &= 0x7f; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
BRT = 0xDC; //设定独立波特率发生器重装值
AUXR |= 0x04; //独立波特率发生器时钟为Fosc,即1T
AUXR |= 0x01; //串口1选择独立波特率发生器为波特率发生器
AUXR |= 0x10; //启动独立波特率发生器
//初始化SPI
SPCTL=0xfc; //详细注释与汇编语言相同
#else
SPCTL=0xec; //详细注释与汇编语言相同
#endif
SPSTAT=0xc0; //清0标志位SPIF和WCOL
IE2=IE2|0x02; //ESPI(IE2.1)=1,允许SPIF产生中断
SPI_Receive=0; //清标志字
EA=1; //开总中断
while(1) //主循环
{
#ifdef MASTER
if(RI) //判RS-232 串口中收到数据否
{
tmpdata=SBUF; //读取RS-232串口中收到的数据
RI=0;
//将数据发送到从机SPI
IE2&=0xfd; // ESPI(IE2.1)=0,禁止SPIF产生中断
SPDAT=tmpdata; //SPI 发送数据
SPI_status=0;
while(SPI_status==0)
{
SPI_status=SPSTAT; //等待SPIF=1即等待SPI发送完毕
SPI_status=SPI_status&0x80;
}
IE2|=0x02; //ESPI(IE2.1)=1,允许SPIF产生中断
continue;
}
if (SPI_Receive) //判收到从SPI发回数据否
{
SPI_Receive=0; //清0主单片机SPI端口收到数据标志位
TI=0; //清零串口发送中断标志
SBUF=SPI_buffer; //将接收到的数据从RS232串口发送到计算机
while(TI==0); //等待发送完毕
TI=0; //清零串口发送中断标志
}
#else
if (SPI_Receive) //判收是否收到主机SPI发来的数据
{
SPI_Receive=0; //清0主单片机SPI端口收到数据标志位
SPDAT=SPI_buffer; //将收到数据送SPDAT,准备下一次通讯时发回
}
#endif
}
}
void SPI_ISR(void) interrupt 9
{
SPSTAT=0xc0; //清0标志位SPIF和WCOL
SPI_buffer=SPDAT; //保存收到的数据
SPI_Receive=1; //设置SPI端口收到数据标志
} |
|