1 / 19

LCD Panel Geometry and Score Demo Topics

Explore LCD panel geometry, drawing characters, utilizing utilities, managing interrupt handlers, and updating scores in this comprehensive demo.

bethanys
Download Presentation

LCD Panel Geometry and Score Demo Topics

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Arch1 LCD Lab Eric Freudenthal

  2. Topics • Score Demo • LCD • Panel Geometry • Utilities to draw to the display • Drawing characters • Buttons • Nuisance: multiple versions • Interrupt handlers • Timer interrupt handler • To update score • Ball Demo • Drawing Ball • Motion • Paddle Demo • Buttons • Drawing paddle

  3. Minor(row % 8) Panel geometry Major(row / 8) Row # • Panel dimensions (lcd_backend.h) • Rows: • Top: 0 • Bottom: 68 (MAX_X) • Broken into 8 row “chunks” • major = row/8, minor=row%8 • Columns • Left: 0 • Right: 96 (MAX_X) 0 0 0 Bit 0 Bit 0 Bit 0 Bit 0 Bit 0 Bit 0 Bit 0 Bit 0 Bit 0 Bit 0 Bit 0 Bit 0 Bit 0 Bit 0 Bit 0 Bit 0 1 0 1 2 0 2 3 0 3 4 0 4 5 0 5 Bit 7 Bit 7 Bit 7 Bit 7 Bit 7 Bit 7 Bit 7 Bit 7 Bit 7 Bit 7 Bit 7 Bit 7 Bit 7 Bit 7 Bit 7 Bit 7 6 0 6 7 0 7 8 1 0 9 1 1 0 0x00 0x20 1 0x10 2 0x08 3 4 0x04 0x02 5 6 0x00 8 0x00 10 1 2 11 1 3 12 1 4 13 1 5 14 1 6 15 1 7

  4. lcd_char.c const char font5x7[][5] = { // basic 5x7 font indexed as [char][chunk#] {0x00, 0x00, 0x00, 0x00, 0x00} // 20 (space) ,{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

  5. lcd_utils.h #ifndeflcd_utils_included #define lcd_utils_included #include "booster1202.h" #include "lcd_backend.h" /* compute major & minor row numbers */ u_charlcd_getYMajor(u_char y); u_charlcd_getYMinor(u_char y); /* displays a chunk (byte of binary pixels) at the given address */ void lcd_setAddr(u_char x, u_charyMajor); /* set addr of next write */ void lcd_writeChunk(char chunk); /* write chunk and increment x */ /* set addr & write */ void lcd_writeChunkAddr(char chunk, u_charxPos, u_charyMajor); /* converts ints to character sequences */ char* itoa(int value, char* result, int base); #endif // lcd_utils_included

  6. lcd_char.c void _lcd_writeChar(char c); /* forward declaration */ void lcd_writeString(const char *string, u_char x, u_charyMajor) { lcd_setAddr(x,yMajor); while (*string) { _lcd_writeChar(*string++); lcd_writeChunk(0); /* whitespace after char */ } } // helper: writes 1 char at current column, advances column void _lcd_writeChar(char c) { char i; for (i = 0; i < 5; i++) { lcd_writeChunk(font5x7[c - 0x20][i]); } } void lcd_writeChar(char c, u_char x, u_charyMajor) { lcd_setAddr(x,yMajor); _lcd_writeChar(c); }

  7. paddle_buttons.h /* P2 bits for paddle buttons */ # define LeftSw BIT2 # define DownSw BIT3 # define UpSw BIT4 #if LCD1202_VERSION == 3 # define RightSw BIT1 #elif LCD1202_VERSION == 1 || LCD1202_VERSION == 2 || LCD1202_VERSION == 4 # define RightSw BIT5 #else # error +++++ # error +++++ LCD1202_VERSION not (properly) defined. See note in Makefile. # error +++++ #endif

  8. score_demomain() void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer lcdinit(); // init LCD (also: CPU clock to 16MHz) CCTL0 = CCIE; // CCR0 interrupt enabled TACTL = TASSEL_2 + MC_1 + ID_3; // Set timer clock to CPU clock/8 CCR0 = 50000; // Interrupt every 10 ms initializeSwitchInterrupts(); resetPaddle(); or_sr(0x18); // CPU off, GIE on }

  9. score_demo.cscores & timer interrupt Timer_0: push r15 push r14 push r13 push r12 mov &clockDivide, r15 mov r15, r14 add #1, r14 mov r14, &clockDivide cmp #21, r15 jl .L9 call #updateScore mov #0, &clockDivide .L9: pop r12 pop r13 pop r14 pop r15 reti void updateScore(void) { char numString[] = " "; score++; lcd_writeString(" ",72,0); itoa(score, numString, 10); lcd_writeString(numString,72,0); } void resetScore(void) { score = 0; } /* timer interrupt */ interrupt(TIMER0_A0_VECTOR) Timer_0(void) { static intclockDivide = 0; if (clockDivide++ > 20) { updateScore(); clockDivide = 0; } }

  10. paddle_buttons.h /* P2 bits for paddle buttons */ # define LeftSw BIT2 # define DownSw BIT3 # define UpSw BIT4 #if LCD1202_VERSION == 3 # define RightSw BIT1 #elif LCD1202_VERSION == 1 || LCD1202_VERSION == 2 || LCD1202_VERSION == 4 # define RightSw BIT5 #else # error +++++ # error +++++ LCD120_VERSION not (properly) defined. See note in Makefile. # error +++++ #endif

  11. score_demo.csetupswitchinterrupts unsigned char oldP1SwVal, oldP2SwVal; #define P1SwMask SW1 //P1.3 #define P2SwMask (UpSw + DownSw + LeftSw + RightSw) void initializeSwitchInterrupts() /* setup interrupts on switch */ { P1REN |= P1SwMask; /* resistors for switches */ P2REN |= P2SwMask; P1OUT |= P1SwMask; /* pull-ups for switches */ P2OUT |= P2SwMask; oldP1SwVal = P1IN & P1SwMask; /* remember current switch vales */ oldP2SwVal = P2IN & P2SwMask; P1IES = oldP1SwVal; /* interrupt when switch bits change */ P2IES = oldP2SwVal; P1IE = P1SwMask; /* enable interrupts from switches */ P2IE = P2SwMask; }

  12. Output from gcc –S –O1 __isr_2: push r15 push r14 push r13 push r12 push r11 mov.b &__P1IN, r11 and.b #8, r11 mov.b r11, &__P1IES mov.b #0, &__P1IFG jne .L6 mov.b &oldP1SwVal, r15 and #8, r15 jeq .L6 call #resetScore .L6: mov.b r11, &oldP1SwVal pop r11 pop r12 pop r13 pop r14 pop r15 reti . score_demo.cSW1 interrupt handlers /* Switches on P1 (far right switch) */ interrupt(PORT1_VECTOR) Port_1(void) { unsigned char p1Val = P1IN & P1SwMask; /* read switches from p1 */ P1IES= p1Val; /* interrupt on value change */ P1IFG = 0; /* clear pending P1 interrupts */ if (!(p1Val & SW1) && (oldP1SwVal & SW1)) /* unpressed to pressed? */ resetScore(); /* re-initialize score */ oldP1SwVal = p1Val; }

  13. Topics • Score Demo • LCD • Panel Geometry • Utilities to draw to the display • Drawing characters • Buttons • Nuisance: multiple versions • Interrupt handlers • Timer interrupt handler • To update score • Ball Demo • Drawing Ball • Motion • Paddle Demo • Buttons • Drawing paddle

  14. Ball_demo.cdrawing 2x2 ball void drawBall(u_char x, u_char y) { u_charmajorYTop = lcd_getYMajor(y); u_charmajorYBot = lcd_getYMajor(y+1); u_charminorYTop = lcd_getYMinor(y); u_charminorYBot = lcd_getYMinor(y+1); clearBall(last_ball_x, last_ball_y); if (majorYTop == majorYBot) { // set the appropriate bits within the upper byte u_char chunk = (3 << minorYTop); lcd_writeChunkAddr(chunk, x, majorYTop); lcd_writeChunk(chunk); } else { // set the appropriate bit for the upper byte u_char chunk = (1 << minorYTop); lcd_writeChunkAddr(chunk, x, majorYTop); lcd_writeChunk(chunk); // set the appropriate bit for the lower byte chunk = (1 << minorYBot); lcd_writeChunkAddr(chunk, x, majorYBot); lcd_writeChunk(chunk); } last_ball_x = x; last_ball_y = y; } static void clearBall(u_char x, u_char y) { u_charyMajor = lcd_getYMajor(y); lcd_writeChunkAddr(0, x, yMajor); lcd_writeChunk(0); // x+1 lcd_writeChunkAddr(0, x, yMajor + 1); lcd_writeChunk(0); // x+1 }

  15. Ball_demo.ctimer & buttoninterrupt handlers /* timer interrupt */ interrupt(TIMER0_A0_VECTOR) Timer_0(void) { static intclockDivide = 0; if (clockDivide++ > 20) { updateBall(); clockDivide = 0; } } interrupt(PORT1_VECTOR) Port_1(void) { unsigned char p1Val = P1IN & P1SwMask; /* read switches from p1 */ P1IES= p1Val; /* interrupt on value change */ P1IFG = 0; /* clear pending P1 interrupts */ if (!(p1Val & SW1) && (oldP1SwVal & SW1)) /* transition from unpressed to pressed? */ resetBall(); /* re-initialize paddle */ oldP1SwVal = p1Val; }

  16. Ball_demo.cball motion updateBall() { /* reverse ball direction at court boundaries */ if ((ballXPos == 0) || (ballXPos == MAX_X -2)) ballXVel = -ballXVel; if ((ballYPos == 0) || (ballYPos == MAX_Y -2)) ballYVel = -ballYVel; /* move ball */ ballXPos += ballXVel; ballYPos += ballYVel; /* draw ball */ drawBall(ballXPos, ballYPos); }

  17. Topics • Score Demo • LCD • Panel Geometry • Utilities to draw to the display • Drawing characters • Buttons • Nuisance: multiple versions • Interrupt handlers • Timer interrupt handler • To update score • Ball Demo • Drawing Ball • Motion • Paddle Demo • Drawing paddle • Buttons • Motion

  18. draw_paddle.c void drawPaddle(u_charyPos) /* ypos is middle of paddle */ { char paddleTopYMajor = lcd_getYMajor(yPos-paddleSize); char paddleBotYMajor = lcd_getYMajor(yPos+paddleSize); u_charyMajor; /* yMajor row index */ u_charyMajorLimit = max(paddleBotYMajor, oldPaddleBotYMajor); for (yMajor = min(paddleTopYMajor, oldPaddleTopYMajor); yMajor <= yMajorLimit;yMajor++) { // yMajor in paddle lcd_setAddr(0, yMajor); if (yMajor < paddleTopYMajor || yMajor > paddleBotYMajor) lcd_writeChunk(0); /* erase if above or below paddle */ else { u_char chunk = 0xffu; /* default: all pixels on */ if (yMajor == paddleTopYMajor) { /* top chunk, clear top pixels */ chunk &= ~chunkMasks[lcd_getYMinor(yPos-paddleSize)]; } if (yMajor == paddleBotYMajor) { /* bot chunk, clear bottom pixels */ chunk &= chunkMasks[1+lcd_getYMinor(yPos+paddleSize)]; } lcd_writeChunk(chunk); } } oldPaddleBotYMajor = paddleBotYMajor; /* remember state */ oldPaddleTopYMajor = paddleTopYMajor; } static constu_charchunkMasks[] = {0x00, 0x01, 0x03, 0x07, 0xf, 0x1f, 0x3f, 0x7f, 0xff};

  19. paddle_demobuttonsmotion /* Switches on P2 (direction pad) */ interrupt(PORT2_VECTOR) Port_2(void) { unsigned char p2Val = P2IN & P2SwMask; /* read switches from p2 */ P2IES= p2Val; /* interrupt on value change */ P2IFG = 0; /* clear pending P2 interrupts */ /* just remember button state */ oldP2SwVal = p2Val; } void updatePaddle(void) /* called by timer interrupt handler */ { // check if up switch is pressed if (!(oldP2SwVal & UpSw)) { if (paddleY > 6) paddleY--; drawPaddle(paddleY); } // check if down switch is pressed if (!(oldP2SwVal & DownSw)) { paddleY++; drawPaddle(paddleY); } }

More Related