______________________________________________________________________ > < > RS232 driver v1.00 < > for < > PICos release 1.04 < > < > PICos - Real-time kernel for PIC18 family < > < > < > www.picos18.com www.pragmatec.net < >______________________________________________________________________< This file contains all necessary informations to use properly the PIC24/30/33 RS232 driver for PICos v1.04. This driver lets you design a multi-task application using the same USART without being concerned by the USART shared access. Then every task of your application can print message without being necessarily synchronised to the others. ______________________________________________________________________ > < > I - Zip file content < >______________________________________________________________________< The drv_rs zip file contains : - drv_rs.c - drv_rs.h : header file - drv_rs.txt : this file To use the PICos RS232 driver, first unzip the file. Place the C and H file in your project directory. This driver is supposed to be use with PICos and has been tested with MPLAB 7.22 and C30 v2.02. Do not use this driver at a frequency lower than 8 Mhz (use the PIC PLL to increase the internal frequency). ______________________________________________________________________ > < > II - Hardware settings < >______________________________________________________________________< Adapt the U1BRG register according to the oscillator frequency to set the correct baud rate generator (file drv_rs.c). // PIC24 settings example #define SYSCLK 16000000 // External oscillator frequency / 2 #define BRGx_19200 51 // BRGx values for Baudrate at SYSCLK #define BRGx_38400 25 // BRGx values for Baudrate at SYSCLK #define BRGx_115200 8 // BRGx values for Baudrate at SYSCLK // PIC33 settings example /* #define SYSCLK 40000000 // External oscillator frequency / 2 #define BRGx_19200 129 // BRGx values for Baudrate at SYSCLK #define BRGx_38400 64 // BRGx values for Baudrate at SYSCLK #define BRGx_115200 21 // BRGx values for Baudrate at SYSCLK */ Look up the PIC datasheet for different settings. ______________________________________________________________________ > < > III - TASCDESC settings (1) < >______________________________________________________________________< Update also the tascdesc.c file to take into account the new RS driver in your application : /********************************************************************** * ----------------------- TASK & STACK DEFINITION -------------------- **********************************************************************/ DeclareTask(Example); DeclareTask(RS_Drv); ... volatile unsigned char stack0[DEFAULT_STACK_SIZE]; volatile unsigned char stack_rs[DEFAULT_STACK_SIZE]; ... ______________________________________________________________________ > < > IV - TASCDESC settings (2) < >______________________________________________________________________< Finally add the task and alarm descriptor to the tascdesc.c file : ... /********************************************************************** * ------------------------------ RS task ----------------------------- **********************************************************************/ rom_desc_tsk rom_desc_RS_DRV = { RDV_RS_PRIO, /* prioinit from 0 to 15 */ stack_rs, /* stack address (16 bits) */ RS_Drv, /* start address (16 bits) */ READY, /* state at init phase */ RS_DRV_ID, /* id_tsk from 0 to 15 */ sizeof(stack_rs) /* ctx address (16 bits) */ }; ... To use the RS232 we propose an EXAMPLE task that prints some string of data. Because the task is a periodic one, we create an alarm : AlarmObject Alarm_list[] = { /******************************************************************* * ----------------------- Example task ---------------------------- *******************************************************************/ { OFF, /* State */ 0, /* AlarmValue */ 0, /* Cycle */ &Counter_kernel, /* ptrCounter */ Example, /* TaskID2Activate */ ALARM_EVENT, /* EventToPost */ 0 /* CallBack */ } }; ______________________________________________________________________ > < > V - TASK Settings < >______________________________________________________________________< Open define.h and add this 3 definitions with correct value : #define RS_NEW_MSG 0x10 #define RS_RCV_MSG 0x20 #define RS_QUEUE_EMPTY 0x10 #define RS_QUEUE_FULL 0x20 #define RS_DRV_ID 6 #define RDV_RS_PRIO 8 #define EXAMPLE_ID 4 #define EXAMPLE_PRIO 5 The RS232 task is considered to be a driver, that means you have to give one of the highest priority to the RS232 driver to let it run each time the RS buffer is updated. Adapt the values to your application is necessary (event values...). ______________________________________________________________________ > < > VI - ISR connection < >______________________________________________________________________< Not any manual intervention needed. Done automaticaly by C30 and the driver. ______________________________________________________________________ > < > VII - RS driver usage < >______________________________________________________________________< In the Example task, include the driver header: #include "drv_rs.h" #include #include And declare a RS message (type RS_message_t): RS_ message_t RS_msg; In the task, a Printf function has been added to automaticaly prepare the RS_message_t buffer with any kind of data. See hereafter a basic example to print à "hello !" sentence with a counter value to HyperTerminal under Microsoft Windows(TM): #include "define.h" #include "drv_rs.h" #include #include /********************************************************************** * Definition dedicated to the local functions. **********************************************************************/ int Printf (const char *fmt, ...); /********************************************************************** * Variables shared with the rest of application. **********************************************************************/ RS_message_t RS_msg; unsigned char buffer[50]; /* This is just an exemple to show how to declare a const string in rom */ far rom char *example = "Oops !"; /********************************************************************** * ------------------------- Example TASK ---------------------------- * * **********************************************************************/ TASK(Example) { SetRelAlarm(0, 1000, 1000); while(1) { WaitEvent(ALARM_EVENT); ClearEvent(ALARM_EVENT); Printf("hello !\r\n"); } } /********************************************************************** * Function in charge of structure registration and buffer transmission. * * @param string IN const string send to the USART port * @return void **********************************************************************/ int Printf (const char *fmt, ...) { va_list ap; int n; RS_enqMsg(&RS_msg, buffer, 0); va_start (ap, fmt); n = vfprintf (_H_USER, fmt, ap); va_end (ap); SetEvent(RS_DRV_ID, RS_NEW_MSG); WaitEvent(RS_QUEUE_EMPTY);ClearEvent(RS_QUEUE_EMPTY); return n; } With such an example you should see under HyperTerminal : hello ! hello ! hello ! ______________________________________________________________________ > < > VIII - Reception < > Fixed length buffer < >______________________________________________________________________< All the data recieved from the RS232 are store in only one reception buffer. In order to capture the content of the reception buffer, you have to create a new task waiting for an event corresponding to the fact the reception buffer is full. This let you design a protocol layer, for instance a PROFIBUS driver that catches the reception buffer then analyze the content and dispatch the content function to the sub-address included. In the waiting task don't forget to include the appropriate header files: #include "drv_rs.h" #include #include And declare a RS message for reception only (type RS_message_t): RS_message_t RS_rcv_msg; Create a buffer to recieve the content of the reception buffer when it is full : unsigned char block[64]; Register the waiting task so that the RS232 driver will wake it up when the reception buffer is full : TASK(Protocol) { RS_RCV_Register(&RS_rcv_msg, (unsigned char*)(block), sizeof(block), 0); while (1) { WaitEvent(RS_QUEUE_FULL); ClearEvent(RS_QUEUE_FULL); switch(block[0]) // the command field for instance { case ACTION_INIT : InitHardware(); break; case ... } } } ______________________________________________________________________ > < > IX - Reception < > Special character expected < >______________________________________________________________________< Insteed of managing a fixed length buffer, you can wait for a specific character like a carriage return of a 0x17 to specify the end of transmission. In the waiting task don't forget to include the appropriate header files: #include "drv_rs.h" #include #include And declare a RS message for reception only (type RS_message_t): RS_message_t RS_rcv_msg; Create a buffer to recieve the content of the reception buffer when it is full : unsigned char block[64]; Register the waiting task so that the RS232 driver will wake it up when the expected character is detected : TASK(Protocol) { unsigned char i; RS_RCV_Register(&RS_rcv_msg, (unsigned char*)(block), 0, '\r'); while (1) { WaitEvent(RS_QUEUE_FULL); ClearEvent(RS_QUEUE_FULL); i = 0; while (block[i] != '\r') i++; block[i+1] = 0; Printf("%s\r\n", block); } } The example above prints at screen each sentence that has been sent from HyperTerminal. ______________________________________________________________________ > < > X - Conclusion < >______________________________________________________________________< If you are using the Explorer 16, the default USART is the number 2. You need then to adapt the driver code to be able to manage the USART2. A next version of this driver will include 2 drivers dedicated to an hardware interface... In this example you can see only one task using the PIC USART. In fact you can add many other tasks sharing this USART without being concerned by the shared access of the USART. This lets you debug easily your tasks with some printf functions... This RS232 driver is provided from the PICos18 web site with other drivers dedicated to oher peripherals. Some zip files are also provided to be used with a driver. For instance a "Profibus protocol" file should be delivered to manage a Profibus based on this RS232 driver. Do not hesitate to check periodicaly the www.picos18.com web site in order to download the last versions of PIC drivers for PICos. /* End of File : drv_rs.txt */