本帖最后由 feng_710 于 2013-4-27 17:44 编辑
1.使能对应SPI模块时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE) for SPI1
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE) for SPI2
RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE) for SPI3.
2.使能对应GPIO的时钟
RCC_AHB1PeriphClockCmd() function. (SCK, MOSI, MISO and NSS ).
3.配置对应引脚的复用功能
GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_SPIx); //引脚映射
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 设置为推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_x ; //引脚选择
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_xxMHz; //速度选择
GPIO_Init(GPIOx, &GPIO_InitStructure); //写入配置信息
4.配置SPI信息
SPI_InitStructure.SPI_Direction = xxx;//工作模式SPI_Direction_2Lines_FullDuplex,SPI_Direction_2Lines_RxOnly等
SPI_InitStructure.SPI_Mode = xxx; //主从模式选择SPI_Mode_Master,SPI_Mode_Slave
SPI_InitStructure.SPI_DataSize = xxx;//数据位选择SPI_DataSize_8b,SPI_DataSize_16b
SPI_InitStructure.SPI_CPOL = xxx;//时钟空闲电平选择SPI_CPOL_High,SPI_CPOL_Low
SPI_InitStructure.SPI_CPHA = xxx;//数据捕捉跳变沿选择SPI_CPHA_2Edge,SPI_CPHA_1Edge
SPI_InitStructure.SPI_NSS = xxx;//NSS信号由硬件还是软件控制SPI_NSS_Soft,SPI_NSS_Hard
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_x;//时钟分频选择
SPI_InitStructure.SPI_FirstBit = xxx;//数据大小端选择SPI_FirstBit_MSB,SPI_FirstBit_LSB
SPI_InitStructure.SPI_CRCPolynomial = 7;//CRC值计算的多项式
SPI_Init(SPI1, &SPI_InitStructure);//写入配置信息
5.发送
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1,u8 xxx);
6.接收
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
SPI_I2S_ReceiveData(SPI1);
程序举例:
本例是对交换机芯片KSZ8873的配置
宏定义:
#define KSZ8873_SPI SPI1
#define KSZ8873_SPI_CLK RCC_APB2Periph_SPI1
#define KSZ8873_SPI_SCK_PIN GPIO_Pin_3
#define KSZ8873_SPI_SCK_GPIO_PORT GPIOB
#define KSZ8873_SPI_SCK_GPIO_CLK RCC_AHB1Periph_GPIOB
#define KSZ8873_SPI_SCK_SOURCE GPIO_PinSource3
#define KSZ8873_SPI_MISO_PIN GPIO_Pin_4
#define KSZ8873_SPI_MISO_GPIO_PORT GPIOB
#define KSZ8873_SPI_MISO_GPIO_CLK RCC_AHB1Periph_GPIOB
#define KSZ8873_SPI_MISO_SOURCE GPIO_PinSource4
#define KSZ8873_SPI_MOSI_PIN GPIO_Pin_5
#define KSZ8873_SPI_MOSI_GPIO_PORT GPIOB
#define KSZ8873_SPI_MOSI_GPIO_CLK RCC_AHB1Periph_GPIOB
#define KSZ8873_SPI_MOSI_SOURCE GPIO_PinSource5
#define KSZ8873_CS_PIN GPIO_Pin_15
#define KSZ8873_CS_GPIO_PORT GPIOA
#define KSZ8873_CS_GPIO_CLK RCC_AHB1Periph_GPIOA
#define KSZ8873_CS_LOW() GPIO_ResetBits(KSZ8873_CS_GPIO_PORT, KSZ8873_CS_PIN)
#define KSZ8873_CS_HIGH() GPIO_SetBits(KSZ8873_CS_GPIO_PORT, KSZ8873_CS_PIN)
#define KSZ8873_WRITE_CMD 0x02
#define KSZ8873_READ_CMD 0x03
程序:
void KSZ8873_SPI_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(KSZ8873_CS_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = KSZ8873_CS_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(KSZ8873_CS_GPIO_PORT, &GPIO_InitStructure);
RCC_AHB1PeriphClockCmd(KSZ8873_SPI_SCK_GPIO_CLK | KSZ8873_SPI_MISO_GPIO_CLK |
KSZ8873_SPI_MOSI_GPIO_CLK, ENABLE);
RCC_APB2PeriphClockCmd(KSZ8873_SPI_CLK, ENABLE);
GPIO_PinAFConfig(KSZ8873_SPI_SCK_GPIO_PORT, KSZ8873_SPI_SCK_SOURCE, GPIO_AF_SPI1);
GPIO_PinAFConfig(KSZ8873_SPI_MISO_GPIO_PORT, KSZ8873_SPI_MISO_SOURCE, GPIO_AF_SPI1);
GPIO_PinAFConfig(KSZ8873_SPI_MOSI_GPIO_PORT, KSZ8873_SPI_MOSI_SOURCE, GPIO_AF_SPI1);
GPIO_InitStructure.GPIO_Pin = KSZ8873_SPI_SCK_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(KSZ8873_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = KSZ8873_SPI_MISO_PIN;
GPIO_Init(KSZ8873_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = KSZ8873_SPI_MOSI_PIN;
GPIO_Init(KSZ8873_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);
KSZ8873_CS_HIGH();
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init( KSZ8873_SPI , &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
}
void KSZ8873_SPI_SendByte(u8 addr,u8 byte)
{
KSZ8873_CS_LOW();
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData( KSZ8873_SPI , KSZ8873_WRITE_CMD);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
SPI_I2S_ReceiveData( KSZ8873_SPI );
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData( KSZ8873_SPI , addr);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
SPI_I2S_ReceiveData( KSZ8873_SPI );
while (SPI_I2S_GetFlagStatus( KSZ8873_SPI , SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1, byte);
while (SPI_I2S_GetFlagStatus( KSZ8873_SPI , SPI_I2S_FLAG_RXNE) == RESET);
SPI_I2S_ReceiveData( KSZ8873_SPI );
KSZ8873_CS_HIGH();
}
u8 KSZ8873_SPI_ReceiveByte(u8 byte)
{
u8 i;
KSZ8873_CS_LOW();
while (SPI_I2S_GetFlagStatus( KSZ8873_SPI , SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1, KSZ8873_READ_CMD);
while (SPI_I2S_GetFlagStatus( KSZ8873_SPI , SPI_I2S_FLAG_RXNE) == RESET);
SPI_I2S_ReceiveData(SPI1);
while (SPI_I2S_GetFlagStatus( KSZ8873_SPI , SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1, byte);
while (SPI_I2S_GetFlagStatus( KSZ8873_SPI , SPI_I2S_FLAG_RXNE) == RESET);
SPI_I2S_ReceiveData(SPI1);
while (SPI_I2S_GetFlagStatus( KSZ8873_SPI , SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1, byte);
while (SPI_I2S_GetFlagStatus( KSZ8873_SPI , SPI_I2S_FLAG_RXNE) == RESET);
i=SPI_I2S_ReceiveData(SPI1);
KSZ8873_CS_HIGH();
return i;
}
|
|