Advertisement
Guest User

Untitled

a guest
Nov 15th, 2019
189
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.35 KB | None | 0 0
  1. ;*****************************************************************
  2. ;* This stationery serves as the framework for a *
  3. ;* user application (single file, absolute assembly application) *
  4. ;* For a more comprehensive program that *
  5. ;* demonstrates the more advanced functionality of this *
  6. ;* processor, please see the demonstration applications *
  7. ;* located in the examples subdirectory of the *
  8. ;* Freescale CodeWarrior for the HC12 Program directory *
  9. ;*****************************************************************
  10.  
  11. ; export symbols
  12. XDEF Entry, _Startup ; export 'Entry' symbol
  13. ABSENTRY Entry ; for absolute assembly: mark this as application entry point
  14.  
  15.  
  16.  
  17. ; Include derivative-specific definitions
  18. INCLUDE 'derivative.inc'
  19.  
  20. ROMStart EQU $4000 ; absolute address to place my code/constant data
  21.  
  22.  
  23. ; equates section
  24.  
  25. LCD_DAT EQU PORTB ; LCD data port, bits - PB7,...,PB0
  26. LCD_CNTR EQU PTJ ; LCD control port, bits - PJ7(E),PJ6(RS)
  27. LCD_E EQU $80 ; LCD E-signal pin
  28. LCD_RS EQU $40 ; LCD RS-signal pin
  29. FWD_INT EQU 69 ; 3 second delay (at 23Hz)
  30. REV_INT EQU 69 ; 3 second delay (at 23Hz)
  31. FWD_TRN_INT EQU 46 ; 2 second delay (at 23Hz)
  32. REV_TRN_INT EQU 46 ; 2 second delay (at 23Hz)
  33. START EQU 0
  34. FWD EQU 1
  35. REV EQU 2
  36. ALL_STP EQU 3
  37. FWD_TRN EQU 4
  38. REV_TRN EQU 5
  39.  
  40.  
  41. ; variable/data section
  42.  
  43. ORG $3850
  44.  
  45. TOF_COUNTER dc.b 0 ; The timer, incremented at 23Hz
  46. CRNT_STATE dc.b 3 ; Current state register
  47. T_FWD ds.b 1 ; FWD time
  48. T_REV ds.b 1 ; REV time
  49. T_FWD_TRN ds.b 1 ; FWD_TURN time
  50. T_REV_TRN ds.b 1 ; REV_TURN time
  51. TEN_THOUS ds.b 1 ; 10,000 digit
  52. THOUSANDS ds.b 1 ; 1,000 digit
  53. HUNDREDS ds.b 1 ; 100 digit
  54. TENS ds.b 1 ; 10 digit
  55. UNITS ds.b 1 ; 1 digit
  56. NO_BLANK ds.b 1 ; Used in ’leading zero’ blanking by BCD2ASC
  57. BCD_SPARE RMB 10
  58.  
  59.  
  60.  
  61. ; code section
  62. ORG $4000
  63.  
  64.  
  65. Entry:
  66. _Startup:
  67.  
  68. CLI ; Enable interrupts |
  69. LDS #$4000 ; Initialize the stack pointer
  70. ; I
  71. BSET DDRA,%00000011 ; STAR_DIR, PORT_DIR N
  72. BSET DDRT,%00110000 ; STAR_SPEED, PORT_SPEED I
  73. ; T
  74. JSR initAD ; Initialize ATD converter I
  75. ; A
  76. JSR initLCD ; Initialize the LCD L
  77. JSR clrLCD ; Clear LCD & home cursor I
  78. ; Z
  79. LDX #msg1 ; Display msg1 A
  80. JSR putsLCD ; " T
  81. ; I
  82. LDAA #$C0 ; Move LCD cursor to the 2nd row O
  83. JSR cmd2LCD ; N
  84. LDX #msg2 ; Display msg2 |
  85. JSR putsLCD ; " |
  86. ; |
  87. JSR ENABLE_TOF ; Jump to TOF initialization ---------------
  88. MAIN JSR UPDT_DISPL ; ----------------------------------------- M
  89. LDAA CRNT_STATE ; A
  90. JSR DISPATCHER ; I
  91. BRA MAIN ;
  92.  
  93.  
  94. ; Insert here your data definition.
  95.  
  96.  
  97. msg1 dc.b "Battery volt ",0
  98. msg2 dc.b "State ",0
  99. tab dc.b "START ",0
  100. dc.b "FWD ",0
  101. dc.b "REV ",0
  102. dc.b "ALL_STP",0
  103. dc.b "FWD_TRN",0
  104. dc.b "REV_TRN",0
  105.  
  106.  
  107. ; subroutine section
  108. ;*******************************************************************
  109. DISPATCHER CMPA #START ; If it’s the START state -----------------
  110. BNE NOT_START ; |
  111. JSR START_ST ; then call START_ST routine D
  112. BRA DISP_EXIT ; and exit I
  113. ; S
  114. NOT_START CMPA #FWD ; Else if it’s the FORWARD state
  115. BNE NOT_FWD
  116. JSR FWD_ST ; then call the FORWARD routine
  117. JMP DISP_EXIT ; and exit
  118.  
  119. NOT_FWD CMPA #REV ; Else if it’s the REVERSE state
  120. BNE NOT_REV
  121. JSR REV_ST ; then call the REVERSE routine
  122. JMP DISP_EXIT ; and exit
  123.  
  124. NOT_REV CMPA #ALL_STP ; Else if it’s the ALL_STOP state
  125. BNE NOT_ALL_STP
  126. JSR ALL_STP_ST ; then call the ALL_STOP routine
  127. JMP DISP_EXIT ; and exit
  128.  
  129. NOT_ALL_STP CMPA #FWD_TRN ; Else if it’s the FORWARD_TURN state
  130. BNE NOT_FWD_TRN
  131. JSR FWD_TRN_ST ; then call the FORWARD_TURN routine
  132. JMP DISP_EXIT
  133. ; T
  134. NOT_FWD_TRN CMPA #REV_TRN ; Else if it’s the REV_TRN state C
  135. BNE NOT_REV_TRN ; H
  136. JSR REV_TRN_ST ; then call REV_TRN_ST routine E
  137. BRA DISP_EXIT ; and exit R
  138. ; |
  139. NOT_REV_TRN SWI ; Else the CRNT_ST is not defined, so stop |
  140. DISP_EXIT RTS ; Exit from the state dispatcher ----------
  141. ;*******************************************************************
  142. START_ST
  143. LDAA TOF_COUNTER
  144. CMPA T_FWD
  145. BRCLR PORTAD0,$04,NO_FWD
  146. JSR INIT_FWD
  147. movb #FWD,CRNT_STATE
  148. BRA START_EXIT
  149. NO_FWD NOP ; Else
  150. START_EXIT RTS ; return to the MAIN routine
  151.  
  152. ;*******************************************************************
  153. FWD_ST LDAA TOF_COUNTER ; If Tc>Trev then
  154. CMPA T_FWD ; the robot should make a FWD turn
  155. BRSET PORTAD0,$04,NO_FWD_BUMP ; If FWD_BUMP
  156. JSR INIT_REV
  157. MOVB #REV,CRNT_STATE ; set the state to rev
  158. BRA FWD_EXIT ; and return
  159.  
  160. NO_FWD_BUMP BRSET PORTAD0,$08,NO_REAR_BUMP ; If REAR_BUMP, then we should stop
  161. JSR INIT_ALL_STP ; so initialize the ALL_STOP state
  162. MOVB #ALL_STP,CRNT_STATE ; and change state to ALL_STOP
  163. JMP FWD_EXIT
  164.  
  165. NO_REAR_BUMP LDAA TOF_COUNTER ; If Tc>Trev then
  166. CMPA T_FWD ; the robot should make a FWD turn
  167. BNE NO_FWD_TRN ; so
  168. JSR INIT_FWD_TRN ; initialize the REV_TRN state
  169. MOVB #FWD_TRN,CRNT_STATE ; set state to REV_TRN
  170. BRA FWD_EXIT ; and return
  171.  
  172.  
  173. NO_FWD_TRN NOP ; Else
  174. FWD_EXIT RTS ; return to the MAIN routine
  175. ;*******************************************************************
  176. REV_ST LDAA TOF_COUNTER ; If Tc>Trev then
  177. CMPA T_REV ; the robot should make a FWD turn
  178. BNE NO_REV_TRN ; so
  179. JSR INIT_REV_TRN ; initialize the REV_TRN state
  180. MOVB #REV_TRN,CRNT_STATE ; set state to REV_TRN
  181. BRA REV_EXIT ; and return
  182. NO_REV_TRN NOP ; Else
  183. REV_EXIT RTS ; return to the MAIN routine
  184. ;*******************************************************************
  185. ALL_STP_ST BRSET PORTAD0,$04,NO_START ; If FWD_BUMP
  186. BCLR PTT,%00110000 ; initialize the START state (both motors off)
  187. MOVB #START,CRNT_STATE ; set the state to START
  188. BRA ALL_STP_EXIT ; and return
  189. NO_START NOP ; Else
  190. ALL_STP_EXIT RTS ; return to the MAIN routine
  191. ;*******************************************************************
  192. FWD_TRN_ST LDAA TOF_COUNTER ; If Tc>Tfwdturn then
  193. CMPA T_FWD_TRN ; the robot should go FWD
  194. BNE NO_FWD_FT ; so
  195. JSR INIT_FWD ; initialize the FWD state
  196. MOVB #FWD,CRNT_STATE ; set state to FWD
  197. BRA FWD_TRN_EXIT ; and return
  198. NO_FWD_FT NOP ; Else
  199. FWD_TRN_EXIT RTS ; return to the MAIN routine
  200. ;*******************************************************************
  201. REV_TRN_ST LDAA TOF_COUNTER ; If Tc>Trevturn then
  202. CMPA T_REV_TRN ; the robot should go FWD
  203. BNE NO_FWD_RT ; so
  204. JSR INIT_FWD ; initialize the FWD state
  205. MOVB #FWD,CRNT_STATE ; set state to FWD
  206. BRA REV_TRN_EXIT ; and return
  207. NO_FWD_RT NOP ; Else
  208. REV_TRN_EXIT RTS ; return to the MAIN routine
  209. ;*******************************************************************
  210. INIT_FWD BCLR PORTA,%00000011 ; Set FWD direction for both motors
  211. BSET PTT,%00110000 ; Turn on the drive motors
  212. LDAA TOF_COUNTER ; Mark the fwd time Tfwd
  213. ADDA #FWD_INT
  214. STAA T_FWD
  215. RTS
  216. ;*******************************************************************
  217. INIT_REV BSET PORTA,%00000011 ; Set REV direction for both motors
  218. BSET PTT,%00110000 ; Turn on the drive motors
  219. LDAA TOF_COUNTER ; Mark the fwd time Tfwd
  220. ADDA #REV_INT
  221. STAA T_REV
  222. RTS
  223. ;*******************************************************************
  224. INIT_ALL_STP BCLR PTT,%00110000 ; Turn off the drive motors
  225. RTS
  226. ;*******************************************************************
  227. INIT_FWD_TRN BSET PORTA,%00000010 ; Set REV dir. for STARBOARD (right) motor
  228. LDAA TOF_COUNTER ; Mark the fwd_turn time Tfwdturn
  229. ADDA #FWD_TRN_INT
  230. STAA T_FWD_TRN
  231. RTS
  232. ;*******************************************************************
  233. INIT_REV_TRN BCLR PORTA,%00000010 ; Set FWD dir. for STARBOARD (right) motor
  234. LDAA TOF_COUNTER ; Mark the fwd time Tfwd
  235. ADDA #REV_TRN_INT
  236. STAA T_REV_TRN
  237. RTS
  238.  
  239. ; utility subroutines
  240. ;*******************************************************************
  241. ;* Initialization of the LCD: 4-bit data width, 2-line display, *
  242. ;* turn on display, cursor and blinking off. Shift cursor right. *
  243. ;*******************************************************************
  244.  
  245.  
  246. initLCD BSET DDRB,%11111111 ; configure pins PS7,PS6,PS5,PS4 for output
  247. BSET DDRJ,%11000000 ; configure pins PE7,PE4 for output
  248. LDY #2000 ; wait for LCD to be ready
  249. JSR del_50us ; -"-
  250. LDAA #$28 ; set 4-bit data, 2-line display
  251. JSR cmd2LCD ; -"-
  252. LDAA #$0C ; display on, cursor off, blinking off
  253. JSR cmd2LCD ; -"-
  254. LDAA #$06 ; move cursor right after entering a character
  255. JSR cmd2LCD ; -"-
  256. RTS
  257.  
  258. ;*******************************************************************
  259. ;* Clear display and home cursor *
  260. ;*******************************************************************
  261.  
  262.  
  263. clrLCD LDAA #$01 ; clear cursor and return to home position
  264. JSR cmd2LCD ; -"-
  265. LDY #40 ; wait until "clear cursor" command is complete
  266. JSR del_50us ; -"-
  267. RTS
  268.  
  269. ;*******************************************************************
  270. del_50us PSHX ; (2 E-clk) Protect the X register
  271. eloop LDX #300 ; (2 E-clk) Initialize the inner loop counter
  272. iloop NOP ; (1 E-clk) No operation
  273. DBNE X,iloop ; (3 E-clk) If the inner cntr not 0, loop again
  274. DBNE Y,eloop ; (3 E-clk) If the outer cntr not 0, loop again
  275. PULX ; (3 E-clk) Restore the X register
  276. RTS ; (5 E-clk) Else return
  277.  
  278. ;*******************************************************************
  279. ;* This function sends a command in accumulator A to the LCD *
  280. ;*******************************************************************
  281.  
  282. cmd2LCD: BCLR LCD_CNTR,LCD_RS ; select the LCD Instruction Register (IR)
  283. JSR dataMov ; send data to IR
  284. RTS
  285.  
  286.  
  287. ;*******************************************************************
  288. ;* This function outputs a NULL-terminated string pointed to by X *
  289. ;*******************************************************************
  290.  
  291. putsLCD LDAA 1,X+ ; get one character from the string
  292. BEQ donePS ; reach NULL character?
  293. JSR putcLCD
  294. BRA putsLCD
  295. donePS RTS
  296.  
  297. ;*******************************************************************
  298. ;* This function outputs the character in accumulator in A to LCD *
  299. ;*******************************************************************
  300.  
  301. putcLCD BSET LCD_CNTR,LCD_RS ; select the LCD Data register (DR)
  302. JSR dataMov ; send data to DR
  303. RTS
  304.  
  305.  
  306. ;*******************************************************************
  307. ;* This function sends data to the LCD IR or DR depening on RS *
  308. ;*******************************************************************
  309.  
  310.  
  311. dataMov BSET LCD_CNTR,LCD_E ; pull the LCD E-sigal high
  312. STAA LCD_DAT ; send the upper 4 bits of data to LCD
  313. BCLR LCD_CNTR,LCD_E ; pull the LCD E-signal low to complete the write oper.
  314. LSLA ; match the lower 4 bits with the LCD data pins
  315. LSLA ; -"-
  316. LSLA ; -"-
  317. LSLA ; -"-
  318. BSET LCD_CNTR,LCD_E ; pull the LCD E signal high
  319. STAA LCD_DAT ; send the lower 4 bits of data to LCD
  320. BCLR LCD_CNTR,LCD_E ; pull the LCD E-signal low to complete the write oper.
  321. LDY #1 ; adding this delay will complete the internal
  322. JSR del_50us ; operation for most instructions
  323. RTS
  324.  
  325. ;*******************************************************************
  326. initAD MOVB #$C0,ATDCTL2 ;power up AD, select fast flag clear
  327. JSR del_50us ;wait for 50 us
  328. MOVB #$00,ATDCTL3 ;8 conversions in a sequence
  329. MOVB #$85,ATDCTL4 ;res=8, conv-clks=2, prescal=12
  330. BSET ATDDIEN,$0C ;configure pins AN03,AN02 as digital inputs
  331. RTS
  332.  
  333. ;*******************************************************************
  334. int2BCD XGDX ;Save the binary number into .X
  335. LDAA #0 ;Clear the BCD_BUFFER
  336. STAA TEN_THOUS
  337. STAA THOUSANDS
  338. STAA HUNDREDS
  339. STAA TENS
  340. STAA UNITS
  341. STAA BCD_SPARE
  342. STAA BCD_SPARE+1
  343. *
  344. CPX #0 ;Check for a zero input
  345. BEQ CON_EXIT ;and if so, exit
  346. *
  347. XGDX ;Not zero, get the binary number back to .D as dividend
  348. LDX #10 ;Setup 10 (Decimal!) as the divisor
  349. IDIV ;Divide: Quotient is now in .X, remainder in .D
  350. STAB UNITS ;Store remainder
  351. CPX #0 ;If quotient is zero,
  352. BEQ CON_EXIT ;then exit
  353. *
  354. XGDX ;else swap first quotient back into .D
  355. LDX #10 ;and setup for another divide by 10
  356. IDIV
  357. STAB TENS
  358. CPX #0
  359. BEQ CON_EXIT
  360. *
  361. XGDX ;Swap quotient back into .D
  362. LDX #10 ;and setup for another divide by 10
  363. IDIV
  364. STAB HUNDREDS
  365. CPX #0
  366. BEQ CON_EXIT
  367. *
  368. XGDX ;Swap quotient back into .D
  369. LDX #10 ;and setup for another divide by 10
  370. IDIV
  371. STAB THOUSANDS
  372. CPX #0
  373. BEQ CON_EXIT
  374. *
  375. XGDX ;Swap quotient back into .D
  376. LDX #10 ;and setup for another divide by 10
  377. IDIV
  378. STAB TEN_THOUS
  379. *
  380. CON_EXIT RTS ;We’re done the conversion
  381.  
  382. ;*******************************************************************
  383.  
  384. BCD2ASC LDAA #0 ;Initialize the blanking flag
  385. STAA NO_BLANK
  386. *
  387. C_TTHOU LDAA TEN_THOUS ;Check the ’ten_thousands’ digit
  388. ORAA NO_BLANK
  389. BNE NOT_BLANK1
  390. *
  391. ISBLANK1 LDAA #' ' ;It’s blank
  392. STAA TEN_THOUS ;so store a space
  393. BRA C_THOU ;and check the ’thousands’ digit
  394. *
  395. NOT_BLANK1 LDAA TEN_THOUS ;Get the ’ten_thousands’ digit
  396. ORAA #$30 ;Convert to ascii
  397. STAA TEN_THOUS
  398. LDAA #$1 ;Signal that we have seen a ’non-blank’ digit
  399. STAA NO_BLANK
  400. *
  401. C_THOU LDAA THOUSANDS ;Check the thousands digit for blankness
  402. ORAA NO_BLANK ;If it’s blank and ’no-blank’ is still zero
  403. BNE NOT_BLANK2
  404. *
  405. ISBLANK2 LDAA #' ' ;Thousands digit is blank
  406. STAA THOUSANDS ;so store a space
  407. BRA C_HUNS ;and check the hundreds digit
  408. *
  409. NOT_BLANK2 LDAA THOUSANDS ;(similar to ’ten_thousands’ case)
  410. ORAA #$30
  411. STAA THOUSANDS
  412. LDAA #$1
  413. STAA NO_BLANK
  414. *
  415. C_HUNS LDAA HUNDREDS ;Check the hundreds digit for blankness
  416. ORAA NO_BLANK ;If it’s blank and ’no-blank’ is still zero
  417. BNE NOT_BLANK3
  418. *
  419. ISBLANK3 LDAA #' ' ;Hundreds digit is blank
  420. STAA HUNDREDS ;so store a space
  421. BRA C_TENS ;and check the tens digit
  422. *
  423. NOT_BLANK3 LDAA HUNDREDS ;(similar to ’ten_thousands’ case)
  424. ORAA #$30
  425. STAA HUNDREDS
  426. LDAA #$1
  427. STAA NO_BLANK
  428. *
  429. C_TENS LDAA TENS ;Check the tens digit for blankness
  430. ORAA NO_BLANK ;If it’s blank and ’no-blank’ is still zero
  431. BNE NOT_BLANK4
  432. *
  433. ISBLANK4 LDAA #' ' ;Tens digit is blank
  434. STAA TENS ;so store a space
  435. BRA C_UNITS ;and check the units digit
  436. *
  437. NOT_BLANK4 LDAA TENS ;(similar to ’ten_thousands’ case)
  438. ORAA #$30
  439. STAA TENS
  440. *
  441. C_UNITS LDAA UNITS ;No blank check necessary, convert to ascii.
  442. ORAA #$30
  443. STAA UNITS
  444. *
  445. RTS ;We’re done
  446.  
  447. ;************************************************************
  448. ENABLE_TOF LDAA #%10000000
  449. STAA TSCR1 ; Enable TCNT
  450. STAA TFLG2 ; Clear TOF
  451. LDAA #%10000100 ; Enable TOI and select prescale factor equal to 16
  452. STAA TSCR2
  453. RTS
  454. ;************************************************************
  455. TOF_ISR INC TOF_COUNTER
  456. LDAA #%10000000 ; Clear
  457. STAA TFLG2 ; TOF
  458. RTI
  459.  
  460. ;************************************************************
  461. DISABLE_TOF LDAA #%00000100 ; Disable TOI and leave prescale factor at 16
  462. STAA TSCR2
  463. RTS
  464.  
  465. ;*******************************************************************
  466. ;* Update Display (Battery Voltage + Current State) *
  467. ;*******************************************************************
  468. UPDT_DISPL MOVB #$90,ATDCTL5 ; R-just., uns., sing. conv., mult., ch=0, start
  469. BRCLR ATDSTAT0,$80,* ; Wait until the conver. seq. is complete
  470. LDAA ATDDR0L ; Load the ch0 result - battery volt - into A
  471. LDAB #39 ;AccB = 39
  472. MUL ;AccD = 1st result x 39
  473. ADDD #600 ;AccD = 1st result x 39 + 600
  474. JSR int2BCD
  475. JSR BCD2ASC
  476. LDAA #$8C ;move LCD cursor to the 1st row, end of msg1
  477. JSR cmd2LCD ;"
  478. LDAA TEN_THOUS ;output the TEN_THOUS ASCII character
  479. JSR putcLCD ;"
  480. LDAA THOUSANDS
  481. JSR putcLCD
  482. LDAA #'.'
  483. JSR putcLCD
  484. LDAA HUNDREDS
  485. JSR putcLCD
  486. LDAA TENS
  487. JSR putcLCD
  488. LDAA UNITS
  489. JSR putcLCD ; Display the battery voltage
  490. ;-------------------------
  491. LDAA #$C6 ; Move LCD cursor to the 2nd row, end of msg2
  492. JSR cmd2LCD ;
  493. LDAB CRNT_STATE ; Display current state
  494. LSLB
  495. LSLB
  496. LSLB
  497. LDX #tab ; "
  498. ABX ; "
  499. JSR putsLCD ; "
  500. RTS
  501.  
  502. ;**************************************************************
  503. ;* Interrupt Vectors *
  504. ;**************************************************************
  505. ORG $FFFE
  506. DC.W Entry ; Reset Vector
  507. ORG $FFDE
  508. DC.W TOF_ISR ; Timer Overflow Interrupt Vector
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement