|
|
View previous topic :: View next topic |
Author |
Message |
siphorob
Joined: 12 Oct 2010 Posts: 12 Location: South Africa
|
Multiplexing an input, using RB0 as INT and display |
Posted: Thu Oct 21, 2010 12:12 am |
|
|
Hi,
I am experiencing difficulties using multiplexing portb, of the PIC16f877A.
I have connected my portb for my lcd, and I am also trying to use RB0 as an external interrupt source.
LCD_DB4 PIN_B0
LCD_DB5 PIN_B1
LCD_DB6 PIN_B2
LCD_DB7 PIN_B3
LCD_E PIN_B4
LCD_RS PIN_B5
There is the code:
Code: |
void main() {
lcd_init();
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);setup_wdt(WDT_288MS);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_16,194,16);// overflow aprox every 50ms
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
ext_int_edge( H_TO_L );
enable_interrupts(GLOBAL);
while (TRUE)
{
set_tris_b(1); //make portb an input
start_measurement();
do{}while(!meas_done);
disable_interrupts(INT_TIMER2);
disable_interrupts(INT_EXT);
RPM = sensor_pulses;
sensor_pulses = 0;
set_tris_b(0); //make portb an output
delay_ms(5000);
printf(lcd_putc,"%lu rpm",RPM);
printf("%lu rpm %F A",RPM);
delay_ms(1000);
}
}
void EXT_isr(void)
{
if(!meas_done)
{sensor_pulses++; } // Sensor pulses (TTL level) must arrieve at PIN_B0
}
#int_TIMER2
void TIMER2_isr(void)
{
if(loops)
{loops--;}
else
{meas_done=true; }
}
void start_measurement()
{
meas_done=false;
loops = 20; // 50ms * 20 = 1000ms
// This is the measurement window time
set_timer2(0);
enable_interrupts(INT_TIMER2);// To create a measurement window
enable_interrupts(INT_EXT); // Generate an interrupt every pulse
} // comming from the sensor |
_________________ Regards,
Brandon |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Thu Oct 21, 2010 12:45 pm |
|
|
Ouch.
As an interrupt input, what's to keep the thing from generating the interrupt (maybe driven low or high) to stomp on the PIC trying to talk to the LCD.
If you had some sort of bus control in there, (like a buffer w/enable and hi-z state) on the thing that's the interrupt, then it might be ok...
You'll have to disable the IRQ every time the LCD service runs.
You could do it - but they can't share lines without some form of collision isolation.
Maybe someone else will find a gotcha too, but input vs. output state contention immediately jumps out screaming.
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Oct 21, 2010 12:58 pm |
|
|
Just choose another pin for your LCD. Use the Flex driver in the Code
library forum and use another pin. It's not worth trying to even worry
about what you're doing. Use another pin.
Flex lcd driver:
http://www.ccsinfo.com/forum/viewtopic.php?t=24661 |
|
|
siphorob
Joined: 12 Oct 2010 Posts: 12 Location: South Africa
|
|
Posted: Fri Oct 22, 2010 12:21 am |
|
|
I tried disabling the lcd routines and tried to run the code on HyperTerminal. As soon as I start generating interrupts on RB0 the HyperTerminal stops working. Please advise on how I can solve this, I am using a hall effect senor to measure the speed.
Code: |
void main()
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);setup_wdt(WDT_288MS);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_16,194,16);// overflow aprox every 50ms
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
ext_int_edge( H_TO_L );
enable_interrupts(GLOBAL);
while(1)
{
start_measurement();
do
{
}while(!meas_done);
disable_interrupts(INT_TIMER2);
disable_interrupts(INT_EXT);
RPM = sensor_pulses * 60;
sensor_pulses = 0;
printf("RPM %04lu", RPM);
}
} |
_________________ Regards,
Brandon |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Fri Oct 22, 2010 3:04 pm |
|
|
On your #use RS232 line, make sure you have 'errors' selected.
Swap the order you declare the INT_EXT, and the INT_TIMER2. Have the INT_EXT interrupt disabled in the INT_TIMER2 code.
Now, what sort of frequency are the hall effect pulses?. Remember it takes significant time to get into, and out of an interrupt. My guess would be that with the current code, the interrupts are arriving faster than they can be handled, effectively 'blocking' the code to permanently stay in the INT_EXT handler, and hence everything else locks up once this interrupt is enabled....
Swapping the interrupt declaration order, makes the timer have 'priority' over INT_EXT, and then this will disable INT_EXT when the time expires, allowing things to keep working.
However, pulses _will_ have been missed, if this is the case. Answer here is to use the hardware CCP to count the pulses, rather than INT_EXT. This is what it is 'for', and doing this will raise the supported pulse rate from perhaps 16Khz, to the maximum clock speed of the chip......
Best Wishes |
|
|
|
|
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
|