LonelyWolf / stm32

STM32 stuff
The Unlicense
949 stars 496 forks source link

errors #5

Closed Bruce9096 closed 7 years ago

Bruce9096 commented 8 years ago

Hi there

i am using a stm32 and bmp180, and i already replace the old cmsis, but there are still many errors in the code, actually there are many undefined varablse in the startup.c. it might be some problem about the direction i have setted. but it a bit hard for me to find to debug.

Could you please share the workspace with bmp180? thank you so much.

Best wishes.

Linyu Cai

LonelyWolf commented 8 years ago

Directory BMP180 contains a CooCox IDE project (BMP180 and STM32F103), just checked - build is ok. This directory contains pretty old code, the latest one for BMP180 you can take from "stm32l151rdt6-dev", but it uses my own "libraries" for GPIO and I2C, so you can change that parts to your own or SPL.

Bruce9096 commented 8 years ago

Hi there

Thank you so much for your reply, I have download the CoIDE, but it said the chips stm32F103RE has something wrong in the project.

And another question: could please tell me which file give the definition of "assert_param" (stm32l1xx_gpio), Cause, the IAR IDE said no definition of the parameter.

Thank you so much.

Best wishes

Linyu

2016-05-26 17:51 GMT+01:00 Dmitry notifications@github.com:

Directory BMP180 contains a CooCox IDE project (BMP180 and STM32F103), just checked - build is ok. This directory contains pretty old code, the latest one for BMP180 you can take from "stm32l151rdt6-dev", but it uses my own "libraries" for GPIO and I2C, so you can change that parts to your own or SPL.

— You are receiving this because you authored the thread. Reply to this email directly or view it on GitHub https://github.com/LonelyWolf/stm32/issues/5#issuecomment-221929257

LonelyWolf commented 8 years ago

It's defined in header for the MCU (stm32l1xx.h) which can be taked from the SPL or CubeMX:

#ifdef USE_FULL_ASSERT
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t* file, uint32_t line);
#else
#define assert_param(expr) ((void)0)
#endif /* USE_FULL_ASSERT */
Bruce9096 commented 8 years ago

very appreciate for your explain in detail, that problem is solved,

I have a new problem, could you please help me: when I add the BMP180.c in the project, "the IDE said that duplicate definition for the BMP180_Calibration in BMP180.o and main.o. " but actually there is no definition for BMP180_Calibration in the main. do you have any idea this problem come from?

thank you so much

Ps: I am a fresh in this area, so may be some of the problem is stupid, sorry for hold_up your time, and thank you for you patience.

Best wishes

Linyu cai

2016-05-29 18:57 GMT+01:00 Dmitry notifications@github.com:

It's defined in header for the MCU (stm32l1xx.h) which can be taken from SPL or CubeMX libraries:

ifdef USE_FULL_ASSERT

define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t

)FILE, LINE)) / Exported functions ------------------------------------------------------- _/ void assert_failed(uint8t file, uint32_t line);

else

define assert_param(expr) ((void)0)

endif /* USE_FULL_ASSERT */

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/LonelyWolf/stm32/issues/5#issuecomment-222373644, or mute the thread https://github.com/notifications/unsubscribe/AR1qLwPHlH_G4OFHfwHwZGaaYAnyf9_Iks5qGdNzgaJpZM4InuhI .

LonelyWolf commented 8 years ago

This is because recurrent include. The code in BMP180 directory is really old and written pretty bad :)

Try to place some guard against recursive inclusion, something like this at the beginning of the .h file:

#ifndef __BMP180_H
#define __BMP180_H

and then close guard adding this string at the end of .h file

#endif // __BMP180_H

In that way you can sure what .h file will be included only once.

Bruce9096 commented 8 years ago

Hi

And when I use the function in bmp180.h (eg.BMP180_ReadReg), the IDE said the function declared implicitly. do you have any idea to solve this problem? thank you so much.

Best wishes

Linyu

2016-05-30 23:31 GMT+01:00 蔡林宇 linyu.cai9096@gmail.com:

very appreciate for your explain in detail, that problem is solved,

I have a new problem, could you please help me: when I add the BMP180.c in the project, "the IDE said that duplicate definition for the BMP180_Calibration in BMP180.o and main.o. " but actually there is no definition for BMP180_Calibration in the main. do you have any idea this problem come from?

thank you so much

Ps: I am a fresh in this area, so may be some of the problem is stupid, sorry for hold_up your time, and thank you for you patience.

Best wishes

Linyu cai

2016-05-29 18:57 GMT+01:00 Dmitry notifications@github.com:

It's defined in header for the MCU (stm32l1xx.h) which can be taken from SPL or CubeMX libraries:

ifdef USE_FULL_ASSERT

define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t

)FILE, LINE)) / Exported functions ------------------------------------------------------- _/ void assert_failed(uint8t file, uint32_t line);

else

define assert_param(expr) ((void)0)

endif /* USE_FULL_ASSERT */

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/LonelyWolf/stm32/issues/5#issuecomment-222373644, or mute the thread https://github.com/notifications/unsubscribe/AR1qLwPHlH_G4OFHfwHwZGaaYAnyf9_Iks5qGdNzgaJpZM4InuhI .

LonelyWolf commented 8 years ago

If you talking about this: "warning: implicit declaration of function" then obviously compiler gets call to function which is not yet declared. Declarations (function prototypes) reside in .h file, like this:

uint8_t BMP180_WriteReg(uint8_t reg, uint8_t value);

Take a look at this article, it describes this moment much better then I can explain: http://stackoverflow.com/questions/8440816/warning-implicit-declaration-of-function

Bruce9096 commented 8 years ago

Hi, thank you for your reply, I have understand the declaration implicitly problem. now it works.

(I use the bmp180 in stm32li51rdt6-dev), I have checked, there are guard sentences you mentioned in the bmp180.h file, but the duplicated definition for "BMP180_Calibration" still exists, and in order to get the pressure value, i added

BMP180_Mode_TypeDef BMP180Mode; in bmp180.h

and the IDE also said error[li006]: duplicated definition for "BMP180_Mode", so the same error on the" BMP180_Calibration" and "BMP180_Mode".

Do you have any idea of that? thank you so much.

Linyu

2016-05-31 0:53 GMT+01:00 Dmitry notifications@github.com:

If you talking about this: "warning: implicit declaration of function" then obviously compiler gets call to function which is not yet declared. Declarations (function prototypes) reside in .h file, like this:

uint8_t BMP180_WriteReg(uint8_t reg, uint8_t value);

Take a look at this article, it describes this moment much better then I can explain:

http://stackoverflow.com/questions/8440816/warning-implicit-declaration-of-function http://url

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/LonelyWolf/stm32/issues/5#issuecomment-222566948, or mute the thread https://github.com/notifications/unsubscribe/AR1qLyUdo2elTghT4Ntwge0nbkuezye3ks5qG3hpgaJpZM4InuhI .

LonelyWolf commented 8 years ago

Thinking about my definition of variable in .h file, like this:

BMP180_Mode_TypeDef BMP180Mode;

...this is not good idea. Better move this definition to the .c file (at top of the file, right next after the #include "bmp180.h"). And in .h file write such line:

extern BMP180_Mode_TypeDef BMP180Mode;

Therefore the real definition of this variable will be only one. And putting the extern in .c/.h files, which will use this variable, will solve error about 'unknown' variable. I'm can't explain this stuff properly due to my english, try to google about "extern".

Bruce9096 commented 8 years ago

Hi Dmitry

Thank you so much, now I can get the right Calibration value of EPORM, but now it always keep loop in Delay_msec(void)

// Loop delay for about one millisecond void Delay_msec(void) { volatile uint16_t tStart; volatile uint16_t tEnd; volatile uint16_t tDiff;

tStart = DELAY_TIM->CNT;
do {
    tEnd = DELAY_TIM->CNT;
    if (tEnd < tStart)
              tDiff = 9999 - tStart + tEnd;
            else
              tDiff = tEnd - tStart;
} while (tDiff < 1);

}

could you please tell me how can I fix this.

Thank you so much

2016-05-31 14:40 GMT+01:00 Dmitry notifications@github.com:

Thinking about my definition of variable in .h file, like this:

BMP180_Mode_TypeDef BMP180Mode;

...this is not good idea. Better move this definition to the .c file (at top of the file, right next after the #include "bmp180.h"). And in .h file write such line:

extern BMP180_Mode_TypeDef BMP180Mode;

Therefore the real definition of this variable will be only one. And putting the extern in .c/.h files, which will use this variable, will solve error about 'unknown' variable. I'm can't explain this stuff properly due to my english, try to google about "extern".

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/LonelyWolf/stm32/issues/5#issuecomment-222691209, or mute the thread https://github.com/notifications/unsubscribe/AR1qL2U7dAutURQsF2UokSu_3nK0Q0pGks5qHDpRgaJpZM4InuhI .

LonelyWolf commented 8 years ago

That's why i dislike the BMP180, for the delays what it demands. The new BME280 (pressure and humidity) or BMP280 (pressure only) sensors much more convenient on this point. As for question about hanging in Delay_msec() - I suspect you forget to call Delay_Init() to initialize and start the delay timer.

Right now I'm playing with L476 MCU, wrote delay function what uses the SysTick counter. You can try to use it instead:

// Initialize delay (configure SysTick counter)
// note: must be called each time when the system core clock has been changed
void Delay_Init(void) {
    // Set reload register to generate IRQ every millisecond
    SysTick->LOAD = (uint32_t)((SystemCoreClock / 1000UL) - 1UL);

    // Set priority for SysTick IRQ
    NVIC_SetPriority(SysTick_IRQn,(1UL << __NVIC_PRIO_BITS) - 1UL);

    // Set the SysTick counter value
    SysTick->VAL = 0UL;

    // Configure SysTick source and enable counter
    SysTick->CTRL = (SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk);
}

void Delay_ms(__IO uint32_t delay_counter) {
    while (delay_counter) {
        if (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) {
            delay_counter--;
        }
    }
}

After startup you call Delay_Init(), then call Delay_ms(xxx) at any time. With one caution: Delay_Init() must be called each time when the system clock frequency has been changed.

Bruce9096 commented 8 years ago

Thank you for your kindness share, thank you so much.

Best wishes

linyu

2016-06-01 15:32 GMT+01:00 Dmitry notifications@github.com:

That's why i dislike the BMP180, for the delays what it demands. The new BME280 (pressure and humidity) or BMP280 (pressure only) sensors much more convenient on this point. As for question about hanging in Delay_msec() - I suspect you forget to call Delay_Init() to initialize and start the delay timer.

Right now I'm playing with L476 MCU, wrote delay function what uses the SysTick counter. You can try to use it instead:

// Initialize delay (configure SysTick counter)// note: must be called each time when the system core clock has been changedvoid Delay_Init(void) { // Set reload register to generate IRQ every millisecond SysTick->LOAD = (uint32_t)((SystemCoreClock / 1000UL) - 1UL);

// Set priority for SysTick IRQ
NVIC_SetPriority(SysTick_IRQn,(1UL << __NVIC_PRIO_BITS) - 1UL);

// Set the SysTick counter value
SysTick->VAL = 0UL;

// Configure SysTick source and enable counter
SysTick->CTRL = (SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk);

} void Delay_ms(__IO uint32_t delay_counter) { while (delay_counter) { if (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) { delay_counter--; } } }

After startup you call Delay_Init(), then call Delay_ms(xxx) at any time. With one caution: Delay_Init() must be called each time when the system clock frequency has been changed.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/LonelyWolf/stm32/issues/5#issuecomment-223011335, or mute the thread https://github.com/notifications/unsubscribe/AR1qL4ckGVN9qxfD7kTUBdQyGGg5c1Tfks5qHZgKgaJpZM4InuhI .

Bruce9096 commented 8 years ago

Dear Dmitry

hows going? thank you for your previous help, I appreciate a lot.

may I ask you one more question? what kind of air humidity sensor and light sensor (400nm-700nm) can be a good choice for agriculture project? do you have any experience on this.

thank you very much

best wishes

Linyu

2016-06-01 15:50 GMT+01:00 蔡林宇 linyu.cai9096@gmail.com:

Thank you for your kindness share, thank you so much.

Best wishes

linyu

2016-06-01 15:32 GMT+01:00 Dmitry notifications@github.com:

That's why i dislike the BMP180, for the delays what it demands. The new BME280 (pressure and humidity) or BMP280 (pressure only) sensors much more convenient on this point. As for question about hanging in Delay_msec() - I suspect you forget to call Delay_Init() to initialize and start the delay timer.

Right now I'm playing with L476 MCU, wrote delay function what uses the SysTick counter. You can try to use it instead:

// Initialize delay (configure SysTick counter)// note: must be called each time when the system core clock has been changedvoid Delay_Init(void) { // Set reload register to generate IRQ every millisecond SysTick->LOAD = (uint32_t)((SystemCoreClock / 1000UL) - 1UL);

// Set priority for SysTick IRQ
NVIC_SetPriority(SysTick_IRQn,(1UL << __NVIC_PRIO_BITS) - 1UL);

// Set the SysTick counter value
SysTick->VAL = 0UL;

// Configure SysTick source and enable counter
SysTick->CTRL = (SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk);

} void Delay_ms(__IO uint32_t delay_counter) { while (delay_counter) { if (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) { delay_counter--; } } }

After startup you call Delay_Init(), then call Delay_ms(xxx) at any time. With one caution: Delay_Init() must be called each time when the system clock frequency has been changed.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/LonelyWolf/stm32/issues/5#issuecomment-223011335, or mute the thread https://github.com/notifications/unsubscribe/AR1qL4ckGVN9qxfD7kTUBdQyGGg5c1Tfks5qHZgKgaJpZM4InuhI .

LonelyWolf commented 8 years ago

I do not have a clue. From my experience all digital humidity sensors (BME280, SHT21, AM2303) give very rough readings. For real work you must search something more precision, like an analog sensors. About light sensors - I don't know. All what I have dealt with - TSL2581 and SI1133. This is ambient light sensors (and UV) with digital interface. Suspect what you need something analog (photodiode?) for your light wave range.

Bruce9096 commented 8 years ago

Hi Dmitry

sorry about interrupt you again, I am now doing a coding of HIH6130 (humidity sensor) to stm32 by I2C interface, basiclly, just following your bmp180 code, I have set ReadHumidity function, and I have the problem now is that the code will always running into this function.

if (!I2Cx_Write(HIH6130_I2C_PORT,&buf[0],1,HIH6130_ADDR,I2C_NOSTOP)) { *p_H_dat = 0; printf("break E"); return HIH6130_ERROR;

and that means there is sth wrong with the I2C write, could you please help me to check if I miss some inprtant part? thank you so much.

best wishes

Linyu

2016-06-28 16:42 GMT+01:00 Dmitry notifications@github.com:

I do not have a clue. From my experience all digital humidity sensors (BME280, SHT21, AM2303) give very rough readings. For real work you must search something more precision, like an analog sensors. About light sensors - I don't know. All what I have dealt with - TSL2581 and SI1133. This is ambient light sensors (and UV) with digital interface. Suspect what you need something analog (photodiode?) for your light wave range.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/LonelyWolf/stm32/issues/5#issuecomment-229090135, or mute the thread https://github.com/notifications/unsubscribe/AR1qL7EjvmzXEiZ69zcQBy9CURG-r4pqks5qQUDvgaJpZM4InuhI .

LonelyWolf commented 8 years ago

I haven't worked with HIH6130, it's pretty expensive for my toys :) Has glanced in datasheet: to wake the sensor you must send a measure request command (with STOP). Then, after at least 40ms, you can get the readings by sending START signal followed by device slave address, sensors responds with ACK and then you must read two bytes of humidity with NACK and STOP command. So it is slightly different from the BMP180, more like common EEPROM's.

Bruce9096 commented 8 years ago

thank you for your kindness help. could you please give me some more idea of which code is used to sending request?

I have try to add "I2Cx_Write(HIH6130_I2C_PORT,&buf[0],1,HIH6130_ADDR,I2C_STOP); Delay_ms(100);"

and then read the value, but the resultsstill shows the device cannot on I2C bus.

thank you so much. Best wishes

2016-07-13 23:05 GMT+01:00 Dmitry notifications@github.com:

I haven't worked with HIH6130, it's pretty expensive for my toys :) Has glanced in datasheet: to wake the sensor you must send a measure request command (with STOP). Then, after at least 40ms, you can get the readings by sending START signal followed by device slave address, sensors responds with ACK and then you must read two bytes of humidity with NACK and STOP command. So it is slightly different from the BMP180, more like common EEPROM's.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/LonelyWolf/stm32/issues/5#issuecomment-232500920, or mute the thread https://github.com/notifications/unsubscribe/AR1qL52xq9z7E9OjmE0P053osnFfen1Eks5qVWEwgaJpZM4InuhI .

LonelyWolf commented 8 years ago

Try this function to check if your I2C device available. If it will not respond, check the hardware.

// Check if target device is ready for communication
// input:
//   I2Cx - I2C port
//   devAddr - target device address
//   Trials - number of trials
// return:
//   I2C_ERROR if there was a timeout during I2C operations, I2C_SUCCESS otherwise
I2CStatus I2Cx_IsDeviceReady(I2C_TypeDef* I2Cx, uint8_t devAddr, uint32_t Trials) {
    volatile uint32_t wait;
    uint32_t reg;

    // Disable POS (just in case)
    I2Cx->CR1 &= ~I2C_CR1_POS;
    do {
        // Generate START condition
        I2Cx->CR1 |= I2C_CR1_START;
        if (I2Cx_WaitFlagSet(I2Cx,I2C_F_SB) == I2C_ERROR) return I2C_ERROR;
        // Send slave address (last bit reset -> transmitter mode)
        I2Cx->DR = devAddr & ~I2C_OAR1_ADD0;
        // Wait for one of the following flags are set: ADDR, BERR or AF
        wait = I2C_WAIT_TIMEOUT;
        while (!((reg = I2Cx->SR1) & (I2C_SR1_ADDR | I2C_SR1_AF | I2C_SR1_BERR)) && --wait);
        // Check if device responded
        if (reg & I2C_SR1_ADDR) {
            // ACK detected
            // Read second status register to clear the ADDR flag
            (void)I2Cx->SR2;
            // Generate STOP condition
            I2Cx->CR1 |= I2C_CR1_STOP;
            // Wait until I2C bus is free
            return (I2Cx_WaitFlagReset(I2Cx,I2C_F_BUSY) == I2C_ERROR) ? I2C_ERROR : I2C_SUCCESS;
        } else {
            if (reg & I2C_SR1_BERR) {
                // Bus error (misplaced START or STOP condition)
                // Wait for the end of the address transmission
                if (I2Cx_WaitFlagSet(I2Cx,I2C_F_ADDR) == I2C_ERROR) return I2C_ERROR;
                // Clear the BERR flag
                I2Cx->SR1 &= ~I2C_SR1_BERR;
            } else {
                // NACK detected
                // Clear the AF flag
                I2Cx->SR1 &= ~I2C_SR1_AF;
            }
            // Generate STOP condition
            I2Cx->CR1 |= I2C_CR1_STOP;
            // Wait until I2C bus is free
            if (I2Cx_WaitFlagReset(I2Cx,I2C_F_BUSY) == I2C_ERROR) return I2C_ERROR;
        }
    } while (--Trials);
    return I2C_ERROR;
}