Zorbing

[TGI] Versuch 11

Jan 30th, 2014
298
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. .include "m16def.inc"
  2.  
  3. #define     SIMULATOR   1           ; set to 1 when running on the simulator to deactivate the UART and the delay
  4.  
  5. ; *********************************************************************
  6. ; Command headers
  7. ; *********************************************************************
  8. .equ    PROD_HEADER     = 0x40
  9. .equ    COIN_HEADER     = 0x00
  10. .equ    DISPLAY_HEADER  = 0x80
  11.  
  12.  
  13. ; *********************************************************************
  14. ; Registers symbolic name
  15. ; *********************************************************************
  16. .def    cmd     = r17               ; command, used in all the UART operation
  17. .def    tmp1    = r18               ; Temp register
  18. .def    tmp2    = r16               ; Temp register
  19. .def    coinVal = r19
  20. .def    creditTmp = r20
  21.  
  22.  
  23. ; *********************************************************************
  24. ; UART parameter
  25. ; *********************************************************************
  26. .equ F_CPU = 1000000                ; Systemtakt in Hz
  27. .equ BAUD  = 9600                   ; Baudrate
  28.  
  29. ; Berechnungen
  30. .equ UBRR_VAL   = ((2*F_CPU+BAUD*8)/(BAUD*16)-1)    ; clever runden
  31. .equ BAUD_REAL  = (2*F_CPU/(16*(UBRR_VAL+1)))       ; Reale Baudrate
  32. .equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)      ; Fehler in Promille
  33.  
  34. .if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))           ; max. +/-10 Promille Fehler
  35.     .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
  36. .endif
  37.  
  38. ; *********************************************************************
  39. ; RAM allocation: current credit, and products' price
  40. ; *********************************************************************
  41. .dseg
  42. .org 0x00060
  43. CREDIT: .byte 1                     ; allocate RAM for CREDIT
  44. PRICE:  .byte 64                    ; allocate RAM for PRICE
  45. _RAM_:                              ; to mark the end of the allocated ram: DO NOT CHANGE IT!
  46.  
  47. .cseg
  48. .org 0000
  49.     rjmp    main_init
  50.  
  51. ; *********************************************************************
  52. ; Constants in PROGRAM memory
  53. ; *********************************************************************
  54. .org 0x0030
  55. ; Products price array. It is possible to add values or change the existing ones
  56. const_PP:   .db 15, 12, 10, 30, 35, 8;
  57. _PP_end_:   ; to mark the end of the array
  58.  
  59. main_init:
  60.     ldi     r17,    high(_RAM_)
  61.     out     SPH,    r17
  62.     ldi     r17,    low(_RAM_)
  63.     out     SPL,    r17
  64.  
  65.     clr     r17
  66.     ldi     r19,    (_RAM_-CREDIT+1)
  67. __clear_ram:
  68.     push    r17
  69.     dec     r19
  70.     brne    __clear_ram
  71.  
  72.     ldi     XL,     low(PRICE)
  73.     ldi     XH,     high(PRICE)
  74.     ldi     ZL,     low(const_PP<<1)
  75.     ldi     ZH,     high(const_PP<<1)
  76.  
  77.     ldi     r19,    (_PP_end_-const_PP)
  78. __init__ram:
  79.     lpm     r17,    Z               ; first byte
  80.     ori     ZL,     0x01
  81.     lpm     r18,    Z+              ; second byte
  82.  
  83.     st      X+,     r17
  84.     st      X+,     r18
  85.  
  86.     dec     r19
  87.     brne    __init__ram
  88.  
  89. ; Baudrate einstellen
  90.     ldi     tmp1,   HIGH(UBRR_VAL)
  91.     out     UBRRH,  tmp1
  92.     ldi     tmp1,   LOW(UBRR_VAL)
  93.     out     UBRRL,  tmp1
  94.  
  95. ; Frame-Format: 8 Bit
  96.     ldi     tmp1,   (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)
  97.     out     UCSRC,  tmp1
  98.     sbi     UCSRA,  U2X
  99.  
  100.     sbi     UCSRB,  TXEN            ; TX aktivieren
  101.     sbi     UCSRB,  RXEN            ; RX aktivieren
  102.  
  103. ; TODO: Stackpointer initialisieren
  104.     ldi     tmp1,   high(RAMEND)
  105.     out     SPH,    tmp1
  106.     ldi     tmp1,   low(RAMEND)
  107.     out     SPL,    tmp1
  108.  
  109. ; TODO: setze das Display auf 0
  110.     ldi     cmd,    (1<<7)
  111.     call    serout
  112.  
  113. main:
  114.     call    serin
  115.     sbrc    cmd,    7
  116.     rjmp    main
  117.     ; decode the command
  118.     sbrs    cmd,    6
  119.     call    coin
  120.     sbrc    cmd,    6
  121.     call    product
  122.     rjmp    main
  123. ; end main
  124.  
  125.  
  126. ; *********************************************************************
  127. ; COIN
  128. ;
  129. ; Decode, update the CREDIT
  130. ; *********************************************************************
  131. coin:
  132.     ldi     YL,     low(CREDIT)
  133.     ldi     YH,     high(CREDIT)
  134.     ld      creditTmp, Y            ; load the credit value
  135.     sbrc    cmd,    5
  136.     rjmp    coins_back              ; eject all coins (bit 5 is set)
  137.     ; decode coin value
  138.     call    decode_coin             ; get coinVal from cmd
  139.     ; check new credit
  140.     add     creditTmp, coinVal      ; add coin to credit
  141.     cpi     creditTmp, 100          ; compare with 100 (represents 10,0 Euro)
  142.     brsh    last_coin_back          ; more than allowed? -> return last coin
  143.     ; update CREDIT
  144.     st      Y,      creditTmp       ; save credit value to RAM
  145.     call    display_update          ; update the display
  146.     ret
  147.  
  148. coins_back:
  149.     call    change_back
  150.     call    display_update          ; update the display
  151.     ret
  152.  
  153. last_coin_back:
  154.     call    serout                  ; cmd is still the coin command
  155.     ret
  156.  
  157.  
  158. decode_coin:
  159.     clr     coinVal                 ; ready to store the coin value
  160.     ; 10 Cent
  161.     sbrc    cmd,    0
  162.     ldi     coinVal, 1
  163.     ; 20 Cent
  164.     sbrc    cmd,    1
  165.     ldi     coinVal, 2
  166.     ; 50 Cent
  167.     sbrc    cmd,    2
  168.     ldi     coinVal, 5
  169.     ; 1 Euro
  170.     sbrc    cmd,    3
  171.     ldi     coinVal, 10
  172.     ; 2 Euro
  173.     sbrc    cmd,    4
  174.     ldi     coinVal, 20
  175.     ret
  176.  
  177.  
  178. ; *********************************************************************
  179. ; PRODUCT
  180. ;
  181. ; Decode, lookup price, release or show the price
  182. ; *********************************************************************
  183. product:
  184.     ldi     XL,     low(PRICE)
  185.     ldi     XH,     high(PRICE)
  186.     andi    cmd,    0b00111111      ; remove the first two bits (2 MSB)
  187.     add     XL,     cmd
  188.     clr     tmp1
  189.     adc     XH,     tmp1
  190. ; TODO: pre-decrement or not?
  191. ; is the first product 0b00000001?
  192. ;   ld      tmp1,   -X              ; load the price
  193.     ld      tmp1,   X               ; load the price
  194.     tst     tmp1
  195.     brne    product_ret
  196.     ldi     YL,     low(CREDIT)
  197.     ldi     YH,     high(CREDIT)
  198.     ld      creditTmp, Y            ; load the credit value
  199.     sub     creditTmp, tmp1         ; substract the price from the credits
  200.     brmi    display_blink           ; not enough credits
  201.     ; output the product
  202.     call    serout                  ; cmd is still the command of the requested product
  203.     st      Y,      creditTmp       ; save the new credits
  204.     call    change_back             ; return the change
  205.     call    display_update
  206.     ret
  207.  
  208. display_blink:
  209.     mov     cmd,    tmp1
  210.     ori     cmd,    (1<<7)
  211.     call    serout                  ; output price
  212.     call    delay_500ms
  213.     call    delay_500ms
  214.  
  215.     ser     cmd                     ; set cmd to $FF (display off)
  216.     call    serout
  217.     call    delay_500ms
  218.  
  219.     mov     cmd,    tmp1
  220.     ori     cmd,    (1<<7)
  221.     call    serout                  ; output price
  222.     call    delay_500ms
  223.     call    delay_500ms
  224.  
  225.     call    display_update
  226. product_ret:
  227.     ret
  228.  
  229. ; *********************************************************************
  230. ; Give CHANGE back
  231. ;
  232. ; Return the change minimizing the number of returned coins
  233. ; *********************************************************************
  234. change_back:
  235.     push    cmd
  236.     push    YL
  237.     push    YH
  238.  
  239.     ldi     YL,     low(CREDIT)
  240.     ldi     YH,     high(CREDIT)
  241.     ld      creditTmp, Y            ; load the credit value
  242.     ldi     cmd,    (1<<4)          ; set cmd to highest coin
  243. change_loop:
  244.     tst     creditTmp
  245.     breq    change_end              ; is credit empty?
  246.     call    decode_coin             ; get coin value
  247.     sub     creditTmp, coinVal      ; substract!
  248.     ; maybe brmi?
  249.     brlo    next_coin               ; next coin?
  250.     call    serout                  ; return that coin
  251.     rjmp    change_loop
  252.  
  253. next_coin:
  254.     lsr     cmd
  255.     add     creditTmp, coinVal
  256.     rjmp    change_loop
  257.  
  258. change_end:
  259.     clr     creditTmp
  260.     st      Y, creditTmp
  261.     pop     YH
  262.     pop     YL
  263.     pop     cmd
  264.     ret
  265.  
  266. ; *********************************************************************
  267. ; Display Update
  268. ;
  269. ; Update the display, based on the current CREDIT
  270. ; *********************************************************************
  271. display_update:
  272.     push    cmd
  273.     ld      creditTmp, Y                ; load the credit value
  274.     mov     cmd,    creditTmp
  275.     ori     cmd,    (1<<7)          ; set the display bit
  276.     call    serout
  277.     pop     cmd
  278.     ret
  279.  
  280.  
  281. ; *********************************************************************
  282. ; Delay routine
  283. ; *********************************************************************
  284. .equ    N1  =   234
  285. .equ    N2  =   255
  286. delay_500ms:
  287. #if !SIMULATOR                      ; prevent the simulator by executing the actual delay.
  288.     push    tmp1
  289.     push    tmp2
  290.     ldi     tmp2,   N1
  291. _delay_loop1:
  292.     dec     tmp2
  293.     breq    _delay_return
  294.     ldi     tmp1,   N2
  295. _delay_loop2:
  296.     nop
  297.     nop
  298.     nop
  299.     nop
  300.     nop
  301.     nop
  302.     nop
  303.     dec     tmp1
  304.     brne    _delay_loop2
  305.     nop
  306.     rjmp    _delay_loop1
  307.  
  308. _delay_return:
  309.     pop     tmp2
  310.     pop     tmp1
  311. #endif
  312.     ret
  313.  
  314. serout:
  315. #if !SIMULATOR
  316.     sbis    UCSRA,  UDRE
  317.     rjmp    serout
  318.     out     UDR,    cmd
  319. #endif
  320.     ret
  321.  
  322. serin:
  323. #if !SIMULATOR
  324.     sbis    UCSRA,  RXC
  325.     rjmp    serin                   ; loop back
  326.     in      cmd,    UDR             ; else get received byte in cmd
  327. #endif
  328.     ret
Advertisement
Add Comment
Please, Sign In to add comment