Hi, My question in a general question about reducing noise in a hardware design. Is there a guideline to follow in order to reduce effect of external noise such as electropump or electric valve which is driven by an MCU using a relay? I am using STM32L152VD LQFP100 running with 16MHz internal oscillator. one of the serious things I see is effect of main power plugin to keypad input of MCU such that it is like a button is pushed when I plug in the 220V switching adapter power. Next is when MCU controls an electric valve in start or stop moment such that it is like a button is pushed. I have used same capacitor and resistor as in discovery board used for push button and used EMI ferrit filter around input power (5V) to my board. I used ferrit bead in series with main VCC of the board. should I used ferrit bead for all interrupt input and all VCC pins of the MCU? is there any other advice like a specific filter?
Power and ground planes are very important.
And capacitors for every VCC pin. Additional inductor in series for analog supply or reference voltages.
The filtering on in- and outside of voltage regulator should be enough to keep the supply voltage stable without anything significant reaching the power planes.
You may also add software filtering for interrupt inputs - the ISR can read the pin again to verify that it wasn't just a short spike that generated the interrupt.
It's common to add series resistors on digital lines to slow down the noise produced when the line toggles - you get an low-pass RC with the capacitance in the wire.
Consider EMI filters on all signals that leaves your board - select proper bandwidth of the EMI filter based on how the signal is used.
Consider pull-up or pull-down on input signals to make sure there is a load - too high impedance and they will work as antennas.
You have made sure there is freewheel diodes on all inductive loads to take care of the voltage spike when you disconnect the load?
It's also meaningful to spend some time reading up on best practices for PCB design, to avoid creating loops that will pick up external noise.
Thanks. I use below code for software filtering for interrupt inputs in my ISR and I have set interrupt for rising edge:
void EXTI1_IRQHandler(void) //PA1 { if(EXTI_GetITStatus(EXTI_Line1) != RESET) { delay_ms(100); if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1 )==1) { SYS.flag_pulse=1; SYS.flowtime=TIM_GetCounter(TIM2); TIM_SetCounter(TIM2,0); } /* Clear the EXTI line 1 pending bit */ EXTI_ClearITPendingBit(EXTI_Line1); } }
However even I use a 100ms delay again electric valve generates a pulse when opened or closed. I tried 1 sec delay but it seems it there is a problem with above code.
Waiting in an interrupt? Are you serious?
I modified the code and didn't use delay too in ISR. In the following code I checked the earlier state and last state of the input pin to make sure it changes state. now it works fine.
void EXTI1_IRQHandler(void) //PA1 {int i; if(EXTI_GetITStatus(EXTI_Line1) != RESET) { if (SYS.flag_pulse_low==1 && (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1 )==1)) { SYS.flag_pulse=1; SYS.flowtime=TIM_GetCounter(TIM2); TIM_SetCounter(TIM2,0); /* Clear the EXTI line 1 pending bit */ } EXTI_ClearITPendingBit(EXTI_Line1); } }
Delays in interrupt handles are no fun unless we are talking about a few NOP - such as when setting a number of digital outputs and then toggle a "latch" pin.
Often, it's enough to sample the pin value in the ISR to verify that it wasn't a single, almost infinitely short, pulse that trigged the interrupt. If more filtering is needed, then a timer can be used, so the pin interrupt handler starts a timer one or a couple of milliseconds later the processor gets a timer interrupt to make a second check of the pin state. It's even possible to let the timer produce a burst of multiple interrupts.
Another option is - if the processor supports it - to generate interrupts both for rising and falling pin and on the first pin interrupt start a timer. Each new pin change restarts the timer. If the timer finally manages to "ring" then you know the pin state has been stable for the full filter time (except for any pulse shorter than the detection logic for the pin interrupt hardware) A potential disadvantage with this method is that a high-frequency pulse train can result in a very large frequency of pin change interrupts which may consume all available CPU resources.
Any delays introduced in an ISR will not only lock up the main loop, but will also affect the servicing of other interrupts. And will break the task switching for programs that are using an RTOS. So a primary goal for an ISR is quick in/quick out.
I collected my hints here www.8052.com/faqs.phtml
Many thanks.