public
Last active

  • Download Gist
PIC18_USART_HAD_contest.c
C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
/* Entry for the Hack A Day easter egg Fubarino contest */
/*
PIC: PIC18F4550
Modules used:
USART: Serial comunication.
Timer 0: 10 ms interrupt to generate the program's clock
Interruptions: Used in Timer 0 and USART modules
IO: PORTD as data echoed from the serial port
bit 2 of PORTE as extra LED
 
Description:
- Using the USART capability of the PIC, serial data is recieved from
a PC using a temrinal program one byte a time. Each byte recieved
is echoed to the PORTD and showed by the LEDs connected. The USART
module is configured with a baud rate of 115200 and 8N1.
- When a byte is recieved, it generates an interrupt.The byte is
saved and a flag is set.
- To control the flow of execution, a 10ms clock is generated by the
Timer 0 module using an interrupt.
- Only when a new byte is recieved and 10ms have passed, the byte saved
is echoed to the PORTD on the microcontroller.
- As and "easter egg", a state machine is used to find the string: "hack".
When the sequence "hack" is found, the message " For awesome hacks visit
http://hackaday.com " is sent back to the computer and another LED is turned on.
More info: http://hackaday.com/2013/12/03/new-contest-win-one-of-20-microchip-fubarino-boards/
 
*/
 
#include <stdint.h>
#include <xc.h>
#include <plib/usart.h>
 
/* Configuration bits */
#include "../config/config.h" // 20 MHz external crystal oscillator
// 48 Mhz Fosc
 
 
/* Baud Rate macros*/
#define _XTAL_FREQ 48000000 // Fosc: 48MHz
#define _BAUD_RATE 115200
#define _SPBRG (_XTAL_FREQ/16/_BAUD_RATE)-1
 
/* ISR variables */
volatile uint8_t message = 0;
volatile uint8_t flag10ms = 0;
volatile uint8_t flagNewMsg = 0;
 
/* Function prototypes */
void configUSART(void);
void configTMR0(void);
void interrupt ISR(void);
 
/* Main loop */
void main(void) {
 
/* States */
enum {
H,
A,
C,
K
};
 
/* Variables */
uint8_t hackADay[] = " For awesome hacks visit http://hackaday.com ";
uint8_t state = H; // Default state
 
/* Port initialization */
TRISD = 0; // PORTD as output (port LEDs)
TRISEbits.RE2 = 0; // RE2 as output (success LED)
LATD = 0; // LEDs OFF
LATEbits.LATE2 = 0; // Succes LED OFF
 
configTMR0(); // Configure Timer0: ~10ms interrupt
configUSART(); // Configure USART: 115200 baudrate
ei(); // Enable inerrupts
 
while(1)
{
// if 10ms have passed AND there is a new byte
if(flag10ms && flagNewMsg)
{
/* State machine to find the sequence "hack" */
switch(state)
{
case H:
LATEbits.LATE2 = 0;
if ('h' == message) state = A; // 'h' found, search for 'a'
else state = H;
break;
 
case A:
if ('a' == message) state = C; // "ha" found, search for 'c'
else state = H;
break;
 
case C:
if ('c' == message) state = K; // "hac" found, search for 'k'
else state = H;
break;
 
case K:
if ('k' == message) // "hack" found
{
LATEbits.LATE2 = 1; // success LED
putsUSART(hackADay); // easter egg message
}
state = H;
break;
 
default:
break;
}
LATD = message; // echo message to PORTD
flagNewMsg = 0; // clear control flags
flag10ms = 0;
}
 
}
}
 
 
void configTMR0(void)
{
T0CONbits.TMR0ON = 0; // TMR0 OFF
T0CONbits.T0PS = 0x7; // 1:256 Prescaler
T0CONbits.PSA = 0; // TMR0 prescaler is assigned. Timer0 clock input comes from prescaler output.
T0CONbits.T0CS = 0; // Internal instruction cycle clock (CLKO)
T0CONbits.T08BIT = 0; // TMR0 is configured as a 16-bit timer/counter
INTCONbits.T0IE = 1; // TMR0 interrupt enabled
 
TMR0 = 65067; // ~ 10 ms interrupt;
 
T0CONbits.TMR0ON = 1; // TMR0 ON
}
 
void configUSART()
{
uint16_t UART1Config = USART_TX_INT_OFF &
USART_RX_INT_ON &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_BRGH_HIGH ;
 
OpenUSART(UART1Config, _SPBRG);
}
 
void interrupt ISR(void)
{
/* Data recieved */
if(PIR1bits.RCIF)
{
message = ReadUSART(); // read 1 byte
flagNewMsg = 1; // new message has arrived
PIR1bits.RCIF = 0;
}
 
/* 10ms interrupt */
if(INTCONbits.T0IF) {
flag10ms = 1; // 10ms have passed
TMR0 = 65067; // Reset timer 0
INTCONbits.T0IF = 0;
}
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.