?? 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 + -