/****************************************************************************** 文 件 名:SPI_Master.c 功能描述:SPI 主机模式驱动库文件 作 者:张暄 版 本:V1.0 日 期:2017.04.02 ******************************************************************************/ #include "SPI_Master.h" SPIDataBlockStruct SPIDataBlock; /****************************************************************************** 函数名:SPI_Master_Start 功 能:初始化并启动SPI主机模式 参 数:Mode:SPI工作模式: SPI_MODE_0 SPI_MODE_1 SPI_MODE_2 SPI_MODE_3 FirstBit:首先发送的数据位:SPI_MSB_FIRST SPI_LSB_FIRST 返回值:无 ******************************************************************************/ void SPI_Master_Start(uint8_t Mode, uint8_t FirstBit) { SPICR1 = 0x00; PTSRR &= 0xCF; PTSRR |= SPI_GPIO_SELECT; SPIBR = 0x32; //Baud Rate = BUSCLK / ((3 + 1) * 2 ^ (2 + 1)) = 1000000 SPICR2 &= 0x40; SPICR1 = 0x50 | Mode | FirstBit; } /****************************************************************************** 函数名:SPI_Master_Stop 功 能:关闭SPI功能 参 数:无 返回值:无 ******************************************************************************/ void SPI_Master_Stop(void) { SPICR1 &= 0x1D; //关闭SPI } /****************************************************************************** 函数名:SPI_Master_Get_Write_Status 功 能:获取当前写入状态 参 数:无 返回值:SPI_WRITE_COMPLETE :数据写入完成 SPI_WRITE_NOT_COMPLETE:数据写入未完成 ******************************************************************************/ uint8_t SPI_Master_Get_Write_Status(void) { if (SPIDataBlock.Status != SPI_DATA_BLOCK_IDLE) return SPI_WRITE_NOT_COMPLETE; if (SPISR_SPIF) return SPI_WRITE_COMPLETE; return SPI_WRITE_NOT_COMPLETE; } /****************************************************************************** 函数名:SPI_Master_Byte_Write 功 能:向SPI总线上写一字节 参 数:Data:要写入的数据 返回值:SPI_WRITE_COMPLETE:数据成功写入 SPI_UNWRITABLE :当前不可写入 ******************************************************************************/ uint8_t SPI_Master_Byte_Write(uint8_t Data) { if (SPIDataBlock.Status != SPI_DATA_BLOCK_IDLE) return SPI_UNWRITABLE; if (SPISR_SPTEF) //数据寄存器为空时方可写入 { SPICR2 &= 0xBF; //启动8位传输 SPIDRL = Data; return SPI_WRITE_COMPLETE; } return SPI_UNWRITABLE; } /****************************************************************************** 函数名:SPI_Master_Byte_Read_Req 功 能:请求在SPI总线上读取一字节数据 参 数:无 返回值:SPI_READ_REQ_COMPLETE:读取请求成功 SPI_READ_NOT_COMPLETE:读取失败 ******************************************************************************/ uint8_t SPI_Master_Byte_Read_Req(void) { uint8_t Data; if (SPIDataBlock.Status != SPI_DATA_BLOCK_IDLE) return SPI_READ_NOT_COMPLETE; if (SPISR_SPIF) Data = SPIDRL; //接收寄存器不为空则清空接收寄存器 if (SPISR_SPTEF) //数据寄存器为空时方可写入 { SPICR2 &= 0xBF; //启动8位传输 SPIDRL = SPI_DUMMY_BYTE; return SPI_READ_REQ_COMPLETE; } return SPI_READ_NOT_COMPLETE; } /****************************************************************************** 函数名:SPI_Master_Get_Read_Byte 功 能:获取在SPI总线上读出的一字节数据 参 数:pData:用于存储读出数据的变量 返回值:SPI_READ_COMPLETE :读取成功 SPI_READ_NOT_COMPLETE:读取失败 ******************************************************************************/ uint8_t SPI_Master_Get_Read_Byte(uint8_t *pData) { if (SPIDataBlock.Status != SPI_DATA_BLOCK_IDLE) return SPI_READ_NOT_COMPLETE; if (SPISR_SPIF) { *pData = SPIDRL; return SPI_READ_COMPLETE; } return SPI_READ_NOT_COMPLETE; } /****************************************************************************** 函数名:SPI_Master_Word_Write 功 能:向SPI总线上写一个字(16bit) 参 数:Data:要写入的数据 返回值:SPI_WRITE_COMPLETE:数据成功写入 SPI_UNWRITABLE :当前不可写入 ******************************************************************************/ uint8_t SPI_Master_Word_Write(uint16_t Data) { if (SPIDataBlock.Status != SPI_DATA_BLOCK_IDLE) return SPI_UNWRITABLE; if (SPISR_SPTEF) //数据寄存器为空时方可写入 { SPICR2 |= 0x40; //启动16位传输 SPIDR = Data; return SPI_WRITE_COMPLETE; } return SPI_UNWRITABLE; } /****************************************************************************** 函数名:SPI_Master_Word_Read_Req 功 能:请求在SPI总线上读取一个字(16bit)的数据 参 数:无 返回值:SPI_READ_REQ_COMPLETE:读取请求成功 SPI_READ_NOT_COMPLETE:读取失败 ******************************************************************************/ uint8_t SPI_Master_Word_Read_Req(void) { uint16_t Data; if (SPIDataBlock.Status != SPI_DATA_BLOCK_IDLE) return SPI_READ_NOT_COMPLETE; if (SPISR_SPIF) Data = SPIDR; //接收寄存器不为空则清空接收寄存器 if (SPISR_SPTEF) //数据寄存器为空时方可写入 { SPICR2 |= 0x40; //启动16位传输 SPIDR = SPI_DUMMY_WORD; return SPI_READ_REQ_COMPLETE; } return SPI_READ_NOT_COMPLETE; } /****************************************************************************** 函数名:SPI_Master_Get_Read_Word 功 能:获取在SPI总线上读出的一个字(16bit)的数据 参 数:pData:用于存储读出数据的变量 返回值:SPI_READ_COMPLETE :读取成功 SPI_READ_NOT_COMPLETE:读取失败 ******************************************************************************/ uint8_t SPI_Master_Get_Read_Word(uint16_t *pData) { if (SPIDataBlock.Status != SPI_DATA_BLOCK_IDLE) return SPI_READ_NOT_COMPLETE; if (SPISR_SPIF) { *pData = SPIDR; return SPI_READ_COMPLETE; } return SPI_READ_NOT_COMPLETE; } /****************************************************************************** 函数名:SPI_Master_Block_Write 功 能:向SPI总线上写一个数据块 参 数:pData:要写入的数据块 Len :数据块长度 返回值:SPI_WRITE_COMPLETE:数据成功写入 SPI_UNWRITABLE :当前不可写入 ******************************************************************************/ uint8_t SPI_Master_Block_Write(uint8_t *pData, uint8_t Len) { uint8_t i; if (SPIDataBlock.Status != SPI_DATA_BLOCK_IDLE) return SPI_UNWRITABLE; //如果有读写正在进行则中止写入 if ((Len == 0) || (Len > SPI_DATA_BUFFER_SIZE)) return SPI_UNWRITABLE; SPIDataBlock.Ptr = 0; SPIDataBlock.ReadComplete = 0; //数据被覆盖,清零标志 SPIDataBlock.Len = Len; for (i = 0; i < Len; i++) SPIDataBlock.Data[i] = pData[i]; if (SPISR_SPTEF == 0) //存储器非空状态不可写入 return SPI_UNWRITABLE; SPIDataBlock.Status = SPI_DATA_BLOCK_WRITE; SPICR1 |= 0x20; //开启发送中断 SPICR2 &= 0xBF; //启动8位传输 SPIDRL = SPIDataBlock.Data[SPIDataBlock.Ptr]; return SPI_WRITE_COMPLETE; } /****************************************************************************** 函数名:SPI_Master_Block_Read_Req 功 能:请求在SPI总线上读取一个数据块 参 数:Len:数据块的长度 返回值:SPI_READ_REQ_COMPLETE:读取请求成功 SPI_READ_NOT_COMPLETE:读取失败 ******************************************************************************/ uint8_t SPI_Master_Block_Read_Req(uint8_t Len) { uint8_t Data; if (SPIDataBlock.Status != SPI_DATA_BLOCK_IDLE) return SPI_READ_NOT_COMPLETE; //如果有读写正在进行则中止读取 if ((Len == 0) || (Len > SPI_DATA_BUFFER_SIZE)) return SPI_READ_NOT_COMPLETE; if (SPISR_SPTEF == 0) //存储器非空状态不可写入 return SPI_READ_NOT_COMPLETE; if (SPISR_SPIF) Data = SPIDRL; //接收寄存器不为空则清空接收寄存器 SPIDataBlock.Status = SPI_DATA_BLOCK_READ; SPIDataBlock.Ptr = 0; SPIDataBlock.ReadComplete = 0; SPIDataBlock.Len = Len; SPICR1 |= 0x80; //开启接收中断 SPICR2 &= 0xBF; //启动8位传输 SPIDRL = SPI_DUMMY_BYTE; return SPI_READ_REQ_COMPLETE; } /****************************************************************************** 函数名:SPI_Master_Get_Read_Block 功 能:获取在SPI总线上读出的数据块 参 数:pData:读出的数据块存储地址 Len:数据块长度 返回值:SPI_READ_COMPLETE :读取成功 SPI_READ_NOT_COMPLETE:读取失败 ******************************************************************************/ uint8_t SPI_Master_Get_Read_Block(uint8_t *pData, uint8_t Len) { uint8_t i; if (SPIDataBlock.Status != SPI_DATA_BLOCK_IDLE) return SPI_READ_NOT_COMPLETE; if (SPIDataBlock.ReadComplete) { SPIDataBlock.ReadComplete = 0; for (i = 0; i < Len; i++) pData[i] = SPIDataBlock.Data[i]; return SPI_READ_COMPLETE; } return SPI_READ_NOT_COMPLETE; } /****************************************************************************** 函数名:SPI_Master_Block_Transmit_ISR 功 能:数据块传输完成中断函数,于整个数据块传输完成后由中断调用 参 数:无 返回值:无 ******************************************************************************/ #if SPI_CALL_DATA_BLOCK_TX_ISR void SPI_Master_Block_Transmit_ISR(void) { } #endif #pragma CODE_SEG __NEAR_SEG NON_BANKED //置所有中断函数放在FLASH的非分页区 /****************************************************************************** 函数名:SPI_ISR 功 能:SPI中断服务函数,用于收发数据 参 数:无 返回值:无 ******************************************************************************/ void interrupt SPI_ISR(void) { if (SPIDataBlock.Status == SPI_DATA_BLOCK_WRITE) { if (SPISR_SPTEF) { SPIDataBlock.Ptr++; if (SPIDataBlock.Ptr < SPIDataBlock.Len) SPIDRL = SPIDataBlock.Data[SPIDataBlock.Ptr]; else { SPICR1 &= 0xDF; //关闭发送中断 SPIDataBlock.Status = SPI_DATA_BLOCK_IDLE; #if SPI_CALL_DATA_BLOCK_TX_ISR SPI_Master_Block_Transmit_ISR(); #endif } } } else if (SPIDataBlock.Status == SPI_DATA_BLOCK_READ) { if (SPISR_SPIF) { SPIDataBlock.Data[SPIDataBlock.Ptr] = SPIDRL; SPIDataBlock.Ptr++; if (SPIDataBlock.Ptr < SPIDataBlock.Len) SPIDRL = SPI_DUMMY_BYTE; else { SPICR1 &= 0x7F; //关闭接收中断 SPIDataBlock.Status = SPI_DATA_BLOCK_IDLE; SPIDataBlock.ReadComplete = 1; //置接收完成标志 } } } else { if (SPISR_MODF) SPICR1 &= 0x7F; //关闭SPI中断 } } #pragma CODE_SEG DEFAULT