实不相瞒,我觉得这个芯片就有毛病设计的,寄存器也不多,数据输出也不是走数字接口,但是就要用SPI接口。尤其脑电这种东西两个芯片能够?真的裂开了。。。
2个KS1092挂在同一个SPI上面,然后使用不同的CS控制
KS1092 采用带通放大器。由于高通滤波特性的超低截止频率,信号可能需要几秒钟才能稳定下来。当电极首次连接时,此稳定时间可能会给用户带来不受欢迎的延迟。
为了解决这个问题,KS1092 的快速恢复引脚 (PIN8: FR) 可以由外部信号控制。通过将 PIN8: FR 设置为高状态,将激活快速恢复模式。
这个是STM32 上面的两个SPI接口
然后围绕下面的空余IO设置一下,完全使用IO模拟,不用硬件。
设置情况
大概就是这样
寄存器也就这样的
设计这样的函数,SPI单独的和封装的传感器读取写入,以及快速稳定
首先是初始化函数,按照数据手册的顺序开关对应的引脚,最后控制SPI
这个功能也简单,就是IO控制就行
还有关
因为是多个器件,所以写了这样的函数,来手动控制对应的器件
SPI(Serial Peripheral Interface,串行外围设备接口)是一种同步串行通信协议,广泛应用于微控制器与各种外围设备之间的数据传输。SPI协议包括四个主要信号:MOSI(主输出从输入),MISO(主输入从输出),SCLK(时钟),以及CS(片选)。
以下是SPI协议读写数据的基本步骤:
- 片选信号(CS):主设备将CS信号拉低,选择目标从设备进行通信。
- 数据传输:
- 写数据:主设备将数据写入MOSI引脚,从设备在时钟信号(SCLK)的上升或下降沿读取数据。
- 读数据:从设备将数据写入MISO引脚,主设备在时钟信号的上升或下降沿读取数据。
- 时钟信号(SCLK):时钟信号由主设备生成,用于同步数据传输。每个时钟周期对应传输一位数据。
- 数据有效性:SPI可以配置为在时钟上升沿或下降沿采样数据,根据不同的设备配置选择不同的模式。
void KS1029_Write_One_Byte(uint8_t Bytein)
{
uint8_t Byte = Bytein;
uint8_t len = 0;
HAL_GPIO_WritePin(KS1092_1_SCLK_GPIO_Port, KS1092_1_SCLK_Pin, GPIO_PIN_SET); // SCLK High
for (len = 0; len < 8; len )
{
if ((Byte & 0x80))
{
HAL_GPIO_WritePin(KS1092_1_SDI_GPIO_Port, KS1092_1_SDI_Pin, GPIO_PIN_SET); // SDI High
}
else
{
HAL_GPIO_WritePin(KS1092_1_SDI_GPIO_Port, KS1092_1_SDI_Pin, GPIO_PIN_RESET); // SDI Low
}
Byte = Byte << 1;
Delay_us(5);
HAL_GPIO_WritePin(KS1092_1_SCLK_GPIO_Port, KS1092_1_SCLK_Pin, GPIO_PIN_RESET); // SCLK Low
Delay_us(5);
HAL_GPIO_WritePin(KS1092_1_SCLK_GPIO_Port, KS1092_1_SCLK_Pin, GPIO_PIN_SET); // SCLK High
Delay_us(5);
}
}
函数控制时钟信号(SCLK)和数据输入引脚(SDI)来向KS1092写入一个字节的数据。每次循环发送一位数据,总共8次循环完成一个字节的发送。
- 设置SCLK高电平:表示准备开始传输数据。
- 检查当前字节的最高位:如果为1,则将SDI设置为高电平;否则,设置为低电平。
- 左移字节:将字节左移一位,为发送下一个数据位做准备。
- 延时:确保信号稳定。
- 设置SCLK低电平:表示数据位已被发送。
- 重复上述步骤:直至发送完一个字节的所有位。
uint8_t SPI_ReadWriteByte(uint8_t byte)
{
uint8_t receivedByte = 0;
for (int i = 0; i < 8; i )
{
// Generate clock rising edge for reading
HAL_GPIO_WritePin(KS1092_1_SCLK_GPIO_Port, KS1092_1_SCLK_Pin, GPIO_PIN_SET);
Delay_us(1);
// Read MISO and store it in the lowest bit of the received byte
receivedByte <<= 1;
if (HAL_GPIO_ReadPin(KS1092_1_SDO_GPIO_Port, KS1092_1_SDO_Pin) == GPIO_PIN_SET)
{
receivedByte |= 0x01;
}
// Write data bit to MOSI
if (byte & 0x80)
{
HAL_GPIO_WritePin(KS1092_1_SDI_GPIO_Port, KS1092_1_SDI_Pin, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(KS1092_1_SDI_GPIO_Port, KS1092_1_SDI_Pin, GPIO_PIN_RESET);
}
byte <<= 1; // Prepare the next bit to send
Delay_us(1);
// Generate clock falling edge for writing
HAL_GPIO_WritePin(KS1092_1_SCLK_GPIO_Port, KS1092_1_SCLK_Pin, GPIO_PIN_RESET);
Delay_us(1);
}
return receivedByte;
}
函数实现SPI协议的读写操作。对于每一位数据:
- 设置SCLK高电平:准备读取数据。
- 读取MISO:将MISO上的数据位存储到接收字节的最低位。
- 写数据到MOSI:根据待发送字节的最高位,设置SDI的电平。
- 左移字节:将待发送字节左移一位,为发送下一个数据位做准备。
- 设置SCLK低电平:表示数据位已被发送和读取。
- 延时:确保信号稳定。 ----------------------------------------------------------------------
KS1029_Write_One_Byte
函数实现了单字节的写操作
SPI_ReadWriteByte
函数则实现了双向数据传输,既可以发送数据,也可以接收数据
----------------------------------------------------------------------
软件SPI vs. 硬件SPI
- 软件SPI:通过软件控制GPIO引脚实现SPI通信,灵活性高,但效率较低。
- 硬件SPI:使用微控制器内部的硬件SPI模块进行通信,效率高,速度快,但灵活性相对较低。
- 在代码里面运行这个就行
为了应对上面的情况,我也设计了一个MSPM0L1106 KS1092的单独方案,使用一颗MCU,将SPI转换为IIC,做到多个传感器一次挂在一个接口上面,节省IO以外还可以扩展多通道检测通道。至于什么时候写,看我时间。