STM32 interrupt pin strange behavior - arm

I am using stm32cubeide to program a stm32f030f4p6 MC. I have assigned one pin as an external interrupt and it is connected to the data output of an RF433 receiver.
Here is a summary of my code:
int k;
int main(void)
{
while (1)
{
k=0;
}
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
k=1;
}
and, the value of 'k' over time is:
the value of 'k' over time("button" is the button of the rf433 transmitter)
as it can be seen from the picture, interrupt is triggered even when no signal is received.
PS. I have tried external pull down and pull pull up resistors 10k and 4.7 k did not have an effect and with 2.2k no signal from rf433 receiver would be detected.

Related

Error occurs when i transmit data with USART

I am stuck on the following problem. Consider this code:
int main(void)
{
SysTickInit();
USART_GPIOInits();
USART_Inits();
char data[] = "hello\n";
for(uint8_t i=0; i<10; i++)
{
HAL_UART_Transmit(&Usart1, (uint8_t*)data, strlen(data), 1000);
}
while(1){}
}
I try to send hello\n to Hercules in 10 times, but Hercules did not receive what i sent
this is what Hercules got , it had รพ every the first time I reset the MCU. But , when I used Debugger mode, it did not get any error.
below is transmit function
below is Init function
but want to communicate with fingerprint , but because of this wrong i cant communicate
Change the order of initialization.
From
USART_GPIOInits();
USART_Inits();
to
USART_Inits();
USART_GPIOInits();
UART's default line state is logic high, logic low (start bit) launches a new transfer.
When GPIO is inialized first, with the corresponding peripheral module disabled, most likely you'll gen a logic low level on the TX pin, because there is no one to set it to a logic high (since UART is still disabled). When UART is initialized, it sets the TX line to a logic high (stop bit), and the terminal appication receives it as a broken byte.
Check your schematics
During and after reset CPU outputs are tri-stated. Most likely they'll stay at zero level until the configuration code will do it's job, leading to the same issue - receiving a garbage byte after the reset.
To prevent it, voltage levels on the interface pins must be defined during reset phase with an external pull-up resistor, like 10kOm, from TX and RX pins to VCC.

8051 two timers and Interrupts problem in c

I want to make two timer works at the same time but it seems not working at all
I wrote the code to blink led.
The led would blink when i used either one of the timer and interrupt
when I used them both, two ports for led are not working.
Was there any rule that can't use two interrupts or timers at the same time?
or just my mcu broken?
btw I am using AT89S52
coding by keil uVision5
and program with WLpro
Here is my code
#include <reg52.h>
sbit LED = P0 ^ 5;
sbit LED2 = P0 ^ 6;
int i = 0;
int y = 0;
int x = 0;
int count = 0;
void blink2()
interrupt 3
{
TH1=0x7d;
TL1=0xec;
y++;
if(y==100) {
if(i==1) {
LED=0;
x=0;
}
else {
LED=1;
x=1;
}
y=0;
}
}
void blink1()
interrupt 1
{
TH0=0xd8;
TL0=0xf0;
count++;
if(count==100) {
if(i==1) {
LED2=0;
i=0;
}
else {
LED2=1;
i=1;
}
count=0;
}
}
void main() {
TMOD = 0x11; // timer mode
TH0 = 0xd8;
TL0 = 0xf0;
TH1 = 0x7d;
TL1 = 0xec;
TR0 = 1;
TR1 = 1;
IE = 0x8a;
}
In blink2() you test the global variable i, but you never change it.
Note aside: blink1() manages LED2, while blink2() manages LED. Perhaps a more consistent naming would help, and the same applies to the variables i, x, y and count.
There is no restriction to use more than one interrupt concurrently, but when of them executes, the others are temporarily blocked. It is not your problem here, your code is fine; but if you want an interrupt be able to be interrupted in turn, for low latency, you must re-enable interrupts in the (relatively) "slow" handler.
Last suggestion: where you have "if (y==100)" and lately "y=0", if you move "y=0" just below "if (y==100)" readability improves.
All the rest seems ok, but I would double-check the setup of the timers; I don't have at hand the datasheet, may be there is a flag to clear in the interrupt handler (I can't remember). Given that you say that a single timer works, I suppose you know what to do, two timers should run without any problem.

Arduino Issue: Using TimerOne and delayMicroseconds()

I have been working with an Arduino and have encountered a very strange problem. Here is the code I am using:
#include <TimerOne.h>
const int LED_PIN = 8;
const int PERIOD = 3000; // micros
void setup()
{
pinMode(LED_PIN, OUTPUT);
Timer1.initialize(PERIOD);
Timer1.attachInterrupt(sendPulse);
Serial.begin(115200);
}
void loop()
{
}
void sendPulse()
{
Serial.println(micros());
delayMicroseconds(x);
Serial.println();
}
So, I have tried changing the value of x in sendPulse(). If x is 300, for example, the Serial monitor outputs "3016 6016 9016...," as expected. However, something strange occurs when x is greater than or equal to 835 -- the Serial monitor outputs "3016 4992 7992...." My question is why is the time between the first and second interrupt not 3000? Furthermore, if I change the code within the interrupt to:
Serial.println(micros());
delayMicroseconds(x);
digitalWrite(LED_PIN, HIGH);
Serial.println();
The code acts strangely for x greater than or equal to 830, rather than 835. Why does this happen? Thank you!
According to this:
you shouldn't use Serial.print()/Serial.read() in an interrupt service routine, because latest version of Serial uses interrupts for read and write but they are disabled from within an ISR.
you shouldn't usedelay()/delayMicroseconds(), because again they make use of interrupts but they are disabled from within an ISR.. your risk making the timer miss some interrupts and loose track of the correct flow of time.
As a remark I repeat here what was said by #Unimportant in the comments: the code within an ISR should be kept as short and fast as possible.

C on Raspberry Pi: SPI order changes when 'printf' statement is executed

I am working on a project in C on the raspberry pi 2 in which the pi is polling a microcontroller via SPI when the microcontroller asserts a particular pin.
There are two functions that are intended to be executed in this fashion. One of the functions - LNK_pollNetwork() - checks to see if the request pin is high and - if it is - then it downloads the data until the pin is low again, then parses. The other function - LNK_generateNetStat() - sends a byte requesting the network status and then downloads data until the pin is low again.
It seems that if I place a 'printf' statement just after the poll byte in LNK_generateNetStat(), everything works fine. If I remove the printf statement, then the program goes haywire and it is clear to me that the other function is executing almost in parallel with this function.
Both functions are on the same thread... or so I believe.
void LNK_generateNetStat(){
uint8_t statusSerialString[(NETSTAT_HEADER_BYTES
+ (MAX_NUM_OF_NODES
* NETSTAT_FIELD_WIDTH_BYTES))];
uint8_t i = 0;
SPI_transfer(0x86);
/* if this printf is executed, all works normally */
if(verbose)
printf("Network status polled");
while(bcm2835_gpio_lev(REQ_PIN) == HIGH){
statusSerialString[i] = SPI_transfer(0xfe);
i++;
}
/* parsing code below this line */
/* ... */
}
The other function simply polls the request pin and, if it is high, then starts pulling data until the pin is low:
void LNK_pollNetwork(){
if(bcm2835_gpio_lev(REQ_PIN) == HIGH){
int i = 0;
uint8_t payload[PAYLOAD_MAX_LENGTH];
SPI_transfer(0xff); // dummy read - allows slave to load the buffer
while(bcm2835_gpio_lev(REQ_PIN) == HIGH){
payload[i] = SPI_transfer(0xff);
i++;
}
/* payload parsing below this line */
/* ... */
}
}
Both of these should be executed sequentially. There is a higher level task manager that executes LNK_pollNetwork() every 1ms and LNK_generateNetStat() every 1250ms.
I know that LNK_generateNetStat() is being pre-empted because I have used different values in the SPI polling routine for each function in order to identify what is going on. The 0x86 executes normally and should begin polling with bytes numbered 0xfe, but I am seeing 0xff bytes in many cases and - sometimes - they are intermixed. I'm using a logic analyzer to observe.
Thoughts?

How can I create interrupts in C for Arduino?

So I did this code for Arduino in C. It is for controlling a stepper motor. But every time I have to wait until the microcontroller begins a new loop so that it can take the value for the new variables, how can I create an interrupt so it will do it in any time of the program?
#include <avr/io.h>
#define F_CPU 4000000UL
#include <util/delay.h>
#include "IO/ioconfig.h"
#include "leebotones/leebotonesA.h"
#include "leebotones/leebotonesB.h"
#include "rutina/avanza.h"
#include "rutina/retrocede.h"
char variableA = 0;
char variableB = 0;
int main(void){
ioconfig();
while(1) {
if (leebotonesA()==1) {
variableA++;
} //Fin de if leebotonesA.
if (leebotonesB()==1) {
if (variableA==0) {
variableB=1;
}
else {
variableB=0;
}
}
if (variableA==2) {
variableA=0;
PORTD=0x00;
_delay_ms(10000);
} //Fin de if variableA.
if (variableA==1 && variableB==0) {
avanza();
} //Fin de if leebotonesA.
if (variableA==1 && variableB==1) {
retrocede();
}
_delay_ms(25);
}//End of while
}// End of main
A hardware interrupt on the Arduino occurs when one of the interrupt pins receives a change of state. The function to use, if you have access to the Arduino library, is attachInterrupt.
Example code to listen for an interrupt (derived from the documentation I linked to, I added comments to help explain):
// The Arduino has an LED configured at pin 13
int pin = 13;
// Holds the current state of the LED to handle toggling
volatile int state = LOW;
void setup()
{
pinMode(pin, OUTPUT);
// First Parameter:
// 0 references the interrupt number. On the Duemilanove, interrupt 0
// corresponds to digital pin 2 and interrupt 1 corresponds to digital pin
// 3. There are only two interrupt pins for the Duemilanove and I believe
// the Uno too.
// Second Parameter:
// blink is the name of the function to call when an interrupt is detected
// Third Parameter:
// CHANGE is the event that occurs on that pin. CHANGE implies the pin
// changed values. There is also LOW, RISING, and FALLING.
attachInterrupt(0, blink, CHANGE);
}
void loop()
{
// Turns the LED on or off depending on the state
digitalWrite(pin, state);
}
void blink()
{
// Toggles the state
state = !state;
}
There is also a concept of Pin Change Interrupts that is supported on every pin. See the bottom part of introduction to interrupts for more info.
However, sometimes a hardware interrupt can be avoided by refactoring your code. For example, keep your loop() running quickly --- mostly just reading inputs, limit the use of delay() --- and in the loop, call a function when the targeted inputted value is detected.
MSTimer2 is an Arduino library function to let you set timer interrupts.
Another alternative to delay, rather than interrupts, is to set a timer and check it each time through the loop. http://arduino.cc/en/Tutorial/BlinkWithoutDelay explains the concepts. The Metro library http://arduino.cc/playground/Code/Metro implements this and is easy to use. I've used it instead of delay() so that I can check for a button push while my robot is moving.

Resources