C:\Documents and Settings\rsceec\My Documents\ROYS\NEW68\RSDEMO3.lst - generated by MGTEK Assembler ASM12 V1.19 Build 122 for WIN32 (x86) - Wed Apr 09 15:50:41 2003 1: * Example 68HC12 programs. There are several distinct programs 2: * embedded in this file - each with distinct starting addresses. 3: * 4: * (1) Marius Grueuel's "Hello World and 1 Hz pulse PPO" starts $d00 5: * 6: * (2) PWM demo starts at location $d5b 7: * 8: * (3) Terminal I/O (polled) starts at $dde 9: * 10: * (4) A/D test starts at $e3c 11: * 12: * (5) Timer Interrupts - both input capture and intervals at $e79-> $ee9 13: * 14: * Port A is configured for output in the A/D test (one 15: * channel's binary output is sent as 8-bit parallel output 16: * to Port A 17: * 18: * Port B is configured as 8-bit inputs for the PWM demo 19: * 20: * 21: * example.asm : displays Hello World and pulses PP0 with 1Hz 22: * 23: * Copyright (c) Marius Greuel 1998 (miniide@tripod.com) 24: * 25: 29: * 30: =00000D00 org EE_START ; for an EEPROM version 31: * 32: * This program segment does not use any RAM variables 33: * 34: 0D00 20 0F bra Main ; To skip around constants/message 35: 36: 0D02 48 65 6C 6C 6F 20 Hello dc.b "Hello world!", $0d, $0a, 0 0D08 77 6F 72 6C 64 21 0D0E 0D 0A 00 37: 38: 0D11 79 0016 Main: clr COPCTL ;disable watchdog 39: 0D14 CF 0A00 lds #USER_STACKTOP ;load stackpointer 40: 41: ;initialize sci 42: 0D17 1803 0034 00C0 movw #$0034,SC0BDH ;baudrate 9600 bits/second 43: 0D1D 180B 00 00C2 movb #$00,SC0CR1 ;loop mode disabled, 8,1,n 44: 0D22 180B 0C 00C3 movb #$0c,SC0CR2 ;transmitter & receiver enabled, sci irq disabled 45: 0D27 96 C4 ldaa SC0SR1 ;clean up 46: 47: ;write string to sci 48: 0D29 CE 0D02 ldx #Hello 49: 0D2C 20 06 bra L2 50: 0D2E 4F C4 80 FC L1: brclr SC0SR1,$80,L1 ;wait for TDRE 51: 0D32 5A C7 staa SC0DRL ;write byte to data transmit register 52: 0D34 A6 30 L2: ldaa 1,X+ ;get next byte 53: 0D36 26 F6 bne L1 54: * 55: ;pulse PP0 with 1Hz 56: 0D38 180B 7F 0040 movb #%01111111,PWCLK ;CON01, clk A = PCLK/128, clk B = PCLK/128 57: 0D3D 180B 01 0041 movb #%00000001,PWPOL ;source is clk A 58: 0D42 79 0054 clr PWCTL 59: 0D45 79 0055 clr PWTST 60: 0D48 1803 F424 004C movw #$f424,PWPER0 ;period 61: 0D4E 1803 7A12 0050 movw #$7a12,PWDTY0 ;duty 62: 0D54 180B 03 0042 movb #%00000011,PWEN ;enable PWEN0/1 63: 64: 0D59 20 FE bra * 65: * 66: ******************************************************************** 67: * 68: * PWM test program written by Roy Czernikowski 69: * 70: * Test of 68HC12 Pulse-Width Modulation on Port P 71: * PWM0 - PWM3 on Port P bits 0 - 3 respectively 72: * It reads a duty cycle count (< 200 decimal) from Port B 73: * 74: *USER_STACKTOP equ $0a00 ; just above RAM 75: *PORTA equ $0000 76: *PORTB equ $0001 77: *DDRA equ $0002 ; Port A data direction register 78: *DDRB equ $0003 ; Port B " " " 79: * 80: *PWCLK equ $0040 ; no concatenate & clock prescalars 81: *PWPOL equ $0041 ; clock selects & output polarities 82: *PWEN equ $0042 ; PWM Enable 83: *PWPRES equ $0043 ; PWM Prescale Counter - free running 84: *PWSCAL0 equ $0044 ; Channels 0 & 1 prescale value 85: *PWSCAL1 equ $0046 ; Channels 2 & 3 prescale value 86: *PWSCNT0 equ $0045 ; Channels 0 & 1 prescale count-down 87: *PWSCNT1 equ $0047 ; Channels 2 & 3 prescale count-down 88: *PWCNT0 equ $0048 ; Channel 0 counter 89: *PWCNT1 equ $0049 ; Channel 1 counter 90: *PWCNT2 equ $004a ; Channel 2 counter 91: *PWCNT3 equ $004b ; Channel 3 counter 92: *PWPER0 equ $004c ; Channel 0 Period Register 93: *PWPER1 equ $004d ; Channel 1 Period Register 94: *PWPER2 equ $004e ; Channel 2 Period Register 95: *PWPER3 equ $004f ; Channel 3 Period Register 96: *PWDTY0 equ $0050 ; Channel 0 Duty Register 97: *PWDTY1 equ $0051 ; Channel 1 Duty Register 98: *PWDTY2 equ $0052 ; Channel 2 Duty Register 99: *PWDTY3 equ $0053 ; Channel 3 Duty Register 100: *PWCTL equ $0054 ; PWM Control Register 101: *PWTST equ $0055 ; PWM Special Mode Register "Test" 102: *PORTP equ $0056 ; Port P Data Register 103: *DDRP equ $0057 ; Port P Data Direction Register 104: *COPCTL equ $0016 ; Watchdog Comp Operating Properly 105: * 106: * We're aiming for approximately 400 Hz waves with 107: * duty cycles setting in 0.5% increm (0-200 decimal) 108: * 109: * org $0800 110: 0D5B CF 0A00 PWMstart lds #USER_STACKTOP 111: 0D5E 79 0016 clr COPCTL ; disable watchdog timer 112: 0D61 180B 1B 0040 movb #%00011011,PWCLK ; E/8 = 1.0 MHz 113: 0D66 180B FF 0041 movb #$FF,PWPOL ; S1 clks, + polarity to start 114: * 115: * Take this 1.0 MHz Eclk/8 and further scale it by 12 116: * to produce ~ 80 KHz "ticks" 117: * 118: 0D6B C6 05 ldab #5 ; (5 + 1)*2 = 12 => ~ 80 KHz tick 119: 0D6D 5B 44 stab PWSCAL0 ; for faster execution & fewer 120: 0D6F 5B 46 stab PWSCAL1 ; code bytes vs movb #5,PWSCAL1 121: 0D71 C6 C8 ldab #200 ; 200 decimal for periods => 400Hz 122: * 123: * If we now count 200 of these ~80KHz ticks/period, 124: * the basic PWM clock "frequency" is ~ 400 Hz = 2.5 msec 125: * 126: 0D73 5B 4C stab PWPER0 127: 0D75 5B 4D stab PWPER1 128: 0D77 5B 4E stab PWPER2 129: 0D79 5B 4F stab PWPER3 130: * 131: 0D7B 180B 00 0054 movb #%00000000,PWCTL ; ? bit 1 for no pull-up R 132: 0D80 180B 0F 0057 movb #$0f,DDRP ; PORTP DDR may be unnec. with PWM 133: 0D85 79 0054 clr PWCTL 134: 0D88 79 0055 clr PWTST 135: 0D8B C6 1E ldab #30 ; we'll start with dummy duty cycles 136: 0D8D 5B 50 stab PWDTY0 137: 0D8F CB 32 addb #50 138: 0D91 5B 51 stab PWDTY1 139: 0D93 CB 32 addb #50 140: 0D95 5B 52 stab PWDTY2 141: 0D97 CB 32 addb #50 142: 0D99 5B 53 stab PWDTY3 143: * 144: 0D9B 79 0003 clr DDRB ; allow switch inputs to Port B 145: 0D9E C6 14 ldab #20 146: 0DA0 5B 48 stab PWCNT0 ; just intialize 'em all 147: 0DA2 5B 49 stab PWCNT1 148: 0DA4 5B 4A stab PWCNT2 149: 0DA6 5B 4B stab PWCNT3 150: 0DA8 CE 0000 ldx #0000 151: 0DAB 87 clra 152: 0DAC 180B 0F 0042 movb #$0f,PWEN ; start 'em running 153: 0DB1 D6 01 loop ldab PORTB 154: 0DB3 16 0DD5 jsr limiter ; make sure Duty Cycle <= 200 155: 0DB6 5B 50 stab PWDTY0 ; send the input to PWM0 156: 0DB8 C3 0032 addd #50 ; just make a different value 157: 0DBB 16 0DD5 jsr limiter 158: 0DBE 5B 52 stab PWDTY2 159: 0DC0 09 delay dex 160: 0DC1 26 FD bne delay 161: 0DC3 D6 51 ldab PWDTY1 162: 0DC5 52 incb 163: 0DC6 16 0DD5 jsr limiter 164: 0DC9 5B 51 stab PWDTY1 165: 0DCB D6 53 ldab PWDTY3 166: 0DCD 52 incb 167: 0DCE 16 0DD5 jsr limiter 168: 0DD1 5B 53 stab PWDTY3 169: 0DD3 20 DC bra loop 170: * 171: 0DD5 8C 00C8 limiter cpd #200 172: 0DD8 23 03 bls limitend 173: 0DDA 83 00C8 subd #200 174: 0DDD 3D limitend rts 175: * 176: * 177: ****************************************************************** 178: * 179: * 180: * Terminal I/O : Reads in a character string from terminal keyboard (echoing 181: * characters to the screen) until a is entered, at 182: * which point it will send the characters entered in reverse 183: * order on a new line of the screen and then go to a new line 184: * to begin again. It uses RAM locations beginning at $800 185: * 186: * Roy Czernikowski - December 27, 1998 187: * 188: 189: * .nolist 190: * #include hc12.inc 192: =00000800 StringBuffer equ $800 193: * 194: * org EE_START 195: 196: 0DDE 79 0016 TermIOStart clr COPCTL ;disable watchdog timer 197: 0DE1 CF 0A00 lds #USER_STACKTOP ;load stackpointer 198: * 199: * Initialize SCI 200: 0DE4 1803 0034 00C0 movw #0052,SC0BDH ;baudrate 9600 201: 0DEA 180B 00 00C2 movb #$00,SC0CR1 ;loop mode disabled, 8 bits data,1 stop,no parity 202: 0DEF 180B 0C 00C3 movb #$0c,SC0CR2 ;transmitter & receiver enabled, SCI IRQ disabled 203: 0DF4 96 C4 ldaa SC0SR1 ;clean up 204: 0DF6 180B 00 0800 movb #$00,StringBuffer ; put a zero for possible terminator 205: * 206: 0DFB CE 0801 Back ldx #StringBuffer+1 207: 0DFE D6 C4 WaitChr ldab SC0SR1 208: 0E00 C4 20 andb #$20 ; check for RDRF, 209: 0E02 27 FA beq WaitChr ; if no new input char, go to WaitChr 210: 0E04 96 C7 ldaa SC0DRL ; else get the new input character 211: 0E06 81 0D cmpa #$0d ; look for , if so go to send routines 212: 0E08 27 06 beq SendString 213: 0E0A 07 29 bsr SendChar ; else echo input to screen 214: 0E0C 6A 30 staa 1,X+ ; else put input char into StringBuffer 215: 0E0E 20 EE bra WaitChr 216: * 217: 0E10 07 23 SendString bsr SendChar ; send the to screen 218: 0E12 86 0A ldaa #$0a ; send a to screen 219: 0E14 07 1F bsr SendChar 220: 0E16 09 dex ; readjust X to point at last char 221: 0E17 A6 3F NextChar ldaa 1,X- ; get next character <<<<<<< check this 222: 0E19 27 04 beq SendCR ; if we encountere $00 (end_of_string) 223: * ; go to clean-up 'WaitCR' 224: 0E1B 07 18 bsr SendChar ; else output character to screen 225: 0E1D 20 F8 bra NextChar 226: * 227: 0E1F 86 0D SendCR ldaa #$0d ; send 228: 0E21 07 12 bsr SendChar 229: 0E23 86 0A ldaa #$0a ; send 230: 0E25 07 0E bsr SendChar 231: 0E27 20 D2 bra Back ; go Back 232: * 233: * dummy alternate code from Marius Greuel's example 234: * not used in this demo program 235: * 236: 0E29 20 06 bra LL2 237: 0E2B 4F C4 80 FC LL1: brclr SC0SR1,$80,LL1 ;wait for TDRE 238: 0E2F 5A C7 staa SC0DRL ;write byte to data transmit register 239: 0E31 A6 30 LL2: ldaa 1,X+ ;get next byte 240: 0E33 26 F6 bne LL1 241: * 242: ********************************************************* 243: * 244: * Subroutine SendChar: it sends the character 245: * passed in Reg A to terminal output screen 246: * - note it does a busy wait for TDRE 247: * this routine trashes Reg B 248: * 249: 0E35 D6 C4 SendChar ldab SC0SR1 ; check for TDRE 250: 0E37 2A FC bpl SendChar ; if not go to WaitLF 251: 0E39 5A C7 staa SC0DRL 252: 0E3B 3D rts 253: * 254: ***************************************************** 255: * 256: * 257: * org $8fe 258: * fdb $0021 ; safety $00 and '!' character 259: * 260: *StringBuffer fcb $00 ; end_of_string delimiter 261: * fcb 'abcdefghijklmnopqrstuvwxyz' ; just to get some indicators 262: * 263: ***************************************************** 264: * 265: * AtoD Converter Test - Scan Mode - 8 channels 266: * 267: * This program deposits the 8 channels' digitized inputs 268: * into 8 locations beginning at location $800 269: * 270: =00000800 ValueTable equ $800 ; 271: * rmb 8 ; space for results 272: 273: * USER_STACKTOP equ $0a00 ; just above RAM 274: * PORTA equ $0000 ; we'll display an A2D result at PortA 275: * DDRA equ $0002 ; 276: *ATDCTL2 equ $0062 ; set bit 7 = 1 to power-up A2D 277: *ATDCTL3 equ $0063 ; cleared at reset - leave it alone 278: *ATDCTL4 equ $0064 ; reset to $01 - leave it alone 279: *ATDCTL5 equ $0065 ; 01110000 for 8 channel scan convers. 280: * ATDSTATH equ $0067 ; bit 7 Scan Complete Flag 281: * ATDSTATL equ $0068 ; 8 channel conversion complete flags 282: *PORTAD equ $006f ; digital values of bits input 283: *ADR0H equ $0070 ; ATD Converter Result Register 0 284: *ADR1H equ $0072 ; ATD Converter Result Register 1 285: *ADR2H equ $0074 ; ATD Converter Result Register 2 286: *ADR3H equ $0076 ; ATD Converter Result Register 3 287: *ADR4H equ $0078 ; ATD Converter Result Register 4 288: *ADR5H equ $007a ; ATD Converter Result Register 5 289: *ADR6H equ $007c ; ATD Converter Result Register 6 290: *ADR7H equ $007e ; ATD Converter Result Register 7 291: * 292: * org $0800 293: 0E3C CF 0A00 AtoDstart lds #USER_STACKTOP ; just above RAM 294: 0E3F C6 80 ldab #$80 ; power-up AtoD Converter 295: 0E41 5B 62 stab ATDCTL2 296: 0E43 C6 70 ldab #$70 ; standard 8 Channel scan conversions 297: 0E45 5B 65 stab ATDCTL5 298: * 299: 0E47 C6 FF ldab #$ff ; enable Port A to be all outputs for 300: 0E49 5B 02 stab DDRA ; sending one channel's results 301: * 302: 0E4B CE 0800 AtoDloop ldx #ValueTable 303: 0E4E D6 66 ldab ATDSTATH ; wait for Scan Complete Flag in 304: 0E50 2C F9 bge AtoDloop ; bit 7 305: 0E52 96 70 ldaa ADR0H ; read channel results and store 306: 0E54 6A 30 staa 1,x+ ; them in ValueTable 307: 0E56 96 72 ldaa ADR1H 308: 0E58 6A 30 staa 1,x+ 309: 0E5A 96 74 ldaa ADR2H 310: 0E5C 6A 30 staa 1,x+ 311: 0E5E 96 76 ldaa ADR3H 312: 0E60 6A 30 staa 1,x+ 313: 0E62 96 78 ldaa ADR4H 314: 0E64 6A 30 staa 1,x+ 315: 0E66 96 7A ldaa ADR5H 316: 0E68 6A 30 staa 1,x+ 317: 0E6A 96 7C ldaa ADR6H 318: 0E6C 6A 30 staa 1,x+ 319: 0E6E 96 7E ldaa ADR7H 320: 0E70 6A 30 staa 1,x+ 321: 0E72 F6 0806 ldab ValueTable+6 322: 0E75 5B 00 stab PORTA 323: 0E77 20 D2 bra AtoDloop 324: * 325: ********************************************************* 326: * 327: * Timer interrupt demo Timer 5 does regular timer 328: * interval interrupts 5 times per second and 329: * toggles output bit PT5. Timer 1 counts until 330: * a one-to-zero transition is detected on PT1 331: * at which point the most significant half of 332: * the TCNT register is output on Port A 333: * 334: =00000800 flags equ $800 ; Debug RAM copy of Timer IRQ Status 335: =00000B2C Timer1vec equ $0b2c ; Ram IRQ vector locations 336: =00000B24 Timer5vec equ $0b24 ; was $ffe4 for ROM & $f7e4 337: 338: 0E79 79 0016 Fast_Timer clr COPCTL ; disable watchdog 339: 0E7C CF 0A00 lds #USER_STACKTOP ; load stackpointer 340: * 341: 0E7F 1410 sei ; disable interrupts for moment 342: * 343: 0E81 1803 0ECE 0B2C movw #Timer1IRQ,Timer1vec ; initialize interrupt 344: 0E87 1803 0ED9 0B24 movw #Timer5IRQ,Timer5vec ; vector locations 345: 0E8D 79 0800 clr flags ; a RAM debug location 346: * 347: 0E90 79 001E clr INTCR ; see page 53 section 9.3 348: 0E93 C6 FF ldab #$ff ; set Port A all outputs for 349: 0E95 5B 02 stab DDRA ; displaying TCNT (msb) when an 350: * ; an external falling edge pulse 351: * ; arrives on bit PT5 352: * 353: 0E97 79 008C clr TMSK1 ; disable all interrupts for now 354: 0E9A C6 05 ldab #%00000101 ; 8MHz / 32 = 250KHz 355: 0E9C 5B 8D stab TMSK2 356: 0E9E C6 08 ldab #%00001000 ; enable timer 1 capture on 357: 0EA0 5B 8B stab TCTL4 ; falling edge 358: 0EA2 C6 20 ldab #$20 ; enable output compare 359: 0EA4 5B 80 stab TIOS ; on Timer 5 output (bit 5) 360: * 361: 0EA6 C6 04 ldab #$04 ; enable toggle output on OC5 362: 0EA8 5B 88 stab TCTL1 363: 0EAA C6 00 ldab #$00 ; no timer outputs on OC3-OC0 364: 0EAC 5B 89 stab TCTL2 ; 365: 0EAE C6 00 ldab #$00 ; No timer input captures on 7-4 366: 0EB0 5B 8A stab TCTL3 ; 367: 0EB2 C6 22 ldab #%00100010 ; enable two interrupts 368: 0EB4 5B 8C stab TMSK1 ; OC5 and IC1 369: 0EB6 96 8E ldaa TFLG1 ; just to read it before 370: 0EB8 C6 FF ldab #$ff ; clearing any possible spurious 371: 0EBA 5B 8E stab TFLG1 ; timer interrupts 372: 0EBC DC 84 ldd TCNTH ; schedule first interrupt in 373: 0EBE C3 C350 addd #50000 ; future 374: 0EC1 5C 92 std TC1H 375: 0EC3 5C 9A std TC5H ; may not be necessary 376: 0EC5 C6 80 ldab #$80 377: 0EC7 5B 86 stab TSCR ; turn on timers 378: 0EC9 10EF cli ; enable interrupts 379: 0ECB A7 backgnd nop 380: 0ECC 20 FD bra backgnd 381: * 382: 0ECE D6 8E Timer1IRQ ldab TFLG1 ; just to read it 383: 0ED0 C6 02 ldab #$02 ; clear C2F in TFLG1 384: 0ED2 5B 8E stab TFLG1 385: 0ED4 DC 92 ldd TC1H ; get entire TCNT at time of 386: * ; external hi-to-low pulse 387: 0ED6 5A 00 staa PORTA ; display hi-order TCNT 388: * 389: * maybe do something "useful" 390: * 391: 0ED8 0B rti 392: * 393: 0ED9 D6 8E Timer5IRQ ldab TFLG1 ; copy timer status 394: 0EDB 7B 0800 stab flags 395: * 396: 0EDE C6 20 ldab #$20 ; clear Timer 5 OCFlag 397: 0EE0 5B 8E stab TFLG1 ; 398: * 399: 0EE2 DC 9A ldd TC5H ; schedule next interrupt in 400: 0EE4 C3 C350 addd #50000 ; future 401: 0EE7 5C 9A std TC5H 402: * 403: * maybe do something useful 404: * 405: 0EE9 0B rti Symbols: adr0h *00000070 adr1h *00000072 adr2h *00000074 adr3h *00000076 adr4h *00000078 adr5h *0000007a adr6h *0000007c adr7h *0000007e atdctl2 *00000062 atdctl5 *00000065 atdstath *00000066 atodloop *00000e4b back *00000dfb backgnd *00000ecb copctl *00000016 ddra *00000002 ddrb *00000003 ddrp *00000057 delay *00000dc0 ee_start *00000d00 flags *00000800 hello *00000d02 intcr *0000001e l1 *00000d2e l2 *00000d34 limitend *00000ddd limiter *00000dd5 ll1 *00000e2b ll2 *00000e31 loop *00000db1 main *00000d11 map_page *00000000 nextchar *00000e17 porta *00000000 portb *00000001 pwclk *00000040 pwcnt0 *00000048 pwcnt1 *00000049 pwcnt2 *0000004a pwcnt3 *0000004b pwctl *00000054 pwdty0 *00000050 pwdty1 *00000051 pwdty2 *00000052 pwdty3 *00000053 pwen *00000042 pwper0 *0000004c pwper1 *0000004d pwper2 *0000004e pwper3 *0000004f pwpol *00000041 pwscal0 *00000044 pwscal1 *00000046 pwtst *00000055 ram_size *00000400 ram_start *00000800 sc0bdh *000000c0 sc0cr1 *000000c2 sc0cr2 *000000c3 sc0drl *000000c7 sc0sr1 *000000c4 sendchar *00000e35 sendcr *00000e1f sendstring *00000e10 stringbuffer *00000800 tc1h *00000092 tc5h *0000009a tcnth *00000084 tctl1 *00000088 tctl2 *00000089 tctl3 *0000008a tctl4 *0000008b tflg1 *0000008e timer1irq *00000ece timer1vec *00000b2c timer5irq *00000ed9 timer5vec *00000b24 tios *00000080 tmsk1 *0000008c tmsk2 *0000008d tscr *00000086 user_ram_size *00000200 user_stacktop *00000a00 valuetable *00000800 waitchr *00000dfe