I am able to put my stm32L1xDiscovery board in STOP mode with RTC running.
according to the datasheet this should draw about 1.3 µA. But my application draws 3.3 µA.
I noticed I did not put the FLASH in a low power mode during sleep. But when I did this, nothing changed.
This is what I use to go into STOP mode:
SCB->SCR |= ((uint32_t)SCB_SCR_SLEEPDEEP);
RCC->APB1ENR |= RCC_APB1Periph_PWR;
PWR->CR |= ((uint32_t)(PWR_CR_LPSDSR|PWR_CR_ULP)); // ULP seems to have no effect on power consumption
RCC->APB1ENR &= ~RCC_APB1Periph_PWR;
FLASH->ACR |= SLEEP_PD; // seems to have no effect at all on power consumption
__WFI();
Any idea what I am missing here?
If you use discovery board your measurement may be not clear because a lot of other components consumpt some energy. It's may be protection diode, driver of 3.3V line or second MCU with ST-LINK/V2 embedded debug tool.
Where did you measure the power consumption? You should do it betwen JP1 pins 1 & 2 (Pin 2 is connected directly to Vdd). That should show the power drawn by the MCU, and of course anything that is powered by the output pins.
The trick is to properly disconnect and shut down all pins (except the wakeup source) as well as all clocks that are not needed.
Set FLASH->ACR |= SLEEP_PD
Enable all GPIO clocks
Put all unneded pins to analog mode
Disable ALL clocks except RCC_APB1ENR_PWREN and wakeup GPIOs in RCC->xxxLPENR
Then start the thing without the debugger, ST-Link (CN3) jumpers removed.
... and there might be other issues. It's hard to get it right.
Related
I have a strange problem that I dont understand. Please bare with me as this is a difficult problem to deconstruct. I will thus give as much information as I can with test cases and results I have found.
The problem:
I need to set PA6 LOW and then use the DAC. When the DAC is changed in a transient manner, the pin PA6 will not return to 3V when set to HIGH.
In other words, the DAC causes the upper voltage limit of PA6 to be 0.6-0.8V.
I have confirmed this with oscilloscope.
The following piece of code is called inside a task/thread and executed at 50Hz:
if (enable == 1)
{
HAL_GPIO_WritePin(PROPULSION_ENABLE_GPIO_PORT, PROPULSION_ENABLE_GPIO_PIN, GPIO_PIN_RESET);
HAL_DAC_SetValue(&PropulsionModule_DAC, PropulsionModule_DAC_CHANNEL, DAC_ALIGN_12B_R, PropulsionData.propulsionSetPoint_12bit);
}
else
{
HAL_GPIO_WritePin(PROPULSION_ENABLE_GPIO_PORT, PROPULSION_ENABLE_GPIO_PIN, GPIO_PIN_SET);
HAL_DAC_SetValue(&PropulsionModule_DAC, PropulsionModule_DAC_CHANNEL, DAC_ALIGN_12B_R, 0);
}
Setup and environment
STM32F4 Discovery board
FreeRTOS configured with threads, queues and everything else works as expected
I have a single DAC set up on DAC_channel_2 (PA5) and a GPIO_output (PA6).
I also have these peripherals enabled, CAN bus, UART, several GPIO's, etc. Please see attached picture
Findings:
When I change the PA6 pin to PC4 (the adjacent pin) the problem goes away
When I change DAC_channel_2 to DAC_channel_1 the problem goes away
I flashed the code to two other brand new, out of the box, boards with the same errors.
Once PA6 is faulty and its high state is at 0.6V, resetting the microcontroller will reset the pin PA6 and PA6 will return to 3V in its HIGH state.
Any help would be greatly appreciated.
I found the problem. The problem is the MEMS chip on the discovery board. It is vitally important one realizes that not all pins on the discovery board are usable.
Refer to the first link below from Page 22 on which pins are available. Please note that some of the pins that are "not free" can still be used. See the application notes on each of the chips on the board in the second link.
Link 1: https://www.st.com/resource/en/user_manual/dm00039084-discovery-kit-with-stm32f407vg-mcu-stmicroelectronics.pdf
Link 2: https://ucilnica.fri.uni-lj.si/pluginfile.php/29604/mod_resource/content/1/en.DM00039084.pdf
I am using Waveshare 1.54" ePaper Module. Using SPI peripheral:
CPU freq is 16Mhz
SPI Prescaler DIV by 8
MSB FIRST
CPOL=0, CPHA=1
The Display does not response but it respond with TI CC1310 properly.
The problem with SPI is after transmitting byte it does not go to ideal high state.
I have checked with logic analyser.
The SPI is initialised thus:
/****************** Initializing The SPI Peripheral ******************/
void SPI_setup(void)
{
CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, ENABLE); //Enable SPI Peripheral Clock
//Set the MOSI, MISO and SCk at high Level.
//GPIO_ExternalPullUpConfig(GPIOC, (GPIO_Pin_TypeDef)(GPIO_PIN_6),ENABLE);
SPI_DeInit();
SPI_Init(SPI_FIRSTBIT_MSB, //Send MSB First
SPI_BAUDRATEPRESCALER_8, //Fosc/16 = 1MHz
SPI_MODE_MASTER,
SPI_CLOCKPOLARITY_LOW, //IDEAL Clock Polarity is LOW
SPI_CLOCKPHASE_2EDGE, //The first clock transition is the first data capture edge
SPI_DATADIRECTION_2LINES_FULLDUPLEX, //Only TX is Enable
SPI_NSS_SOFT,
0x00);
SPI_Cmd(ENABLE);
}
This is pretty much the same problem you had at Issue in interfacing SPI e-ink display with PIC 18F46K22 only on a different processor. Worth noting that CPHA on STM8 has the opposite sense to CPE on PIC18 which may be the cause of your error. That is to say that CPHA=1 on the STM8 has the same effect as CKE=0 on the PIC18. You really have to look at the timing diagrams for each part carefully.
From https://www.waveshare.com/wiki/1.54inch_e-Paper_Module:
Compare with the STM8 reference manual:
Clearly you need one of:
CPHA=1 / CPOL=1 (SPI_CLOCKPOLARITY_HIGH / SPI_CLOCKPHASE_2EDGE) or
CPHA=0 / CPOL=0 (SPI_CLOCKPOLARITY_LOW / SPI_CLOCKPHASE_1EDGE)
If it is the SCLK that you want to be normally-high, then you need the first option - although I fail to see why that is "ideal", the Waveshare diagram clearly indicates that either is acceptable.
My config: STM32F407VGT, ide STM32CubeIDE.
I put MCU in standby mode and there is two ways to MCU leave standby state. First way is to connect PA0 pin with 3.3v and second way is to wait for RTC timer to count to the specified value. Both ways works fine.
Now my question is How I can distinguish events? I find this in datasheet
Bit 8 EWUP: Enable WKUP pin
This bit is set and cleared by software.
0: WKUP pin is used for general purpose I/O. An event on the WKUP pin does not wakeup
the device from Standby mode.
1: WKUP pin is used for wakeup from Standby mode and forced in input pull down
configuration (rising edge on WKUP pin wakes-up the system from Standby mode).
Note: This bit is reset by a system reset.
With this code I tried to come up with an idea
if(PWR_CSR_EWUP == 0x00000100) // PA0 is used to leave standby mode
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);
HAL_Delay(2500);
}
else // mcu leave standby mode because RTC timer count desired value
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET);
HAL_Delay(2500);
}
Enter_StandbyMode();
For some reason I always got that PWR_CSR_EWUP isn't equal with 0x00000100 even if I leave standby mode by connecting PA0 with 3.3V. So the conclusion is that I always get it else state ( green led (PD14) is always turned on after mcu left standby mode).
This looks as if you have to correct two things:
you must read the register PWR_CSR, not the bitmask PWR_CSR_EWUP
you shouldn't check for being equal (because the 32-bit register holds 6 more bits which indicate other stuff), but mask out the bit you need and check the result:
((PWR_CSR & PWR_CSR_EWUP) == PWR_CSR_EWUP)
Of course, you can also check STM32CubeF4 HAL library for a function that delivers the information you want. When you look at its implementation, you should find something like this (but I admit I haven't checked...).
I am trying to make it so that then PINB7 is pressed (which is pin of botton) LED to light up.
PINB7 is PCINT8 on board.
So i set
PCICR|=(1<<1);//enable interrupts for pins 14-8
sei();
PCMSK1|=(<<PCINT8); // mask for pin 8
i don't get what vector i should use in ISR. From what i saw I should just do PCINT8_vect, however vector doesn't get highlighted like then i use "TIMER2_COMPB_vect".So does PCINT8 vector not exist or is there way to use PCINT0 and 1 for this?
Apparently , on mega328pb , there is no vectors for individual pin interrupts but there are vectors for PCIE0,1,2,3.
0- bits 0:7
1-8:14
2-16:23
3-24:27
so if u want to use interrupt for pin b7.
PB7 is PCINT7(can be seen in chapter about i/o ports).
So id have to enable PCIE0 in PCIRC register, correct mask it TMSK0. and use ISR(PCINT0_vect).
But if you have interrupt on PCINT6 and PCINT7 , you need if else in ISR to determine which of 2 pins triggered interrupt
the MCP23017 from Microchip is an I2C based 16-pin IO extender. I have been able to set up the device once (set pin direction and values), but after that i cannot change the values as expected unless i reset / power cycle the device. this is the code i used to initalize it and set the pins up the first time:
I2C_Start();
I2C_Write(0x40); // slave address
I2C_Write(0x00); // address register
... (sequential mode so next 10 are set to I2C_Write(0x00);
I2C_Write(0x08); // IOCON: HAEN=1
I2C_Write(0x08); // IOCON: HAEN=1
... (sequential mode so next 6 are set to I2C_Write(0x00);
I2C_Write(0xFEu); // GPIOA
I2C_Write(0x01u); // GPIOB
I2C_Stop();
after this i would like to be able to toggle the output values (0xFE <-> 0x01).
I attempted this code:
I2C_Start();
I2C_Write(0x40); // slave address
I2C_Write(0x12); // address register
I2C_Write(0x01u); // GPIOA
I2C_Write(0xFEu); // GPIOB
I2C_Stop();
at this point it seems to go out to lunch, the pins seem to be random in value (input vs. output, output High vs Low). If anyone as used this I2C IO extender please help me out. even if your not fully sure your more than welcome to comment. NOTE: I2C API shown here is a bit bang algorithm all clock cycles have aprox. 1ms weights between them.
useful documents (kind of): http://ww1.microchip.com/downloads/en/DeviceDoc/21952b.pdf
Try looking at the SCL and SDA signals using an oscilloscope or logic analyzer to check your timing and the data to make sure you are sending the I/O expander the values you think you are.