//******************************************************//
/*spi_m是发送或接收标志位,SPIE为中断允许位,scon中TI,RI怎么考虑??
/********************************************************/
#include <AT89X52.H>
#include <stdio.h>
#define uchar unsigned char;
#define uint unsigned int;
#define MOSI P1_5;
#define MISO P1_6;
#define SCK P1_7;
#define SS P1_4;
#define TXD P3_1;
sfr SPCR = 0xD5;
sfr SPSR = 0xAA;
sfr SPDR = 0x86;
sbit SPIF = 0xB1;
sbit WCOL = 0xB0;
sbit MSTR = 0xD9;
sbit SPIE = 0xDC;
/****定义变量*****************/
//SPSR=00h;
//SPDR=00h;
uchar SPI_RxHead;
uchar SPI_TxHead;
uint SPI_RxBuf[]; //选择字节,还是字容量?//
uint SPI_TxBuf[]; //选择字节,还是字容量?//
uint ReSend_FLAG[];
uchar crc_array[];
uint array_sscl[];
uint array_krzt[];
uint array_bwjl[];
uint array_sjjl[];
uint array_fwjl[];
uint array_xtsz[];
uint array_ddz[];
int crc_buf;
/******************************************************/
/*模拟量装入
/******************************************************/
/*******************************************************/
/*SPI初始化
/*******************************************************/
void int_spi(void)
{
SPCR =0x50; //spe=1,mstr=1:主方式,4倍分频//
SPSR =0x40;
IE =0x90; //ES=1:允许串行中断/
//SS=0; //spi为主器件//
SPI_RxHead=0;
SPI_TxHead=0;
ReSend_FLAG[0]=0x55;
ReSend_FLAG[1]=0x55;
ReSend_FLAG[2]=0x55;
ReSend_FLAG[3]=0x55;
ReSend_FLAG[4]=0x55;
RT=TXD;
}
/**************************************/
/*CRC校验初始化
/**************************************/
void inti_crc(void)
{
char i;
for(i=0;i<16;i++)
crc_array[i]=0x1021*i ;/*为CRC数组赋初值*/
}
/**********************************************************************/
/****CRC校验程序*******************************************************/
/****data为待计算CRC的数据的地址,lenght为参与CRC计算的数据长度*********/
/**********************************************************************/
void crc_cal(int *crc_data,int length)
{
int n1;
int n2;
for(;length!=0;length--)
{
n2=*crc_data++ ;
n1=(crc_buf>>12)&0xf ; /*取此前CRC的高4位*/
crc_buf<<=4 ; /*将此前CRC左移4位*/
crc_buf^=crc_array[n1^((n2>>4&0xf))];
n1=(crc_buf>>12)&0xf ; /*取此前CRC的高4位*/
crc_buf<<=4 ; /*将此前CRC左移4位*/
crc_buf^=crc_array[n1^(n2&0xf)] ;
}
return;
}
/********************************************/
/*把电压电流等参数赋给对应的数组
/********************************************/
/*******************************************/
/*判断接收的是哪种类型BianMa_J()
/*******************************************/
void BianMa_J(void)
{
if(SPI_RxBuf[0]==0x10&&SPI_RxBuf[1]==0x01)
{
int i;
for(;i>=0;i--)array_sscl[i]=SPI_RxBuf[i];//实时测量//
}
if(SPI_RxBuf[0]==0x10&&SPI_RxBuf[1]==0x02)
{
int i;
for(;i>=0;i--)array_krzt[i]=SPI_RxBuf[i];//开入状态//
}
if(SPI_RxBuf[0]==0x10&&SPI_RxBuf[1]==0x03)
{
int i;
for(;i>=0;i--)array_bwjl[i]=SPI_RxBuf[i];//变位记录//
}
if(SPI_RxBuf[0]==0x10&&SPI_RxBuf[1]==0x04)
{
int i;
for(;i>=0;i--)array_sjjl[i]=SPI_RxBuf[i];//事件记录//
}
if(SPI_RxBuf[0]==0x10&&SPI_RxBuf[1]==0x05)
{
int i;
for(;i>=0;i--)array_fwjl[i]=SPI_RxBuf[i];//复位记录//
}
if(SPI_RxBuf[0]==0x10&&SPI_RxBuf[1]==0x06)
{
int i;
for(;i>=0;i--)array_ddz[i]=SPI_RxBuf[i];//读定值//
}
if(SPI_RxBuf[0]==0x10&&SPI_RxBuf[1]==0x07)
{
int i;
for(;i>=0;i--)array_xtsz[i]=SPI_RxBuf[i];//系统设置//
}
//未完//
}
/*******************************************/
/*fill_tx_buffer()
/*******************************************/
fill_tx_buffer()
{
; //判断//
}
//******************************************
// SPI发送/接收一帧
//******************************************
void spi_RT(int SPI_RT_LENGTH)
{
if(TXD&0x01) //如果TXD(spi_m)为0,表明是接收状态
{
if ( SPI_RxHead > SPI_RT_LENGTH ) //如果是接收帧的最后一个数据
{
//把帧中crc地址付给crc_data//
crc_cal(SPI_RxBuf,SPI_RT_LENGTH);//CRC校验
if(crc_buf!=0)TXD=0;
else
{
if(SPI_RxBuf[0]&0x55)TXD=0;
else
{
BianMa_J(); //判断//
}
SPI_RxHead = 0; //计数还原
MSTR=1; //接收完成,将SPI设回主方式?????
SPIE=0; //清空中断申请//
SPIF=1; //置接收完成标志 ,置传输结束标志//
}
}
else
{
SPI_RxBuf[SPI_RxHead] = SPDR; //将接收到的数据存入接收缓存区
SPI_RxHead++; //已接收数据计数器加1
}
}
else //如果spi_m为1,表明是发送状态
{
SPI_TxHead = 0;
if(crc_buf!=0)
{
char j;
for(j=0;;j++)SPI_TxBuf[j]=ReSend_FLAG[j];
if ( SPI_TxHead <= SPI_RT_LENGTH) //如果要发送的数据还未全部发完
{
SPDR = SPI_TxBuf[SPI_TxHead]; //从发送缓存区取数发送
SPI_TxHead++; //已发送数据计数器加1
//while(1);
}
else //如果要发送的数据已全部发完
{
SPI_TxHead=0; //已发送数据计数器还原
//SET_SPI_MODE=1; //释放总线,以便接收方进入主发送。
//spi_m=0;
MSTR=1;
SPIE=0; //清空中断申请//
SPIF=1; //清空发送中标记 ,置传输结束标志//
}
}
if(SPI_RxBuf[0]&0x55)
{
if ( SPI_TxHead <= SPI_RT_LENGTH) //如果要发送的数据还未全部发完
{
SPDR = SPI_TxBuf[SPI_TxHead]; //从发送缓存区取数发送
SPI_TxHead++; //已发送数据计数器加1
//while(1);
}
else //如果要发送的数据已全部发完
{
SPI_TxHead=0; //已发送数据计数器还原
//SET_SPI_MODE=1; //释放总线,以便接收方进入主发送。
//spi_m=0;
MSTR=1;
SPIE=0; //清空中断申请//
SPIF=1; //清空发送中标记 ,置传输结束标志//
}
}
/*根据dis_enter和key_enter值定时发送设定值//
}
//******************************************
//发送数据 中断服务程序
//******************************************/
main()
{
int_spi(); //初始化spi为主方式
SPDR=0xFF; //开始发送,接收方接收到的第一个数据为0xFF应忽略
delay_us(10);
spi_RT(N); //执行数据接发//
}