STM32 CS5532 SPI问题
这个是我在网上下的程序,CS5532在初始化的时候,一直过不去,请高手指点
#include "mcusys.h"
#include "flash.h"
#include "spi.h"
#include "delay.h"
#include "led.h"
/*************************************************************************
* 函数名称: SPI模块的初始化
* 函数描述:
* 输入参数:
* 输出参数: 无
* 返 回 值: 无
* 函数作者: 韩贵宾
* 创建日期: 2014-08-22
* 其他说明:
**************************************************************************/
void SPI_X_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
//RCC_APB2PeriphClockCmd( RCC_AHB1Periph_GPIOB, ENABLE );//PORTB时钟使能
//RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOB, ENABLE);
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE );//SPI2时钟使能
//RCC_AHB1Periph_GPIOB
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15 | GPIO_Pin_12;
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
// GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
// GPIO_PinAFConfig(GPIOB,GPIO_PinSource5,GPIO_AF_SPI2); //PB3复用为 SPI1
// GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_SPI2); //PB4复用为 SPI1
// GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_SPI2); //PB5复用为 SPI1
//
// //这里只针对SPI口初始化
// RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2,ENABLE);//复位SPI1
// RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2,DISABLE);//停止复位SPI1
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //SPI设置为双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置为主SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //SPI发送接收8位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //串行同步时钟的空闲状态为低电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //串行同步时钟的第一个跳变沿数据被采样
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //内部NSS信号有SSI位控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //波特率预分频值为256 speed=36M/256
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
SPI_I2S_DeInit(SPI2);//复位为缺省值
SPI_Init(SPI2, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
SPI_Cmd(SPI2, ENABLE); //使能SPI外设
}
/*************************************************************************
* 函数名称: SPI 速度设置函数
* 函数描述:
* 输入参数: SPI_BaudRatePrescaler_2-->2分频;SPI_BaudRatePrescaler_8-->8分频......;
* 输出参数: 无
* 返 回 值: 无
* 函数作者: 韩贵宾
* 创建日期: 2014-08-22
* 其他说明:
**************************************************************************/
void SPI_SetSpeed(unsigned char SPI_BaudRatePrescaler)
{
assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
SPI2->CR1&=0XFFC7;
SPI2->CR1|=SPI_BaudRatePrescaler; //设置SPI2速度
SPI_Cmd(SPI2,ENABLE);
}
/*************************************************************************
* 函数名称: SPI串口写一个字节函数
* 函数描述: 带有超时判断
* 输入参数: TxData:一字节数据
* 输出参数: 无
* 返 回 值: 无
* 函数作者: 韩贵宾
* 创建日期: 2014-08-22
* 其他说明: 与cs5532的接口函数
**************************************************************************/
void SPI_Write_Byte(u8 TxData)
{
u8 retry=0;
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) //发送缓存空标志位
{
retry++;
if(retry>200)
{
break;
}
}
SPI_I2S_SendData(SPI2, TxData); //通过外设SPIx发送一个数据
retry=0;
}
/*************************************************************************
* 函数名称: SPI读取一字节
* 函数描述: 带有超时判断
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 无
* 函数作者: 韩贵宾
* 创建日期: 2014-08-22
* 其他说明: 与cs5532的接口函数
**************************************************************************/
unsigned char SPI_Read_Byte(void)
{
u8 retry=0;
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) //接受缓存非空标志位
{
retry++;
if(retry>200)
{
break;
}
}
retry=0;
return SPI_I2S_ReceiveData(SPI2); //返回通过SPIx最近接收的数据
}
/*************************************************************************
* 函数名称: 复位cs5532
* 函数描述: CS5532软复位,使之再次返回到命令模式
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 无
* 函数作者: 韩贵宾
* 创建日期: 2014-08-22
* 其他说明: CS5532再次返回到命令模式需要先向芯片内连续写入15个0xff,再写入1个0xfe ;
**************************************************************************/
void Reset_CS5532(void)
{
u8 i;
for(i=0;i<15;i++)
{
SPI_Write_Byte(0xff);
}
SPI_Write_Byte(0xfe);
}
/*************************************************************************
* 函数名称: 写命令子函数
* 函数描述: 向ADC内写入命令控制指令
* 输入参数: cmd_reg:命令寄存器; reg_data:命令控制字
* 输出参数: 无
* 返 回 值: 无
* 函数作者: 韩贵宾
* 创建日期: 2014-08-22
* 其他说明:
**************************************************************************/
void Write_CS5532_CMD(u8 cmd_reg,u32 reg_data)
{
u8 i,*p;
u32 tmp;
tmp = reg_data;
p = (unsigned char *)&tmp;//指针转换
SPI_Write_Byte(cmd_reg);//通过写入命令寄存器相关命令告诉CS5532要操作哪个寄存器
for(i=0;i<4;i++)
{
SPI_Write_Byte(*(p+3-i));//把要写的32位数据分成4个字节写入,高字节在前
}
}
/*************************************************************************
* 函数名称: 读取命令控制字子函数
* 函数描述: MCU从cs5532寄存器读取命令
* 输入参数: cmd_reg:命令寄存器;
* 输出参数: 无
* 返 回 值: 返回读取的32位的一个字
* 函数作者: 韩贵宾
* 创建日期: 2014-08-22
* 其他说明:
**************************************************************************/
u32 Read_CS5532_CMD(u8 cmd_reg)
{
u8 i,*p;
u32 reg;
p = (unsigned char *)®//指针转换
SPI_Write_Byte(cmd_reg);//通过写入命令寄存器相关命令告诉CS5532要操作哪个寄存器
for(i=0;i<4;i++)
{
SPI_Write_Byte(0);//NULL:功能是,清串口标识并使ADC保持在连续转换模式
*(p+3-i) = SPI_Read_Byte();//把每次读取的1个字节(共4个字节)组合成要读取的32位的数据
}
return reg;
}
/*************************************************************************
* 函数名称: 设置CS5532输出字速率子函数
* 函数描述:
* 输入参数: rate:输出字速率
* 输出参数: 无
* 返 回 值: 无
* 函数作者: 韩贵宾
* 创建日期: 2014-08-22
* 其他说明: 输入参数缺省时输出字速率为240Hz
**************************************************************************/
void Config_CS5532_SPS(u32 rate)
{
CS5532_CS_L; //CS5532片选拉低
/*0x03是写配置寄存器,第19位FRS=0,使用缺省输出字速率;
第25位VRS=0,参考电压选择在2.5V <VREF<=VA+范围内,若VRS=1则参考电压选择在1V <=VREF<=2.5V;*/
Write_CS5532_CMD(0x03,0x00000000);
switch(rate)
{
case ADC_SPS_7_5hz:
Write_CS5532_CMD(0x05,ADC_SPS_7_5hz); //写通道设置寄存器
break;
case ADC_SPS_15hz:
Write_CS5532_CMD(0x05,ADC_SPS_15hz);
break;
case ADC_SPS_30hz:
Write_CS5532_CMD(0x05,ADC_SPS_30hz);
break;
case ADC_SPS_60hz:
Write_CS5532_CMD(0x05,ADC_SPS_60hz);
break;
case ADC_SPS_120hz:
Write_CS5532_CMD(0x05,ADC_SPS_120hz);
break;
case ADC_SPS_240hz:
Write_CS5532_CMD(0x05,ADC_SPS_240hz);
break;
case ADC_SPS_480hz:
Write_CS5532_CMD(0x05,ADC_SPS_480hz);
break;
case ADC_SPS_960hz:
Write_CS5532_CMD(0x05,ADC_SPS_960hz);
break;
case ADC_SPS_1920hz:
Write_CS5532_CMD(0x05,ADC_SPS_1920hz);
break;
case ADC_SPS_3840hz:
Write_CS5532_CMD(0x05,ADC_SPS_3840hz);
break;
default:
Write_CS5532_CMD(0x05,ADC_SPS_240hz);
break;
}
}
/*************************************************************************
* 函数名称: CS5532初始化子函数
* 函数描述: 初始化ADC的相关参数,如:输出速率
* 输入参数: adc_Rate:控制输出字速率
* 输出参数: 无
* 返 回 值: 无
* 函数作者: 韩贵宾
* 创建日期: 2014-08-22
* 其他说明:
**************************************************************************/
void CS5532_Init(u32 adc_Rate)
{
u32 tmp;
CS5532_CS_L; //CS5532片选拉低
do
{
Reset_CS5532();//使cs5532返回命令模式
Write_CS5532_CMD(0x03,0x20000000);//写入CS5532复位命令,0x03是配置寄存器地址,0x20000000是配置寄存器RS位为1,即一个复位周期。
tmp = Read_CS5532_CMD(0x0b);//读取配置寄存器内容
}
while(tmp!=0x10000000);
Config_CS5532_SPS(adc_Rate);
SPI_Write_Byte(0);//NULL:功能是,清串口标识并使ADC保持在连续转换模式
}
/*************************************************************************
* 函数名称: 启动cs5532连续转模式
* 函数描述:
* 输入参数:
* 输出参数: 无
* 返 回 值: 无
* 函数作者: 韩贵宾
* 创建日期: 2014-08-22
* 其他说明: 此函数用于连续转换模式下
**************************************************************************/
void Start_CS5532(u32 rate)
{
SPI_Write_Byte(0xc0); //执行连续转换,并制定Setup1
}
/*************************************************************************
* 函数名称: 停止连续转换子函数
* 函数描述: 参见cs5532的datasheet的执行转换章节,第28页
* 输入参数:
* 输出参数: 无
* 返 回 值: 无
* 函数作者: 韩贵宾
* 创建日期: 2014-08-22
* 其他说明: 此函数用于连续转换模式下
**************************************************************************/
void Stop_CS5532(void)
{
u8 i;
u32 cnt=0;
do
{
cnt ++;
}
while( CS5532_conversion_complete != RESET); //wait conversion complete
SPI_Write_Byte(0xFF); //SDI="1111111"则退出执行转换
for(i=0;i<4;i++)
{
SPI_Write_Byte(0);//NULL:功能是,清串口标识并使ADC保持在连续转换模式
}
}
/*************************************************************************
* 函数名称: 读取CS5532转换结果子函数
* 函数描述:
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 无
* 函数作者: 韩贵宾
* 创建日期: 2014-08-22
* 其他说明:
**************************************************************************/
u32 Read_ADC(void)
{
u8 i,retry,*p;
u32 ad_result;
SPI_Write_Byte(0);//NULL:功能是,清串口标识并使ADC保持在连续转换模式
// SPI_Write_Byte(0xC0);//启动连续转换模式
p = (u8*)&ad_result;
while (CS5532_conversion_complete != RESET)
{
retry++;
if(retry>200)
{
retry=0;
break;
}
}
for(i=0;i<4;i++)
{
*(p+3-i) = SPI_Read_Byte();
}
return ad_result>>11;
}
|
|