Save to EEPROM at power down using STM32 - stm32

I am using STM32F030R8. I have enabled a counter that counts value at fixed interval. I was wondering whether i can save this counter value to eeprom as soon as i switch off the power to the uController. I am using 24C08 i2c eeprom. I can use large bulk capacitor say 1000uF or any suggested value ..

After lots of reading i have finally found that PVD is not supported in STM32F030R8 ... I need to look for another alternative method.
Thanks.

If no PDV use ADC in the watchdog mode.

Related

How fast can I read an ADC of a 2-dimensional array?

I have an application where it must control the ADC reading of the array 32x32 element.
For each element I have to choose point - read ADC - turn off ADC. Currently I am using a scanning method like LED scanning. For each scan I read 1 point. Then store the value in the array and transmit it.
However, I found this to be very slow. I want to use DMA to automate this reading, then all I need to do is pass it on.
Is there a way to do this?
I didn't quite understand your question.
Let's suppose that you want to read data from external signals on the ADC MCU input pin.
I recommend you first, two solutions for ADC Reading that data:
Configure your ADC in continuous mode.
Configure your ADC in single mode, and configure another peripheral (like timer) that will trigger the ADC to start the conversion at each event.
Second, there are two different way to manage your converted data:
After each End Of Conversion Interrupt of the ADC you can store your data manually and do your stuff.
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef AdcHandle)
{
/ Get the converted value of regular channel */
uhADCxConvertedValue = HAL_ADC_GetValue(AdcHandle);
}
Configure a DMA Handler that will deal with the ADC converted data and store it in RAM automatically without the CPU intervention.
#define ADC_CONVERTED_DATA_BUFFER_SIZE ((uint32_t) 32) /* Size of array aADCxConvertedData[] */
static uint16_t aADCxConvertedData[ADC_CONVERTED_DATA_BUFFER_SIZE];
HAL_ADC_Start_DMA(&AdcHandle,uint32_t *)aADCxConvertedData,ADC_CONVERTED_DATA_BUFFER_SIZE
You will find a lot of details in the Reference Manual.

How to use STM32L0xx 's Comparator in Stop mode?

I want to use Comparator, for comparing external voltage with Vref in stop mode
so that if external voltage is more than Vref, wake up from stop mode and do something.
I read example code about Comparator, LPTIMER ... but they are not exact solution about my project
so Can you give some idea or example about how to using Comparator in stop mode ?

How to decrease SPI overhead time for STM32L4 HAL library

I am using a STM32L476RG board and HAL SPI functions:
HAL_SPI_Transmit(&hspi2, &ReadAddr, 1, HAL_MAX_DELAY);
HAL_SPI_Receive(&hspi2, pBuffer, 4, HAL_MAX_DELAY);
I need to receive data from accelerometer's buffer with maximum speed and I have a problem with delay in these functions. As you can see on the oscilloscope screenshots, there are several microseconds during which nothing happens. I have no idea how to minimize the transmission gap.
I tried using HAL_SPI_Receive_DMA function and this delay was even bigger. Do you have any idea how to solve this problem using HAL functions or any pointers on how I could write my SPI function without these delays?
TL;DR Don't use HAL, write your transfer functions using the Reference Manual.
HAL is hopelessly overcomplicated for time-critical tasks (among others). Just look at the HAL_SPI_Transmit() function, it's over 60 lines of code till it gets to actually touching the Data Register. HAL will first mark the port access structure as busy even when there is no multitasking OS in sight, validates the function parameters, stores them in the hspi structure for no apparent reason, then goes on figuring out what mode SPI is in, etc. It's not necessary to check timeouts in SPI master mode either, because master controls all bus timings, if it can't get out a byte in a finite amount of time, then the port initialization is wrong, period.
Without HAL, it's a lot simpler. First, figure out what should go into the control registers, set CR1 and CR2 accordingly.
void SPIx_Init() {
/* full duplex master, 8 bit transfer, default phase and polarity */
SPIx->CR1 = SPI_CR1_MSTR | SPI_CR1_SPE | SPI_CR1_SSM | SPI_CR1_SSI;
/* Disable receive FIFO, it'd complicate things when there is an odd number of bytes to transfer */
SPIx->CR2 = SPI_CR2_FRXTH;
}
This initialization assumes that Slave Select (NSS or CS#) is handled by separate GPIO pins. If you want CS# managed by the SPI peripheral, then look up Slave select (NSS) pin management in the Reference Manual.
Note that a full duplex SPI connection can not just transmit or receive, it always does both simultaneously. If the slave expects one command byte, and answers with four bytes of data, that's a 5-byte transfer, the slave will ignore the last 4 bytes, the master should ignore the first one.
A very simple transfer function would be
void SPIx_Transfer(uint8_t *outp, uint8_t *inp, int count) {
while(count--) {
while(!(SPIx->SR & SPI_SR_TXE))
;
*(volatile uint8_t *)&SPIx->DR = *outp++;
while(!(SPIx->SR & SPI_SR_RXNE))
;
*inp++ = *(volatile uint8_t *)&SPIx->DR;
}
}
It can be further optimized when needed, by making use of the SPI fifo, interleaving writes and reads so that the transmitter is always kept busy.
If speed is critical, don't use generalized functions, or make sure they can be inlined when you do. Use a compiler with link-time optimization enabled, and optimize for speed (quite obviously).
You can use HAL_SPI_TransmitReceive(&hspi2, ReadAddr, pBuffer, 1 + 4, HAL_MAX_DELAY); instead of a HAL_SPI_Transmit and a HAL_SPI_Receive. This will avoid the time between transmit and receive.
You can also try changing compilation settings to optimize the speed.
You can also check the accelerometer's datasheet, may be you can read all the buffer with a single frame, something lie this:
HAL_SPI_TransmitReceive(&hspi2, ReadAddr, pBuffer, 1 + (4 * numOfSamples), HAL_MAX_DELAY);
What worked for me:
Read SPI registers directly
Optimize your function for speed
For example function (code); See solution by “JElli.1” in ST- Community >>
ST Community answer

Libnodave on value changed

I am using libnodave 0.8.4.4 library to connect to a S7 PLC and what I would like to know if how can I detect if a bit (e.g. DB100.DBX8.0) in PLC DB changes its value. What I did is to read this bit within a while loop but I would like to create an event on value changed on this bit and launch a task when it happens.
There is no default event available with libnodave or any other libraries like S7.net.
Either you need to use OPCor write your own function which will read the set of bits set on time and notify to the main program.

SPI bit banging; MCP3208; Raspberry;error

I am using Raspberry Pi 2 board with raspbian loaded. need to do SPI by bit banging & interface MCP3208.
I have taken code from Github. It is written for MCp3008(10 bit adc).
Only change I made in code is that instead of calling:
adcValue = recvBits(12, clkPin, misoPin)
I called adcValue = recvBits(14, clkPin, misoPin) since have to receive 14 bits of data.
Problem: It keeps on sending random data ranging from 0-10700. Even though data should be max 4095. It means I am not reading data correctly.
I think the problem is that MCP3208 has max freq = 2Mhz, but in code there is no delay between two consecutive data read or write. I think I need to add some delay of 0.5us whenever I need to transition clock since I am operating at 1Mhz.
For a small delay I am currently reading Accurate Delays on the Raspberry Pi
Excerpt:
...when we need accurate short delays in the order of microseconds, it’s
not always the best way, so to combat this, after studying the BCM2835
ARM Peripherals manual and chatting to others, I’ve come up with a
hybrid solution for wiringPi. What I do now is for delays of under
100μS I use the hardware timer (which appears to be otherwise unused),
and poll it in a busy-loop, but for delays of 100μS or more, then I
resort to the standard nanosleep(2) call.
I finally found some py code to simplify reading from the 3208 thanks to RaresPlescan.
https://github.com/RaresPlescan/daisypi/blob/master/sense/mcp3208/adc_3.py
I had a data logger build on the pi, that was using a 3008. The COTS data logger I was trying to replicate had better resolution, so I started looking for a 12 bit and found the 3208. I literally swapped the 3008 out for the 3208 and with this guys code I have achieved better resolution than the COTS data logger.