new c part

2 views
Skip to first unread message

Hao Zhang

unread,
Oct 6, 2011, 3:02:18 PM10/6/11
to 3K04 project grp
/* TransmissionHardware
* This is a Hardware Hiding module, for which the "secret"
* is the details of the hardware configuration
*/
#include "globals.h"
#include "Clock.h"
#include "delays.h"
#include <p18f4520.h>

#define BRG_VALUE(FOSC, BAUD_RATE) (((FOSC / BAUD_RATE)/64)-1)
#define BAUD_RATE 2400
#define TX_DELAY 1

// "private" functions
int setBaudrate(long baudrate);
char sData[16];

Sdata dataRecieved;

// "private" variables
short rxInitialized = FALSE;
short txInitialized = FALSE;

/** /name configureTranmission
* /brief Function that configures the hardware to allow tranmission
* /note This function must be called before we can transmit data
*/
int configureTransmission(){
// 1. Initialize the SPBRGH:SPBRG registers for the appropriate baud
rate.
if(!setBaudrate(BAUD_RATE)) return FAILURE;

/* 2. Enable the asynchronous serial port by clearing bit SYNC and
setting bit SPEN.
* we must also set the pin direction (using tristate registers)
because the RX & TX pins
* are multiplexed with PORTC pins */
TXSTAbits.SYNC = 0;
RCSTAbits.SPEN = 1;
TRISCbits.TRISC6 = 1;
TRISCbits.TRISC7 = 1;

// 3. Enable the transmission by setting bit TXEN which will also set
bit TXIF.
TXSTAbits.TXEN = 1;

// Set a flag to signify that we can now transmit data
txInitialized = TRUE;
return SUCCESS;
}
/** /name configureReception
* /brief Function that configures the hardware to allow reception
* /note This function must be called before we can receive data
*/
int configureReception(){
// 1. Initialize the SPBRGH:SPBRG registers for the appropriate baud
rate. Set or clear the BRGH and BRG16 bits, as required, to achieve
the * desired baud rate.
if(!setBaudrate(BAUD_RATE)) return FAILURE;

// 2. Enable the asynchronous serial port by clearing bit SYNC and
setting bit SPEN.
// 3. Enable the reception by setting bit CREN.
}

/** /name setBaudrate
* /brief Function to set the baudrate of the UART peripheral
* /param baudrate - The baud rate (tranmission rate) the UART
peripheral should run
*/
int setBaudrate(long baudrate){
//but what about overflow? what about SPBRGH? BRGH?
SPBRG = (int)BRG_VALUE(clock(),baudrate);

//error handling
return SUCCESS;
}

/** /name sendData
* /brief Function to send a stream of characters over UART
* /param txData - pointer to a block of memory containing the data
we wish to send.
* Must be allocated by caller!
* /param length - Number of characters we wish to send
* /returns -1 on error, number of characters sent otherwise
*/
int sendData(char *txData, int length){
int index = -1;
if(txData==(void*)0 || txInitialized==FALSE) return FAILURE;

/* Load data to the TXREG register (starts transmission).
* wait for TXIF to be set (tx complete)
* load next byte into TXREG, repeat
*/
while(index++<length){
TXREG = txData[index];
while(PIR1bits.TXIF==0);
}
return index;
}

/** /name receiveData
* /brief Receives a stream of characters, which are loaded into an
array pointed to by rxData
* /param rxData - pointer to an array in which we want the received
data.
* Must be allocated by caller
* /param length - The number of bytes we wish to receive
* /returns Length of received data, -1 on error
*/

// returns length of received data, -1 on error
int receiveData(char *rxData, int length){
/* 1. Flag bit, RCIF, will be set when reception is complete and an
interrupt will be generated if enable bit, RCIE, was set.
* 2. Read the RCSTA register to get the 9th bit (if enabled) and
determine if any error occurred during reception.
* 3. Read the 8-bit received data by reading the RCREG register.
* 4. If any error occurred, clear the error by clearing enable bit
CREN.
*/
int index = -1;
if(RCREG==((void*)0||txInitialized==FALSE) return FAILURE;
INTCONbits.GIEH = 1;
PIE1bits.RCIE = 1;
while(index++<length)
{
rxData[index]=RCREG;
while(!PIR1bits.RCIF);
}
//if (TXSTAbits.TX9) =TXSTAbits.TX9D;

return index;
}

Keybo Qian

unread,
Oct 6, 2011, 5:35:31 PM10/6/11
to 3k04-pro...@googlegroups.com
/* Turn off watchdog timer */
#pragma config WDT=OFF

/* Set oscillator mode to be HS (high speed) */
#pragma config OSC=HS


#include <p18cxxx.h>
#include <delays.h>
#include <math.h>


/* Frequency of the oscillator */
#define FOSC                    4000000

/* Baud rate for serial communication */
#define BAUD_RATE               19200

/* Timer0 interval in microseconds */
#define TIMER0                  500000


/* ANSI escape sequences */
#define ANSI_ESC                "\033["
#define ANSI_CLEAR_SCREEN       (ANSI_ESC"2J")
#define ANSI_CLEAR_LINE         (ANSI_ESC"K")
#define ANSI_SAVE_CURSOR        (ANSI_ESC"s")
#define ANSI_RESTORE_CURSOR     (ANSI_ESC"u")


/* A simple cyclic buffer implementation */
/* The size of such buffer is 2^5 = 32 */
#define BUF_BITS                5
#define BUF_SIZE                (1 << BUF_BITS)
#define BUF_MASK                (BUF_SIZE - 1)

/* Initialize buffer */
#define BUF_INIT(buf)                           \
    do {                                        \
        (buf).head = (buf).tail = 0;            \
    } while (0)

/* Pop an element from the head of the FIFO buffer */
#define BUF_GET(buf)                            \
    ((buf).data[(buf).head++ & BUF_MASK])

/* Append an element into the end of the FIFO buffer */
#define BUF_ADD(buf, c)                                 \
    do {                                                \
        (buf).data[(buf).tail & BUF_MASK] = (c);    \
    (buf).tail++;                    \
    } while (0)

/* Append an array of elements into the buffer */
#define BUF_ADDSTR(buf, str)                    \
    do {                                        \
        char __i;                               \
        for(__i = 0; (str)[__i]; __i++) {       \
            BUF_ADD(buf, (str)[__i]);           \
        }                                       \
    } while(0)

/* Test if the buffer is empty */
#define BUF_EMPTY(buf)                          \
    (!(((buf).tail ^ (buf).head) & BUF_MASK))

/* Test if the buffer is full */
#define BUF_FULL(buf)                                   \
    (!((((buf).tail + 1) ^ (buf).head) & BUF_MASK))

/* Return the number of elements in the buffer */
#define BUF_LEN(buf)                            \
    (((buf).tail - (buf).head) & BUF_MASK)


/* A struct for the cyclic buffer */
struct buffer {
    char        data[BUF_SIZE];
    volatile char    head;
    volatile char    tail;
};


/* Sending buffer */
struct buffer txbuf;
/* Receiving buffer */
struct buffer rcbuf;


/* Interrupt handler function */
void intr_handler(void);

/* Setting interrupt entrance on PIC18 */
#pragma code intr_section = 0x8
void intr_entry(void) {
    _asm goto intr_handler _endasm
        }
#pragma code


/* Interrupt handler function */
#pragma interrupt intr_handler
void intr_handler(void) {
    /* If the microcontroller received a byte */
    if (PIR1bits.RCIF) {
        /* Add the byte into receiving buffer */
        BUF_ADD(rcbuf, RCREG);
    }
    /* If the microcontroller sent a byte */
    if (PIR1bits.TXIF) {
        /* If there is nothing to send (the sending buffer is empty) */
        if (BUF_EMPTY(txbuf)) {
            /* Turn off sending interrupt */
            PIE1bits.TXIE = 0;
        } else {
            /* Send the first byte in the sending buffer */
            TXREG = BUF_GET(txbuf);
        }
    }
    if (INTCONbits.TMR0IF) {
        //INTCONbits.TMR0IF = 0;
        INTCONbits.TMR0IE = 0;
    }
}

/* Initialize serial port */
void uart_init(void) {
    unsigned int i;

    /* Set baud rate */
    /* BRGH mode */
    TXSTAbits.BRGH      = 1;
    /* BRG16 mode */
    BAUDCONbits.BRG16   = 0;
    /* Value of the SPBRG registor for the given baud rate.  Check datasheet
       to make sure that the combination of BAUD_RATE,FOSC,BRGH,BRG16 produces
       a valid SPBRG. */
    i                   = 64 >> ((TXSTAbits.BRGH + BAUDCONbits.BRG16) * 2);
    i                   = FOSC / BAUD_RATE / i  - 1;
    SPBRGH              = i >> 8;
    SPBRG               = i & 0xFF;

    /* Configure the pins for UART */

    TRISCbits.TRISC6    = 1;
    TRISCbits.TRISC7    = 1;

    /* Enable serial port */
    RCSTAbits.SPEN      = 1;
    /* Enable asynchronous mode */
    TXSTAbits.SYNC      = 0;
    /* Enable transmission (sending) */
    TXSTAbits.TXEN      = 1;
    /* Enable receiving */
    RCSTAbits.CREN      = 1;

    /* Enable interrupt priority */
    RCONbits.IPEN       = 1;
    /* Set high priority for sending and receiving interrupt */
    IPR1bits.RCIP       = 1;
    IPR1bits.TXIP       = 1;
    /* Enable high priority interrupt */
    INTCONbits.GIEH     = 1;
    /* Enable receiving interrupt */
    PIE1bits.RCIE       = 1;

    /* Initialize receiving buffer */
    BUF_INIT(rcbuf);
    /* Initialize sending buffer */
    BUF_INIT(txbuf);
}

/* Initialize Timer0 */
void timer0_init(void) {
    /* Clock periods needed to get the time interval */
    unsigned long i     = (float)FOSC * TIMER0 / 1000000;

    /* TMR0ON T08BIT T0CS T0SE PSA T0PS2 T0PS1 T0PS0 */
    T0CON               = 0b10000000;

    /* Set prescaler */
    if (i >> 16) {
        for (i >>= 1; i >> 16; i >>= 1, T0CON++);
    } else {
        T0CON |= 8;
    }

    /* Set TMR0 = 65536 - i, so after i periods, an interrupt will
       fire up */
    i                   = (0xFFFF ^ i) + 1;
    TMR0H               =  i >> 8;
    TMR0L               = i & 0xFF;

    /* Clear TMR0IF flag */
    INTCONbits.TMR0IF   = 0;
    /* Enable Timer0 interrupt */
    INTCONbits.TMR0IE   = 1;
}

/* Initialize ventricle sense */
void sense_init(void) {
    /* Set ventricle sense (pin33) to be input */
    TRISBbits.TRISB0    = 1;
}

/* Initialize A/D converter */
void adc_init(void) {
    /* Enable ventricle sensing (MICRO_VENT_SENSE_BLANK_CNTL) */ 
    TRISDbits.TRISD4    = 0;
    PORTDbits.RD4       = 1;

    /* Enable atrial sensing (MICRO_ATRIAL_SENSE_BLANK_CNTL) */ 
    TRISDbits.TRISD5    = 0;
    PORTDbits.RD5       = 1;

    /* Set SCK to be output pin */
    TRISCbits.TRISC3    = 0;
    /* Set SDI to be input pin */
    TRISCbits.TRISC4    = 1;
    /* Set SDO to be output pin */
    TRISCbits.TRISC5    = 0;
    /* Set SS to be input pin */
    TRISAbits.TRISA5    = 1;
}

/* Read a number from A/D converter */
unsigned int adc_get(void) {
    unsigned int c      = 0;
    char i;

    for (i = 0; i < 16; i++) {
        /* Flip clock line (SCK) */
        PORTCbits.SCK   = 0;
        PORTCbits.SCK   = 1;
        /* Shift buffer */
        c               <<= 1;
        /* Read a bit and place it at the end of the buffer */
        c               |= PORTCbits.SDI;
    }

    return c;
}

/* Wait for A/D converter to be ready for reading */
void adc_start(void) {
    /* Ask if A/D converter is ready */
    PORTCbits.SDO       = 0;
    PORTCbits.SCK       = 0;
    PORTCbits.SCK       = 1;
    PORTCbits.SDO       = 1;
                       
    /* Wait for reply */
    while (!PORTCbits.SDI);
}

/* Turn off the conversation with A/D converter */
void adc_stop(void) {
    PORTCbits.SCK       = 0;
    PORTCbits.SDO       = 0;
}

/* Convert an integer to string, similar to printf("%0nd", i) */
char *intstr(unsigned int i, char n) {
    static char buf[6];
    char        j;

    /* Get the least significant digit */
    buf[4]      = '0' + i % 10;
    buf[5]      = 0;

    /* Get the rest digits */
    for (i /= 10, j = 3; i; i /= 10, j--) {
        buf[j]  = '0' + i % 10;
    }
   
    /* Fill the leading zeros */
    n           = (n >= 4 - j) ? n : (4 - j);
    for (; j > 4 - n; j--) {
        buf[j]  = '0';
    }

    return &buf[j + 1];
}

/* Timer0 event handler */
void on_timer0(void) {
    char                buf[6];
    unsigned int        d;
    float               v;

    /* Reset Timer0 */
    timer0_init();
   
    /* Start conversation with A/D converter */
    adc_start();

    /* Save the current cursor position */
    BUF_ADDSTR(txbuf, ANSI_SAVE_CURSOR);

    /* Get ventricle voltage */
    v   = 5.0 * adc_get() / 65535;
    /* Print integer part */
    BUF_ADDSTR(txbuf, intstr(v, 0));
    v   = modf(v, (void *)0) * 1000;
    /* Print decimal point */
    BUF_ADD(txbuf, '.');
    /* Print decimal part */
    BUF_ADDSTR(txbuf, intstr(v, 3));
    BUF_ADD(txbuf, ' ');

    /* Get atrial voltage */
    v   = 5.0 * adc_get() / 65535;
    /* Print integer part */
    BUF_ADDSTR(txbuf, intstr(v, 0));
    v   = modf(v, (void *)0) * 1000;
    /* Print decimal point */
    BUF_ADD(txbuf, '.');
    /* Print decimal part */
    BUF_ADDSTR(txbuf, intstr(v, 3));
    BUF_ADD(txbuf, ' ');
                                       
    /* Stop conversation with A/D converter */
    adc_stop();

    /* Print ventricle sensing bit */
    BUF_ADD(txbuf, '0' + PORTBbits.RB0);
    BUF_ADD(txbuf, '\n');
                               
    /* Clear rest of the line */
    BUF_ADDSTR(txbuf, ANSI_CLEAR_LINE);
    /* Restore cursor position */
    BUF_ADDSTR(txbuf, ANSI_RESTORE_CURSOR);
   
    /* Enable sending interrupt */
    PIE1bits.TXIE = 1;
}

/* UART event handler */
void on_uart(void) {
    char c;
    char d;

    BUF_ADDSTR(txbuf, "\n\r");
    /* Read one byte from the receiving buffer */
    c = BUF_GET(rcbuf);
    /* Get the first hex code of the byte */
    d = c >> 4;
    d += (d < 10) ? '0' : ('a' - 10);
    /* Put the code in sending buffer */
    BUF_ADD(txbuf, d);
    /* Get the second hex code of the byte */
    d = c & 0xF;
    d += (d < 10) ? '0' : ('a' - 10);
    /* Put the code in sending buffer */
    BUF_ADD(txbuf, d);
    BUF_ADD(txbuf, ' ');
   
    /* Now the sending buffer is non-empty, we enable
       transmission interrupt to send the contents in sending
       buffer */
    PIE1bits.TXIE = 1;
}

/* Main entrance */
void main(void) {

    /* Initialize */
    sense_init();
    uart_init();
    timer0_init();
    adc_init();
    char sData[16];
    char checkSum;

    /* Clear screen and append a string to sending buffer */
    BUF_ADDSTR(txbuf, ANSI_CLEAR_SCREEN);
    //BUF_ADDSTR(txbuf, "Hello!\n\r");
   
    /* Enable sending interrupt */
    PIE1bits.TXIE = 1;
   
    while (1) {
        /* If the receiving buffer is not empty and there is enough
           space in the sending buffer */


        if (!BUF_EMPTY(rcbuf)&&BUF_GET(rcbuf) == 0x16) {
            int index =-1;
            checkSum = 0x00;
            while(index++ < 16){

                char sData[index] = BUF_GET(rcbuf);
                if(index>2 && index<14) checkSum ^= sData[index];
                 
                //BUF_ADD(txbuf, sData[index]);
            }
        if (checkSum !=
            //PIE1bits.TXIE = 1;
        }

        if (INTCONbits.TMR0IF && BUF_LEN(txbuf) + 16 < BUF_SIZE) {
            on_timer0();
        }
        /* Put the microcontroller in idle mode */
        /* WARNING: If you want to debug the code with MPLAB Sim, you
           need to remove the following two lines, since MPLAB Sim
           cannot be waked up in idle mode by UART interrupt */
        //OSCCONbits.IDLEN = 1;
        //Sleep();
    }
}

Hao Zhang

unread,
Oct 6, 2011, 5:51:25 PM10/6/11
to 3K04 project grp
TRISCbits.TRISC6 = 1;
TRISCbits.TRISC7 = 1;

Reply all
Reply to author
Forward
0 new messages