/*******************************************************************************  * File Name : SIG24130_STM32_spi.c  * Description : Implementation of SIG24130/SIG24131/SIG24132 Driver. * Author : Bob Zhou(support@signal-micro.com) ******************************************************************************** * Copyright 2023(c) Nanjing Signal Micro. * * All rights reserved. * * Software License Agreement * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * - Neither the name of Nanjing Signal Micro nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * - The use of this software may or may not infringe the patent rights of one * or more patent holders. This license does not release you from the requirement * that you obtain separate licenses from these patent holders to use this software. * * - Use of the software either in source or binary form, must be run on or directly * connected to an Nanjing Signal Micro component. * * THIS SOFTWARE IS PROVIDED BY NANJING SIGNAL MICRO "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL NANJING SIGNAL MICRO BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ******************************************************************************** * SVN Revision: 1.0 *******************************************************************************/ #include "stm32f4xx_hal.h" #include "spi.h" #include #include "math.h" // Add printf1 for debug purpose to print out register content. #include "usart.h" #include #define printf1(...) HAL_UART_Transmit((UART_HandleTypeDef *)&huart1, (uint8_t *)u1_buf, \ sprintf((char *)u1_buf, __VA_ARGS__), 0xFFFF); uint8_t u1_buf[256]; uint32_t reg_info; uint8_t DATACHK = 0; // Store CONF0 register bit22 content to rdata command usage. uint8_t PARITY = 0; // Store parity byte for ADC data. uint32_t SIG24130_adc_data = 0; uint32_t SIG16130_adc_data = 0; unsigned char RH_DATA = 0, RM_DATA = 0, RL_DATA = 0, RS_DATA = 0; void delay_nus(int nus) { volatile int i, j; for (i = 0; i != nus; i++) for (j = 0; j < 4; j++) ; } // SPI interface: SIG24130_CS_Pin, SIG24130_SCLK_Pin, SIG24130_DIN_Pin, SIG24130_DOUT_Pin // SIG24130 works with standard SPI MODE1; if spi is not used, the initialized states are SIG24130_CSn_HIGH; SIG24130_SCLK_LOW; SIG24130_DIN_LOW if GPIO are used. /**************************************************************************/ void SIG24130_SendByte(uint8_t tx_data) { uint8_t rx_data = 0; HAL_SPI_TransmitReceive(&hspi2, &tx_data, &rx_data, 1, 1000); } uint8_t SIG24130_ReceiveByte(void) { uint8_t tx_data = 0x00; uint8_t rx_data = 0; HAL_SPI_TransmitReceive(&hspi2, &tx_data, &rx_data, 1, 1000); return rx_data; } uint8_t SPIDEV1_transfer(uint8_t *send, uint8_t *receive, uint8_t bytes_num) { HAL_SPI_TransmitReceive(&hspi2, send, receive, bytes_num, 1000); return 0; } /***********************************************************************  * Function Name : WriteRegister  * Description   : Write 24-bit register  * Returns       : None  * Params        : addr=>CONF0|CONF1|OFFSET|GAIN, H_DATA, M_DATA, L_DATA  ***********************************************************************/ // Only work for 24-bit register void SIG24130_WriteRegister(uint8_t addr, uint8_t H_DATA, uint8_t M_DATA, uint8_t L_DATA) { SIG24130_CSn_HIGH; delay_nus(2); SIG24130_CSn_LOW; delay_nus(2); // Toggle CSn in case SPI is out of sync SIG24130_SendByte(CMD_WRITE | addr); SIG24130_SendByte((addr == CONF0) ? (H_DATA & 0x7F) : H_DATA); // Force bit23 to 0 for CONF0 write operation. SIG24130_SendByte(M_DATA); SIG24130_SendByte(L_DATA); delay_nus(2); SIG24130_CSn_HIGH; // Force CSn back to high to prevent unexpected command if ((addr == 0x01) & ((RH_DATA & 0x40) == 0x40)) DATACHK = 1; // Force DATACHK = CONF0[22]. return; } /****************************************************************  * Function Name : ReadRegister  * Description   : Read 24-bit register  * Returns       : None  * Params        : addr=>CONF0|CONF1|OFFSET|GAIN  ****************************************************************/ // Only work for 24-bit register uint32_t SIG24130_ReadRegister(uint8_t addr) { uint32_t reg_info; SIG24130_CSn_HIGH; delay_nus(2); SIG24130_CSn_LOW; delay_nus(2); // Toggle CSn in case SPI is out of sync SIG24130_SendByte(CMD_READ | addr); RH_DATA = SIG24130_ReceiveByte(); RM_DATA = SIG24130_ReceiveByte(); RL_DATA = SIG24130_ReceiveByte(); delay_nus(2); SIG24130_CSn_HIGH; // Force CSn back to high to prevent unexpected command reg_info = (RH_DATA << 16) | (RM_DATA << 8) | RL_DATA; return (reg_info); } /****************************************************************  * Function Name : SetInputMux  * Description   : Set Input Mux  * Returns       : None  * Params        : muxp=>0(AIN0), 1(AIN1), 2(AIN2), 3(AIN3), 4(AIN4), 5(AIN5), 6(AIN6), 7(AIN7), 8(AINCOM), 9(TPS+), 10(REFP), 11(AVSS), 12(DVSS), 13((AVDD-AVSS)/4+), 14((DVDD-DVSS)/4+) * muxp=>0(AIN0), 1(AIN1), 2(AIN2), 3(AIN3), 4(AIN4), 5(AIN5), 6(AIN6), 7(AIN7), 8(AINCOM), 9(TPS-), 10(REFN), 11(AVSS), 12(DVSS), 13((AVDD-AVSS)/4-), 14((DVDD-DVSS)/4-) * 4(AIN4), 5(AIN5), 6(AIN6), 7(AIN7) is only available for SIG24131/SIG24132  ****************************************************************/ void SIG24130_SetInputMux(uint8_t muxp, uint8_t muxn) { SIG24130_ReadRegister(CONF1); SIG24130_WriteRegister(CONF1, RH_DATA, RM_DATA, (muxp << 4) | muxn); // SIG24130_ReadRegister(CONF1); // Read CONF1 register if wanted for verification return; } /****************************************************************  * Function Name : SetSpeed  * Description   : Set ADC speed  * Returns       : None  * Params        : speed=>SPEED_2p5|SPEED_5|...|SPEED_8000|SPEED_9600  ****************************************************************/ void SIG24130_SetSpeed(uint8_t speed) { SIG24130_ReadRegister(CONF1); SIG24130_WriteRegister(CONF1, RH_DATA, (RM_DATA & 0xC0) | speed, RL_DATA); // Update CONF1 register with speed // SIG24130_ReadRegister(CONF1); // Read CONF1 register if wanted for verification return; } /****************************************************************  * Function Name : SetFilter  * Description   : Set Filter  * Returns       : None  * Params        : sinc4=>0(sinc1), 1(sinc4) * rej60=>0(no), 1(yes) * data rate need to be 50sps for rej60 to be effective  ****************************************************************/ void SIG24130_SetFilter(uint8_t sinc4, uint8_t rej60) { SIG24130_ReadRegister(CONF1); SIG24130_WriteRegister(CONF1, RH_DATA, (RM_DATA & 0x3F) | (sinc4 << 7) | (rej60 << 6), RL_DATA); // SIG24130_ReadRegister(CONF1); // Read CONF1 register if wanted for verification return; } /****************************************************************  * Function Name : SetGain  * Description   : Set ADC Gain  * Returns       : None  * Params        : gain=0(1), 1(2), 2(4), 3(8), 4(16), 5(32), 6(64), 7(128), 8(256)  ****************************************************************/ void SIG24130_SetGain(uint8_t gain) { SIG24130_ReadRegister(CONF1); SIG24130_WriteRegister(CONF1, (RH_DATA & 0xF0) | gain, RM_DATA, RL_DATA); // Update CONF1 register with gain // SIG24130_ReadRegister(CONF1); // Read CONF1 register if wanted for verification return; } /****************************************************************  * Function Name : SetBuffer  * Description   : Set buffer  * Returns       : None  * Params        : buffer=>0(off), 1(on) * buffer can only be off if gain is not 1  ****************************************************************/ void SIG24130_SetBuffer(uint8_t buffer) { SIG24130_ReadRegister(CONF0); SIG24130_WriteRegister(CONF0, RH_DATA & 0x7F, (RM_DATA & 0x7F) | (buffer << 7), RL_DATA); // Force bit23 to 0 for CONF0 write operation. // SIG24130_ReadRegister(CONF0); // Read CONF0 register if wanted for verification return; } /****************************************************************  * Function Name : SetRefMux  * Description   : Set ADC reference connection  * Returns       : None  * Params        : refmux=>0(REFP/REFN), 1(REFP1/REFN1), 2(2.5V Int. Ref), 3(1.17V Int. Ref) * 1(REFP1/REFN1) is only available for SIG24132  ****************************************************************/ void SIG24130_SetRefMux(uint8_t refmux) { SIG24130_ReadRegister(CONF1); SIG24130_WriteRegister(CONF1, (RH_DATA & 0xCF) | (refmux << 4), RM_DATA, RL_DATA); // SIG24130_ReadRegister(CONF1); // Read CONF1 register if wanted for verification return; } /****************************************************************  * Function Name : SetSingleShot  * Description   : Set ADC to run at continuous mode or single shot mode  * Returns       : None  * Params        : single=>0(continuous), 1(single shot mode)  ****************************************************************/ void SIG24130_SetSingleShot(uint8_t single) { SIG24130_ReadRegister(CONF1); SIG24130_WriteRegister(CONF1, (RH_DATA & 0xBF) | (single << 6), RM_DATA, RL_DATA); // SIG24130_ReadRegister(CONF1); // Read CONF1 register if wanted for verification return; } /****************************************************************  * Function Name : SetZeroLatency  * Description   : Set ADC to run at zero latency mode or not  * Returns       : None  * Params        : latency=>0(no), 1(yes)  ****************************************************************/ void SIG24130_SetZeroLatency(uint8_t latency) { SIG24130_ReadRegister(CONF1); SIG24130_WriteRegister(CONF1, (RH_DATA & 0x7F) | (latency << 7), RM_DATA, RL_DATA); // SIG24130_ReadRegister(CONF1); // Read CONF1 register if wanted for verification return; } /****************************************************************  * Function Name : SetIDAC  * Description   : Set IDAC  * Returns       : None  * Params        : idac_size=>0(off), 1(10uA), 2(50uA), 3(100uA), 4(200uA), 5(250uA), 6(500uA), 7(1000uA) * idac2_mux=>0(AIN0), 1(AIN1), 2(AIN2), 3(AIN3), 4(AIN4), 5(AIN5), 6(AIN6), 7(AIN7) * idac1_mux=>0(AIN0), 1(AIN1), 2(AIN2), 3(AIN3), 4(AIN4), 5(AIN5), 6(AIN6), 7(AIN7) * idac_pair=>0(no), 1(yes) * 4(AIN4), 5(AIN5), 6(AIN6), 7(AIN7) is only available for SIG24131/SIG24132  ****************************************************************/ void SIG24130_SetIDAC(uint8_t idac_size, uint8_t idac2_mux, uint8_t idac1_mux, uint8_t idac_pair) { SIG24130_ReadRegister(CONF0); SIG24130_WriteRegister(CONF0, RH_DATA & 0x7F, (RM_DATA & 0xF8) | idac_size, (RL_DATA & 0xBF) | (idac_pair << 7) | (idac2_mux << 3) | idac1_mux); // Force bit23 to 0 for CONF0 write operation. // SIG24130_ReadRegister(CONF0); // Read CONF0 register if wanted for verification return; } /****************************************************************  * Function Name : SetBCS  * Description   : Set burnout current source(BCS) at input pins.  * Returns       : None  * Params        : burnout=>0(no), 1(1uA)  ****************************************************************/ void SIG24130_SetBCS(uint8_t burnout) { SIG24130_ReadRegister(CONF0); SIG24130_WriteRegister(CONF0, RH_DATA & 0x7F, (RM_DATA & 0xF7) | (burnout << 3), RL_DATA); // Force bit23 to 0 for CONF0 write operation. // SIG24130_ReadRegister(CONF0); // Read CONF0 register if wanted for verification return; } /****************************************************************  * Function Name : SetVbias  * Description   : Set Vbias at AINCOM pin.  * Returns       : None  * Params        : vbias=>0(no), 1(AINCOM=(AVDD-AVSS)/2)  ****************************************************************/ void SIG24130_SetVbias(uint8_t vbias) { SIG24130_ReadRegister(CONF0); SIG24130_WriteRegister(CONF0, (RH_DATA & 0x77) | (vbias << 3), RM_DATA, RL_DATA); // Force bit23 to 0 for CONF0 write operation. // SIG24130_ReadRegister(CONF0); // Read CONF0 register if wanted for verification return; } /****************************************************************  * Function Name : SetDelay  * Description   : Add extra delay before filter starts to work, allocate extra time needed for analog input to fully settle.  * Returns       : None  * Params        : delay=0(0us), 1(104.2us), 2(416.7us), 3(1.667ms), 4(6.667ms), 5(26.67ms), 6(106.7ms), 7(426.7ms)  ****************************************************************/ void SIG24130_SetDelay(uint8_t delay) { SIG24130_ReadRegister(CONF0); SIG24130_WriteRegister(CONF0, RH_DATA & 0x7F, (RM_DATA & 0x8F) | (delay << 4), RL_DATA); // Force bit23 to 0 for CONF0 write operation. // SIG24130_ReadRegister(CONF0); // Read CONF0 register if wanted for verification return; } /****************************************************************  * Function Name : SetDataChk  * Description   : Set ADC checksum function during rdata command.  * Returns       : None  * Params        : datachk=>0(no), 1(checksum enabled)  ****************************************************************/ void SIG24130_SetDataChk(uint8_t datachk) { SIG24130_ReadRegister(CONF0); SIG24130_WriteRegister(CONF0, (RH_DATA & 0x3F) | (datachk << 6), RM_DATA, RL_DATA); // Force bit23 to 0 for CONF0 write operation. // SIG24130_ReadRegister(CONF0); // Read CONF0 register if wanted for verification return; } /****************************************************************  * Function Name : SetRefOut  * Description   : Set ADC Int. Ref to output pin.  * Returns       : None  * Params        : refout=>0(no), 1(yes) * if REFOUT=1, Int. Ref connected to REFP pin for SIG24130/SIG24131 and REFP1 pin for SIG24132.  ****************************************************************/ void SIG24130_SetRefOut(uint8_t refout) { SIG24130_ReadRegister(CONF0); SIG24130_WriteRegister(CONF0, (RH_DATA & 0x7E) | refout, RM_DATA, RL_DATA); // Force bit23 to 0 for CONF0 write operation. // SIG24130_ReadRegister(CONF0); // Read CONF0 register if wanted for verification return; } /****************************************************************  * Function Name : Reset  * Description   : Resets the SIG24130  * Returns       : None  * Params        : None  ****************************************************************/ void SIG24130_Reset() { SIG24130_CSn_HIGH; delay_nus(2); SIG24130_CSn_LOW; delay_nus(2); // Toggle CSn in case SPI is out of sync SIG24130_SendByte(0x02); // Send 0x02 reset command delay_nus(10); SIG24130_CSn_HIGH; // Force CSn back to high to prevent unexpected command } /****************************************************************  * Function Name : Sync  * Description   : Sync the SIG24130 conversion  * Returns       : None  * Params        : None  ****************************************************************/ void SIG24130_Sync() { SIG24130_CSn_HIGH; delay_nus(2); SIG24130_CSn_LOW; delay_nus(2); // Toggle CSn in case SPI is out of sync SIG24130_SendByte(0x04); // Send 0x04 sync command delay_nus(2); SIG24130_CSn_HIGH; // Force CSn back to high to prevent unexpected command } /****************************************************************  * Function Name : Sleep  * Description   : Put the SIG24130 into sleep mode  * Returns       : None  * Params        : None  ****************************************************************/ void SIG24130_Sleep() { SIG24130_CSn_HIGH; delay_nus(2); SIG24130_CSn_LOW; delay_nus(2); // Toggle CSn in case SPI is out of sync SIG24130_SendByte(0x0A); // Send 0x0A sleep command delay_nus(2); SIG24130_CSn_HIGH; // Force CSn back to high to prevent unexpected command } /****************************************************************  * Function Name : Wakeup  * Description   : Put the SIG24130 into sleep mode  * Returns       : None  * Params        : None  ****************************************************************/ void SIG24130_Wakeup() { SIG24130_CSn_HIGH; delay_nus(2); SIG24130_CSn_LOW; delay_nus(2); // Toggle CSn in case SPI is out of sync SIG24130_SendByte(0x0C); // Send 0x0C wakeup command delay_nus(2); SIG24130_CSn_HIGH; // Force CSn back to high to prevent unexpected command } /****************************************************************  * Function Name : SYSOCAL  * Description   : System offset cal  * Returns       : None  * Params        : None  ****************************************************************/ void SIG24130_SYSOCAL() { SIG24130_CSn_HIGH; delay_nus(2); SIG24130_CSn_LOW; delay_nus(2); // Toggle CSn in case SPI is out of sync SIG24130_SendByte(0x10); // Send 0x10 SYSOCAL command delay_nus(2); SIG24130_CSn_HIGH; // Force CSn back to high to prevent unexpected command } /****************************************************************  * Function Name : SYSGCAL  * Description   : System gain cal  * Returns       : None  * Params        : None  ****************************************************************/ void SIG24130_SYSGCAL() { SIG24130_CSn_HIGH; delay_nus(2); SIG24130_CSn_LOW; delay_nus(2); // Toggle CSn in case SPI is out of sync SIG24130_SendByte(0x11); // Send 0x11 SYSGCAL command delay_nus(2); SIG24130_CSn_HIGH; // Force CSn back to high to prevent unexpected command } /****************************************************************  * Function Name : SELFOCAL  * Description   : Self offset cal  * Returns       : None  * Params        : None  ****************************************************************/ void SIG24130_SELFOCAL() { SIG24130_CSn_HIGH; delay_nus(2); SIG24130_CSn_LOW; delay_nus(2); // Toggle CSn in case SPI is out of sync SIG24130_SendByte(0x12); // Send 0x12 SELFOCAL command delay_nus(2); SIG24130_CSn_HIGH; // Force CSn back to high to prevent unexpected command } void SIG24130_Init(void) { HAL_Delay(100); // Wait time after power-up before SPI communication. Power-On Reset(POR) time is 43ms. SIG24130_Reset(); delay_nus(100); // RESET SIG24130 SIG24130_WriteRegister(CONF1, 0x20, 0x89, 0xDD); // Update CONF1 register with 0x2089DD for int 2.5V ref, SINC4, 50sps(0x2089) or 1200sps(0x2096), 0xDD=>(AVDD-AVSS)/4 or 0xBB=>(AVSS-AVSS), reg_info = SIG24130_ReadRegister(CONF1); // Read CONF1 register if wanted // printf1("Register CONF1= %x \r\n", (unsigned int)reg_info); // Used only for manual debug with breakpoint. SIG24130_CSn_LOW; delay_nus(2); // DOUT/DRDYn signal can only be available at the pin while CSn pin is low, otherwise it is tri-state. } /*************************************************  * Function Name : RetrievalData for SIG24130/24131/24132  * Description   : Retrieval ADC Data  * Returns       : ADC data  * Params        : rdata=>0(no), 1(yes) * * 1. Extra byte is clocked with chksum=1 or DATACHK=1 to force DOUT to high at the end of data retrieval. * 2. Rdata command is provided to guarantee that the retrieved data is always correct with rdata command sent at any time. * 3. Data retrieval without rdata command should start right after DOUT falling edge and finish * before the next new data is updating, otherwise the data could be corrupted. *************************************************/ unsigned long SIG24130_RetrievalData(uint8_t rdata, uint8_t chksum) { unsigned char Rx_bytes[4] = {0, 0, 0, 0}; uint8_t parity_cal = 0; SIG24130_adc_data = 0; SIG24130_CSn_HIGH; delay_nus(2); SIG24130_CSn_LOW; delay_nus(2); // Toggle CSn in case SPI is out of sync if (rdata) SIG24130_SendByte(0x60); // rdata command is used to make sure that the retrieved data is also correct. // Method #1 HAL_SPI_Receive(&hspi2, Rx_bytes, (rdata & DATACHK) | chksum ? 4 : 3, 1000); // Rx_bytes[3] is the parity byte. // Method #2 // unsigned char Tx_bytes[4] = {0x00,0x00,0x00,0x00}; // HAL_SPI_TransmitReceive(&hspi2, Tx_bytes, Rx_bytes, (rdata & DATACHK)|chksum ? 4 : 3, 1000); // Method #3 // Rx_bytes[0]=SIG24130_ReceiveByte(); // Rx_bytes[1]=SIG24130_ReceiveByte(); // Rx_bytes[2]=SIG24130_ReceiveByte(); // if((rdata & DATACHK)|chksum) Rx_bytes[3]=SIG24130_ReceiveByte(); SIG24130_adc_data = (SIG24130_adc_data | Rx_bytes[0]) << 8; SIG24130_adc_data = (SIG24130_adc_data | Rx_bytes[1]) << 8; SIG24130_adc_data = (SIG24130_adc_data | Rx_bytes[2]); if ((rdata & DATACHK) | chksum) { PARITY = Rx_bytes[3]; // Store parity byte if retrieved. parity_cal = Rx_bytes[0] + Rx_bytes[1] + Rx_bytes[2] + 0x5B; parity_cal = parity_cal | 0x81; // Force bit7 and bit0 to 1. if (PARITY != parity_cal) return (0xFFFFFFFF); // Return 0xFFFFFFFF if checksum calculation is not correct. } SIG24130_CSn_HIGH; delay_nus(2); SIG24130_CSn_LOW; delay_nus(2); // Toggle CSn in case SPI is out of sync return (SIG24130_adc_data); } /*************************************************  * Function Name : RetrievalData for SIG16130/16131/16132  * Description   : Retrieval ADC Data  * Returns       : ADC data  * Params        : rdata=>0(no), 1(yes) * * 1. Extra byte is clocked with chksum=1 or DATACHK=1 to force DOUT to high at the end of data retrieval. * 2. Rdata command is provided to guarantee that the retrieved data is always correct with rdata command sent at any time. * 3. Data retrieval without rdata command should start right after DOUT falling edge and finish * before the next new data is updating, otherwise the data could be corrupted. *************************************************/ unsigned long SIG16130_RetrievalData(uint8_t rdata, uint8_t chksum) { unsigned char Rx_bytes[3] = {0, 0, 0}; uint8_t parity_cal = 0; SIG16130_adc_data = 0; SIG24130_CSn_HIGH; delay_nus(2); SIG24130_CSn_LOW; delay_nus(2); // Toggle CSn in case SPI is out of sync if (rdata) SIG24130_SendByte(0x60); // rdata command is used to make sure that the retrieved data is also correct. // Method #1 HAL_SPI_Receive(&hspi2, Rx_bytes, (rdata & DATACHK) | chksum ? 3 : 2, 1000); // Rx_bytes[2] is the parity byte. // Method #2 // unsigned char Tx_bytes[3] = {0x00,0x00,0x00}; // HAL_SPI_TransmitReceive(&hspi2, Tx_bytes, Rx_bytes, (rdata & DATACHK)|chksum ? 3 : 2, 1000); // Method #3 // Rx_bytes[0]=SIG24130_ReceiveByte(); // Rx_bytes[1]=SIG24130_ReceiveByte(); // if((rdata & DATACHK)|chksum) Rx_bytes[2]=SIG24130_ReceiveByte(); SIG16130_adc_data = (SIG16130_adc_data | Rx_bytes[0]) << 8; SIG16130_adc_data = (SIG16130_adc_data | Rx_bytes[1]); if ((rdata & DATACHK) | chksum) { PARITY = Rx_bytes[2]; // Store parity byte if retrieved. parity_cal = Rx_bytes[0] + Rx_bytes[1] + 0x5B; parity_cal = parity_cal | 0x81; // Force bit7 and bit0 to 1. if (PARITY != parity_cal) return (0xFFFFFFFF); // Return 0xFFFFFFFF if checksum calculation is not correct. } SIG24130_CSn_HIGH; delay_nus(2); SIG24130_CSn_LOW; delay_nus(2); // Toggle CSn in case SPI is out of sync return (SIG16130_adc_data); } void fun_get_sig16132_ch(uint8_t channel, float32 *data) { if (!data) return; BOOL config_flag = FALSE; static uint8_t last_ch = 0; if (channel != last_ch) { last_ch = channel; config_flag = TRUE; } if (config_flag == TRUE) { config_flag = FALSE; if ((channel == 2) || (channel == 3) || (channel == 4) || (channel == 5) || (channel == 7)) { HAL_Delay(100); // Wait time after power-up before SPI communication. Power-On Reset(POR) time is 43ms. SIG24130_Reset(); delay_nus(100); // RESET SIG24130 SIG24130_SetRefMux(2); // 内部2.5V参考 SIG24130_SetInputMux(channel, 11); // 单端输出对地,11(AVSS) SIG24130_CSn_LOW; delay_nus(2); // DOUT/DRDYn signal can only be available at the pin while CSn pin is low, otherwise it is tri-state. //*data = SIG16130_RetrievalData(1, 0); } else if (channel == 10) { HAL_Delay(100); // Wait time after power-up before SPI communication. Power-On Reset(POR) time is 43ms. SIG24130_Reset(); delay_nus(100); // RESET SIG24130 SIG24130_SetRefMux(2); // 内部2.5V参考 SIG24130_SetInputMux(0, 1); // 差分输入(in0+ in1-) SIG24130_SetIDAC(6, 6, 6, 0); // 1mA IDAC0 IDAC1 pair 0 SIG24130_CSn_LOW; delay_nus(2); // DOUT/DRDYn signal can only be available at the pin while CSn pin is low, otherwise it is tri-state. //*data = SIG16130_RetrievalData(1, 0); } else *data = 0; } else { float32 ad_16 = SIG16130_RetrievalData(1, 0); float32 voltage = (float32)(2.5f * ad_16 / 32767.0f); float32 Rt = 0; if (channel == 2) // 0~30V电压输入检测 { *data = voltage * 16.0f; } else if (channel == 3) // mV电压输入检测 { *data = voltage * 1000.0f - 0.2f; } else if (channel == 4) //-2.5~2.5V输出反馈 { *data = 2.0f * voltage - 2.5f; } else if (channel == 5) // 4`20mA输入检测 { *data = voltage / 100.0f * 1000.0f; } else if (channel == 7) // 4`20mA输出反馈 { *data = voltage * 1000.0f * 0.02f * 0.5f; } else if (channel == 10) // RTD输入检测 { // 在0~650℃范围内: // Rt =R0 (1+At+Bt2) // 在-190~0℃范围内: // Rt =R0 (1+At+Bt2+C(t-100)t3) // 式中A、B、C 为常数, // A=3.96847×10-3; // B=-5.847×10-7; // C=-4.22×10-12; #define R0 100.0f #define A 3.96847e-3 #define B -5.847e-7 #define C -4.22e-12 Rt = voltage * 1000.0f / 1.0f; float32 temp1 = (-A + sqrt(A * A - 4 * B * (1 - Rt / R0))) / (2 * B); float32 temp2 = (-A - sqrt(A * A - 4 * B * (1 - Rt / R0))) / (2 * B); *data = temp1; //*data = voltage * 1000.0f; } } }