【问题解决记录】STM32F030C8读取CS1237采集模拟

编程入门 行业动态 更新时间:2024-10-24 05:24:12

【问题解决记录】STM32F030C8读取CS1237采集模拟

【问题解决记录】STM32F030C8读取CS1237采集模拟

问题描述

提示:这里描述项目中遇到的问题:

使用STM32F030C8读取CS1237采集模拟电压时,遇到CS1237的CONFIG寄存器无法读写正常的困扰;就是配置 RefOut_OFF | SpeedSelct_1280HZ | PGA_1 | CH_A 这些参数无法正确写入,实际是我要写入0x70,但是读出来是随机值;而修改代码,上电MCU直接读取CONFIG,得到数值是0x0C(和手册默认值是对应的,说明读操作正常)。
而直接读取CS1237的ADC转换数值是和外界输入电压是一致的,只是设置CONFG寄存器读写不一致。

原因分析:

提示:这里填写问题的分析:

第一个想到的原因是,CS1237的操作时序问题,有几个注意点是:
(1) 设置STM32的DOUT端口为INPUT,监测来自CS1237的DOUT电平,一般芯片上电后,CS1237的DOUT会不断地输出高脉冲(示波器测量约20us的高脉冲),代码中要监测到DOUT的”下降沿“,然后才是读写配置和读取ADC转换数值的操作;
(2)参考了网络好多示例代码,尤其是”技小新“的CS1237模块,LCSC立创商城可以搜到有;我的代码基本和他的demo一样;
(3)CS1237上电后需要延时300毫秒的启动时间?这个实际测试后发现,这个时间不是必须;

一顿仔细检查代码,发现了STM32端口配置的”笔误“,修改后,仍然无法正确配置CONFIG;
第二个想到的原因是,硬件CS1237和STM32的电平兼容问题,我的电路CS1237是5V供电,stm32是3V3供电,它们之间SPI通过22欧姆电阻串联。修改硬件电路,将CS1237的电源电压改为3V3后,虽然仍无法正确配置CONFIG,但是采集电压变得稳定许多;
修改串联电阻为100欧姆,600欧姆,6k5欧姆,几乎没有改善;
第三个原因是,设置CS1237的转换速率是不是对于STM32F0这个MCU来说有点太快了?于是我配置了SpeedSelct_1280HZ 是配置不正常,而设置其他SpeedSelct_640HZ及以下频率,发现CONFIG寄存器正常读写 ,没错!是可以正常读写,而PGA的放大倍数也可以正常设置了。

下面是关键部分的代码:

#include "gp8211s.h"
#include "main.h"
#include "delay.h"uint8_t Gp8211s_Channel_Sel;void Gp8211s_Choose_Channel(uint8_t ch)
{if( !ch ) Gp8211s_Channel_Sel = 0;elseGp8211s_Channel_Sel = 1;
}void Gp8211s_SCL_Clr()
{if( !Gp8211s_Channel_Sel )HAL_GPIO_WritePin(GP1_SCLK_GPIO_Port, GP1_SCLK_Pin, GPIO_PIN_RESET);else	HAL_GPIO_WritePin(GP2_SCLK_GPIO_Port, GP2_SCLK_Pin, GPIO_PIN_RESET);
}
void Gp8211s_SCL_Set()
{if( !Gp8211s_Channel_Sel )HAL_GPIO_WritePin(GP1_SCLK_GPIO_Port, GP1_SCLK_Pin, GPIO_PIN_SET);else	HAL_GPIO_WritePin(GP2_SCLK_GPIO_Port, GP2_SCLK_Pin, GPIO_PIN_SET);
}
void Gp8211s_SDA_Clr()
{if( !Gp8211s_Channel_Sel )HAL_GPIO_WritePin(GP1_SDA_GPIO_Port, GP1_SDA_Pin, GPIO_PIN_RESET);else	HAL_GPIO_WritePin(GP2_SDA_GPIO_Port, GP2_SDA_Pin, GPIO_PIN_RESET);
}
void Gp8211s_SDA_Set()
{if( !Gp8211s_Channel_Sel )HAL_GPIO_WritePin(GP1_SDA_GPIO_Port, GP1_SDA_Pin, GPIO_PIN_SET);else	HAL_GPIO_WritePin(GP2_SDA_GPIO_Port, GP2_SDA_Pin, GPIO_PIN_SET);
}void Gp8211s_IIC_SdaOut()
{GPIO_InitTypeDef GPIO_InitStruct;if( !Gp8211s_Channel_Sel ){GPIO_InitStruct.Pin = GP1_SDA_Pin;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init( GP1_SDA_GPIO_Port, &GPIO_InitStruct );}else{GPIO_InitStruct.Pin = GP2_SDA_Pin;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init( GP2_SDA_GPIO_Port, &GPIO_InitStruct );}
}void Gp8211s_IIC_SdaIn()
{GPIO_InitTypeDef GPIO_InitStruct;//return;if( !Gp8211s_Channel_Sel ){GPIO_InitStruct.Pin = GP1_SDA_Pin;GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init( GP1_SDA_GPIO_Port, &GPIO_InitStruct );}else{GPIO_InitStruct.Pin = GP2_SDA_Pin;GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init( GP2_SDA_GPIO_Port, &GPIO_InitStruct );}
}void Gp8211s_IIC_Init()
{Gp8211s_IIC_SdaOut();Gp8211s_SDA_Set();Gp8211s_SCL_Set();delay_us(10);
}void Gp8211s_IIC_Start(void)
{Gp8211s_IIC_SdaOut();Gp8211s_SDA_Set();Gp8211s_SCL_Set();delay_us(10);Gp8211s_SDA_Clr();delay_us(10);
}void Gp8211s_IIC_Stop(void)
{Gp8211s_IIC_SdaOut();Gp8211s_SDA_Clr();Gp8211s_SCL_Set();delay_us(10);Gp8211s_SDA_Set();delay_us(10);
}void Gp8211s_IIC_SendByte(uint8_t txd)
{uint8_t t;  uint8_t tdata = txd;	Gp8211s_IIC_SdaOut();Gp8211s_SCL_Clr();delay_us(10);for(t=0; t<8; t++){              if( tdata & 0x80 )Gp8211s_SDA_Set();elseGp8211s_SDA_Clr();tdata <<= 1; 	  delay_us(10);Gp8211s_SCL_Set();delay_us(10);Gp8211s_SCL_Clr();delay_us(10);}	 
}uint8_t Gp8211s_IIC_SdaState()
{uint8_t ret;if( !Gp8211s_Channel_Sel )ret = HAL_GPIO_ReadPin(GP1_SDA_GPIO_Port, GP1_SDA_Pin);elseret = HAL_GPIO_ReadPin(GP2_SDA_GPIO_Port, GP2_SDA_Pin);return ret;
}uint8_t Gp8211s_IIC_ReadByte(void)
{uint8_t t;  uint8_t rdata=0;	Gp8211s_IIC_SdaIn();for(t=0; t<8; t++){      Gp8211s_SCL_Set();delay_us(10);rdata <<= 1; if( Gp8211s_IIC_SdaState() )rdata|=0x01;Gp8211s_SCL_Clr();delay_us(10);}	 return rdata;
}uint8_t Gp8211s_IIC_WaitAck(void)
{uint32_t ucErrTime = 0;GPIO_PinState sda_state;uint8_t RetValue = 0;Gp8211s_SCL_Set();delay_us(20);#if 0	Gp8211s_IIC_SdaIn();while(ucErrTime++ < 10000){delay_us(20);sda_state = Gp8211s_IIC_SdaState();if( sda_state == GPIO_PIN_RESET ){RetValue = 1;break;}}if( ucErrTime >= 10000 ){printf("Gp8211s_IIC_WaitAck timeout\n");Gp8211s_IIC_Stop();}#endifreturn RetValue;
}void Gp8211s_Init(void)
{	//Range 0 to 5VGp8211s_IIC_Start();Gp8211s_IIC_SendByte(0xB0);Gp8211s_IIC_WaitAck();Gp8211s_IIC_SendByte(0x01);Gp8211s_IIC_WaitAck();Gp8211s_IIC_SendByte(0x55);   //0x44, 5V; 0x55: 10V; 0x77:12V;Gp8211s_IIC_WaitAck();Gp8211s_IIC_Stop(); 
}// data_hex max: 0x7FFF
void gp8211s_send_cmd(uint16_t data_hex )
{	uint8_t data8_tmp = 0;//Set Reg valueGp8211s_IIC_Start();Gp8211s_IIC_SendByte(0xB0);Gp8211s_IIC_WaitAck();Gp8211s_IIC_SendByte(0x02);Gp8211s_IIC_WaitAck();data8_tmp = data_hex & 0xFF;Gp8211s_IIC_SendByte(data8_tmp);//DATA Low//Gp8211s_IIC_WaitAck();   //!!! add this, not OK;data8_tmp = (data_hex & 0x7F00 )>> 8;Gp8211s_IIC_SendByte(data8_tmp);//DATA HighGp8211s_IIC_WaitAck();Gp8211s_IIC_Stop(); 
}void gp8211s_OutPutVolt(uint16_t volt_in_mv )
{	uint32_t VoltRange = 10*1000; //10Vuint16_t  RegVal = 0;if( volt_in_mv > VoltRange )volt_in_mv = VoltRange;RegVal = volt_in_mv * 0x7FFF / VoltRange;RegVal &= 0x7FFF;//printf("volt_in_mv: %d, RegVal: %X  \n ", volt_in_mv, RegVal);gp8211s_send_cmd(RegVal);
//		gp8211s_send_cmd(0x4000);//printf("volt_in_mv: %d, RegVal: %X  \n ", volt_in_mv, RegVal);
}

main部分

configData = RefOut_OFF | SpeedSelct_640HZ | PGA_1 | CH_A;Con_CS1237(configData);if( Read_CON() != configData )printf("config in1 error! set: %X, get:%X \r\n ", configData,  Read_CON());printf("> config ch1 ok! \n");

解决方案:

提示:这里填写该问题的具体解决方案:
实物照片:外部输入1.50V,OLED的IN1显示1.472V;基本正确;

例如:新建一个 Message 对象,并将读取到的数据存入 Message,然后 mHandler.obtainMessage(READ_DATA, bytes, -1, buffer).sendToTarget();换成 mHandler.sendMessage()

更多推荐

【问题解决记录】STM32F030C8读取CS1237采集模拟

本文发布于:2024-03-14 20:01:41,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1737222.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!