View previous topic :: View next topic |
Author |
Message |
g-netix
Joined: 19 Aug 2012 Posts: 19
|
RTOS and interrupt |
Posted: Sun Aug 19, 2012 3:25 am |
|
|
Hi, I try to experiment with #use_rtos and #task but I encountered some difficulty to use those instructions with the RS-232 interrupts.
- I succeeded in using #int_RDA to receive some data in the uart's buffe.r
- I succeeded in using tasks to blink 3 LEDs at different frequencies.
But it seems that RTOS short-circuits the interrupt and when I send any data on th RX pin nothing happens, whereas when I use only interrupt I am able to interact with the received data (I use the switch/case function to test each received byte).
Is someone succeeded in doing that?
thank you |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Aug 19, 2012 3:40 am |
|
|
What you describe should be possible.
For more help: Read the first sticky post on this forum and act according to the 4 mentioned items when posting (especially item 4). |
|
|
g-netix
Joined: 19 Aug 2012 Posts: 19
|
|
Posted: Sun Aug 19, 2012 4:10 am |
|
|
Ok thank you, so here are the information :
Compiler version : 4.135.16.14
PIC Microcontroller : PIC18F46K22
Standard Run Mode
Target voltage : 5V
Target oscillator : Internal RC (No clockout) @ 16MHz
Some code lines :
Code: |
#include <rtos.h>
#define terminaison 0x7E
#use_rtos (timer=0, minor_cycle = 100ms)
#int_RDA
void RDA_isr (void)
{
trame_RS232_1 = fgetc(RS232_1);
if (trame_RS232_1 == terminaison)
{
trame_RS232_1_presente = true;
buffer_RS232_1 [pointeur_buffer_RS232_1] = 0;
pointeur_buffer_RS232_1 = 0;
}
else
{
buffer_RS232_1 [pointeur_buffer_RS232_1++] = trame_RS232_1;
if (pointeur_buffer_RS232_1 == 10)
{
pointeur_buffer_RS232_1 = 0;
}
}
}
#task (rate=1ms)
void the_first_rtos_task()
{
if(trame_RS232_1_presente == true)
{
analyse_trame ();
trame_RS232_1_presente == false;
}
}
void main()
{
rtos_run();
} |
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Aug 19, 2012 4:57 am |
|
|
The code as posted is incomplete. Please post a program that we can copy/paste to our IDE without modifications.
Here is one error in your program: Code: | trame_RS232_1_presente == false; | Change the '==' to '='.
A good programming practice is to write all your constants in capital letters, i.e. 'false' becomes 'FALSE' and 'terminaison' becomes 'TERMINAISON'. This way you easily see the difference between constants and variables. |
|
|
g-netix
Joined: 19 Aug 2012 Posts: 19
|
|
Posted: Sun Aug 19, 2012 5:26 am |
|
|
Yes I've noticed that but too late to edit, it's just a copy/paste error, because I've just rewrote one of the three or four syntaxes I tried and didn't save because they didn't work...
But thanks for the idiea to change the case of constant and variable ;) |
|
|
g-netix
Joined: 19 Aug 2012 Posts: 19
|
|
Posted: Mon Aug 20, 2012 6:41 am |
|
|
It's OK, I finally found a way to make my design work.
Here's the solution I used :
Code: | #include <18F46K22.h>
#device ICD=TRUE
#device adc=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPLLEN //4X HW PLL disabled, 4X PLL enabled in software
#FUSES NOBROWNOUT //No brownout reset
#FUSES WDT_NOSLEEP //Watch Dog Timer, disabled during SLEEP
#FUSES NOPBADEN //PORTB pins are configured as digital I/O on RESET
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#use delay (int=16000000)
#use rs232 (baud = 57600, parity = N, xmit = PIN_C6, rcv = PIN_C7, bits = 9, stream = RS232)
#define terminaison 0x24
short trame_RS232_presente = FALSE;
int pointeur_buffer_RS232 = 0;
char buffer_RS232 [11];
char trame_RS232;
#int_RDA
void RDA_isr (void)
{
trame_RS232 = fgetc (RS232); // RS232 is the stream
if (trame_RS232 == TERMINAISON)
{
trame_RS232_presente = TRUE;
buffer_RS232 [pointeur_buffer_RS232] = 0;
pointeur_buffer_RS232 = 0;
}
else
{
buffer_RS232 [pointeur_buffer_RS232++] = trame_RS232;
if (pointeur_buffer_RS232 == 10)
{
pointeur_buffer_RS232 = 0;
}
}
}
#use rtos (timer = 0) // #use_rtos must be after interrupt
#task (rate=250ms)
void toggle_led_1 ()
{
output_toggle (PIN_B0);
}
#task (rate=1s)
void toggle_led_2 ()
{
output_toggle (PIN_B1);
}
#task (rate=10ms)
void uart_use ()
{
rtos_await (trame_RS232_presente);
fprintf (RS232, "UART OK\r\n");
trame_RS232_presente = FALSE;
}
void main()
{
setup_adc_ports(sAN0);
setup_adc (ADC_CLOCK_DIV_2 | ADC_TAD_MUL_0);
setup_timer_2 (T2_DIV_BY_1, 127, 1);
setup_timer_3 (T3_DISABLED | T3_DIV_BY_1);
setup_timer_4 (T4_DISABLED, 0, 1);
setup_timer_5 (T5_DISABLED | T5_DIV_BY_1);
setup_timer_6 (T6_DISABLED, 0, 1);
setup_comparator (NC_NC_NC_NC);
enable_interrupts (INT_RDA);
enable_interrupts (GLOBAL);
while (true)
{
rtos_run ();
}
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Mon Aug 20, 2012 7:52 am |
|
|
Well done.
One comment. Add ERRORS to your #USE RS232.
When using the hardware UART, either _you_ must handle hardware ERRORS if they occur, or you _must_ have the ERRORS declaration. Without this, if you do miss a receive character, or there is a framing error in the data, the UART _will_ become hung.
Best Wishes |
|
|
g-netix
Joined: 19 Aug 2012 Posts: 19
|
|
Posted: Mon Aug 20, 2012 11:56 am |
|
|
I think I should add "errors" in the line of the UART like this :
Code: | #use rs232 (baud = 57600, parity = N, xmit = PIN_C6, rcv = PIN_C7, bits = 9, stream = RS232, errors) |
but I don't know what I've to do with it, does the compiler use it automatically? because with the old version of CCS, when I did that it sent me "Warning, variable never used : errors" but since I upgraded CCS it doesn't send this anymore...
Thank you. |
|
|
g-netix
Joined: 19 Aug 2012 Posts: 19
|
|
Posted: Mon Aug 20, 2012 12:42 pm |
|
|
And then in my application I analyze the characters that arrive on the UART, if there is one or more errors it sends to the user "incorrect command". So at the moment I read this on the virtual terminal in Proteus ISIS, but I'll use either a program that I wrote, or a virtual instrument in Labview, so all that the PIC will return will be interpreted by the computer... ;) |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Mon Aug 20, 2012 12:45 pm |
|
|
Yes.
When you add 'ERRORS', two things happen.
First the compiler automatically generates code to clear UART errors, and as a 'convenience' then this code also creates a varible 'RS232_ERRORS', which contains any error data found by the code.
Depending on the compiler settings, this 'unused' variable, results in a _warning_ (not an error), pointing out that it exists, but is never used.
That it does, results in a lot of people not using ERRORS, when it is needed....
The warning can be turned off.
Best Wishes |
|
|
g-netix
Joined: 19 Aug 2012 Posts: 19
|
|
Posted: Mon Aug 20, 2012 12:50 pm |
|
|
Ok now I understand I had it on the code so I'll be quite about any problem that could occur while data transfering ;) |
|
|
|