历史上的今天
今天是:2024年09月10日(星期二)
2018年09月10日 | STM32F4使用硬件SPI驱动ADS8322
2018-09-10 来源:eefocus
以前写过STM32F103ZET6驱动ADS8332的代码,不过是使用IO模拟SPI驱动的,在本博客前面可以查询。今天在STE_V2.1验证平台上编写了STM32F429BIT6驱动ADS8332的代码,本次使用了STM32F4的硬件SPI,使用SPI2。代码亲自测试,效果不错。鉴于在网上看到很多人在找STM32硬件SPI驱动ADS8332,在此贴出代码工大家参考。
/**
* 函数功能:采集待测芯片电流取样电阻处理后的电压的ADS8332复位
* 输入参数:无
* 输出参数:无
* 全局变量:无
* 作者:LuJ
* 修改日期:2015/09/02
* 备注:无
*/
void DUT_Power_ADS8332_Reset(void)
{
ADS8332_POWER_SCK_OUT=0;
ADS8332_POWER_CS_OUT=1;//CS=1
ADS8332_POWER_MOSI_OUT=1;
ADS8332_POWER_CONVST_OUT=1;
ADS8332_POWER_RESET_OUT=1;
Delay_us(100);
ADS8332_POWER_RESET_OUT=0;//minimum 25ns
Delay_us(100);
ADS8332_POWER_RESET_OUT=1;//minimum 2us
Delay_us(100);
}
/**
* 函数功能:采集待测芯片电流取样电阻处理后的电压的ADS8332模数转换器开始转换
* 输入参数:无
* 输出参数:无
* 全局变量:无
* 作者:LuJ
* 修改日期:2015/09/02
* 备注:CONVST信号下降沿开始采集
*/
void DUT_Power_ADS8332_Convst(void)
{
ADS8332_POWER_CS_OUT=1;//CS=1
ADS8332_POWER_CONVST_OUT=1;
Delay_us(100);
ADS8332_POWER_CONVST_OUT=0;//minimum 40ns
Delay_us(100);
ADS8332_POWER_CONVST_OUT=1;
}
/**
* 函数功能:采集待测芯片电流取样电阻处理后的电压的ADS8332模数转换器读配置信息
* 输入参数:无
* 输出参数:读取配置数据
* 全局变量:无
* 作者:LuJ
* 修改日期:2015/09/02
* 备注:下降沿,D15:12 1100b D11:D0 Don't care
*/
uint16_t DUT_Power_ADS8332_ReadCFR(void)
{
uint16_t temp_a = ADS8332_READ_CFR;
uint16_t ConFR = 0x0000;
ADS8332_POWER_CS_OUT=0;//CS=0
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET){;}//等待发送区空
SPI_I2S_SendData(SPI2, temp_a); //通过外设SPIx发送一个数据
Delay_us(100);
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET){;}//等待接收完
ConFR = SPI_I2S_ReceiveData(SPI2); //返回通过SPIx最近接收的数据
Delay_us(100);
ADS8332_POWER_CS_OUT=1;//CS=1
return ConFR;
}
/**
* 函数功能:采集待测芯片电流取样电阻处理后的电压的ADS8332模数转换器写配置信息
* 输入参数:cfr_data:写入的配置数据
* 输出参数:无
* 全局变量:无
* 作者:LuJ
* 修改日期:2015/09/02
* 备注:下降沿,D15:12 1110b D11:D0 Don't care
*/
void DUT_Power_ADS8332_WriteCFR(uint16_t cfr_data)
{
ADS8332_POWER_CS_OUT=0;//CS=0
cfr_data = (ADS8332_WRITE_CFR | (0x0fff&cfr_data));//0xE000=0b 1100 0000 0000 0000
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET){;}//等待发送区空
SPI_I2S_SendData(SPI2, cfr_data); //通过外设SPIx发送一个数据
Delay_us(100);
ADS8332_POWER_CS_OUT=1;//CS=1
}
/**
* 函数功能:采集待测芯片电流取样电阻处理后的电压的ADS8332模数转换器通道选择
* 输入参数:ADS8332_Channel_x:选择的通道
* 输出参数:无
* 全局变量:无
* 作者:LuJ
* 修改日期:2015/09/02
* 备注:无
*/
void DUT_Power_ADS8332_ChannelSel(uint16_t ADS8332_Channel_x)
{
ADS8332_POWER_CS_OUT=0;//CS=0
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET){;}//等待发送区空
SPI_I2S_SendData(SPI2, ADS8332_Channel_x); //通过外设SPIx发送一个数据
Delay_us(100);
ADS8332_POWER_CS_OUT=1;//CS=1
}
/**
* 函数功能:采集待测芯片电流取样电阻处理后的电压的ADS8332模数转换器ADC采集,读取数据
* 输入参数:ADS8332_Channel_x:选择的通道
* 输出参数:读取到的数据
* 全局变量:无
* 作者:LuJ
* 修改日期:2015/09/02
* 备注:无
*/
uint16_t DUT_Power_ADS8332_ReadData(uint16_t ADS8332_Channel_x)
{
uint8_t temp_a;
uint16_t ConFR = 0x0000;
DUT_Power_ADS8332_ChannelSel(ADS8332_Channel_x);
//channel sel
DUT_Power_ADS8332_Convst();
temp_a = ADS8332_POWER_EOC_IN;
while(!temp_a)
{
temp_a = ADS8332_POWER_EOC_IN;
}
//check convert over
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET){;}
ADS8332_POWER_CS_OUT=0;//CS=0
SPI_I2S_SendData(SPI2, ADS8332_READ_DATA);
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET){;}
ConFR = SPI_I2S_ReceiveData(SPI2);//读出一次数据扔掉,该次数据不对
ConFR = SPI_I2S_ReceiveData(SPI2);//返回通过SPIx最近接收的数据
Delay_us(100);
ADS8332_POWER_CS_OUT=1;//CS=1
return ConFR;
}
/**
* 函数功能:采集待测芯片电流取样电阻处理后电压的ADS8332初始化
* 输入参数:无
* 输出参数:无
* 全局变量:无
* 作者:LuJ
* 修改日期:2015/09/01
* 备注:无
*/
void DUT_Power_ADS8332_Init(void)
{
uint16_t cfr_old_config=0x0000,cfr_config=0x0000;
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOG, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//采样启动信号CONVST
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_UP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;//复位信号RESET
GPIO_Init(GPIOG, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//CS;
GPIO_Init(GPIOG, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;//采样结束标志信号EOC
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_Init(GPIOG, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_SPI2); //PB13复用为 SPI2
GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_SPI2);
// Data on the DO and DIO pins are clocked out on the falling edge of CLK.
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);
/* Enable SPI2 */
SPI_Cmd(SPI2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_15;//SCK MOSI
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_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
DUT_Power_ADS8332_Reset();//复位ADS8332芯片
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;//SCK MISO MOSI
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_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
cfr_old_config = (ADS8332_WRITE_CFR|ADS8332_INT_CLK|ADS8332_TR_MANUL|ADS8332_SMPL_250K|ADS8332_EOC_LOW\
|ADS8332_P10_EOC|ADS8332_P10_OUT|ADS8332_AUTONAP_DIS|ADS8332_NAP_DIS|ADS8332_PD_DIS|ADS8332_NOSW_RST);//配置工作模式0xE7FD,具体见手册
DUT_Power_ADS8332_WriteCFR(cfr_old_config);
cfr_config=DUT_Power_ADS8332_ReadCFR();//读出一次数据扔掉,该次数据不对
cfr_config=DUT_Power_ADS8332_ReadCFR();
while((0x0FFF&cfr_config) != (0x0FFF&cfr_old_config));//比较写入读出的配置相同,否则错误死循环,待特殊处理
}
/**
* 函数功能:ADS8332采集待测芯片电流取样电阻处理后的电压
* 输入参数:Power_Channal_x:电流通道选择
* DUT_Power_Channal_1 DUT供电通道1
* DUT_Power_Channal_2 DUT供电通道2
* DUT_Power_Channal_3 DUT供电通道3
* DUT_Power_Channal_4 DUT供电通道4
* DUT_Power_Channal_5 DUT供电通道5
* 输出参数:无
* 全局变量:无
* 作者:LuJ
* 修改日期:2015/09/01
* 备注:无
*/
void DUT_Power_ADS8332_GetCurrentVal(uint8_t Power_Channal_x)
{
uint16_t Current_1=0x0000,Current_2=0x0000;
float Voltage_val;
while(1)
{
Current_1=DUT_Power_ADS8332_ReadData(ADS8332_Channel_0);
Voltage_val=((float)Current_1*4.096f)/65536.0f;
printf("\r\n ADS8332_Channel_0=%6f \r\n",Voltage_val);
Current_2=DUT_Power_ADS8332_ReadData(ADS8332_Channel_1);
Voltage_val=((float)Current_2*4.096f)/65536.0f;
printf("\r\n ADS8332_Channel_1=%6f \r\n",Voltage_val);
Delay_ms(30);
}
}
/**
* 函数功能:TLV5618可调电源DAC输出测试
* 输入参数:无
* 输出参数:无
* 全局变量:无
* 作者:LuJ
* 修改日期:2015/08/31
* 备注:在主函数中调用,然后使用万用表测试Target的电源电压为3.3V
*/
void DUT_Power_Test(void)
{
// DUT_TLV5618_Init();//初始化STM32的SPI2
//DUT_TLV5618_Conver(0x0672,0x0672,TLV5618_Channal_AB,TLV5618_Fast_mode);//A通道输出,快速模式,电源控制位正常
DUT_Power_ADS8332_Init();
DUT_Power_ADS8332_GetCurrentVal(DUT_Power_Channal_1);
while (1)
{
;
}
}
史海拾趣
|
小弟通过单片机与PC串口通信,遇到了问题,望大哥大姐们指教 PC暂时用串口调试助手代替吧,51单片机往PC发多个字节的数据,串口调试助手接收,但是无论如何都只能接收到第一个字节的数据。我用串口调试助手向单片机发送数据,如果只发一个字节,单 ...… 查看全部问答> |
|
最近我的EVC工程不知道改了哪里 出了点小问题,改动文件后,新编译的执行文件却没变 时间还是旧的 整个重新编译也还是没有作用 必须把MIPSIIRel 或者 MIPSIIDbg 整个文件夹删掉才行 找了很久&nb ...… 查看全部问答> |
|
我用的时候广州友善之臂的开发板,现在再没有操作系统的情况下,就用了友善之臂提供的启动代码,写了一个定时器程序,但是现在就是跑不起来,能不能帮忙看看? #include \"def.h\" #include \"option.h\" #include \"2410addr.h\" #include \"2 ...… 查看全部问答> |
|
经过King和包租婆的各方奔走,囊中羞涩的我们(仅2W项目经费)总算了找到了以下单位提供的免费样品,真是感激淋涕啊!1、 欧司朗中国提供的R,G,B,W灯珠2、 忆光提供的R,G,B,W灯珠3、 信驰达科技提供的CC2540 蓝牙模块4、 四正节能提供的散热器5、进 ...… 查看全部问答> |
|
该视频介绍了主要充电器的参数及其相关的应用背景信息,在此基础上比较分析了TI与其他竞争对手的解决方案的不同,以使大家更好地理解TI电源解决方案的独特之处。 … 查看全部问答> |
|
【TI首届低功耗设计大赛】sacq的金刚狼(7):最简单的数字电压表 replyreload += \',\' + 1767184;这个“简单”,更多的意义是:这个编程的过程很简单。 Energia的例程AnalogInOutSerial的主要功能是把采集的ADC结果通过串口发送出去, 这次就准备增加个LCD1602的显示功能,并把ADC结果转换成电压值(V)。 ...… 查看全部问答> |




