I am trying to move a project to the STM32F103 from STM32F303, so I should recode some things.
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
This part of the code was working fine but now I get error messages because STM32f3 HAL library has initializations only for Timing registers.
How can I arrange clock speed and duty-cycle in this case? Can you explain it using these pieces of code?
Related
Here's my configuration:
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = 8;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOJ, &GPIO_InitStruct);
When I put the signal on the input pin (square, 2Hz, 3.3Vp-p) I get an interrupt every 250ms, so - on every RISING and falling edge of the signal. I changed the test signal duty cycle to test if it's really what is happening and it confirmed it. I get the interrupt on both edges.
I even debugged the HAL driver to test if it does what I think it does. And yes, it seems to configure the EXTI correctly, only for the falling edge for my pin.
What may be the cause of such behavior? My device is STM32H747I-DISCO discovery board with TouchGFX software used for presentation. The software works correctly, I tested it on measuring the time between other timer interrupts.
I monitor the test signal on the oscilloscope to ensure the input signal on my pin is correct. I tried to use another pin on the same port, but I observe identical behavior. I get interrupts on both rising and falling edges of the signal, despite the pin is configured to trigger the interrupt only on the falling edge.
I also tested the case with the rising edge only. Also in this case I get the interrupt on both edges.
The problem turned out to be a hardware error, a voltage spike I overlooked. The STM32 EXTI input worked correctly all the time. There was indeed a spurious falling edge.
Simulated problem illustration, the 10n capacitor causes voltage spikes and spurious edge detection. In the real circuit, when a digital oscilloscope was used and the time base was too long to capture the spike - the signal looked like a proper square wave. After shortening the time base I noticed the spike. As it is shown on the illustration, this behavior can be easily simulated in a circuit simulator:
SIMULATION LINK
Removing the capacitor from the circuit solved the problem.
To avoid getting noise and other spurious signals on the input shielded wires can be used. The real world circuit was tested and it works properly without the capacitor.
The opto-coupler is just a simplified model of the optical sensor used in the real machine.
I am trying to know the status of MCP3424, either it is connected or not to the master STM32 with defined address 0x68. The ADC module gets connected with the Arduino in same address but using STM32, I am not able to get connected with the following code:
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if((HAL_I2C_IsDeviceReady(&hi2c1, 0x68 << 1, 100, 1000))==HAL_OK){
HAL_UART_Transmit(&huart2, "device connected\r\n", 10, 10);
}
else{
HAL_UART_Transmit(&huart2, "no device\r\n", 100, 10);
}
}
Is there any mistake that I have done in this code by chance or any other way there is to deal with MCP3424 ADC module specifically? Please suggest me.
I believe your problem lies with voltage levels: your STM32 functions with 3.3V, while MCP3424 is powered from 5V. Let's open the datasheet of the MCP3424, page 6:
High level input voltage is 0.7Vdd, which is 0.7V*5V=3.5V, which means your A/D can't detect "1" on the line. It sees the line as always "0", even when STM32 MCU outputs HIGH (3.3V).
Possible solutions:
Logic level conversion (various ways). A circuit between A/D IC and MCU to convert 3.3V levels into 5V levels. There are dedicated chips for that, there are also other approaches using resistors and mosfets. Something you may want to explore on electrical engineering stackexchange.
Check the datasheet of the MCU, find GPIO properties. It's very likely those I2C pins are in fact 5V-tolerant, meaning you can pull up I2C lines to 5V and still drive them with 3.3V STM32, and it will be within the spec of STM32 MCU. If that's the case, no extra circuit will be necessary.
I've got a strange issue I can't seem to get my head around. I'm using a STM32F411 board and ST32CubeIDE (eclipse based). I want to use PWM so I've used cubeMX to configure TIM4 in PWM output mode, with a prescaler and load value that is appropriate for the PWM frequency/pulse widths I want. I've also enabled global interrupt for TIM4 as I want to use the HAL_TIM_PWM_PulseFinishedCallback function later on.
Before the main loop, I initialise TIM4 and all 4 channels as so:
HAL_TIM_PWM_Start_IT(&htim4, TIM_CHANNEL_1); //Start up PWM
HAL_TIM_PWM_Start_IT(&htim4, TIM_CHANNEL_2); //Start up PWM
HAL_TIM_PWM_Start_IT(&htim4, TIM_CHANNEL_3); //Start up PWM
HAL_TIM_PWM_Start_IT(&htim4, TIM_CHANNEL_4); //Start up PWM
Then after I just set the PWM pulse widths manually:
htim4.Instance->CCR1 = 100;
htim4.Instance->CCR2 = 100;
htim4.Instance->CCR3 = 100;
htim4.Instance->CCR4 = 100;
For some reason however, when I turn compiler optimisation on 'Optimise for speed -Ofast'* the program seems to get stuck after the final line, whilst debugging, where CCR4 gets set, and can't progress.
This only happens when compiler optimisation for speed is enabled. By default it was set to optimise for debug and it was fine that way.
Optimizing for anything but debug can confuse the debugger.
Things that you can try: (You didn't specify your toolchain, I'm assuming it's something eclipse/gcc based.)
Enable instruction stepping to step through the assembly instructions one at a time. It should work even when debugging by source lines doesn't.
Set a breakpoint two or three lines further down in the code, and let the debugger run through the critical part.
Hit the pause button just to see where it got stuck. It might not be available if you don't have an active breakpoint somewhere in the code.
I am using internal ADC temp sensor , in a low power device without the sensor in stop mode ,the uController consumes around 4 uA but when the temp sensor is on the consumption goes up to 8-9 uA
the problem is i can not turn the sensor OFF / i just measured the off current by setting it off from start by stmcube
i am searching for a code that can turn off the temp sensor
up until now i have tested these:
1-
HAL_ADC_Init(&hadc);
hadc.Lock=HAL_UNLOCKED;
__HAL_UNLOCK(&hadc);
HAL_ADCEx_DisableVREFINTTempSensor();
2-
ADC1->CR&=0X00000000;
ADC->CCR&=~(1<<23);
i prefer to work with HAL , it dose not seems to cut the Sensor power
Your ADC1->CR &= 0x00000000; line looks wrong to me, depending on the controller you're using.
There is usually a bit to disable the ADC which needs to be set, rather than writing all 0s. Try ADC1->CR = (0x01 << 1); instead. If you have the ST Micro written defines for your processor ADC1->CR = ADC_CR_ADDIS; should be the same but more readable. After disabling the ADC you will be able to turn off the TSEN bit of ADC->CCR.
I am trying to read data from potentionmeter using an arduino microcontroller (tried both arduino UNO, arduino FIO) and using serial communication interface it to Simulink (I tried baud rates ranging from 57600-921600).
Here is the Arduino source code:
/*
AnalogReadSerial
Reads an analog input on pin 0, prints the result to the serial monitor.
*/
#define ana_pin A0
void setup() {
analogReference(DEFAULT);
Serial.begin(57600);
}
// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin 0:
int sensorValue = analogRead(ana_pin);
// print out the value you read:
Serial.print(sensorValue);
// delay(500); // delay in between reads for stability
}
I interfaced it with Tera Term software and there is instantaneous change of values corresponding to 3 V or 0V.
However when I tried to interface it with Simulink model using instrument control toolbox:
there is a 10 second lag when value changes from ASCII representation of 3V to 0V
The block sample time is 0.01 seconds and the model configuration parameters are adjusted accordingly (I tried it for 1 second or more and the delay still remains. Also, I was able to record data from another sensor and LPC1768 development board without any delay.
I also tried it with Arduino support libraries in Simulink:
And it seems that no data is received, as you can see from Scope1 in the png file the status signal is always 0. I have also attached hardware implementation properties from Arduino block in Simulink:
Could you help me understand what is going on and how to solve this issue?
#Patrick Trentin -
I get a delay of 4 seconds when I use baud rates of 230400, 460800 and 921600.
For baud rate of 57600, 115200 I get a delay of 10 seconds.
Thank you for pointing it out I did not focus on that previously.
However since I will be using the sensor in an application which accurately needs reading every 0.01 sec. I dont think I can work with 4 sec delay.