/****************************************************************************** �� �� ����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�����ݿ�ij��� ����ֵ��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