⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spi.c

📁 SPI接口通信源程序
💻 C
字号:
//******************************************************//
/*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);		//执行数据接发//  
}
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -