Using PIC 16f819 and an LCD screen, code a game of tetris in C language that will use the PIC and four buttons to play tetris on the LCD.
The game should use the clock/timer fuction of the PIC- such as to time the length of each game and the eeprom function- to record th eplyaers high scores, as well as three levels of difficulty/speeds.
You are given the code to set up the LCD and the eeprom code.
DM3330 CLASS ASSIGNMENT
Using PIC 16f819 and an LCD screen, code a game of tetris in C language that will use the PIC and four buttons to play tetris on the LCD.
The game should use the clock/timer fuction of the PIC- such as to time the length of each game and the eeprom function- to record th eplyaers high scores, as well as three levels of difficulty/speeds.
You are given the code to set up the LCD and the eeprom code.
Nokia LCD Code (Can be attached as a text file)
//Nokia 5110 display example using basic font driver
//Separate large font driver can be included - experimental
//No graphic routines included (so far)
//Dr A Vilches
#include //Include 16F819 header file
#device PASS_STRINGS = IN_RAM //Allows pointers to ROM strings
#fuses INTRC_IO,NOWDT,NOPROTECT,MCLR,NOBROWNOUT
#use delay(clock=8000000)
#include "5110.c" //Non SPI driver
//#include "5110LargeFont.c" //Add if 10x15 large fonts wanted
void main(){
delay_ms(100);
nokia_init(); //Initialise module
// nokia_clear_screen(); //Clear screen
// nokia_printchar10x15('0'); //Print a large number
// nokia_printchar_inv('A'); //Print character in inverse mode
// nokia_gotoxy(0,1); //Move to screen position
prints("Hi everyone!"); //x = 0-83 and y = 0-5
prints("\nthis is some");
prints("\nsmall text!!"); //Print a string
prints("\n "); //preceed with \r to move to start of line
prints("\nTest OK"); //preceed with \n to move to next line down
while(1);
}
Test eeprom code
/*
24512 EEPROM Test code
Writes 0 to 255 to the first 256 memory locations
And then reads it back to the PC via RS232
Must define RS232 pins in main code:
#use rs232(baud=9600,xmit=PIN_B5,rcv=PIN_B2)
Must define I2C pins below
Must include this file before main
Run using TestEeprom();
*/
#define EEPROM_SDA PIN_A0
#define EEPROM_SCL PIN_A1
#include
void TestEeprom(){
int c=0;
printf("\nInitialising Eeprom.");
init_ext_eeprom();
printf("..Ok\n");
while(c
write_ext_eeprom(c, c);
printf("%c:%X ", c, read_ext_eeprom(c));
c++;
}
}
Include File (Available as a separate text file)
/*Graphic LCD Nokia 5110 (LPH7779) routines v1 - NON SPI
Pin define:
1. RST - Reset
2. CE - Chip Select *
3. DC - data/instruction selection *
4. DIN - serial data line *
5. CLK - Serial Clock Line *
6. VCC - power input (3.3v or 5v)
7. BL - backlight control
8. GND - Ground
*/
#define nok_sda PIN_B2
#define nok_sclk PIN_B4
#define nok_dc PIN_A1
#define nok_cs PIN_B3
#define nok_res PIN_B0
#define high_nok_dc output_high(nok_dc)
#define high_nok_cs output_high(nok_cs)
#define high_nok_res output_high(nok_res)
#define high_nok_sda output_high(nok_sda);
#define high_nok_sclk output_high(nok_sclk);
#define low_nok_dc output_low(nok_dc)
#define low_nok_cs output_low(nok_cs)
#define low_nok_res output_low(nok_res)
#define low_nok_sda output_low(nok_sda);
#define low_nok_sclk output_low(nok_sclk);
#define NULL '\0'
#define LCD_X_RES 84
#define LCD_Y_RES 48
#define LCD_CACHE_SIZE ((LCD_X_RES * LCD_Y_RES) / 8 )
char line=0; //Max 6 lines on display page
char char_col,charsel,charpos,chardata;
int16 ddram;
BYTE const Table5[240]=
{
0x00,0x00,0x00,0x00,0x00, // 20 space ASCII table for NOKIA LCD: 96 rows * 5 bytes= 480 bytes
0x00,0x00,0x5f,0x00,0x00, // 21 !
0x00,0x07,0x00,0x07,0x00, // 22 "
0x14,0x7f,0x14,0x7f,0x14, // 23 #
0x24,0x2a,0x7f,0x2a,0x12, // 24 $
0x23,0x13,0x08,0x64,0x62, // 25 %
0x36,0x49,0x55,0x22,0x50, // 26 &
0x00,0x05,0x03,0x00,0x00, // 27 '
0x00,0x1c,0x22,0x41,0x00, // 28 (
0x00,0x41,0x22,0x1c,0x00, // 29 )
0x14,0x08,0x3e,0x08,0x14, // 2a *
0x08,0x08,0x3e,0x08,0x08, // 2b +
0x00,0x50,0x30,0x00,0x00, // 2c ,
0x08,0x08,0x08,0x08,0x08, // 2d -
0x00,0x60,0x60,0x00,0x00, // 2e .
0x20,0x10,0x08,0x04,0x02, // 2f /
0x3e,0x51,0x49,0x45,0x3e, // 30 0
0x00,0x42,0x7f,0x40,0x00, // 31 1
0x42,0x61,0x51,0x49,0x46, // 32 2
0x21,0x41,0x45,0x4b,0x31, // 33 3
0x18,0x14,0x12,0x7f,0x10, // 34 4
0x27,0x45,0x45,0x45,0x39, // 35 5
0x3c,0x4a,0x49,0x49,0x30, // 36 6
0x01,0x71,0x09,0x05,0x03, // 37 7
0x36,0x49,0x49,0x49,0x36, // 38 8
0x06,0x49,0x49,0x29,0x1e, // 39 9
0x00,0x36,0x36,0x00,0x00, // 3a :
0x00,0x56,0x36,0x00,0x00, // 3b ;
0x08,0x14,0x22,0x41,0x00, // 3c
0x14,0x14,0x14,0x14,0x14, // 3d =
0x00,0x41,0x22,0x14,0x08, // 3e >
0x02,0x01,0x51,0x09,0x06, // 3f ?
0x32,0x49,0x79,0x41,0x3e, // 40 @
0x7e,0x11,0x11,0x11,0x7e, // 41 A
0x7f,0x49,0x49,0x49,0x36, // 42 B
0x3e,0x41,0x41,0x41,0x22, // 43 C
0x7f,0x41,0x41,0x22,0x1c, // 44 D
0x7f,0x49,0x49,0x49,0x41, // 45 E
0x7f,0x09,0x09,0x09,0x01, // 46 F
0x3e,0x41,0x49,0x49,0x7a, // 47 G
0x7f,0x08,0x08,0x08,0x7f, // 48 H
0x00,0x41,0x7f,0x41,0x00, // 49 I
0x20,0x40,0x41,0x3f,0x01, // 4a J
0x7f,0x08,0x14,0x22,0x41, // 4b K
0x7f,0x40,0x40,0x40,0x40, // 4c L
0x7f,0x02,0x0c,0x02,0x7f, // 4d M
0x7f,0x04,0x08,0x10,0x7f, // 4e N
0x3e,0x41,0x41,0x41,0x3e // 4f O
};
BYTE const TABLE6[240]= {
0x7f,0x09,0x09,0x09,0x06, // 50 P
0x3e,0x41,0x51,0x21,0x5e, // 51 Q
0x7f,0x09,0x19,0x29,0x46, // 52 R
0x46,0x49,0x49,0x49,0x31, // 53 S
0x01,0x01,0x7f,0x01,0x01, // 54 T
0x3f,0x40,0x40,0x40,0x3f, // 55 U
0x1f,0x20,0x40,0x20,0x1f, // 56 V
0x3f,0x40,0x38,0x40,0x3f, // 57 W
0x63,0x14,0x08,0x14,0x63, // 58 X
0x07,0x08,0x70,0x08,0x07, // 59 Y
0x61,0x51,0x49,0x45,0x43, // 5a Z
0x00,0x7f,0x41,0x41,0x00, // 5b [
0x02,0x04,0x08,0x10,0x20, // 5c
0x00,0x41,0x41,0x7f,0x00, // 5d
0x04,0x02,0x01,0x02,0x04, // 5e
0x40,0x40,0x40,0x40,0x40, // 5f
0x00,0x01,0x02,0x04,0x00, // 60
0x20,0x54,0x54,0x54,0x78, // 61 a
0x7f,0x48,0x44,0x44,0x38, // 62 b
0x38,0x44,0x44,0x44,0x20, // 63 c
0x38,0x44,0x44,0x48,0x7f, // 64 d
0x38,0x54,0x54,0x54,0x18, // 65 e
0x08,0x7e,0x09,0x01,0x02, // 66 f
0x0c,0x52,0x52,0x52,0x3e, // 67 g
0x7f,0x08,0x04,0x04,0x78, // 68 h
0x00,0x44,0x7d,0x40,0x00, // 69 i
0x20,0x40,0x44,0x3d,0x00, // 6a j
0x7f,0x10,0x28,0x44,0x00, // 6b k
0x00,0x41,0x7f,0x40,0x00, // 6c l
0x7c,0x04,0x18,0x04,0x78, // 6d m
0x7c,0x08,0x04,0x04,0x78, // 6e n
0x38,0x44,0x44,0x44,0x38, // 6f o
0x7c,0x14,0x14,0x14,0x08, // 70 p
0x08,0x14,0x14,0x18,0x7c, // 71 q
0x7c,0x08,0x04,0x04,0x08, // 72 r
0x48,0x54,0x54,0x54,0x20, // 73 s
0x04,0x3f,0x44,0x40,0x20, // 74 t
0x3c,0x40,0x40,0x20,0x7c, // 75 u
0x1c,0x20,0x40,0x20,0x1c, // 76 v
0x3c,0x40,0x30,0x40,0x3c, // 77 w
0x44,0x28,0x10,0x28,0x44, // 78 x
0x0c,0x50,0x50,0x50,0x3c, // 79 y
0x44,0x64,0x54,0x4c,0x44, // 7a z
0x00,0x08,0x36,0x41,0x00, // 7b
0x00,0x00,0x7f,0x00,0x00, // 7c
0x00,0x41,0x36,0x08,0x00, // 7d
0x10,0x08,0x08,0x10,0x08, // 7e
0x78,0x46,0x41,0x46,0x78 // 7f
};
/*-----------------------------------------------------------------------------*/
void nokia_write_data_inv(char bytefornokia_data_inv)
{
char caa;
high_nok_dc;
low_nok_cs; // chip enabled
bytefornokia_data_inv =~ bytefornokia_data_inv;
for (caa=8;caa>0;caa--)
{
low_nok_sclk;
if ((bytefornokia_data_inv & 0x80)==0)
{
low_nok_sda;
}
else
high_nok_sda;
high_nok_sclk;
bytefornokia_data_inv = bytefornokia_data_inv
}
}
/*-----------------------------------------------------------------------------*/
void nokia_write_dorc(char bytefornokia) // serial write data or command subroutine
{
char caa;
for (caa=8;caa>0;caa--)
{
low_nok_sclk;
if ((bytefornokia & 0x80)==0)
{
low_nok_sda;
}
else
high_nok_sda;
high_nok_sclk;
bytefornokia=bytefornokia
}
}
/*-----------------------------------------------------------------------------*/
void nokia_write_command(char bytefornokia_command)
{
low_nok_dc;
low_nok_cs;
nokia_write_dorc(bytefornokia_command);
high_nok_cs; // chip disabled
}
/*-----------------------------------------------------------------------------*/
void nokia_gotoxy(int8 xnokia, int8 ynokia) // Nokia LCD 3310 Position cursor
// where x = 0-83 and y = 0-5
{
nokia_write_command(0x40|(ynokia & 0x07)); // Y axe initialisation: 0100 0yyy
nokia_write_command(0x80|(xnokia & 0x7f)); // X axe initialisation: 1xxx xxxx
}
/*-----------------------------------------------------------------------------*/
void nokia_write_data(char bytefornokia_data)
{
high_nok_dc;
low_nok_cs; // chip enabled
nokia_write_dorc(bytefornokia_data);
high_nok_cs; // chip disabled
}
/*-----------------------------------------------------------------------------*/
void nokia_clean_ddram(void)
{
nokia_gotoxy(0,0); // 84*6=504 clear LCD
for (ddram=504;ddram>0;ddram--)
nokia_write_data(0x00);
}
/*-----------------------------------------------------------------------------*/
void table_to_nokialcd(int1 mode) // extract ascii from tables & write to LCD
{
if (charsel
if (charsel>0x7f)return;
for (char_col=0;char_col
{
if (charsel
{
charpos=(((charsel&0xff)-0x20)*5);
chardata=TABLE5[(charpos+char_col)];
} // use TABLE5
else
if (charsel>0x4f)
{
charpos=(((charsel&0xff)-0x50)*5);
chardata=TABLE6[(charpos+char_col)];
} // use TABLE6
if (!mode)
{
nokia_write_data(chardata); // send data to nokia
// 1 byte (always blank)
}
else
{
nokia_write_data_inv(chardata); // send data to nokia
}
}
if (!mode)
nokia_write_data(0x00);
else
nokia_write_data(0xff);
}
/*-----------------------------------------------------------------------------*/
void nokia_printchar(int8 cvar) // Write 1 character to LCD
{
charsel=cvar;
table_to_nokialcd(0);
}
/*-----------------------------------------------------------------------------*/
void nokia_printchar_inv(int8 cvar) // Write 1 character to LCD
{
charsel=cvar;
table_to_nokialcd(1);
}
/*-----------------------------------------------------------------------------*/
void nokia_erase_y(int8 ynokia)
{
nokia_gotoxy(0,ynokia);
printf(nokia_printchar," ");
}
/*-----------------------------------------------------------------------------*/
void nokia_erase_x(int8 xnokia)
{
char column;
for (column=0;column!=6;column++)
{
nokia_gotoxy(xnokia,column);
nokia_write_data(0x00);
nokia_write_data(0x00);
nokia_write_data(0x00);
nokia_write_data(0x00);
nokia_write_data(0x00);
nokia_write_data(0x00);
}
}
/*-----------------------------------------------------------------------------*/
void nokia_clear_screen(void)
{
nokia_erase_y(0);
nokia_erase_y(1);
nokia_erase_y(2);
nokia_erase_y(3);
nokia_erase_y(4);
nokia_erase_y(5);
}
/*-----------------------------------------------------------------------------*/
void nokia_clear_xy(int8 xnokia, int8 ynokia)
{
nokia_gotoxy(xnokia,ynokia);
nokia_printchar(" ");
}
/*-----------------------------------------------------------------------------*/
void nokia_init(void)
{
delay_us(200);
high_nok_dc;
high_nok_cs;
delay_us(200);
low_nok_res;
delay_ms (10);
high_nok_res;
nokia_write_command(0x21); // set extins extended instruction set
nokia_write_command(0xC2); // Vop v1: 0xc8 (for 3V)// v2: 0xa0 (for 3V) // v3: 0xc2 (2v6-5v) ********************************************************************************************************************
nokia_write_command(0x80 + 60); //Set Screen Contrast, from 60 to 127
nokia_write_command(0x13); // bias
nokia_write_command(0x20); // horizontal mode from left to right, X axe are incremented automatically,
// 0x22 for vertical addressing ,back on normal instruction set too
nokia_write_command(0x09); // all on
delay_ms(50);
nokia_clean_ddram(); // clear DDRAM, otherwise the lcd is blurred with random pixels
delay_ms(10);
nokia_write_command(0x08); // mod control blank change (all off)
delay_ms(10);
nokia_write_command(0x0c); // mod control normal change
}
void prints(char *s){ //Accepts strings like printf() does
while(*s!=NULL) {
if(*s=='\n') { //Preceed with \n to move to new line
nokia_gotoxy(0,line+1);
line++;
s++;
}
if(*s=='\r') { //Preceed with \r to move to start of current line
nokia_gotoxy(0,line);
line++;
s++;
}
nokia_printchar(*s);
s++;
}
}