Arch1 LCD Lab Eric Freudenthal. Topics Score Demo LCD Panel Geometry Utilities to draw to the display Drawing characters Buttons Nuisance: multiple versions.

Slides:



Advertisements
Similar presentations
Why Keliang’s code maybe did (or maybe didn’t) work … or High (impedance) Anxiety.
Advertisements

Interrupts, Low Power Modes and Timer A (Chapters 6 & 8)
Chung-Ta King National Tsing Hua University
Chung-Ta King National Tsing Hua University
C Examples 1.
Chung-Ta King National Tsing Hua University
ECE 447 Fall 2009 Lecture 9: TI MSP430 Interrupts & Low Power Modes.
LAB 6: Serial Communication
Butterfly I/O Ports CS-212 Dick Steflik. I/O for our labs To get data into and out of our Butterfly its a little trickier than using printf and scanf.
AVR Programming CS-212 Dick Steflik. ATmega328P I/O for our labs To get data into and out of our Arduino its a little trickier than using printf and.
ECE 382 Lesson 2 Readings Lesson Outline Admin Assembler Linker
Arduino Interrupts Paul MacDougal September 8, 2014.
CS4101 嵌入式系統概論 Software UART Revisited Prof. Chung-Ta King Department of Computer Science National Tsing Hua University, Taiwan ( Materials from MSP430.
Lecture 13: TI MSP430 Watchdog Timer and Real-Time Clock
LAB 7: WDT+ and Low-Power Optimization
Lecture 18: ADC Implementation Lecturers: Professor John Devlin.
Development. Development Environment Editor Assembler or compiler Embedded emulator/debugger IAR Embedded Workbench Kickstart Code Composer Essentials.
CS-280 Dr. Mark L. Hornick 1 ASCII table. 2 Displaying Numbers as Text Problem: display numerical values as text Consider the numerical value 0x5A held.
UNIT 8 Keypad Interface Contact Closure Counter Exceptions (Interrupts and Reset)
LEVEL 0. レス キューロ ボット制 御システ ム Press Button SW0, SW1 Toggle switch Tsw0->Tsw7 モータ センサー タイマー1 LCD LED Event input Enter a setting value Sensor Data Time.
CPE 323 Introduction to Embedded Computer Systems: Watchdog Timer, Timer A Instructor: Dr Aleksandar Milenkovic Lecture Notes.
Practical Electronics & Programming
MCU: Interrupts and Timers Ganesh Pitchiah. What’s an MCU ?
Page 1 D&C EBV Seminar June 2003 Motor Demo C868 Chevillot/Jansen June 2003 N e v e r s t o p t h i n k i n g. Infineon C868 Hands On Training CAPCOM6.
1 Copyright (c) 2003 by Valery Sklyarov and Iouliia Skliarova: DETUA, IEETA, Aveiro University, Portugal.
Lecture 11: TI MSP430 Timers Compare Modes
LAB 8: Program Design Pattern and Software Architecture
Lecturers: Professor John Devlin Mr Robert Ross
UniMAP 1 Interfacing Peripherals. UniMAP 2 Interfacing devices on Embedded Linux In general, to interface to a device connected to an embedded Linux platform.
FREQUENCY COUNTER USING Silicon Labs C8051F020 microcontroller
ECE 371 – Unit 9 Interrupts (continued). Example Set up Two Interrupt Request Inputs: –Port H[0] Set Interrupt Flag on “0” to “1” transition (rising edge)
CIS 3.5 Lecture 2.2 More programming with "Processing"
Chapter 10 Glass Bliss Using the Parallel Master Port to communicate with Alphanumeric LCD displays.
10H Interrupt. Option 0H – Sets video mode. Registers used: – AH = 0H – AL = Video Mode. 3H - CGA Color text of 80X25 7H - Monochrome text of 80X25 Ex:
ECE Lecture 1 1 L15 –I/O Part II Department of Electrical and Computer Engineering The Ohio State University ECE 2560.
LHO 22 C and the  The Silicon Labs ISE uses the Keil C51 compiler.  The code size is limiter to 2K  C has replaced PL/M (the original Intel high.
UNIT 7 - INTRODUCTION TO I/O INTERFACING. TWO MAJOR TYPES OF I/O INTERFACING ISOLATED I/O - DEDICATED I/O INSTRUCTIONS ARE USED TO ACCESS I/O DEVICES.
WCL 조윤정 Arduino Bootloader 코드 분석. BAUD_RATE 설정 /* set the UART baud rate defaults */ #ifndef BAUD_RATE #if F_CPU >= L #define BAUD_RATE.
Direct-Access Color Graphics Chapter 11. Graphics modes C++ provides a different combination of graphics characteristics. These characteristics include.
One more PIC18F252 example and revision for exam B222L Branislav Vuksanovic, UoP, ECE.
UNIT 2. CPUXV2 20-bit addressing User-definable Boot Strap Loader RAM starts at 0x1C00 Beginning of MAIN flash moves according to RAM Vector table starts.
CS4101 嵌入式系統概論 General Purpose IO
Peripherals – Keypad The Keypad provides a simple means of numerical data or control input. The keys can be attributed whatever data or control values.
LCD Interfacing using Atmega 32
Lecture 8: TI MSP430 Interrupts, ISRs
80C51 Block Diagram ECE Overview.
Embedded Systems Programming Examples and Comparison
CS4101 嵌入式系統概論 Interrupts Prof. Chung-Ta King
Lesson Outline Interrupts Admin Assignment #9 due next lesson
CS4101 Introduction to Embedded Systems Lab 6: Low-Power Optimization
Chapter 6 General Purpose Input/Output
CS4101 Introduction to Embedded Systems Lab 1: General Purpose IO
Prof. Chung-Ta King Department of Computer Science
CS4101 嵌入式系統概論 General Purpose IO
Instructor: Dr Aleksandar Milenkovic Lecture Notes
ADVANCED BRAIN Training
CS4101 Introduction to Embedded Systems Lab 4: Interrupt
8051 Programming in C rhussin.
Example 10 ASCII String to Binary Conversion
Keypad Source: under under
Example 15 Interrupt-Driven Controller
Example 13 The Serial Peripheral Interface (SPI)
Lecture 9: TI MSP430 Interrupts & Low Power Modes
EE 319K Introduction to Embedded Systems
Keypad Source: under under
Keypad Source: under under
CS4101 Introduction to Embedded Systems Lab 2: Basic IO and Timer
Prof. Chung-Ta King Department of Computer Science
MSP430 Clock System and Timer
ECE 3567 Microcontroller Lab
Presentation transcript:

Arch1 LCD Lab Eric Freudenthal

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

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 Row # Major (row / 8) Minor (row % 8) x000x200x100x080x040x020x00 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

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

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

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); }

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

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 }

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

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

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; }

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.

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

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 }

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; }

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); }

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

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 };

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); }