根据不同外设模块的需求,来对GD32 105R_STAR的SPI外设进行不同的匹配设置,楼主根据PT6315的外设需求,进行如下初始化配置:
view plaincopy to clipboardprint?
/*
****************************************************************************
*函数名称:void Pt_SPIInit(void)
*函数功能:PT6315 SPI 总线初始化
*日期:2015 4 6
*版本:V1.0
*作者:yrj
*SPI_FirstBit_MSB;//高位在前 PT6315手册对应改为低位在前。
****************************************************************************
*/
// PB12/SPI2NSS PB13/SPI2CLK PB14/SPI2MISO PTOUT PB15/SPI2MOSI PTIN
void Pt_SPIInit(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
//PB14 (MISO)浮空输入
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_14;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB,&GPIO_InitStructure);
//PB15 MOSI PB13 SCK 复用推挽输出(外设总线用)
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
//PB12 NSS,PB11 WP写保护普通推挽输出 本实验用软件控制NSS(主从设备的选择控制端)
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
Pt_Disable(); //PB12/NSS 失能
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
view plaincopy to clipboardprint?
SPI_InitTypeDef SPI_InitStructure;
SPI_I2S_DeInit(SPI2);
SPI_Cmd(SPI2,DISABLE);//在改变CPOL/CPHA位之前必须清除SPE位将SPI禁止
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//主模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//8位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;//时钟悬空低
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;//数据捕获与第1个时钟沿
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//软件控制NSS信号
SPI_InitStructure.SPI_BaudRatePrescaler =SPI_BaudRatePrescaler_8;//比特率预分频值为8。最大18MHz
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB; /*SPI_FirstBit_MSB; //高位在前 7 7 与PT6315手册对应改为低位在前。*/
SPI_InitStructure.SPI_CRCPolynomial = 7;//定义用于CRC值计算的多项式 7
SPI_Init(SPI2, &SPI_InitStructure);
SPI_Cmd(SPI2,ENABLE);
}
view plaincopy to clipboardprint?
<p>
此外由于SPI是一种全双工的同步通信总线,所以在进行数据通信中收发是同步进行的,为了在实际的函数调用中简单明了,针对GD32 105R_STAR SPI数据的收发,楼主在此分别设计了两个函数来进行数据的发送和接收。
</p>
<p>
SPI发送函数:
</p>
<pre class="c" name="code">/*
****************************************************************************
*函数名称:uint8 Send_Byte(void)
*函数功能:通过硬件SPI发送一个字节
*日期:2015 4 6
*版本:V1.0
*作者:yrj
****************************************************************************
*/
uint32 CsyCnt;
void SendPt_Byte(uint8 data)
{
SPI_I2S_SendData(SPI2, data);//发送数据
CsyCnt = 0;
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE)==RESET) //等待数据发送完毕
{
CsyCnt++;
if(CsyCnt>10000) break ;
}
SPI_I2S_ClearFlag(SPI2,SPI_I2S_FLAG_TXE); //清除发送完成
//////////// 测试是否正常写入
if( CsyCnt >10000) // 有故障
{
/*重新初始化*/
Pt_SPIInit();
/*重新发送数据*/
SPI_I2S_SendData(SPI2, data);/*发送数据*/
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE)==RESET); /*等待数据发送完毕*/
}
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE)==RESET); /*等待数据发接收完毕*/
SPI_I2S_ReceiveData(SPI2); /*接收返回的数据,在此无实意*/
}
</pre>
<pre class="c" name="code">SPI接收函数:
</pre>
<pre class="c" name="code"><pre class="c" name="code">/*
****************************************************************************
*函数名称:uint8 Get_Byte(void)
*函数功能:通过硬件SPI接口接收一个字节到处理器
*日期:2015 4 6
*版本:V1.0
*作者:yrj
****************************************************************************
*/
uint8 GetPt_Byte(void)
{
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE)==RESET); /*等待数据发送完毕*/
SPI_I2S_SendData(SPI2, 0);/*发送该数据易产生时钟,数据本身无意义。*/
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE)==RESET);/*等待接收完成*/
return SPI_I2S_ReceiveData(SPI2);/*返回最近接收到的数据*/
}</pre>
<p>
<br>
</p>
</pre>
|