How to quit loop after string finish print?  - Page 1
Forum section: electronics / general

author: singlarrysong
author_rank: Contributor
timestamp: May 01, 2015, 09:55:18 pm
content: Below is my code, do anyone know how to stop print string after the given string had printed once? It just continue print right after each print.And weird thing is once it enter while loop, it seems escape and start the main program once again although I had set while to infinity. I found this problem when I change the very first delay_ms(500) to other value.I'm also not really understand the operator *x.This is program is for 8bit VFD where I take a 4bit LCD code as reference, the sample code is from hitech C content folder.The function DispData() is just playing with arrangement of the output as 8th bit not use as TRISA5 is input only.(I had clear it out from here)#include <htc.h>#include <pic.h>__CONFIG (0x0FAC); //see "Config" > "Configuration bits" for detail__CONFIG (0x1CFF); //as above#define _XTAL_FREQ 16000000 //for __delay_ purposevoid main(void){OSCCON = 0b01111010; //16MHz Fosc, Int Osc moduleTRISB = 0b00000000;PORTB = 0;TRISA = 0b00100000;__delay_ms(500); //Display Powerup delayconst char *x = "Bye World =P";while(1){DispData(*x);RB0 = 1;__delay_us(280);RB0 = 0;__delay_us(280);*x++;}}

author: Andy Watson
author_rank: Super Contributor
timestamp: May 01, 2015, 10:08:10 pm
content: Quote from: singlarrysong on May 01, 2015, 09:55:18 pmWhat do you expect it to do? It is in a while loop - forever! If you want it to "not" do it, you will have to give it something else to do - like another "while(1); "QuoteIs the processor being reset via the watchdog timer ?Quote*x means "the value that x points to" - I assume you have "pointed" x to somewhere ?

author: Rick Law
author_rank: Super Contributor
timestamp: May 01, 2015, 10:31:40 pm
content: A C-string should be null terminated. So test for that condition.while(1)while (*x){DispData(*x);RB0 = 1;__delay_us(280);RB0 = 0;__delay_us(280);*x++;}

author: singlarrysong
author_rank: Contributor
timestamp: May 01, 2015, 10:35:06 pm
content: I put on while loop after trying do while and for. What I wish to know is the condition that make it quit the loop once the string done printed.About the WDT I think that is it.I'll look for it ASAP.

author: Rick Law
author_rank: Super Contributor
timestamp: May 01, 2015, 10:37:37 pm
content: Quote from: singlarrysong on May 01, 2015, 10:35:06 pmI just show you that. Instead ofwhile(1), usewhile(*x).So, while *xx!=0, the loop keeps going,when at the end of the string, *x==0, (*x) is now false and while loop stops.

author: singlarrysong
author_rank: Contributor
timestamp: May 01, 2015, 10:39:05 pm
content: I'll try it ASAP. It's mid night in UK now.Thanks a lot(emoji error)

author: langwadt
author_rank: Super Contributor
timestamp: May 01, 2015, 10:41:48 pm
content: Quote from: singlarrysong on May 01, 2015, 10:35:06 pmas mentioned there is numerous way to do it, but then what? In most embedded code you never return from main

author: singlarrysong
author_rank: Contributor
timestamp: May 01, 2015, 10:45:11 pm
content: I need it at the moment cause I need print more different string. This is still in testing phase.thank you

author: AndreasF
author_rank: Frequent Contributor
timestamp: May 02, 2015, 08:50:41 am
content: The end of the loop should look like this:x++;not*x++;since you want to increment the address, not it's content. (see K&R, p.98)

author: mikerj
author_rank: Super Contributor
timestamp: May 02, 2015, 11:47:20 am
content: Quote from: AndreasF on May 02, 2015, 08:50:41 am*x++ is equivalent to *(x++) so the current pointer value is first dereferenced, and then the pointer is incremented. The dereferenced value is not changed.Since there is no need to dereference the pointer in this case then x++ is clearly the correct construct to use, but *x++ would also work, though potentially creating some useless extra instructions.

author: singlarrysong
author_rank: Contributor
timestamp: May 02, 2015, 09:17:12 pm
content: Hi everyone, the code is now below.instead *x++ or *(x++), x++ is work for testing weather the loop quit or not, I put on a delay after the loop to observe. it did. [*x++ is which used in the sample code provided in hitech c folder]BUT there is still a problem, where the program seems restartingvoid main(void){OSCCON = 0b01111010; //16MHz Fosc, Int Osc moduleTRISB = 0b00000000;PORTB = 0;TRISA = 0b00100000;__delay_ms(500); //Display Powerup delayconst char *x = "Bye World =P";while(*x){DispData(*x);RB0 = 1;__delay_us(280);RB0 = 0;__delay_us(280);x++;}__delay_ms(2000);}

author: zapta
author_rank: Super Contributor
timestamp: May 02, 2015, 10:02:36 pm
content: If you want to iterate the characters of a string you can use a for loopCode:for(const char* x = "My String"; *x; x++) {// the current character is available here as: *x}

author: singlarrysong
author_rank: Contributor
timestamp: May 02, 2015, 10:16:17 pm
content: Thanks, for loop help save a few program memory.Btw just to reply the comment before above, the program seems restart it self each time after the main had end. (WDT disable) I had attachment showing my device config

author: mikerj
author_rank: Super Contributor
timestamp: May 03, 2015, 01:40:43 pm
content: Quote from: singlarrysong on May 02, 2015, 10:16:17 pmWhat do you think will happen when execution reaches the end of the main() function? There is no operating system to return to, and the micro won't just stop executing instructions. In this case, either the compiler puts an explicit jump back to the reset vector at the end of the main() function, or the micro may simply keep executing instructions in the memory after main until it reaches the end of the memory space, and rolls over back to zero. The value held in a 'blank' program memory address is usually a valid instruction.If you want to stop the micro exiting the main function, then you need to put an endless loop at the end of the function. Either use for( ; ; ); or while(1);Code:void main(void){OSCCON = 0b01111010; //16MHz Fosc, Int Osc moduleTRISB = 0b00000000;PORTB = 0;TRISA = 0b00100000;__delay_ms(500); //Display Powerup delayconst char *x = "Bye World =P";while(*x){DispData(*x);RB0 = 1;__delay_us(280);RB0 = 0;__delay_us(280);x++;}for(;;); /* Stop here */}

author: singlarrysong
author_rank: Contributor
timestamp: May 03, 2015, 01:45:25 pm
content: Thanks, I found that solution too. I Just don't care about the restart anymore because seldom have program that need to go up to ending and instead going in infinity loop after few setting of main

author: Rick Law
author_rank: Super Contributor
timestamp: May 04, 2015, 04:11:59 am
content: Quote from: singlarrysong on May 03, 2015, 01:45:25 pmAny microprocessor/mcu/cpu is always doing something. From the moment of power up, it will be executing instructions given to iteven if the instructions results in doing nothing useful. To stop the CPU, you basically can power down, or to stop the CPU clock from ticking.If it is a multi-processing/multi-treaded systems, one can say: this thread you are doing for me has nothing left to do, so terminate me. The CPU terminates that thread and go do other active things - if such other active threads exists. For a single-tasking system, when your main() is done, it got nothing to do other than looping waiting for an interrupt to occur in which case it would still be not doing anything of interest as you have no further instructions for it.With typical MCU being single tasking, once you have no further instructions for it to do, it is done. Empty loop, or loop forever to blick an LED, or HALT doesn't really matter. If your hardware doesn't have a software triggerable power off, it will just have to bore itself to death.One can of course implement a power save state or sleep state to save power. But it adds cost and judging from its availability on typical MCU broads, apparently there is not enough of a market for it.

author: singlarrysong
author_rank: Contributor
timestamp: May 04, 2015, 08:58:49 am
content: I seeThanks for the information.have a nice day