cancel
Showing results for 
Search instead for 
Did you mean: 

SysTick interrupt problem

mohamad_armoon
Associate III
Posted on September 05, 2014 at 19:12

hi every body .

i have systick in 25hz(each 0.04 sec) send my sensors data through usart. but the it just execute my main ''while(1)'' just once , and after that just my void SysTick_Handler(void) executes send repetitive value . why may main loop doesn't execute ?? here is code :

char Result[7] ;
void main()
{
while(1)
{
result[0] = getSensor1();
result[1] = getSensor2();
result[2] = getSensor3();
result[3] = getSensor4();
result[4] = getSensor5();
result[5] = getSensor6();
result[6] = getSensor7();
}
}
//and void SysTick_Handler(void) in stm32f4xx_it.c
extern char Result[7];
void SysTick_Handler(void)
{
for(int i = 0 ; i <44 ; i++)
{
while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
USART_SendData(USART2,Result[i]);
} 
}

is it something related to interrupt priority ??
7 REPLIES 7
Posted on September 05, 2014 at 21:19

This is NOT how to use interrupts. Your array doesn't have 44 elements.

Don't spin of TXE under interrupt. Copy your data to a buffer, and have the USART TXE interrupt dispatch a character at a time as the USART is ready to take them.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mohamad_armoon
Associate III
Posted on September 06, 2014 at 00:33

that's right . in my original code i have 44 byte to send.. but here i made mistake to change.

in that code i used printf () in <stdio.h> to send data from usart . but it didn't worked too. if i use interrupt for USART TXE i think there would be a problem. because the data will send as soon as USART is ready . but i want to take the data output from usart under control in different frequencies . by the way,my code seems to have problems but it's not weird that the micro after just 1 cycle always execute the interrupt function ?? it runs each 1/25 sec but my micro is 168Mhz. it shuold execute my while.

if
(SysTick_Config(0x57E40))
{ 
/* Capture error */
while
(1);
}
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);

mohamad_armoon
Associate III
Posted on September 08, 2014 at 09:32

ok . i found the problem.

my main while doesn't work because of i2c connection between mcu and sensors.

i don't know why but when ever the program fall in into this loop it never goes out :

 while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));

while the program works well when i don't have Systick or i put the whole sensor reading in systick interrupt function (gather all sensors data and send by usart each time the systick triggers) 

does any body know how to implement DMA on I2C. i suppose if  i use dma i this problem will be ok.

mohamad_armoon
Associate III
Posted on September 10, 2014 at 11:02

hi again . i hope there will be an answer for this question .

my main question was about sensors which i have to read from i2c and send it from usart in specified frequency. this time i decided to measure the time of getting data from 1 sensor from i2c by oscilloscope (put prob on PD12). i put my code in while(1) loop without any delay , and for example for accelerometer i found the speed of reading 2.5ms . i don't know this speed is low or high for reading from i2c. here is my code :

int
main
{ 
while
(1)
{
for
(
int
i = 0 ; i <6 ; i++)
{
Result[28+i] = readByte((DevAddr<<1)|1,ACCEL_XOUT_H + i);
}
j1 = ~j1;
if
(j1)
{
GPIO_SetBits(GPIOD, GPIO_Pin_12);
}
else
{
GPIO_ResetBits(GPIOD, GPIO_Pin_12);
}
}
return
0;
}

after that i decided to measure the frequency of my main loop through oscilloscope . so i this time i wrote my code in this way : (my pin speed: GPIO_Speed = GPIO_Speed_100MHz)

int
main
{
uint8_t j1 = 0
while
(1)
{
j1 = ~j1;
if
(j1)
{
GPIO_SetBits(GPIOD, GPIO_Pin_12);
}
else
{
GPIO_ResetBits(GPIOD, GPIO_Pin_12);
}
}
return
0;
}

and the frequency that oscpe showed was 4.96Mhz so the freq will be (4.96*2) one for set and one for reset. it means that my ''if else'' get more than 16 cycle (my micro is 168Mhz). is it true ?? or i made mistake with measuring frequency ??? is if statement gets 16 cycle to execute ???
Posted on September 10, 2014 at 19:14

The processor doesn't run C code, you'd want to look at the assembler generated, and the optimization used.

A loop with some loads, stores, logic, compare, call of a subroutine, I could easily see 16 cycles getting eaten. There are more efficient ways to toggle pins.

I2C devices would likely support a stream of bytes, and auto-incrementing register addresses.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mohamad_armoon
Associate III
Posted on September 12, 2014 at 17:15

thanks clive .

after you mentioned that ''

I2C devices would likely support a stream of bytes

'' i reviewed the data sheet of sensors and found that  all of my sensors supports 400khz speed .

i just set my i2c _clockspeed  in 400000 and reduced my sensors reading data as much as i need.
Posted on September 12, 2014 at 19:09

Reading multiple bytes from the device will be significantly faster than addressing each byte individually.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..