Download presentation
Presentation is loading. Please wait.
Published byLindsey Patterson Modified over 9 years ago
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
Panel geometry 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) Bit 0 Bit 7 Bit 0 Bit 7 Bit 0 Bit 7 Bit 0 Bit 7 Bit 0 Bit 7 Bit 0 Bit 7 Bit 0 Bit 7 Bit 0 Bit 7 0 0 0 1 0 1 2 0 2 3 0 3 4 0 4 5 0 5 6 0 6 7 0 7 8 1 0 9 1 1 10 1 2 11 1 3 12 1 4 13 1 5 14 1 6 15 1 7 Row # Major (row / 8) Minor (row % 8) 01234568 0x000x200x100x080x040x020x00 Bit 0 Bit 7 Bit 0 Bit 7 Bit 0 Bit 7 Bit 0 Bit 7 Bit 0 Bit 7 Bit 0 Bit 7 Bit 0 Bit 7 Bit 0 Bit 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 #ifndef lcd_utils_included #define lcd_utils_included #include "booster1202.h" #include "lcd_backend.h" /* compute major & minor row numbers */ u_char lcd_getYMajor(u_char y); u_char lcd_getYMinor(u_char y); /* displays a chunk (byte of binary pixels) at the given address */ void lcd_setAddr(u_char x, u_char yMajor); /* set addr of next write */ void lcd_writeChunk(char chunk); /* write chunk and increment x */ /* set addr & write */ void lcd_writeChunkAddr(char chunk, u_char xPos, u_char yMajor); /* 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_char yMajor) { 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_char yMajor) { lcd_setAddr(x,yMajor); _lcd_writeChar(c); }
7
paddle_button s.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_demo main() 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.c scores & timer interrupt 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 int clockDivide = 0; if (clockDivide++ > 20) { updateScore(); clockDivide = 0; } Timer_0: pushr15 pushr14 pushr13 pushr12 mov&clockDivide, r15 movr15, r14 add#1, r14 movr14, &clockDivide cmp#21, r15 jl.L9 call#updateScore mov#0, &clockDivide.L9:popr12 popr13 popr14 popr15 reti
10
paddle_button s.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.c setup switch interrupts 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
score_demo.c SW1 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; } Output from gcc –S –O1 __isr_2: pushr15 pushr14 pushr13 pushr12 pushr11 mov.b&__P1IN, r11 and.b#8, r11 mov.br11, &__P1IES mov.b#0, &__P1IFG jne.L6 mov.b&oldP1SwVal, r15 and#8, r15 jeq.L6 call#resetScore.L6:mov.br11, &oldP1SwVal popr11 popr12 popr13 popr14 popr15 reti.
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.c drawing 2x2 ball void drawBall(u_char x, u_char y) { u_char majorYTop = lcd_getYMajor(y); u_char majorYBot = lcd_getYMajor(y+1); u_char minorYTop = lcd_getYMinor(y); u_char minorYBot = 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_char yMajor = 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.c timer & button interrupt handlers /* timer interrupt */ interrupt(TIMER0_A0_VECTOR) Timer_0(void) { static int clockDivide = 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.c ball 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_char yPos)/* ypos is middle of paddle */ { char paddleTopYMajor = lcd_getYMajor(yPos-paddleSize); char paddleBotYMajor = lcd_getYMajor(yPos+paddleSize); u_char yMajor; /* yMajor row index */ u_char yMajorLimit = max(paddleBotYMajor, oldPaddleBotYMajor); for (yMajor = min(paddleTopYMajor, oldPaddleTopYMajor); yMajor <= yMajorLimit; yMajor++) { // yMajor in paddle lcd_setAddr(0, yMajor); if (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 const u_char chunkMasks[] = {0x00, 0x01, 0x03, 0x07, 0xf, 0x1f, 0x3f, 0x7f, 0xff };
19
paddle_demo buttons motion /* 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); }
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.