|
#include <pic.h> //obligatory
//Quartz 4Mhz
#define PIC_CLK 4000000
//The delay routines
#include "delay.h"
//I use a chrystal and my code is not protected
__CONFIG(FOSC0|PWRTE |CP);
/**
* RS232 link management at 9600 bauds
*
*/
//This replaces bitfields implementation
#define PORTBIT(adr, bit) ((unsigned)(&adr)*8+(bit))
#define getbit(data,bitno) ((data>>bitno)&0x01)
#define setnbit(data,bitno) (data<<bitno)
#define setbit(data,bitno,value) (data&(~setnbit(1,bitno))|setnbit(value,bitno))
#define togglebit(data) (data^0x01)
//Duration in microsecond (the microcontroler is blind during this duration
if the signal change on its 'IT interruption pin)
#define TirqLatency 60
/************Serial link*******************************/
//Receiver parameters
//-----------------------------
#define Tbit_rx_RS232 104 //Reception T=1/9600=104us à 9600 bauds
#define Jump_over_RS232_rx_startbit (Tbit_rx_RS232-TirqLatency+(Tbit_rx_RS232/2))
#define Nb_RS232_rx_databits 8 // 8 bits de données
#define Jump_over_RS232_rx_databits (Tbit_rx_RS232-15) //the loop takes
12us
#define Nb_RS232_rx_stopBits 1 //1 bit stop
#define Jump_over_RS232_rx_stopbits (Nb_RS232_rx_stopBits*Tbit_rx_RS232)
//Emitter parameters
//--------------------------
#define Tbit_tx_RS232 104
#define Duration_RS232_tx_startbit (Tbit_tx_RS232-30)
#define Nb_RS232_tx_databits 8
#define Duration_RS232_tx_databits (Tbit_tx_RS232-30)
#define Nb_RS232_tx_stopBits 1
#define Duration_RS232_tx_stopbits (Nb_RS232_tx_stopBits*Tbit_tx_RS232)
#define ITMask 0B10110000
//---- Pin attributions -------------
static bit RS_OUT @ PORTBIT(PORTA, 4); //Send pin
static bit RS_IN @ PORTBIT(PORTB, 7); //Get pin
//To display voir the char on a 8 leds panel
volatile bit D1 @ PORTBIT(PORTB, 3);
volatile bit D2 @ PORTBIT(PORTB, 2);
volatile bit D3 @ PORTBIT(PORTB, 1);
volatile bit D4 @ PORTBIT(PORTB, 0);
volatile bit D5 @ PORTBIT(PORTA, 3);
volatile bit D6 @ PORTBIT(PORTA, 2);
volatile bit D7 @ PORTBIT(PORTA, 1);
volatile bit D8 @ PORTBIT(PORTA, 0);
//---- Working variables ---------------------------
//used by the delay routines
volatile unsigned int timeout;
//buffer variable
unsigned char Buff;
unsigned char TxBuff; // char to send
unsigned char RxBuff;// char received
//------ Declaration of the RS232 routines -------------------------------
void RSsend(void); /* Send the char Buff on the serial port */
void RSget(void); /* Read the serial port and save it into Buff*/
//-------Panel Leds routines -------------
void WriteParport(void);
void ReadParport(void);
//------ Main program to init ports and allow interrupts---------
main()
{
//Indicate pin direction (INPUT /OUTPUTS)
TRISB = ITMask;
TRISA = 0;
//Set the default pin levels
PORTA = 0;
PORTB = 0b10000000;
RS_OUT=1;
//grant the interrupts on the port B
RBIE=1;
GIE=1;
//infinite loop to disturb
for(;;) {
}
}
//-----Show the Buff content on the 8 leds panel
void WriteParport(void) {
D1=getbit(Buff,0);
D2=getbit(Buff,1);
D3=getbit(Buff,2);
D4=getbit(Buff,3);
D5=getbit(Buff,4);
D6=getbit(Buff,5);
D7=getbit(Buff,6);
D8=getbit(Buff,7);
}
//----Retreive the value of the 8 leds (D1-D8) and store
it into Buff .
void ReadParport(void) {
Buff=setbit(Buff,0,D1);
Buff=setbit(Buff,1,D2);
Buff=setbit(Buff,2,D3);
Buff=setbit(Buff,3,D4);
Buff=setbit(Buff,4,D5);
Buff=setbit(Buff,5,D6);
Buff=setbit(Buff,6,D7);
Buff=setbit(Buff,7,D8);
}
unsigned char prev_portb=0B10000000; //latch the value of B port
// Interruption routine triggered by a signal change (and lasts more
thanTirqLatency!) on any pin:
// RB7, RB6,RB5,RB4 and RB0
interrupt isr()
{
//Try to know which pin change..
if (RBIF)
{
RBIF=0; //Interruption acquittment
if ((prev_portb ^ (PORTB&ITMask)) == 0B10000000)
{
//It is the RB7=RS IN which has changed, a char need to be analyzed
if ((PORTB & 0B10000000) == 0) //If it is the falling edge of
the start bit then
{
//receive the char behind
RSget();
//display its value on the panel leds
Buff=RxBuff;
WriteParport();
//and send it for acknowledgment
TxBuff=RxBuff;
RSsend();
}
}
prev_portb=PORTB&ITMask; //Next char..
}
}
// RS232 routines
//------------------
/*Send a char defined in TxBuff on RA4 pin at RS232 format */
void RSsend(void) {
unsigned b;
unsigned prevbit;
// start pattern
RS_OUT=0;
DelayUs(Duration_RS232_tx_startbit); // start pattern duration
//for each data pattern
for(b=Nb_RS232_tx_databits;b--;) {
prevbit=(TxBuff&0x01);
if(prevbit^RS_OUT) //si the previous pattern value is different from
the actual pattern value
RS_OUT=TxBuff&0x01; //send it else don't change anything
if(b>0) //if it is not the first pattern, go on..
TxBuff=TxBuff>>1; //I have finished the process for this patttern
, newt one pleaset
DelayUs(Duration_RS232_tx_databits);//data pattern duration
}
//Bit stop
RS_OUT=1;
DelayUs(Duration_RS232_tx_stopbits);//stop pattern duration
}
/* Receives a char on RA1 and stores it into RXBuff **/
void RSget(void) {
unsigned b;
RxBuff='\0';
//Jump over the start pattern and select the half first data pattern
.
//RS_OUT=0;
DelayUs(Jump_over_RS232_rx_startbit); // Delay for this
//RS_OUT=1;
//Read the 8 data patterns one after the other that is being send to
me..
for(b=Nb_RS232_rx_databits;b--;) {
RxBuff=RxBuff | ((RS_IN&0x01)<<(Nb_RS232_rx_databits-1));
/* For debug */
//RS_OUT=0;
if(b>0) //Patterns remaining?
RxBuff=RxBuff >> 1; //yes, next please.
DelayUs(Jump_over_RS232_rx_databits); //we jump a pattern duration to
go to the next pattern
//RS_OUT=1;
}
DelayUs(Jump_over_RS232_rx_stopbits); //optionnal as STOP pattern does
not contain any data.
}
|