#include "H/Function_Init.H"
#include "stdio.h"

#if (Test == 5)

//选择三合一模式：
#define  Uart1  0
#define  TWI    1
#define  SPI    2

#define  SSI_Mode  0

#define SPI_Mode 0 //0:主机工作模式   1：从机工作模式
#define SCK P05
void Uart1_Init(uint Freq,unsigned long int baud);
void TWI_Init(void);
void SPI_Init(void);

unsigned char xdata SPOS_SSICK  _at_  0x011D;
unsigned char xdata SPOS_SSITX  _at_  0x011E;
unsigned char xdata SPOS_SSIRX  _at_  0x011F;

bit Uart1SendFlag = 0;    //Uart发送中断标志位
bit Uart1ReceiveFlag = 0; //Uart接收中断标志位
bit SPIFlag = 0;          //SPI数据传输完成标志位
bit TWIFlag = 0;          //中断标志位

volatile uint8_t Uart1_RxData[5]=0;

volatile uint8_t TWI_Slaver_ReceiveData[8]=0;

uint8_t SPI_Master_SendData[8] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
volatile uint8_t SPI_Master_ReceiveData[8];
uint8_t SPI_Slaver_SendData[8] = {0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F};
volatile uint8_t SPI_Slaver_ReceiveData[8];

uint8_t TxXferCount = 0;  //SPI/TWI发送数据数目
uint8_t RxXferCount = 0;  //SPI/TWI接受数据数目

volatile uint8_t tt=0;/*printf(删)*/
/*****************************************************
*函数名称：void SSI_Test(void)
*函数功能：SSI测试
*入口参数：void
*出口参数：void
*****************************************************/
void SSI_Test(void)
{
	int num1,num2,i;
  /* 进行端口映射 */
  SPOS_SSICK = 5;  //SSI CLK映射到P05
	SPOS_SSITX = 8;  //SSI TX映射到P20
	SPOS_SSIRX = 9;  //SSI RX映射到P21
	
#if (SSI_Mode == Uart1)

	Uart1_Init(32,9600);
	while(1)
	{
		  for(num1=0;num1<5;num1++)
			{
        i = 0x8000;   //用作超时处理，通过改变这个变量改变超时时间长度，用户可根据波特率进行调整
				while(!Uart1ReceiveFlag)
        {
          i--;
          if(i == 0)
          {
            break; //超时退出
          }
        }
        if(i == 0)
        {
          break;
        }
				Uart1ReceiveFlag = 0;
				Uart1_RxData[num1] = SSDAT ;
			}
      if(num1 == 5)
      {
        for(num2=0;num2<5;num2++)
        {
          SSDAT  = Uart1_RxData[num2];
          i = 0x8000;   //用作超时处理，通过改变这个变量改变超时时间长度，用户可根据波特率进行调整
          while(!Uart1SendFlag)
          {
            i--;
            if(i == 0)
            {
              break; //超时退出
            }
          }
          Uart1SendFlag = 0;
        }
      }
	}
#endif
	
#if (SSI_Mode == TWI)
	
		TWI_Init();
		while((0x07 & SSCON0)!=0x02);//判断为接收状态
		Delay(50);
	/* 接收数据过程 */
		do
		{
		
			while(TWIFlag == 0);
			TWIFlag = 0;  
			TWI_Slaver_ReceiveData[RxXferCount] = SSDAT;             //TWI接收数据
			if(TWI_Slaver_ReceiveData[0]==0x01)
			RxXferCount++; 
		}  while(RxXferCount < 8);

		SSCON0 |= 0X08; //AA使能位
		RxXferCount =0;
		while((0x07 & SSCON0)!=0x00);
		
    

#endif

#if (SSI_Mode == SPI)
	SPI_Init();
	while(1)
	{
	 #if (SPI_Mode == 0)  //主机
		TxXferCount = 0;
		while(TxXferCount <  8)
		{
		 
			SSDAT = SPI_Master_SendData[TxXferCount];
			
		  /* 等待SPI中断标志位置起 */
			while(SPIFlag == 0);	//等待发送完成
		 
			SPIFlag = 0;		
			SPI_Master_ReceiveData[TxXferCount]=SSDAT;  //读取16位数据,并且地址自增
			TxXferCount ++;	//发送数据量计数加1
		
		}
	  Delay(1000);

	 #elif (SPI_Mode == 1) //从机
		while(RxXferCount <8)
		{
			 SSDAT=SPI_Slaver_SendData[RxXferCount];
			
			/* 等待SPI中断标志位置起 */
			while(SPIFlag == 0);	//等待发送完成
			 
			SPIFlag = 0;		
			SPI_Slaver_ReceiveData[RxXferCount] = SSDAT;			//读取16位数据,并且地址自增
			RxXferCount++;	//接收数据量计数加1
			
		}
		Delay(100);
	  RxXferCount = 0;
	 #endif
	
	}

#endif	
}
/*****************************************************
*函数名称：void Uart1_Init(uint Freq,unsigned long int baud)
*函数功能：Uart1中断初始化
*入口参数：Freq-主频，baud-波特率
*出口参数：void
*****************************************************/
void Uart1_Init(uint Freq,unsigned long int baud)
{
	P2CON &= 0xFC;   //TX/RX设置为输入带上拉
	P2PH  |= 0x03;

	OTCON &= 0X3F;
	OTCON |= 0xC0;    //串行接口SSI选择Uart1通信
	SSCON0 = 0x10;   //设置通信方式为模式一，允许接收
	SSCON1 = Freq*1000000/baud;   //波特率低位控制
	SSCON2 = (Freq*1000000/baud)>>8;   //波特率高位控制
	IE1 = 0x01;      //开启SSI中断
  EA = 1;	
}

/*****************************************************
*函数名称：void TWI_Init(void)
*函数功能：TWI初始化
*入口参数：void
*出口参数：void
*****************************************************/
void TWI_Init(void)
{	
	P0CON &= 0xDF;    //SCK设置为输入带上拉
	P0PH  |= 0x20;

	P2CON &= 0xFE;    //SDA设置为输入带上拉
	P2PH  |= 0x01;
	
	OTCON &= 0X3F;
	OTCON |= 0x80;  //选择TWI模式
	SSCON1 = 0x02;  //xxxx xxxy  x为地址寄存器，y为0禁止/1允许通用地址响应
	SSCON0 = 0x88;  // ---- x---  0为不允许接收，1为允许接收
	IE1 |= 0x01;
	EA = 1;
}
/*****************************************************
*函数名称：void SPI_Init(void)
*函数功能：SPI初始化
*入口参数：void
*出口参数：void
*****************************************************/
void SPI_Init(void)
{
	P2CON &= 0xFC;
	P2PH  |= 0x03;				//MOSI/MISO设置为输入带上拉
	
	OTCON &= 0X3F;
	OTCON |= 0X40;  //选择SPI模式
#if (SPI_Mode == 0)	
	P05=0;
	P0CON |= 0x20;				//SCK设置为输出
 {  SSCON0 = 0x23;   }   //设置SPI0为主设备，SCK空闲时间为低电平，SCK周期第一沿采集数据，时钟速率为Fsy/32
#elif (SPI_Mode == 1)	
 {  SSCON0 = 0x03;   }   //设置SPI0为从设备，SCK空闲时间为低电平，SCK周期第一沿采集数据，时钟速率为Fsy/32
#endif 
  
  SSCON1 = 0x00;   //MSB优先发送
 	SCK = SSCON0 & 0x10; 		//将IO口设置为CLK的空闲电平
  SSCON0 |= 0x80;  //开启SPI1
	IE1 |= 0x01;
	EA = 1;
}


/*****************************************************
*函数名称：void TWI/SPI/UART1_Int() interrupt 7
*函数功能：SSI中断函数
*入口参数：void
*出口参数：void
*****************************************************/
#if (SSI_Mode == Uart1)
void Uart1_Int() interrupt 7   //Uart1中断函数
{
	if(SSCON0&0x02)    //发送标志位判断
	{
		SSCON0 &= 0xFE;    //写1清0
		Uart1SendFlag = 1;
	}
	if((SSCON0&0x01))  //接收标志位判断
	{
		SSCON0 &= 0xFD;    //写1清0
		Uart1ReceiveFlag = 1;
	}	
}
#endif

#if (SSI_Mode == TWI)
void TWI_Int() interrupt 7     //TWI中断函数
{
	if(SSCON0&0x40)
	{
		SSCON0 &= 0xbf;  //中断清零
		TWIFlag = 1;
	}	
}
#endif 

#if (SSI_Mode == SPI)
void SpiInt(void) interrupt 7    //SPI中断函数
{	  
	if(SSCON1&0X08)    //发送缓存器空标志判断
	{
		SSCON1 &= ~0X08;
	}
	if(SSCON1&0X80)    //数据传输标志位判断
	{
		SSCON1 &= ~0X80;
		SPIFlag = 1;
	}
}
#endif 

#endif

