您好、社区
我尝试设置传感器的某些寄存器的值(I2C 从设备) 但问题是、当我使用断点运行程序时、一切都很好、但当我在没有任何断点的情况下尝试相同的操作时、它只会将值发送到传感器、但传感器中没有响应。 我将在 guys.please 下方分享我的代码、并提出您的建议
代码:
#include <msp430.h> #include <stdio.h> #include <stdint.h> #include <stdbool.h> #include <I2C.h> //#include <algorithm.h> /** * main.c */ #define BMP280_ADDRESS 0X57 #define PART_ID 0XFF #define MEAN_FILTER_SIZE 15 //Registers #define Mode_Register 0x06 #define MAX30100_REG_SPO2_CONFIGURATION 0x07 #define MAX30100_REG_LED_CONFIGURATION 0x09 #define MAX30100_REG_FIFO_WRITE_POINTER 0x02 #define MAX30100_REG_FIFO_READ_POINTER 0x04 #define MAX30100_REG_FIFO_DATA 0x05 #define MAX30100_INTR 0X01 //Modes #define HR_Mode 0x02 //HR Mode #define Spo2_Mode 0x03 // Spo2 Mode #define Spo2_config 0x05 #define redLedCurrent 0x02 #define irLedCurrent 0x02 #define deviceaddr 0x57 #define Intr_enable 0x30 //Enable Spo2 and HR ready #define ALPHA 0.95 //dc filter alpha value uint8_t chip_ID=0; uint8_t mBuffer[]; uint8_t rxData=0; uint8_t i; uint8_t nack_received; uint8_t rxCount; uint8_t *rxBuffer; uint8_t txCount; uint8_t *txBuffer; //Variables uint8_t P_LED_PULSE_WIDTH=0; //Prev values uint8_t P_SAMPLING_RATE=0; uint8_t Read_Pointer=1; uint8_t Write_Pointer=1; uint8_t i=0; uint8_t P_Spo_2_config=0; //Prev values of SPo2_Reg uint8_t receive_initiated=0; uint8_t transmit_initiated=0; uint8_t clock_timeout=0; uint32_t ir_Array[100]; uint32_t red_Array[100]; uint8_t Rx_Buffer[64]; // Transfer the values between Receive inteerupt and R_read uint32_t un_temp; uint32_t IR; uint32_t RED; uint8_t led[4]={0,0,0,0}; uint8_t RxByteCtr; int32_t n_spo2; //SPO2 value int8_t h_spo2_valid; //indicator to show if the SPO2 calculation is valid int32_t n_heart_rate; //heart rate value int8_t ch_hr_valid; //indicator to show if the heart rate calculation is valid uint8_t uch_dummy; //--------------------------------------------------------------------------------| // Filters | //--------------------------------------------------------------------------------| float meanDiffResIR=0; struct dcFilter_t { float w; float result; }; //struct butterworthFilter_t //{ // float v[2]; // float result; //}; struct meanDiffFilter_t { float values[MEAN_FILTER_SIZE]; uint8_t index; float sum; uint8_t count; }; struct butterworthFilter_t { float v[2]; float result; }; struct result1 { uint8_t IR; uint8_t RED; }; struct dcFilter_t dcFilterIR = {0,0}; struct dcFilter_t dcFilterRed = {0,0}; struct meanDiffFilter_t meanDiffIR={0,0,0}; struct result1 result1={0,0}; void intialize() { //Configure GPIO P1OUT &= ~BIT0; P1DIR |=BIT0; //--setup ports P7SEL1 &= ~BIT1; //P7.1 = SCL P7SEL0 |= BIT1; P7SEL1 &= ~BIT0; //P7.0 = SDA P7SEL0 |= BIT0; P7DIR &= ~(BIT0 | BIT1); PM5CTL0 &= ~LOCKLPM5; //Disable GPIO power-on high impedance mode __delay_cycles(50); __bis_SR_register(GIE); } void i2cConfig() { UCB2CTLW0 = UCSWRST; // Reset I2C interface for config UCB2CTLW0 = /* USCI - B2 configuration register */ UCMST | // Master mode UCSYNC | // Synchronous mode UCMODE_3 | // I2C mode UCSSEL__SMCLK | // Select SMCLK UCTR | // Transmitter mode UCSWRST | // Don't release reset (yet) 0; UCB2CTLW1 = UCCLTO_1 | // Clock low time-out select (28ms) UCASTP_2 | // Automatic STOP condition generation (enabled) UCGLIT_0 | // Deglitch time (50ns) 0; UCB2BRW = 10; // Bit clock divider 1M/10 = 100kHz UCB2CTLW0 &= ~UCSWRST; // Clear reset bit to start operation UCB2IE = UCNACKIE | // Enable Nack interrupt UCTXIE | // Enable TX interrupt UCRXIE | // Enable RX interrupt UCCLTOIE | // Enable clock low time-out interrupt 0; } uint8_t read(uint8_t reg) { i2c_start(BMP280_ADDRESS,WRITE); i2c_write(reg); i2c_repeated_start(BMP280_ADDRESS,READ); i2c_read(led,2); chip_ID=led[1]; return chip_ID; } void write(uint8_t reg,uint8_t data) { i2c_start(BMP280_ADDRESS,WRITE); i2c_write(reg); i2c_write(data); STOP_I2C; } void set_mode() { // uint8_t temp=read(0x06); // temp = temp & 0x00; // temp = temp|mode; // write(0x06,0x02); // Mode_Reg, HR_MODE // i2c_stop(); // write(0x06,0x00); // Mode_Reg, HR_MODE // write(0x06,0x02); // Mode_Reg, HR_MODE // i2c_start(BMP280_ADDRESS,WRITE); i2c_write(0x06); i2c_write(0x03); // Mode_Reg, HR_MODE __delay_cycles(5); i2c_stop (); chip_ID=read(0x06); } void spo2_config() { uint8_t P_Spo_2_config = read(MAX30100_REG_SPO2_CONFIGURATION); write(MAX30100_REG_SPO2_CONFIGURATION, (P_Spo_2_config & 0x00) | Spo2_config); i2c_stop(); chip_ID=read(MAX30100_REG_SPO2_CONFIGURATION); } void LED_CURRENT() { write(MAX30100_REG_LED_CONFIGURATION, redLedCurrent << 4 | irLedCurrent); i2c_stop(); } uint8_t init_device() { chip_ID=read(0xFF); if(chip_ID==17) { return 0; } else { return 1; } } //----------------------------------------------------------------------------------------------------------------------------------------------- // //------------------------------------------------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------------------------------------------------------| // FILTERS | //-----------------------------------------------------------------------------------------------------------------------------------------------------------| int main(void) { WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer intialize(); i2cConfig(); initI2C(); while(init_device()) { printf("Couldn't able to establish I2C connection with MAX30100"); } set_mode(); spo2_config(); LED_CURRENT(); }
I2C 头文件
/* * i2c.h * * Created on: 7 Dec 2020 * Author: forat */ #ifndef I2C_H_ #define I2C_H_ #include <stdint.h> #define READ 0 #define WRITE 1 #define STOP_I2C (UCB2CTLW0 |= UCTXSTP) void initI2C (void); void i2c_start (uint8_t,unsigned int); void i2c_stop (void); void i2c_repeated_start(uint8_t,unsigned int); void i2c_write (uint8_t);//write data or reg_address void i2c_read (uint8_t*,unsigned int); #endif /* I2C_H_ */
I2c.c
#include <msp430.h> #include <stdint.h> #include "i2c.h" void initI2C() { //config P1.6 SDA P1.7 SCL UCB2CTLW0 &=0x00; UCB2CTLW1 &=0x00; UCB2TBCNT =0x00; P1SEL1 &= ~ (BIT6 | BIT7); P1SEL0 |= (BIT6 | BIT7); UCB2CTLW0 = UCSWRST; // Enable SW reset UCB2CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK | UCSYNC; // I2C master mode, SMCLK UCB2BRW = 20;//3;//10; // fSCL = SMCLK/10 = ~100kHz //UCB2I2CSA = SLAVE_ADDR; // Slave Address UCB2CTLW0 &= ~UCSWRST; // Clear SW reset, resume operation UCB2IE |= UCNACKIE;//enable NACK ISR (TX and RX?) UCB2IE &= ~UCTXIE; UCB2IE &= ~UCRXIE; UCB2IE &= ~UCCLTOIE; } void i2c_start (uint8_t dev_addr,unsigned int RW) { while(UCB2STAT & UCBBUSY);//check if SDA and SCL are idle UCB2I2CSA = dev_addr; if(RW == READ){UCB2CTLW0 &= ~UCTR;} else{UCB2CTLW0 |= UCTR;} UCB2CTLW0 |= UCTXSTT; while (UCB2CTLW0 & UCTXSTT);//wait till the whole address has been sent and ACK'ed } void i2c_stop (void) { UCB2CTLW0 |= UCTXSTP;//stop while(UCB2CTLW0 & UCTXSTP);//wait for a stop to happen } void i2c_repeated_start(uint8_t dev_addr, unsigned int RW) { UCB2I2CSA = dev_addr; if(RW == READ){UCB2CTLW0 &= ~UCTR;} else{UCB2CTLW0 |= UCTR;} UCB2CTLW0 |= UCTXSTT; while (UCB2CTLW0 & UCTXSTT);//wait till the whole address has been sent and ACK'ed } void i2c_write (uint8_t data) { UCB2TXBUF = data; while(UCB2CTLW0 & UCTXIFG0);//1 means data is sent completely } void i2c_read (uint8_t * led,unsigned int RxByteCtr) { int i = 0; for(i = 0; i < RxByteCtr;i++) { while(!(UCB2IFG & UCRXIFG0));//make sure rx buffer got data if(i == RxByteCtr - 1) STOP_I2C; led[i] = UCB2RXBUF; } while(UCB2CTLW0 & UCTXSTP);//wait for a stop to happen }
你们可以离开过滤器。我没有使用它们。