C:\Documents and Settings\rsceec\My Documents\ROYS\NEW68\Rdemo2.lst - generated by MGTEK Assembler ASM12 V1.19 Build 122 for WIN32 (x86) - Mon Sep 08 12:00:21 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 $800 5: * 6: * (2) PWM demo starts at location $85b 7: * 8: * (3) Terminal I/O (polled) starts at $8de 9: * 10: * (4) A/D test starts at $93c 11: * 12: * (5) Timer Interrupts - both input capture and intervals at $979-> $9e9 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: =00000800 org $800 ; for a RAM version 31: * org EE_START ; for an EEPROM version 32: * 33: * This program segment does not use any RAM variables 34: * 35: 0800 20 0F [03] bra Main ; To skip around constants/message 36: 37: 0802 48 65 6C 6C 6F 20 Hello dc.b "Hello world!", $0d, $0a, 0 0808 77 6F 72 6C 64 21 080E 0D 0A 00 38: 39: 0811 79 0016 [03] Main: clr COPCTL ;disable watchdog 40: 0814 CF 0A00 [02] lds #USER_STACKTOP ;load stackpointer 41: 42: ;initialize sci 43: 0817 1803 0034 00C0 [05] movw #$0034,SC0BDH ;baudrate 9600 bits/second 44: 081D 180B 00 00C2 [04] movb #$00,SC0CR1 ;loop mode disabled, 8,1,n 45: 0822 180B 0C 00C3 [04] movb #$0c,SC0CR2 ;transmitter & receiver enabled, sci irq disabled 46: 0827 96 C4 [03] ldaa SC0SR1 ;clean up 47: 48: ;write string to sci 49: 0829 CE 0802 [02] ldx #Hello 50: 082C 20 06 [03] bra L2 51: 082E 4F C4 80 FC [04] L1: brclr SC0SR1,$80,L1 ;wait for TDRE 52: 0832 5A C7 [02] staa SC0DRL ;write byte to data transmit register 53: 0834 A6 30 [03] L2: ldaa 1,X+ ;get next byte 54: 0836 26 F6 [03] bne L1 55: * 56: ;pulse PP0 with 1Hz 57: 0838 180B 7F 0040 [04] movb #%01111111,PWCLK ;CON01, clk A = PCLK/128, clk B = PCLK/128 58: 083D 180B 01 0041 [04] movb #%00000001,PWPOL ;source is clk A 59: 0842 79 0054 [03] clr PWCTL 60: 0845 79 0055 [03] clr PWTST 61: 0848 1803 F424 004C [05] movw #$f424,PWPER0 ;period 62: 084E 1803 7A12 0050 [05] movw #$7a12,PWDTY0 ;duty 63: 0854 180B 03 0042 [04] movb #%00000011,PWEN ;enable PWEN0/1 64: 65: 0859 20 FE [03] bra * 66: * 67: ******************************************************************** 68: * 69: * PWM test program written by Roy Czernikowski 70: * 71: * Test of 68HC12 Pulse-Width Modulation on Port P 72: * PWM0 - PWM3 on Port P bits 0 - 3 respectively 73: * It reads a duty cycle count (< 200 decimal) from Port B 74: * 75: *USER_STACKTOP equ $0a00 ; just above RAM 76: *PORTA equ $0000 77: *PORTB equ $0001 78: *DDRA equ $0002 ; Port A data direction register 79: *DDRB equ $0003 ; Port B " " " 80: * 81: *PWCLK equ $0040 ; no concatenate & clock prescalars 82: *PWPOL equ $0041 ; clock selects & output polarities 83: *PWEN equ $0042 ; PWM Enable 84: *PWPRES equ $0043 ; PWM Prescale Counter - free running 85: *PWSCAL0 equ $0044 ; Channels 0 & 1 prescale value 86: *PWSCAL1 equ $0046 ; Channels 2 & 3 prescale value 87: *PWSCNT0 equ $0045 ; Channels 0 & 1 prescale count-down 88: *PWSCNT1 equ $0047 ; Channels 2 & 3 prescale count-down 89: *PWCNT0 equ $0048 ; Channel 0 counter 90: *PWCNT1 equ $0049 ; Channel 1 counter 91: *PWCNT2 equ $004a ; Channel 2 counter 92: *PWCNT3 equ $004b ; Channel 3 counter 93: *PWPER0 equ $004c ; Channel 0 Period Register 94: *PWPER1 equ $004d ; Channel 1 Period Register 95: *PWPER2 equ $004e ; Channel 2 Period Register 96: *PWPER3 equ $004f ; Channel 3 Period Register 97: *PWDTY0 equ $0050 ; Channel 0 Duty Register 98: *PWDTY1 equ $0051 ; Channel 1 Duty Register 99: *PWDTY2 equ $0052 ; Channel 2 Duty Register 100: *PWDTY3 equ $0053 ; Channel 3 Duty Register 101: *PWCTL equ $0054 ; PWM Control Register 102: *PWTST equ $0055 ; PWM Special Mode Register "Test" 103: *PORTP equ $0056 ; Port P Data Register 104: *DDRP equ $0057 ; Port P Data Direction Register 105: *COPCTL equ $0016 ; Watchdog Comp Operating Properly 106: * 107: * We're aiming for approximately 400 Hz waves with 108: * duty cycles setting in 0.5% increm (0-200 decimal) 109: * 110: * org $0800 111: 085B CF 0A00 [02] PWMstart lds #USER_STACKTOP 112: 085E 79 0016 [03] clr COPCTL ; disable watchdog timer 113: 0861 180B 1B 0040 [04] movb #%00011011,PWCLK ; E/8 = 1.0 MHz 114: 0866 180B FF 0041 [04] movb #$FF,PWPOL ; S1 clks, + polarity to start 115: * 116: * Take this 1.0 MHz Eclk/8 and further scale it by 12 117: * to produce ~ 80 KHz "ticks" 118: * 119: 086B C6 05 [01] ldab #5 ; (5 + 1)*2 = 12 => ~ 80 KHz tick 120: 086D 5B 44 [02] stab PWSCAL0 ; for faster execution & fewer 121: 086F 5B 46 [02] stab PWSCAL1 ; code bytes vs movb #5,PWSCAL1 122: 0871 C6 C8 [01] ldab #200 ; 200 decimal for periods => 400Hz 123: * 124: * If we now count 200 of these ~80KHz ticks/period, 125: * the basic PWM clock "frequency" is ~ 400 Hz = 2.5 msec 126: * 127: 0873 5B 4C [02] stab PWPER0 128: 0875 5B 4D [02] stab PWPER1 129: 0877 5B 4E [02] stab PWPER2 130: 0879 5B 4F [02] stab PWPER3 131: * 132: 087B 180B 00 0054 [04] movb #%00000000,PWCTL ; ? bit 1 for no pull-up R 133: 0880 180B 0F 0057 [04] movb #$0f,DDRP ; PORTP DDR may be unnec. with PWM 134: 0885 79 0054 [03] clr PWCTL 135: 0888 79 0055 [03] clr PWTST 136: 088B C6 1E [01] ldab #30 ; we'll start with dummy duty cycles 137: 088D 5B 50 [02] stab PWDTY0 138: 088F CB 32 [01] addb #50 139: 0891 5B 51 [02] stab PWDTY1 140: 0893 CB 32 [01] addb #50 141: 0895 5B 52 [02] stab PWDTY2 142: 0897 CB 32 [01] addb #50 143: 0899 5B 53 [02] stab PWDTY3 144: * 145: 089B 79 0003 [03] clr DDRB ; allow switch inputs to Port B 146: 089E C6 14 [01] ldab #20 147: 08A0 5B 48 [02] stab PWCNT0 ; just intialize 'em all 148: 08A2 5B 49 [02] stab PWCNT1 149: 08A4 5B 4A [02] stab PWCNT2 150: 08A6 5B 4B [02] stab PWCNT3 151: 08A8 CE 0000 [02] ldx #0000 152: 08AB 87 [01] clra 153: 08AC 180B 0F 0042 [04] movb #$0f,PWEN ; start 'em running 154: 08B1 D6 01 [03] loop ldab PORTB 155: 08B3 16 08D5 [04] jsr limiter ; make sure Duty Cycle <= 200 156: 08B6 5B 50 [02] stab PWDTY0 ; send the input to PWM0 157: 08B8 C3 0032 [02] addd #50 ; just make a different value 158: 08BB 16 08D5 [04] jsr limiter 159: 08BE 5B 52 [02] stab PWDTY2 160: 08C0 09 [01] delay dex 161: 08C1 26 FD [03] bne delay 162: 08C3 D6 51 [03] ldab PWDTY1 163: 08C5 52 [01] incb 164: 08C6 16 08D5 [04] jsr limiter 165: 08C9 5B 51 [02] stab PWDTY1 166: 08CB D6 53 [03] ldab PWDTY3 167: 08CD 52 [01] incb 168: 08CE 16 08D5 [04] jsr limiter 169: 08D1 5B 53 [02] stab PWDTY3 170: 08D3 20 DC [03] bra loop 171: * 172: 08D5 8C 00C8 [02] limiter cpd #200 173: 08D8 23 03 [03] bls limitend 174: 08DA 83 00C8 [02] subd #200 175: 08DD 3D [05] limitend rts 176: * 177: * 178: ****************************************************************** 179: * 180: * 181: * Terminal I/O : Reads in a character string from terminal keyboard (echoing 182: * characters to the screen) until a is entered, at 183: * which point it will send the characters entered in reverse 184: * order on a new line of the screen and then go to a new line 185: * to begin again. It uses RAM locations beginning at $800 186: * 187: * Roy Czernikowski - December 27, 1998 188: * 189: 190: * .nolist 191: * #include hc12.inc 193: =00000800 StringBuffer equ $800 194: * 195: * org EE_START 196: 197: 08DE 79 0016 [03] TermIOStart clr COPCTL ;disable watchdog timer 198: 08E1 CF 0A00 [02] lds #USER_STACKTOP ;load stackpointer 199: * 200: * Initialize SCI 201: 08E4 1803 0034 00C0 [05] movw #0052,SC0BDH ;baudrate 9600 202: 08EA 180B 00 00C2 [04] movb #$00,SC0CR1 ;loop mode disabled, 8 bits data,1 stop,no parity 203: 08EF 180B 0C 00C3 [04] movb #$0c,SC0CR2 ;transmitter & receiver enabled, SCI IRQ disabled 204: 08F4 96 C4 [03] ldaa SC0SR1 ;clean up 205: 08F6 180B 00 0800 [04] movb #$00,StringBuffer ; put a zero for possible terminator 206: * 207: 08FB CE 0801 [02] Back ldx #StringBuffer+1 208: 08FE D6 C4 [03] WaitChr ldab SC0SR1 209: 0900 C4 20 [01] andb #$20 ; check for RDRF, 210: 0902 27 FA [03] beq WaitChr ; if no new input char, go to WaitChr 211: 0904 96 C7 [03] ldaa SC0DRL ; else get the new input character 212: 0906 81 0D [01] cmpa #$0d ; look for , if so go to send routines 213: 0908 27 06 [03] beq SendString 214: 090A 07 29 [04] bsr SendChar ; else echo input to screen 215: 090C 6A 30 [02] staa 1,X+ ; else put input char into StringBuffer 216: 090E 20 EE [03] bra WaitChr 217: * 218: 0910 07 23 [04] SendString bsr SendChar ; send the to screen 219: 0912 86 0A [01] ldaa #$0a ; send a to screen 220: 0914 07 1F [04] bsr SendChar 221: 0916 09 [01] dex ; readjust X to point at last char 222: 0917 A6 3F [03] NextChar ldaa 1,X- ; get next character <<<<<<< check this 223: 0919 27 04 [03] beq SendCR ; if we encountere $00 (end_of_string) 224: * ; go to clean-up 'WaitCR' 225: 091B 07 18 [04] bsr SendChar ; else output character to screen 226: 091D 20 F8 [03] bra NextChar 227: * 228: 091F 86 0D [01] SendCR ldaa #$0d ; send 229: 0921 07 12 [04] bsr SendChar 230: 0923 86 0A [01] ldaa #$0a ; send 231: 0925 07 0E [04] bsr SendChar 232: 0927 20 D2 [03] bra Back ; go Back 233: * 234: * dummy alternate code from Marius Greuel's example 235: * not used in this demo program 236: * 237: 0929 20 06 [03] bra LL2 238: 092B 4F C4 80 FC [04] LL1: brclr SC0SR1,$80,LL1 ;wait for TDRE 239: 092F 5A C7 [02] staa SC0DRL ;write byte to data transmit register 240: 0931 A6 30 [03] LL2: ldaa 1,X+ ;get next byte 241: 0933 26 F6 [03] bne LL1 242: * 243: ********************************************************* 244: * 245: * Subroutine SendChar: it sends the character 246: * passed in Reg A to terminal output screen 247: * - note it does a busy wait for TDRE 248: * this routine trashes Reg B 249: * 250: 0935 D6 C4 [03] SendChar ldab SC0SR1 ; check for TDRE 251: 0937 2A FC [03] bpl SendChar ; if not go to WaitLF 252: 0939 5A C7 [02] staa SC0DRL 253: 093B 3D [05] rts 254: * 255: ***************************************************** 256: * 257: * 258: * org $8fe 259: * fdb $0021 ; safety $00 and '!' character 260: * 261: *StringBuffer fcb $00 ; end_of_string delimiter 262: * fcb 'abcdefghijklmnopqrstuvwxyz' ; just to get some indicators 263: * 264: ***************************************************** 265: * 266: * AtoD Converter Test - Scan Mode - 8 channels 267: * 268: * This program deposits the 8 channels' digitized inputs 269: * into 8 locations beginning at location $800 270: * 271: =00000800 ValueTable equ $800 ; 272: * rmb 8 ; space for results 273: 274: * USER_STACKTOP equ $0a00 ; just above RAM 275: * PORTA equ $0000 ; we'll display an A2D result at PortA 276: * DDRA equ $0002 ; 277: *ATDCTL2 equ $0062 ; set bit 7 = 1 to power-up A2D 278: *ATDCTL3 equ $0063 ; cleared at reset - leave it alone 279: *ATDCTL4 equ $0064 ; reset to $01 - leave it alone 280: *ATDCTL5 equ $0065 ; 01110000 for 8 channel scan convers. 281: * ATDSTATH equ $0067 ; bit 7 Scan Complete Flag 282: * ATDSTATL equ $0068 ; 8 channel conversion complete flags 283: *PORTAD equ $006f ; digital values of bits input 284: *ADR0H equ $0070 ; ATD Converter Result Register 0 285: *ADR1H equ $0072 ; ATD Converter Result Register 1 286: *ADR2H equ $0074 ; ATD Converter Result Register 2 287: *ADR3H equ $0076 ; ATD Converter Result Register 3 288: *ADR4H equ $0078 ; ATD Converter Result Register 4 289: *ADR5H equ $007a ; ATD Converter Result Register 5 290: *ADR6H equ $007c ; ATD Converter Result Register 6 291: *ADR7H equ $007e ; ATD Converter Result Register 7 292: * 293: * org $0800 294: 093C CF 0A00 [02] AtoDstart lds #USER_STACKTOP ; just above RAM 295: 093F C6 80 [01] ldab #$80 ; power-up AtoD Converter 296: 0941 5B 62 [02] stab ATDCTL2 297: 0943 C6 70 [01] ldab #$70 ; standard 8 Channel scan conversions 298: 0945 5B 65 [02] stab ATDCTL5 299: * 300: 0947 C6 FF [01] ldab #$ff ; enable Port A to be all outputs for 301: 0949 5B 02 [02] stab DDRA ; sending one channel's results 302: * 303: 094B CE 0800 [02] AtoDloop ldx #ValueTable 304: 094E D6 66 [03] ldab ATDSTATH ; wait for Scan Complete Flag in 305: 0950 2C F9 [03] bge AtoDloop ; bit 7 306: 0952 96 70 [03] ldaa ADR0H ; read channel results and store 307: 0954 6A 30 [02] staa 1,x+ ; them in ValueTable 308: 0956 96 72 [03] ldaa ADR1H 309: 0958 6A 30 [02] staa 1,x+ 310: 095A 96 74 [03] ldaa ADR2H 311: 095C 6A 30 [02] staa 1,x+ 312: 095E 96 76 [03] ldaa ADR3H 313: 0960 6A 30 [02] staa 1,x+ 314: 0962 96 78 [03] ldaa ADR4H 315: 0964 6A 30 [02] staa 1,x+ 316: 0966 96 7A [03] ldaa ADR5H 317: 0968 6A 30 [02] staa 1,x+ 318: 096A 96 7C [03] ldaa ADR6H 319: 096C 6A 30 [02] staa 1,x+ 320: 096E 96 7E [03] ldaa ADR7H 321: 0970 6A 30 [02] staa 1,x+ 322: 0972 F6 0806 [03] ldab ValueTable+6 323: 0975 5B 00 [02] stab PORTA 324: 0977 20 D2 [03] bra AtoDloop 325: * 326: ********************************************************* 327: * 328: * Timer interrupt demo Timer 5 does regular timer 329: * interval interrupts 5 times per second and 330: * toggles output bit PT5. Timer 1 counts until 331: * a one-to-zero transition is detected on PT1 332: * at which point the most significant half of 333: * the TCNT register is output on Port A 334: * 335: =00000800 flags equ $800 ; Debug RAM copy of Timer IRQ Status 336: =00000B2C Timer1vec equ $0b2c ; Ram IRQ vector locations 337: =00000B24 Timer5vec equ $0b24 ; was $ffe4 for ROM & $f7e4 338: 339: 0979 79 0016 [03] Fast_Timer clr COPCTL ; disable watchdog 340: 097C CF 0A00 [02] lds #USER_STACKTOP ; load stackpointer 341: * 342: 097F 1410 [01] sei ; disable interrupts for moment 343: * 344: 0981 1803 09CE 0B2C [05] movw #Timer1IRQ,Timer1vec ; initialize interrupt 345: 0987 1803 09D9 0B24 [05] movw #Timer5IRQ,Timer5vec ; vector locations 346: 098D 79 0800 [03] clr flags ; a RAM debug location 347: * 348: 0990 79 001E [03] clr INTCR ; see page 53 section 9.3 349: 0993 C6 FF [01] ldab #$ff ; set Port A all outputs for 350: 0995 5B 02 [02] stab DDRA ; displaying TCNT (msb) when an 351: * ; an external falling edge pulse 352: * ; arrives on bit PT5 353: * 354: 0997 79 008C [03] clr TMSK1 ; disable all interrupts for now 355: 099A C6 05 [01] ldab #%00000101 ; 8MHz / 32 = 250KHz 356: 099C 5B 8D [02] stab TMSK2 357: 099E C6 08 [01] ldab #%00001000 ; enable timer 1 capture on 358: 09A0 5B 8B [02] stab TCTL4 ; falling edge 359: 09A2 C6 20 [01] ldab #$20 ; enable output compare 360: 09A4 5B 80 [02] stab TIOS ; on Timer 5 output (bit 5) 361: * 362: 09A6 C6 04 [01] ldab #$04 ; enable toggle output on OC5 363: 09A8 5B 88 [02] stab TCTL1 364: 09AA C6 00 [01] ldab #$00 ; no timer outputs on OC3-OC0 365: 09AC 5B 89 [02] stab TCTL2 ; 366: 09AE C6 00 [01] ldab #$00 ; No timer input captures on 7-4 367: 09B0 5B 8A [02] stab TCTL3 ; 368: 09B2 C6 22 [01] ldab #%00100010 ; enable two interrupts 369: 09B4 5B 8C [02] stab TMSK1 ; OC5 and IC1 370: 09B6 96 8E [03] ldaa TFLG1 ; just to read it before 371: 09B8 C6 FF [01] ldab #$ff ; clearing any possible spurious 372: 09BA 5B 8E [02] stab TFLG1 ; timer interrupts 373: 09BC DC 84 [03] ldd TCNTH ; schedule first interrupt in 374: 09BE C3 C350 [02] addd #50000 ; future 375: 09C1 5C 92 [02] std TC1H 376: 09C3 5C 9A [02] std TC5H ; may not be necessary 377: 09C5 C6 80 [01] ldab #$80 378: 09C7 5B 86 [02] stab TSCR ; turn on timers 379: 09C9 10EF [01] cli ; enable interrupts 380: 09CB A7 [01] backgnd nop 381: 09CC 20 FD [03] bra backgnd 382: * 383: 09CE D6 8E [03] Timer1IRQ ldab TFLG1 ; just to read it 384: 09D0 C6 02 [01] ldab #$02 ; clear C2F in TFLG1 385: 09D2 5B 8E [02] stab TFLG1 386: 09D4 DC 92 [03] ldd TC1H ; get entire TCNT at time of 387: * ; external hi-to-low pulse 388: 09D6 5A 00 [02] staa PORTA ; display hi-order TCNT 389: * 390: * maybe do something "useful" 391: * 392: 09D8 0B [08] rti 393: * 394: 09D9 D6 8E [03] Timer5IRQ ldab TFLG1 ; copy timer status 395: 09DB 7B 0800 [03] stab flags 396: * 397: 09DE C6 20 [01] ldab #$20 ; clear Timer 5 OCFlag 398: 09E0 5B 8E [02] stab TFLG1 ; 399: * 400: 09E2 DC 9A [03] ldd TC5H ; schedule next interrupt in 401: 09E4 C3 C350 [02] addd #50000 ; future 402: 09E7 5C 9A [02] std TC5H 403: * 404: * maybe do something useful 405: * 406: 09E9 0B [08] rti 407: 09EA 1C 09F3 04 [04] TestInstr bset Dummy,#4 408: 09EE 1E 09F3 03 E6 [05] brset Dummy,#3,Timer5IRQ 409: 09F3 +0001 Dummy ds.b 1 Symbols: adr0h *00000070 adr1h *00000072 adr2h *00000074 adr3h *00000076 adr4h *00000078 adr5h *0000007a adr6h *0000007c adr7h *0000007e atdctl2 *00000062 atdctl5 *00000065 atdstath *00000066 atodloop *0000094b back *000008fb backgnd *000009cb copctl *00000016 ddra *00000002 ddrb *00000003 ddrp *00000057 delay *000008c0 dummy *000009f3 flags *00000800 hello *00000802 intcr *0000001e l1 *0000082e l2 *00000834 limitend *000008dd limiter *000008d5 ll1 *0000092b ll2 *00000931 loop *000008b1 main *00000811 map_page *00000000 nextchar *00000917 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 *00000935 sendcr *0000091f sendstring *00000910 stringbuffer *00000800 tc1h *00000092 tc5h *0000009a tcnth *00000084 tctl1 *00000088 tctl2 *00000089 tctl3 *0000008a tctl4 *0000008b tflg1 *0000008e timer1irq *000009ce timer1vec *00000b2c timer5irq *000009d9 timer5vec *00000b24 tios *00000080 tmsk1 *0000008c tmsk2 *0000008d tscr *00000086 user_ram_size *00000200 user_stacktop *00000a00 valuetable *00000800 waitchr *000008fe