Advertisement
Guest User

LAB5A

a guest
Oct 19th, 2017
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.30 KB | None | 0 0
  1. ;still in the process of writing up comments, sorry if some parts don't make sense
  2. ;also some parts might not be needed, i didn't have enough time to thoroughly check
  3. ;what functions/lines of codes were doing nothing
  4.  
  5. .include "m2560def.inc"
  6.  
  7. .def temp = r16
  8. .def temp2 = r17
  9. .def ten = r18
  10. .def counter = r19
  11.  
  12. .def lcd = r20 ;to handle the LCD
  13. .def digit = r21 ;register to display digits
  14. .def holes = r22 ;register for hole in the motor that we use to calculate speed
  15. ;(note for function EXT_INT2: there are 4 holes)
  16.  
  17. .macro do_lcd_command
  18. ldi lcd, @0
  19. rcall lcd_command
  20. rcall lcd_wait
  21. .endmacro
  22.  
  23. .macro do_lcd_data
  24. ldi lcd, @0
  25. rcall lcd_data
  26. rcall lcd_wait
  27. .endmacro
  28.  
  29. ;need own register command because do_lcd_data does not work on registers
  30. .macro register_lcd_data
  31. mov lcd, @0
  32. subi lcd, -'0'
  33. rcall lcd_data
  34. rcall lcd_wait
  35. .endmacro
  36.  
  37. ;clear a word from memory
  38. ;the parameter A0 is the memory address for that word #
  39. .macro clear
  40. ldi YL, low(@0) ; load the memory address to Y
  41. ldi YH, high(@0)
  42. clr temp
  43. st Y+, temp ; clear the two bytes at @0 in SRAM
  44. st Y, temp
  45. .endmacro
  46.  
  47. .dseg
  48. TimerCounter: .byte 2 ;Temporary counter to see if 1 second has passed
  49.  
  50. ;just dealing with vector table stuff here, used to be really long but i cleaned up some stuff
  51. .cseg
  52. .org 0x0000
  53. jmp RESET
  54. jmp DEFAULT ;interrupt request 0 not dealt with
  55. jmp DEFAULT ;interrupt request 1 not dealt with
  56. .org INT2addr ;INT2addr is the address of the ext interrupt request 2
  57. jmp EXT_INT2 ;jump to the interrupt handler for the external interrupt
  58. .org OVF0addr ;OVF0addr is the address of the timer0 overflow interrupt vector
  59. jmp Timer0OVF ;jump to the interrupt handler for timer0 overflow
  60. jmp DEFAULT
  61.  
  62. DEFAULT:
  63. reti
  64.  
  65. ;standard stuff
  66. RESET:
  67. clr holes ;clear holes on reset//make sure that we're not using previous value of holes prior
  68. ldi r16, low(RAMEND)
  69. out SPL, r16
  70. ldi r16, high(RAMEND)
  71. out SPH, r16
  72. ser temp ;Set temp to all 1's
  73. out DDRC,temp ;Set PortC to Output
  74. clr temp
  75. out PORTC, temp ;Set all LED's to 0
  76. sei
  77.  
  78. ser r16 ;Set r16 all to 1's
  79. out DDRF, r16 ;Set PortF to Output
  80. out DDRA, r16 ;Set portA to Output
  81. clr r16 ;Setting r16 to 0
  82. out PORTF, r16
  83. out PORTA, r16
  84.  
  85. do_lcd_command 0b00111000 ; 2x5x7
  86. rcall sleep_5ms
  87. do_lcd_command 0b00111000 ; 2x5x7
  88. rcall sleep_1ms
  89. do_lcd_command 0b00111000 ; 2x5x7
  90. do_lcd_command 0b00111000 ; 2x5x7
  91. do_lcd_command 0b00001000 ; display off?
  92. do_lcd_command 0b00000001 ; clear display
  93. do_lcd_command 0b00000110 ; increment, no display shift
  94. do_lcd_command 0b00001110 ; Cursor on, bar, no blink
  95.  
  96. do_lcd_data 'S' ;make LCD display "Speed: "
  97. do_lcd_data 'p' ;was thinking of making it display units/second as well but too much effort
  98. do_lcd_data 'e'
  99. do_lcd_data 'e'
  100. do_lcd_data 'd'
  101. do_lcd_data ':'
  102. do_lcd_data ' '
  103.  
  104. rjmp main
  105.  
  106. incCounter:
  107. inc counter
  108. clr holes
  109. jmp back
  110.  
  111. EXT_INT2:
  112. in temp, SREG
  113. push temp
  114. push ten
  115. inc holes
  116. cpi holes,4 ;check if 1 whole spin has occurred (because there are 4 holes)
  117. breq incCounter
  118. rjmp EXT_INT2
  119.  
  120. END_INT2:
  121. pop ten
  122. pop temp
  123. out SREG, temp
  124. reti
  125.  
  126. Timer0OVF: ;interrupt subroutine to Timer0
  127. in temp, SREG
  128. push temp
  129. push YH ;save conflicting registers
  130. push YL
  131. push r25
  132. push r24
  133.  
  134. newSecond: ;load value of the temporary counter
  135. lds r24, TimerCounter
  136. lds r25, TimerCounter+1
  137. adiw r25:r24, 1 ;inc the temp counter by 1
  138.  
  139. cpi r24, low(781) ;check if (r25:r24) = 781 (100ms) since 7812 = 10^6/128 (1s)
  140. ldi temp, high(781) ;7812 = 10^6/128
  141. cpc r25, temp
  142. brne notSecond
  143.  
  144. isSecond: ;100ms is 781, since the counter is at 100ms
  145. do_lcd_command 0b00000001 ;Clear Display
  146. do_lcd_command 0b00000110 ;Increment, no display shift
  147. do_lcd_command 0b00001110 ;Cursor on, bar, no blink
  148.  
  149. do_lcd_data 'S'
  150. do_lcd_data 'p'
  151. do_lcd_data 'e'
  152. do_lcd_data 'e'
  153. do_lcd_data 'd'
  154. do_lcd_data ':'
  155. do_lcd_data ' '
  156. rjmp display
  157.  
  158. end:
  159. clr counter
  160. clear TimerCounter
  161. rjmp endIf
  162.  
  163. notSecond: ;store new value
  164. sts TimerCounter, r24
  165. sts TimerCounter+1, r25
  166.  
  167. endIf:
  168. pop r24 ;restore conflicting
  169. pop r25
  170. pop YL
  171. pop YH
  172. pop temp
  173. out SREG, temp
  174. reti
  175.  
  176. main:
  177. clear TimerCounter
  178. clr counter
  179. clr digit
  180.  
  181. ;external interrupt, mostly taken from prev. labs/lectures
  182. ldi temp, (2 << ISC20) ;Set INT0 as falling edge triggered interrupt
  183. sts EICRA, temp
  184. in temp, EIMSK ;Enable INT2
  185. ori temp, (1<<INT2)
  186. out EIMSK, temp
  187.  
  188. ;timer 0
  189. ldi temp, 0b00000000 ;Loading 0 into a temp register
  190. out TCCR0A, temp ;Setting TCR0A to a input
  191. ldi temp, 0b00000010 ;Loading 8 into a temp register
  192. out TCCR0B, temp ;Setting prescalar value to 8
  193. ldi temp, 1<<TOIE0 ;TOIE0 is the bit number of TOIE0 which is 0 (128 microseconds)
  194. sts TIMSK0, temp ;Enale Timer0 overflow Interrupt (T/C0 interrupt enable)
  195. sei ;Enable Global Interrupt Bit
  196.  
  197. loop:
  198. rjmp loop
  199.  
  200. ;LED display
  201. display:
  202. ldi ten,10
  203. mul counter,ten ;multi counter*10 (Since we did 100ms, this is for 1 second)
  204. mov temp, r0
  205. out PORTC,temp ;display respective speed of LCD
  206. clr digit
  207.  
  208. ifHundred:
  209. cpi temp, 100 ;check if number is >100
  210. brsh countHundred
  211. cpi digit, 0 ;check if digit is 0
  212. breq ifTen
  213. register_lcd_data digit
  214. clr digit
  215. ldi temp2,1
  216.  
  217. ifTen:
  218. cpi temp, 10 ;if temp is >10
  219. brsh countTen
  220. cpi temp2, 1 ;else if temp2 is 1
  221. breq else
  222. cpi digit, 0
  223. breq checkOne
  224.  
  225. else:
  226. register_lcd_data digit
  227. clr digit
  228. rjmp checkOne
  229.  
  230. checkOne:
  231. register_lcd_data temp
  232. rjmp end
  233.  
  234. countTen:
  235. subi temp, 10 ;subtract 10 from the speed
  236. inc digit ;inc digits to be displayed
  237. rjmp ifTen
  238.  
  239. countHundred:
  240. subi temp, 100 ;subtract 100 from the speed
  241. inc digit ;incr the first digit to be displayed
  242. rjmp ifHundred
  243.  
  244. ;standard lcd stuff
  245. .equ LCD_RS = 7
  246. .equ LCD_E = 6
  247. .equ LCD_RW = 5
  248. .equ LCD_BE = 4
  249.  
  250. .macro lcd_set
  251. sbi PORTA, @0
  252. .endmacro
  253. .macro lcd_clr
  254. cbi PORTA, @0
  255. .endmacro
  256.  
  257. ;slightly modified some bits to suit ports
  258. lcd_command:
  259. out PORTF, lcd ;Displaying contents stored in r20
  260. rcall sleep_1ms
  261. lcd_set LCD_E
  262. rcall sleep_1ms
  263. lcd_clr LCD_E
  264. rcall sleep_1ms
  265. ret
  266.  
  267. lcd_data:
  268. out PORTF, lcd
  269. lcd_set LCD_RS
  270. rcall sleep_1ms
  271. lcd_set LCD_E
  272. rcall sleep_1ms
  273. lcd_clr LCD_E
  274. rcall sleep_1ms
  275. lcd_clr LCD_RS
  276. ret
  277.  
  278. lcd_wait:
  279. push lcd ;so it doesn't conflict
  280. clr lcd
  281. out DDRF, lcd
  282. out PORTF, lcd
  283. lcd_set LCD_RW
  284.  
  285. lcd_wait_loop:
  286. rcall sleep_1ms
  287. lcd_set LCD_E
  288. rcall sleep_1ms
  289. in lcd, PINF
  290. lcd_clr LCD_E
  291. sbrc lcd, 7
  292. rjmp lcd_wait_loop
  293. lcd_clr LCD_RW
  294. ser lcd
  295. out DDRF, lcd
  296. pop lcd ;restore
  297. ret
  298.  
  299. ;delay stuff as normal
  300. .equ F_CPU = 16000000
  301. .equ DELAY_1MS = F_CPU / 4 / 1000 - 4 ;4 cycles per iteration - setup/call-return overhead
  302.  
  303. sleep_1ms:
  304. push r24
  305. push r25
  306. ldi r25, high(DELAY_1MS)
  307. ldi r24, low(DELAY_1MS)
  308.  
  309. delayloop_1ms:
  310. sbiw r25:r24, 1
  311. brne delayloop_1ms
  312. pop r25
  313. pop r24
  314. ret
  315.  
  316. sleep_5ms:
  317. rcall sleep_1ms
  318. rcall sleep_1ms
  319. rcall sleep_1ms
  320. rcall sleep_1ms
  321. rcall sleep_1ms
  322. ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement