smartLED (ws2812b) | PIC16F887 @ 19660800Hz | XC8 compiler

  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
#include<xc.h>
#define _XTAL_FREQ 19660800
// CONFIG1
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = ON       // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown Out Reset Selection bits (BOR enabled)
#pragma config IESO = ON        // Internal External Switchover bit (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)
#pragma config LVP = OFF        // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)

// CONFIG2
#pragma config BOR4V = BOR21V   // Brown-out Reset Selection bit (Brown-out Reset set to 2.1V)
#pragma config WRT = OFF        // Flash Program Memory Self Write Enable bits (Write protection off)

#define NUMLEDS 20               //Number of LED's in series

unsigned char ledByte[NUMLEDS*3];		//Single array, 3 bytes per LED
unsigned char index = 0;

void setLED(unsigned char led, unsigned char R, unsigned char G, unsigned char B);
void writeLED(void);
void AllOff(void)

void main (){
	TRISC = 0x00;			//Set PORTC output
	PORTC = 0x00;			//PORTC low
	TRISD = 0x00;			//PORTC output
	PORTD = 0x00;			//PORTD low
	ANSEL = 0x00;			//Analog input disabled	
	ANSELH = 0x00;			//Analog input disabled
	AllOff();
        __delay_us(1);
    
	while(1){
        for(unsigned char i = 0; i<255; i++)
        {    
        setLED(0,i,0,0);   //first led red=i
        writeLED();        //write leds
        __delay_ms(10);
        }
        for(unsigned char i = 0; i<255; i++)
        {    
        setLED(1,0,i,0);   //second led green=i
        writeLED();        //write leds
        __delay_ms(10);
        }
        for(unsigned char i = 0; i<255; i++)
        {    
        setLED(2,0,0,i);   //thirth led blue=i
        writeLED();        //write leds
        __delay_ms(10);
        }
        for(unsigned char i = 0; i<255; i++)
        {    
        setLED(3,i,i,i);   //fourth led all=i
        writeLED();        //write leds
        __delay_ms(10);
        }
        AllOff();
        __delay_ms(1000);  //all of for 1 second         
}

void setLED(unsigned char led, unsigned char R, unsigned char G, unsigned char B) {
	//1 gezamelijke array met 3 indexen per led
	//led0 wordt dan ledByte[0]=G,ledByte[1]=R,ledByte[2]=B
	//led1 1*3 = 3, ledByte[3]=G,.....
	index = led * 3;
	ledByte[index] = G;
	ledByte[index+1] = R;
	ledByte[index+2] = B;
}

void AllOff(void){
       for(unsigned int a = 0; a<NUMLEDS;a++){
       setLED(a,0,0,0); 
       }
       writeLED();
}

/*BSF: set bit in register*/
/*BCF: clear bit in register*/
/*PORTC is register 07h*/
void writeLED(void) {
	GIE = 0;                             //Time sensitive code
	unsigned char Temp = 0;
	for(unsigned int i = 0; i<NUMLEDS*3; i++){ 	//Loop all the bytes
                Temp = 0x00;
		Temp = ledByte[i];					//Place current byte to temporary
		for(unsigned char j = 0; j<8; j++){	//Loop all the bits
			if(Temp&0x80)				 //if msb is 1
			{
                        asm("BSF 07h, 0");       //Set RC0 (1cycle)
                        asm("NOP");              //Wait 1cycle
                        asm("NOP");              //Wait 1cycle
                        asm("NOP");              //Wait 1cycle
                        asm("BCF 07h, 0");       //Reset RC0 (1cycle)
			}
			else
			{
                        asm("BSF 07h, 0");        //Set RC0 (1cycle)
                        asm("NOP");               //Wait 1cycle
                        asm("BCF 07h, 0");        //Reset RC0 (1cycle)
			}
		Temp = Temp << 1;			  //Shift left
		}
	}
	__delay_us(50);
	GIE = 1;
}

MP3 module (DFPlayer mini) | PIC16F887 @ 19660800Hz | HITECH-C compiler

  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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#include <stdio.h>
#include <stdlib.h>
#include <htc.h>
#include "HITECH_LCD.h"
#define _XTAL_FREQ 19660800

__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_OFF & MCLRE_ON & CP_OFF & CPD_OFF & BOREN_ON & IESO_ON & FCMEN_ON & LVP_OFF);
__CONFIG(BOR4V_BOR21V & WRT_OFF);

#define START_BYTE 0x7E
#define VERSION 0xFF
#define DATA_LEN 0x06
#define END_BYTE 0xEF

void sendCMD(unsigned char CMD, int VAL, char FEEDBACK);
void setVOL(unsigned char VOL);
void playNUM(unsigned char NUM);
void playSTOP(void);
void waitForStop(void);
void startUP(void);
void teamSelect(void);
void startGame(void);
void fire(void);
void reload(void);
void error(void);

unsigned char ADs = 0;
unsigned char Ammo = 0;

void main(void){
    /* UART settings */
    SPBRGH = 511 >> 8;      // Baudrate high register -> 8 MSB of SPBRG -> 0x00
    SPBRG = 511 & 0xFF;     // Baudrate low register  -> 8 LSB of SPBRG -> 0x7F
    TRISC6 = 0;             // RC6 is TX -> output
    TRISC7 = 1;             // RC7 is RX -> input
    BAUDCTL = 0x08;         // Non inverted TX data, 16bit baud gen
    RCSTA = 0x90;           // Enable serial, enable receiver
    TXSTA = 0x24;           // Send 8bits, enable transmitter, high speed, asynchronous mode
    /* PORT settings */
    TRISD = 0x00;           // PORTD output
    PORTD = 0x00;           // PORTD low
    TRISA = 0x00;           // PORTA output
    PORTA = 0x00;           // PORTA low
    TRISB = 0x0F;           // RB0-RB3 input
    PORTB = 0x00;           // PORTB low
    TRISC0 = 0;
    /* LCD init */
    ANSEL=0x00;             // No analog function
    ANSELH = 0x00;          // No analog function
    LCD_Start();            // Start the LCD
    LCD_Clear();            // Clear the LCD

    startUP();              // Welkom screen and sound
    //PORTD = 0xFF;           // All LED's on
    teamSelect();           // Team select screen
    startGame();            // Start game screen

    LCD_Clear();            // Clear the LCD
    LCD_Cursor(0,0);
    LCD_PrintString("S5 to FIRE");//Write on lcd
    LCD_ClearLine(1);       // Clear line 1
    Ammo = 20;              // Reset ammo
    LCD_Cursor(0,1);
    LCD_PrintString("Ammo: ");//Print ammo
    LCD_PrintNumber(Ammo);

    while(1){
        if(RB1){            // when RB1 is high
            if(Ammo != 0){  // Is ammo available
                fire();     // Flash leds and play sound
                Ammo--;     // Decrese ammo
                LCD_ClearLine(1);//Clear line 1
                LCD_Cursor(0,1);
                LCD_PrintString("Ammo: ");//print ammo
                LCD_PrintNumber(Ammo);
                __delay_ms(120);//debounce
            }
            else{           //Ammo is empty
                error();    //Error sound
            }
        }
        else if(RB0){       // when RB0 is high
            Ammo = 20;      // Reset ammo
            reload();       // PLay reload sound
            LCD_ClearLine(1);  //Clear line 1
            LCD_Cursor(0,1);
            LCD_PrintString("Ammo: ");//print ammp
            LCD_PrintNumber(Ammo);
        }
     }
}

void sendCMD(unsigned char CMD, int VAL, char FEEDBACK){
    //Checksum formula: -(VERSION+LEN+CMD+FEEDBACK+VALH+VALL)
    int checksum = -(VERSION + DATA_LEN + CMD + FEEDBACK + (VAL >>8) + (VAL & 0xFF));
    //10 bytes to send, found in datasheet
    unsigned char data[10]={START_BYTE,VERSION,DATA_LEN,0,0,0,0,0,0,END_BYTE};
    data[3]=CMD;
    data[4]=FEEDBACK;
    data[5]=VAL >> 8;
    data[6]=VAL & 0xFF;
    data[7]=checksum >> 8;
    data[8]=checksum & 0xFF;
    //send all 10 bytes
    for(char i = 0; i<10; i++){
        while(!TXIF)continue;//Wait for previous data to be send
        TXREG = data[i];     //Write byte to UART
    }
}

void setVOL(unsigned char VOL){
    sendCMD(0x06,VOL,0);    //set volume, no feedback
}

void playNUM(unsigned char NUM){
    sendCMD(0x03,NUM,0);    //Play requested number
}

void playSTOP(void){
    sendCMD(0x16,0,0);      //Stop playing
    __delay_ms(200);
}

void startUP(void){
    LCD_Clear();            //Clear the LCD
    LCD_Cursor(0,0);
    LCD_PrintString("Laser TAG");//Print on LCD
    setVOL(20); //set volume to 20, max 30
    playNUM(1); //play number 1
    waitForStop(); //wait for module to send feedback
    
}

void waitForStop(void){
    while(!RCIF)continue; //Wait for data
    unsigned char dataIn[10];
    dataIn[3]=0;
    while(dataIn[3] != 0x3D){
        for(char i = 0; i<10; i++){
        while(!RCIF)continue;//wait for data
        dataIn[i]=RCREG;  //Read data
        }
    }
}

void teamSelect(void){
    LCD_Clear();    //Clear LCD
    LCD_Cursor(0,0);
    LCD_PrintString("Kies team");//Print on LCD
    LCD_Cursor(0,1);
    LCD_PrintString("<= team1    team2 =>");
    while(!(RB1 || RB2))continue;//While not selected team
    if(RB1){    //if RB1 was high
        setVOL(27);//Set volume 27
        playNUM(2);//Play number 2
    }
    else{       //else RB2
        setVOL(27);//Set volume 27
        playNUM(3);//Play number 2
    }
    waitForStop();//Wait for stop
}

void startGame(void){
    LCD_Clear();//Clear LCD
    LCD_Cursor(0,0);
    LCD_PrintString("ready");//Print on LCD
    LCD_Cursor(0,1);
    LCD_PrintString("S1 to start game");
    while(!RB0)continue;//While RB0 is not high
    setVOL(27);//Set volume 27
    playNUM(4);//Play number 4
    waitForStop();//Wait for stop
}

void fire(void){
    setVOL(27); //Set volume 27
    playNUM(5); //Play number 5
    PORTD = 0x00;//All leds off
    __delay_ms(5);
    PORTD = 0xFF;//All leds on
    __delay_ms(5);
    waitForStop();//Wait for stop
    
}

void reload(void){
    setVOL(27); //Set volume 27
    playNUM(6); //PLay number 6
    waitForStop();//Wait for stop
}

void error(void){
    setVOL(27); //Set volume 27
    playNUM(7); //Play number 7
    waitForStop();//Wait for stop
}