Pastebin launched a little side project called HostCabi.net, check it out ;-)Don't like ads? PRO users don't see any ads ;-)
Guest

Mine Dodger (8051)

By: a guest on Oct 27th, 2010  |  syntax: C  |  size: 8.90 KB  |  hits: 30  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. /* Made by Ben Duncan (C) */
  2.  
  3. // Included header files
  4.  
  5. #include <8051.h>
  6. #include <string.h>
  7. #include <stdio.h>      /* for printf, printf_fast, etc */
  8.  
  9. // Subroutine decleration
  10.  
  11. extern void delay_ms(unsigned char ms);
  12. extern void restart(void);
  13. extern char key_char(void);
  14. extern void lcd_putchar(char c);
  15. extern void lcd_command(unsigned char cmd);
  16. extern void lcd_set_xy_raw(unsigned int x_and_y);
  17. extern char a2d(void);
  18. void delay(int s);                      // Integer seconds only delay
  19. void display_rules(void);
  20. void display_countdown(char count);     // Displays a countdown from 'count' to 0
  21. void generate_player(void);
  22. void generate_enemies(void);
  23.  
  24. // Memory map locations for TAD board
  25.  
  26. #define DIL_SWITCH 0x0000               // DIL Switch at address 0000h 
  27. #define DAC 0x0600                      // DAC at address 0600h
  28. #define LCD_COMMAND_WR 0x0800           // Write LCD Command at address 0800h
  29. #define LCD_STATUS_RD 0x0801            // Read LCD Status at address 0801h
  30. #define LCD_DATA_WR 0x0802              // Write LCD Data at address 0802h
  31. #define LCD_DATA_RD 0x0803              // Read LCD Data at address 0803h
  32. #define COMPARATOR P3_5                 // Comparator is set to bit P3.5
  33.  
  34. // External data locations
  35.  
  36. volatile xdata at DAC unsigned char dac;
  37. volatile xdata at LCD_COMMAND_WR unsigned char lcd_command_wr;
  38. volatile xdata at LCD_STATUS_RD unsigned char lcd_status_rd;
  39. volatile xdata at LCD_DATA_WR unsigned char lcd_data_wr;
  40. volatile xdata at LCD_DATA_RD unsigned char lcd_data_rd;
  41.  
  42. // LCD commands
  43.  
  44. #define LCD_CLEAR_CMD 0x01
  45. #define LCD_HOME_CMD 0x02
  46. #define LCD_ON_CMD 0x0C
  47. #define LCD_SHIFT_CMD 0x10
  48. #define LCD_CONFIG_CMD 0x38
  49.  
  50. // Macro to merge two parameters into a single 16-bit parameter
  51.  
  52. #define lcd_set_xy(x, y) (lcd_set_xy_raw((x) + ((y) << 8)))
  53.  
  54. // LCD screen parameters
  55.  
  56. #define LCD_HORIZ_SIZE  16
  57. #define LCD_VERT_SIZE   2
  58. #define LCD_BYTES_PER_LINE  (128 / LCD_VERT_SIZE)
  59.  
  60. // Send serial data to LCD or Serial Port
  61.  
  62. bit print_to_lcd=0;
  63.  
  64. // Interrupt declaration
  65.  
  66. void ex0_isr(void) interrupt 0;
  67. void ex1_isr(void) interrupt 2;
  68.  
  69. // Set the side of the 'track' the player is on
  70.  
  71. bit player_side = 0;                                            // Defaults to the right side '0'
  72.  
  73. // Soft-enable/disables interrupts
  74.  
  75. bit enable_interrupts;
  76.  
  77. /* Player and characters */
  78.  
  79. #define PLAYER "X"
  80. #define MINE "*"
  81. #define PLAYER_X 16                                             // Sets player to right of screen
  82. #define ENEMY_SPACES 12                                         // # spaces enemies can exist in
  83. #define ENEMY_START 0                                           // Start position of enemies
  84. #define ENEMY_END_ 11                                           // End position of enemies
  85. #define NUM_ENEMY_STR 1                                         // Number of enemy strings
  86.  
  87. /* Enemy sprites */
  88.  
  89. char enemy_track1[20] = {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0};      // Sprites of enemies on track 1
  90. char enemy_track2[20] = {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0};      // Sprites of enemies on track 2
  91.  
  92. /* Keyboard character codes */
  93.  
  94. #define BS_KEY 8
  95. #define ESC_KEY 27
  96. #define SPACE_KEY 32
  97. #define DEL_KEY 127
  98.  
  99. /* Main code section */
  100.  
  101. void main(){
  102.         /* Initialise devices */
  103.         enable_interrupts = 0;                                  // Disallow interrupt functions to change 'player_side' state
  104.         EA=1;                                                   // Configure interrupt 0 for falling edge on /INT0 (P3.2)
  105.         EX0 = 1;                                                // Enable EX0 Interrupt
  106.         EX1 = 1;                                                // Enable EX1 Interrupt
  107.         lcd_command(LCD_HOME_CMD);                              // Initialise LCD
  108.         lcd_command(LCD_CLEAR_CMD);                             // Clear LCD screen
  109.         print_to_lcd=1;                                         // Select LCD
  110.         lcd_set_xy(0,0);                                        // Select LCD character
  111.         printf_fast("- Mine Dodger! -");                        // Display first line of LCD
  112.         lcd_set_xy(0,1);                                        // Select LCD character
  113.         printf_fast(" By Ben Duncan  ");                        // Display second line of LCD
  114.         delay(3);                                               // Wait for 3 seconds
  115.         lcd_command(LCD_CLEAR_CMD);                             // Clear LCD screen
  116.        
  117.         /* Main control loop that exits when 'esc' is pressed on the keyboard */
  118.        
  119.         do{
  120.                 enable_interrupts = 1;                          // Allow interrupt functions to change 'player_side' state
  121.                 generate_player();                              // Print player to screen
  122.                 generate_enemies();                             // Display enemies on LCD screen
  123.         } while(key_char() != ESC_KEY);                         // When 'esc' is pressed escape loop
  124. }
  125.  
  126. /* Subroutines for Display */
  127.  
  128. void generate_enemies(void){
  129.         int j,i;
  130.         for(i=0; i<ENEMY_SPACES; i++){
  131.                 for(j=0; j<ENEMY_SPACES; j++){
  132.                         lcd_set_xy(i, 0);                       // Set position of line 1 of enemies
  133.                         printf_fast(enemy_track1[j]);
  134.                         lcd_set_xy(i, 1);                       // Set position of line 2 of enemies
  135.                         printf_fast(enemy_track2[j]);
  136.                 }
  137.                 speed_delay(1);                                 // Delay for enemy speed
  138.                 i++                                             // Move enemies up one place on the screen
  139.                 if(i=>ENEMY_SPACES){                            // If the next enemy moves past the end position
  140.                         i=0;                                    // Start at 0 again
  141.                 }
  142.         }
  143. }
  144.  
  145. void generate_player(void){
  146.         lcd_set_xy(PLAYER_X, player_side);                      // Place player on right of screen on 'player_side'
  147.         printf_fast(PLAYER);                                    // Print player (X)
  148.         delay_ms(10);                                           // Wait for LCD to refresh
  149. }
  150.  
  151. void display_countdown(char count){                             // Passes value of countdown
  152.         int n;                                                  // Counting variable
  153.         lcd_command(LCD_CLEAR_CMD);                             // Clear LCD screen
  154.         for(n=count; n>0; n--){                                 // Count 5-0
  155.                 lcd_set_xy(0,0);                                // Select LCD character
  156.                 printf_fast("Start in: %d     ", n);            // Display first line of LCD
  157.                 delay(1);                                       // Wait for 1 second
  158.         }
  159. }
  160.  
  161. void display_rules(void){
  162.         lcd_command(LCD_CLEAR_CMD);                             // Clear LCD screen
  163.         lcd_set_xy(0,0);                                        // Select LCD character
  164.         printf_fast("* are the mines ");                        // Display first line of LCD
  165.         lcd_set_xy(0,1);                                        // Select LCD character
  166.         printf_fast(" & are dangerous");                        // Display second line of LCD
  167.         delay(5);                                               // Wait for 5 seconds
  168.         lcd_set_xy(0,0);                                        // Select LCD character
  169.         printf_fast("X is the vehicle");                        // Display first line of LCD
  170.         lcd_set_xy(0,1);                                        // Select LCD character
  171.         printf_fast("Avoid the mines!");                        // Display second line of LCD
  172.         delay(5);                                               // Wait for 5 seconds
  173. }
  174.  
  175. /* Subroutines for Interrupts */
  176.  
  177. void ex0_isr(void)  interrupt 0{                                // 'Left' button
  178.         if(enable_interrupts==1){                               // If enabled
  179.                 if(player_side==1){                             // If player on right
  180.                         player_side = 0;                        // Set player to left side
  181.                         lcd_set_xy(PLAYER_X,player_side);       // Select location of player
  182.                         printf_fast(PLAYER);                    // Display player on screen
  183.                 }
  184.         }
  185. }
  186.  
  187. void ex1_isr(void)  interrupt 2{                                // 'Right' button
  188.         if(enable_interrupts==1){                               // If enabled
  189.                 if(player_side==0){                             // If player on left
  190.                         player_side = 1;                        // Set player to right side
  191.                         lcd_set_xy(PLAYER_X,player_side);       // Select location of player
  192.                         printf_fast(PLAYER);                    // Display player on screen
  193.                 }
  194.         }
  195. }
  196.  
  197. /* Subroutines to control and communicate with the LCD */
  198.  
  199. void putchar(char c)                                            // Write character to lcd or serial port
  200. {
  201.         if (print_to_lcd)                                       // If print_to_lcd is set then write to lcd
  202.         {
  203.                 lcd_putchar(c);
  204.         }
  205.         else                                                    // Else write to the serial port
  206.         {
  207.         while(!TI);  /* Wait for ready */
  208.         TI=0;
  209.         SBUF = c;
  210.         }
  211. }
  212.  
  213. char getchar(void)                                              // Get character from serial port
  214. {
  215.         char c;
  216.         while(!RI);
  217.         RI =0;
  218.         c = SBUF;
  219.         return c;
  220. }
  221.  
  222. void restart(void)                                              // Soft reset, jumps to address 0000h
  223. {
  224.         _asm
  225.         ljmp    0
  226.         _endasm;
  227. }
  228.  
  229. char key_char(void)
  230. {
  231.         char c;
  232.         if (RI)
  233.         {
  234.                 RI = 0;
  235.                 c = SBUF;
  236.         }
  237.         return c;
  238. }
  239.  
  240. char a2d(void)
  241. {
  242.  
  243.         unsigned char val=0;
  244.        
  245.         dac = 0;
  246.         delay_ms(1);
  247.         while (COMPARATOR == 1)
  248.         {
  249.                 val = val + 1;
  250.                 dac = val;             
  251.                 delay_ms(1);                                    // Allow time for DAC to settle
  252.         }
  253.         return (val);
  254. }
  255.  
  256.  
  257. /* This is a simple delay based on a busy loop */
  258. /* with an 11.0592 MHz crystal, the delay lasts */
  259. /* for approximately 1 ms times the number passed */
  260. /* Of course, it will take longer if there are */
  261. /* interrupts occuring... */
  262.  
  263. void delay_ms(unsigned char ms)
  264. {
  265.         ms;
  266.         _asm
  267.                 mov     r0, dpl
  268. 00001$:         mov     r1, #250
  269. 00002$:         nop
  270.                 djnz    r1, 00002$
  271.                 djnz    r0, 00001$
  272.                 ret
  273.         _endasm;
  274. }
  275.  
  276. void delay(int s){                                              // Wait for 1 second
  277.         int i,j;
  278.         for(j=0; j<4; j++){
  279.                 for(i=0; i<s; i++){                             // Delays multiple times
  280.                         delay_ms(250);                          // Quater of a second
  281.                 }
  282.         }
  283. }
  284.  
  285. /* This C-only version is easier to read and understand, but it is
  286.  * not as fast and efficient as the assembly version below.  You
  287.  * should normally use the optimized assembly version, but read
  288.  * this one to understand the code.
  289.  */
  290.  
  291. volatile xdata at LCD_COMMAND_WR unsigned char lcd_command_wr;
  292. volatile xdata at LCD_STATUS_RD unsigned char lcd_status_rd;
  293. volatile xdata at LCD_DATA_WR unsigned char lcd_data_wr;
  294. volatile xdata at LCD_DATA_RD unsigned char lcd_data_rd;
  295.  
  296.  
  297. void lcd_busy(void)
  298. {
  299.         while (lcd_status_rd & 0x80)  ;
  300. }
  301.  
  302. void lcd_command(unsigned char cmd)
  303. {
  304.         lcd_busy();
  305.         lcd_command_wr = cmd;
  306. }
  307.  
  308. void lcd_putchar(char c)
  309. {
  310.         lcd_busy();
  311.         if (c=='\n') lcd_command_wr = LCD_CLEAR_CMD;
  312.         else lcd_data_wr = c;
  313. }
  314.  
  315. void lcd_set_xy_raw(unsigned int x_and_y)
  316. {
  317.         unsigned char x, y;
  318.         if ((x = x_and_y & 255) >= LCD_HORIZ_SIZE) x = LCD_HORIZ_SIZE - 1;
  319.         if ((y = x_and_y >> 8) >= LCD_VERT_SIZE) y = LCD_VERT_SIZE - 1;
  320.         lcd_busy();
  321.         lcd_command_wr = (y * LCD_BYTES_PER_LINE + x) | 0x80;
  322. }
  323.  
  324. // End