最近在项目中,用到了LTC2315-12采集外部电压。原理图参考了数据手册中的最小系统例子。而芯片中的cs片选,sck时钟,sdo数据输出引脚连接到stm32f4最小系统,以获取外部输入的电压。
驱动采用了模拟SPI。由于LTC2315-12不需要写操作,即保持片选,则一直向外发送数据,因此只需要硬件模拟SPI读函数即可,硬件模拟SPI及数据解析相关函数如下:
#define SPI_SCK_1 GPIO_SetBits(GPIOA, GPIO_Pin_9)
#define SPI_SCK_0 GPIO_ResetBits(GPIOA, GPIO_Pin_9)
#define SPI_READ_MISO GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_10)
#define SPI1_CS PFout(9)
//初始化SPI
void SPI_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOF, ENABLE);
//CS引脚初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT ; //推挽输出
GPIO_InitStructure.GPIO_OType=GPIO_OType_pp;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.PuPd=GPIO_PuPd_DOWN;
GPIO_Init(GPIOF, &GPIO_InitStructure);
GPIO_SetBits(GPIOF, GPIO_Pin_9);
//SCK引脚初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT ; //推挽输出
GPIO_InitStructure.GPIO_OType=GPIO_OType_pp;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.PuPd=GPIO_PuPd_DOWN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA, GPIO_Pin_9);
//MISO引脚初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN ; //浮空输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.PuPd=GPIO_PuPd_DOWN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
//SPI读函数
uint16_t SPI_ReadByte(uint16_t txData)
{
uint8_t i;
uint16_t rxData = 0;
for(i = 0; i < 14; i++)
{
SPI_SCK_1;
//delay_us(1);
SPI_SCK_0;
//delay_us(1);
//数据接收
rxData <<= 1;
if(SPI_READ_MISO)
{
rxData |= 0x0001;
}
}
//SPI_SCK_0;
return rxData;
}
//LTC2315-12非连续采样只需要14个时钟,
//则返回的数据需要右移2位。
float data_analyze(u16 data)
{
data>>2;
return (float)(data*(4.096/(4095*1.0)));
}
获取并解析数据采用定时器定时获取的方式,即每隔50us获取一拍数据,根据数据手册中的不连续获取数据的时序图,获取一拍LTC2315-12的数据,需要先拉低片选CS,随后硬件产生14个SCK时钟信号,SDO引脚向外更新14位数据,即STM32F4的输入引脚获取一拍数据,最后拉高片选。实际调试中,遇到了返回的电压数据波动较大的情况,最后分析的原因是STM32F4芯片的输入输出引脚需要下拉,且后端不要连接电路,则避免了信号的相互影响。