CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Exiting from a do while loop

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
A_L_E_X



Joined: 21 Feb 2010
Posts: 11

View user's profile Send private message

Exiting from a do while loop
PostPosted: Sun May 23, 2010 4:51 am     Reply with quote

I have a pic16f648A connected to RS232. The system reads a pressure and sends data to an LCD and to RS232 in a do while loop. When i press a button (may be any button but it would be better to be a specific one) on the keyboard, i want to exit the loop.
Code:
if (c=='k')
{
do
{
read_adc();
ADC=ADC_result;
kpa=ADC*3.125;
printf("\fReading pressure");
printf(lcd_putc,"\fThe pressure is :\n%f kPa \r",kpa);
init_ext_eeprom();
write_ext_eeprom(a,kpa);
a++;
delay_ms(100);
}
while(1);

if i put getc() the system makes only one pass and hangs at getc(). I need something like an intrerupt. but i don't know how to do it
tesla80



Joined: 23 May 2007
Posts: 81

View user's profile Send private message

PostPosted: Sun May 23, 2010 6:18 am     Reply with quote

Hi,

if you add these lines somewhere in the do-while loop, you can exit from the loop

Code:
if(input(button))
   break;


pic16f648A has hardware usart module. You can use the INT_RDA for interrupt driven rs232 connection or in the loop add this:
Code:
if(kbhit())
{
foo = getc();
}

kbhit checks incoming rs232 information.

Read help ;)
A_L_E_X



Joined: 21 Feb 2010
Posts: 11

View user's profile Send private message

PostPosted: Sun May 23, 2010 9:08 am     Reply with quote

If i don't use USART port, can i still use that code ? i can't use the usart ports because other peripherals are conected to those ports.
A_L_E_X



Joined: 21 Feb 2010
Posts: 11

View user's profile Send private message

PostPosted: Sun May 23, 2010 9:31 am     Reply with quote

It worked with this code :
Code:
if(kbhit())
{
break;
}

But then it exits from the loop only if I press a button 3 or more times. Can I do something else ? It is good this way, but it would be better if I could press a specific button only one time.
languer



Joined: 09 Jan 2004
Posts: 144
Location: USA

View user's profile Send private message

PostPosted: Sun May 23, 2010 9:32 pm     Reply with quote

Best option is, of course, to use the HW USART function. Using the SW to emulate the UART, you have to poll the pin fast enough.

Excerpt for CCS help file:
Quote:

Note that in the case of software RS232 this function should be called at least 10 times the bit rate to ensure incoming data is not lost.

The following lines in your code probably may prevent the proper polling:
Quote:
printf("\fReading pressure");
printf(lcd_putc,"\fThe pressure is :\n%f kPa \r",kpa);
...
init_ext_eeprom();
write_ext_eeprom(a,kpa);
...
delay_ms(100);

If the pin where the RS232 input resides has an interrupt vector, then you can use the interrupt-on-change option. Unfortunately it looks like the only pin on the 648A with this capability is RB0.

A few options:
1) Re-map the IO so you use the HW USART - this is the reason for having multiplexed HW on the MCU.
2) Migrate to a newer drop-in device (e.g. 16F88) which allows interrupt-on-change on multiple pins.
3) Add the HW function to detect edge-changes external to the MCU (quite a shame, since the MCU already has some of this built-in).
4) Re-evaluate your requirements

On thing worth mentioning, you may not require to initialize the EEPROM each time you access it (checkout continuous write on the EEPROM datasheet).

A possible work-around the delay_ms(100) would be something as follows (assuming 4MHz clock):
Code:
int1 break_flag = 0;
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_2 );
set_timer1(15539);
TMR1IF = 0;
while (!TMR1IF)
(
   if(kbhit())
   {
      break_flag = 1;
      break;
   }
)
if (break_flag)
{
   break_flag = 0;
   break
}
A_L_E_X



Joined: 21 Feb 2010
Posts: 11

View user's profile Send private message

PostPosted: Tue May 25, 2010 2:50 pm     Reply with quote

How can i remap the IO ports ? Do you have a link or a document ?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue May 25, 2010 3:37 pm     Reply with quote

By "remap the i/o pins", he just means to specify the TX and RX pins
for the hardware UART in the #use rs232() statement. Example:
Code:
#use rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1, ERRORS)

But, in an earlier post, you said you can't do that because the Tx and Rx
pins are already used for some other purpose.

Another possible solution is to assign the 'rcv' to Pin B0. It has the
External Interrupt feature on that pin. You could cause an interrupt
when you get the start bit for the incoming byte on RS232. Then get
the character in the #int_ext interrupt routine. Set a global flag to
TRUE inside the interrupt routine. Then poll the flag inside your while()
loop in main. When the flag == TRUE, then exit the loop. Also set the
flag to FALSE at that time. Also initialize the flag to FALSE at the start
of main().
tesla80



Joined: 23 May 2007
Posts: 81

View user's profile Send private message

PostPosted: Wed May 26, 2010 4:36 am     Reply with quote

Additionally, the RX pin must be configured as input.
A_L_E_X



Joined: 21 Feb 2010
Posts: 11

View user's profile Send private message

PostPosted: Mon Jun 28, 2010 5:56 pm     Reply with quote

Looks like the code
Code:
if(kbhit())
{
break;
}

works only in Proteus. In real hardware it doesn't work and I don't know why.
Also I've looked at my code and looks like I can use the receive pin from the the hardware uart. Can I use hardware now even though the transmit pin is not an uart pin ?
Code:
#use rs232(baud=9600,parity=N,xmit=PIN_B0,rcv=PIN_B1) 

Also, can I use the uart to make an interrupt ? Can you give me an example ?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jun 28, 2010 7:12 pm     Reply with quote

Quote:

I use hardware now even though the transmit pin is not an uart pin ?

#use rs232(baud=9600,parity=N,xmit=PIN_B0,rcv=PIN_B1)

That line will not generate code to use the hardware UART.

The hardware UART is on pins B2 and B1 in the 16F648A.
See the pin diagrams near the front of the data sheet.
http://ww1.microchip.com/downloads/en/DeviceDoc/40044G.pdf

If you use the hardware UART, then kbhit() will work reliably.
A_L_E_X



Joined: 21 Feb 2010
Posts: 11

View user's profile Send private message

PostPosted: Tue Jun 29, 2010 12:27 pm     Reply with quote

So there is there any other solution ? I must use those pins.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jun 29, 2010 12:32 pm     Reply with quote

Is pin B2 unused ?
A_L_E_X



Joined: 21 Feb 2010
Posts: 11

View user's profile Send private message

PostPosted: Thu Jul 01, 2010 12:20 pm     Reply with quote

All pins are used. In fact i've already made the board and I don't want to do it again. I'm looking for a simpler solution like making the modification in the software.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group