Advertisement
Guest User

Untitled

a guest
Jan 20th, 2020
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.31 KB | None | 0 0
  1. .nolist
  2. .include "m128def.inc"
  3. .include "hd44780.inc"
  4. .list
  5.  
  6. .dseg
  7. .def temp = r16
  8. .def sys = r17
  9. .def counter = r18
  10. .def hours = r19
  11. .def minutes = r20
  12.  
  13. .equ KEYPAD_PORT = PORTE
  14. .equ KEYPAD_DDR = DDRE
  15. .equ KEYPAD_PIN = PINE
  16.  
  17. .equ FREQ = 8000000
  18. .equ LCD_PORT = PORTB
  19. .equ LCD_DDR = DDRB
  20. .equ LCD_PIN = PINB
  21. .equ LCD_D4 = 4
  22. .equ LCD_D5 = 5
  23. .equ LCD_D6 = 6
  24. .equ LCD_D7 = 7
  25. .equ LCD_RS = 0
  26. .equ LCD_EN = 2
  27.  
  28. PressureSensorByte: // 2 байта под данные регистров АЦП вход ADC0
  29. .byte 2
  30. TemperatureSensorByte: // 2 байта под данные регистров АЦП вход ADC1
  31. .byte 2
  32. PressureSensor: // 4 байта под промежуточный расчет данных Вольтметра 1
  33. .byte 4
  34. TemperatureSensor: // 4 байта под промежуточный расчет данных Вольтметра 2
  35. .byte 4
  36.  
  37. .cseg
  38. .org 0 ;reset interruption
  39. jmp Reset
  40. .org $0002
  41. jmp EXT_INT0 ; Keypad
  42. .org $0014
  43. jmp TIM2_OVF ; Timer2 Overflow Handler
  44. .org $0020
  45. jmp TIM0_OVF ; Timer0 Overflow Handler
  46. .org $002A // Адрес вектора прерывания по конвертации АЦП
  47. jmp ADC_Conv
  48.  
  49. Reset:
  50. ldi temp, high(RAMEND)
  51. out sph, temp
  52. ldi temp, low(RAMEND)
  53. out spl, temp
  54.  
  55. ldi temp, 0b11110111
  56. out DDRB, temp
  57.  
  58. ldi temp, 0b00000000
  59. out KEYPAD_DDR, temp
  60. ldi temp, 0b00001111
  61. out KEYPAD_PORT, temp
  62.  
  63. ldi temp, 0b00000011 ; rising edge for INT0
  64. sts EICRA, temp
  65. ldi temp, 0b00000001 ; enable INT0
  66. out EIMSK, temp
  67.  
  68. rcall LCD_init
  69.  
  70. ldi temp, 0b00000101
  71. out TCCR2, temp
  72. ldi temp, 0b00000010
  73. out TCCR0, temp
  74.  
  75. ldi temp, 0b01000001
  76. out TIFR, temp
  77. out TIMSK, temp
  78.  
  79. ldi temp, 0xf0
  80. out TCNT0, temp
  81.  
  82. ldi temp, 0xf0
  83. out TCNT2, temp
  84.  
  85. ldi temp, 0b01000000 // REFS = 01, ADLAR = 0, опорное напряжение выход AVCC, Мультиплексор
  86. out ADMUX, temp // на ADC0
  87. ldi temp, 0b11011110 // Разрешаем АЦП, запускаем конвертацию, и предделитель на 64
  88. out ADCSRA, temp // частота АЦП должна быть 50-200 кГц, при наших 8 Мгц, у нас будет 125 Кгц
  89.  
  90. ldi hours, 0x17
  91. ldi minutes, 0x3b
  92. ldi counter, 0x00
  93. ldi temp, 0
  94. mov R15, temp
  95. sei
  96.  
  97. start:
  98. nop
  99. rjmp start
  100.  
  101. TIM2_OVF:
  102. cli
  103. push temp
  104. inc counter
  105. cpi counter, 0xff
  106. breq Timer_DEC
  107. Vix:
  108.  
  109. ldi temp, 0xf0
  110. out TCNT2, temp
  111.  
  112. pop temp
  113. sei
  114. reti
  115.  
  116. Timer_DEC:
  117. dec minutes
  118. ldi counter, 0x00
  119. cpi minutes, 0x00
  120. breq Minutes_RESET
  121. rjmp Vix
  122.  
  123. Hours_RESET:
  124. ldi hours, 0x17
  125. rjmp Vix
  126.  
  127. Minutes_RESET:
  128. ldi minutes, 0x3b
  129. dec hours
  130. cpi hours, 0x00
  131. brlt Hours_RESET
  132. rjmp Vix
  133.  
  134. TIM0_OVF:
  135. cli
  136. push temp
  137. push sys
  138.  
  139. ldi temp, (128+0x63)
  140. rcall LCD_command
  141.  
  142. mov temp, minutes
  143. call bin_to_dec ;temp - единицы / sys - десятки
  144.  
  145. /*
  146. ldi zh, high(<STRING_NAME>*2)
  147. ldi zl, low(<STRING_NAME>*2)
  148. ldi sys, <STRING_LENGTH>
  149.  
  150. loop:
  151. lpm temp, z+
  152. rcall LCD_data
  153. dec sys
  154. brne loop*/
  155.  
  156. mov temp, hours
  157. mov R1, temp
  158. rcall fpconv8
  159. mov temp, R7
  160. rcall LCD_data
  161. mov temp, R8
  162. rcall LCD_data
  163. ldi temp, ':'
  164. rcall LCD_data
  165. mov temp, minutes
  166. mov R1, temp
  167. rcall fpconv8
  168. mov temp, R7
  169. rcall LCD_data
  170. mov temp, R8
  171. rcall LCD_data
  172.  
  173.  
  174. pop sys
  175. pop temp
  176. sei
  177. reti
  178.  
  179. EXT_INT0:
  180. cli
  181. push temp
  182.  
  183. ldi temp, (128+0x00)
  184. rcall LCD_command
  185.  
  186. ReadKey:
  187. ;
  188. ldi temp, 0x0f
  189. andi temp, KEYPAD_PIN
  190. cpi temp, 0x00
  191. breq Put0
  192. ;
  193. ldi temp, 0x0f
  194. andi temp, KEYPAD_PIN
  195. cpi temp, 0x01
  196. breq Put1
  197. ;
  198. ldi temp, 0x0f
  199. andi temp, KEYPAD_PIN
  200. cpi temp, 0x02
  201. breq Put2
  202. ;
  203. ldi temp, 0x0f
  204. andi temp, KEYPAD_PIN
  205. cpi temp, 0x03
  206. breq Put3
  207. ;
  208. ldi temp, 0x0f
  209. andi temp, KEYPAD_PIN
  210. cpi temp, 0x04
  211. breq Put4
  212. ;
  213. ldi temp, 0x0f
  214. andi temp, KEYPAD_PIN
  215. cpi temp, 0x05
  216. breq Put5
  217. ;
  218. ldi temp, 0x0f
  219. andi temp, KEYPAD_PIN
  220. cpi temp, 0x06
  221. breq Put6
  222. ;
  223. ldi temp, 0x0f
  224. andi temp, KEYPAD_PIN
  225. cpi temp, 0x07
  226. breq Put7
  227. ;
  228. ldi temp, 0x0f
  229. andi temp, KEYPAD_PIN
  230. cpi temp, 0x08
  231. breq Put8
  232. ;
  233. ldi temp, 0x0f
  234. andi temp, KEYPAD_PIN
  235. cpi temp, 0x09
  236. breq Put9
  237. ;
  238. ldi temp, 0x0f
  239. andi temp, KEYPAD_PIN
  240. cpi temp, 0x0a
  241. breq PutA
  242. ;
  243. ldi temp, 0x0f
  244. andi temp, KEYPAD_PIN
  245. cpi temp, 0x0b
  246. breq PutB
  247. ;
  248. ldi temp, 0x0f
  249. andi temp, KEYPAD_PIN
  250. cpi temp, 0x0c
  251. breq PutC
  252. ;
  253. ldi temp, 0x0f
  254. andi temp, KEYPAD_PIN
  255. cpi temp, 0x0d
  256. breq PutD
  257. ;
  258. ldi temp, 0x0f
  259. andi temp, KEYPAD_PIN
  260. cpi temp, 0x0e
  261. breq PutE
  262. ;
  263. ldi temp, 0x0f
  264. andi temp, KEYPAD_PIN
  265. cpi temp, 0x0f
  266. breq PutF
  267. NoKey:
  268. jmp exit_interrupt
  269. Put0:
  270. ldi temp, '0'
  271. jmp print_key_interrupt
  272. Put1:
  273. ldi temp, '1'
  274. jmp print_key_interrupt
  275. Put2:
  276. ldi temp, '2'
  277. jmp print_key_interrupt
  278. Put3:
  279. ldi temp, '3'
  280. jmp print_key_interrupt
  281. Put4:
  282. ldi temp, '4'
  283. jmp print_key_interrupt
  284. Put5:
  285. ldi temp, '5'
  286. jmp print_key_interrupt
  287. Put6:
  288. ldi temp, '6'
  289. jmp print_key_interrupt
  290. Put7:
  291. ldi temp, '7'
  292. jmp print_key_interrupt
  293. Put8:
  294. ldi temp, '8'
  295. jmp print_key_interrupt
  296. Put9:
  297. ldi temp, '9'
  298. jmp print_key_interrupt
  299. PutA:
  300. ldi temp, 'A'
  301. jmp print_key_interrupt
  302. PutB:
  303. ldi temp, 'B'
  304. jmp print_key_interrupt
  305. PutC:
  306. ldi temp, 'C'
  307. jmp print_key_interrupt
  308. PutD:
  309. ldi temp, 'D'
  310. jmp print_key_interrupt
  311. PutE:
  312. ldi temp, 'E'
  313. jmp print_key_interrupt
  314. PutF:
  315. ldi temp, 'F'
  316. print_key_interrupt:
  317. rcall LCD_data
  318. exit_interrupt:
  319. pop temp
  320. sei
  321. reti
  322.  
  323. LCD_init:
  324. sbi LCD_DDR, LCD_D4
  325. sbi LCD_DDR, LCD_D5
  326. sbi LCD_DDR, LCD_D6
  327. sbi LCD_DDR, LCD_D7
  328. sbi LCD_DDR, LCD_RS
  329. sbi LCD_DDR, LCD_EN
  330. cbi LCD_PORT, LCD_RS
  331. cbi LCD_PORT, LCD_EN
  332. ldi temp, 100
  333. rcall WaitMiliseconds
  334. ldi sys, 0b0000011
  335.  
  336. LCD_init_loop:
  337. ldi temp, 0x03
  338. rcall LCD_write_nibble
  339. ldi temp, 5
  340. rcall WaitMiliseconds
  341. dec sys
  342. brne LCD_init_loop
  343. ldi temp, 0x02
  344. rcall LCD_write_nibble
  345. ldi temp, 1
  346. rcall WaitMiliseconds
  347. ldi temp, HD44780_FUNCTION_SET | HD44780_FONT5x7 | HD44780_TWO_LINE | HD44780_4_BIT
  348. rcall LCD_command
  349. ldi temp, HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_OFF
  350. rcall LCD_command
  351. ldi temp, HD44780_CLEAR
  352. rcall LCD_command
  353. ldi temp, HD44780_ENTRY_MODE | HD44780_EM_SHIFT_CURSOR | HD44780_EM_INCREMENT
  354. rcall LCD_command
  355. ldi temp, HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_ON | HD44780_CURSOR_OFF | HD44780_CURSOR_NOBLINK
  356. rcall LCD_command
  357. ret
  358.  
  359. LCD_data:
  360. push zh
  361. push zl
  362. sbi LCD_PORT, LCD_RS
  363. push temp
  364. swap temp
  365. rcall LCD_write_nibble
  366. pop temp
  367. rcall LCD_write_nibble
  368. clr xh
  369. ldi xl, low(FREQ/80000)
  370. rcall Wait4xCycles
  371. pop zl
  372. pop zh
  373. ret
  374.  
  375. LCD_command:
  376. cbi LCD_PORT, LCD_RS
  377. push temp
  378. swap temp
  379. rcall LCD_write_nibble
  380. pop temp
  381. rcall LCD_write_nibble
  382. ldi temp, 2
  383. rcall WaitMiliseconds
  384. ret
  385.  
  386. LCD_write_nibble:
  387. sbi LCD_PORT, LCD_EN
  388. sbrs temp, 0
  389. cbi LCD_PORT, LCD_D4
  390. sbrc temp, 0
  391. sbi LCD_PORT, LCD_D4
  392. sbrs temp, 1
  393. cbi LCD_PORT, LCD_D5
  394. sbrc temp, 1
  395. sbi LCD_PORT, LCD_D5
  396. sbrs temp, 2
  397. cbi LCD_PORT, LCD_D6
  398. sbrc temp, 2
  399. sbi LCD_PORT, LCD_D6
  400. sbrs temp, 3
  401. cbi LCD_PORT, LCD_D7
  402. sbrc temp, 3
  403. sbi LCD_PORT, LCD_D7
  404. cbi LCD_PORT, LCD_EN
  405. ret
  406.  
  407. WaitMiliseconds:
  408. push zh
  409. push zl
  410. push temp
  411. WaitMsLoop:
  412. ldi xh, high(FREQ/17777)
  413. ldi xl, low(FREQ/17777)
  414. rcall Wait4xCycles
  415. ldi xh, high(FREQ/17777)
  416. ldi xl, low(FREQ/17777)
  417. rcall Wait4xCycles
  418. dec temp
  419. brne WaitMsLoop
  420. pop temp
  421. pop zl
  422. pop zh
  423. ret
  424.  
  425. Wait4xCycles:
  426. sbiw xh:xl, 1
  427. brne Wait4xCycles
  428. ret
  429.  
  430. bin_to_dec:
  431. ldi sys, 0
  432. subi temp, 10
  433. inc sys
  434. brcc PC-2
  435. dec sys
  436. subi temp, -10
  437. ret
  438.  
  439. fpconv8:
  440. rcall fpconv8a ; convert to ASCII string
  441. ldi temp,'.' ; set decimal char
  442. mov R6,temp
  443. ret ; all done
  444. fpconv8m:
  445. clr R4 ; set the multiplicant to 502
  446. ldi temp,$01
  447. mov R3,temp
  448. ldi temp,$F6
  449. mov R2,temp
  450. clr R7 ; clear the result
  451. clr R6
  452. clr R5
  453. fpconv8m1:
  454. or R1,R1 ; check if the number is all zeros
  455. brne fpconv8m2 ; still one's, go on convert
  456. ret ; ready, return back
  457. fpconv8m2:
  458. lsr R1 ; shift number to the right (div by 2)
  459. brcc fpconv8m3 ; if the lowest bit was 0, then skip adding
  460. add R5,R2 ; add the number in R6:R5:R4:R3 to the result
  461. adc R6,R3
  462. adc R7,R4
  463. fpconv8m3:
  464. lsl R2 ; multiply R4:R3:R2 by 2
  465. rol R3
  466. rol R4
  467. rjmp fpconv8m1
  468. fpconv8r:
  469. clr temp ; put zero to rmp
  470. lsl R5 ; rotate bit 7 to carry
  471. adc R6,temp ; add LSB with carry
  472. adc R7,temp ; add MSB with carry
  473. mov R2,R7 ; copy the value to R2:R1 (divide by 256)
  474. mov R1,R6
  475. ret
  476. fpconv8a:
  477. clr R4 ; Set the decimal divider value to 100
  478. ldi temp,100
  479. mov R3,temp
  480. rcall fpconv8d ; get ASCII digit by repeated subtraction
  481. mov R5,temp ; set hundreds string char
  482. ldi temp,10 ; Set the decimal divider value to 10
  483. mov R3,temp
  484. rcall fpconv8d ; get the next ASCII digit
  485. mov R7,temp ; set tens string char
  486. ldi temp,'0' ; convert the rest to an ASCII char
  487. add temp,R1
  488. mov R8,temp ; set ones string char
  489. ret
  490. fpconv8d:
  491. ldi temp,'0' ; start with decimal value 0
  492. fpconv8d1:
  493. cp R1,R3 ; Compare word with decimal divider value
  494. cpc R2,R4
  495. brcc fpconv8d2 ; Carry clear, subtract divider value
  496. ret ; done subtraction
  497. fpconv8d2:
  498. sub R1,R3 ; subtract divider value
  499. sbc R2,R4
  500. inc temp ; up one digit
  501. rjmp fpconv8d1 ; once again
  502.  
  503. ADC_Conv: // Прерывание по конвертации АЦП
  504. cli // Запрещаем прерывания
  505. push temp // Запихиваем temp в стек
  506. push sys
  507. in temp, ADCL // Читаем младший, а потом старший регистр АЦП,
  508. push temp
  509. in temp, ADCH // при записи будет наоборот, не забывать
  510. push temp
  511. mov sys, R15
  512. cpi sys, 0 // Проверяем какой канал в прошлый раз запускали на конвертацию
  513. breq ADC_Conv0 // Переходим по метке, если 0
  514. ldi sys, 0 // иначе sys = 0
  515. mov R15, sys
  516. pop temp
  517. sts PressureSensorByte, temp // Сохраняем наши данные с АЦП в ОЗУ
  518. pop temp
  519. sts PressureSensorByte+1, temp
  520. ldi temp, 0b01000001 // Настраиваем мультиплексор на ADC1
  521. out ADMUX, temp
  522. ADC_Conv_exit:
  523. ldi temp, 0b11011110 // Повторяем запуск конвертации
  524. out ADCSRA, temp
  525. pop sys
  526. pop temp // Дергаем значение temp из стека
  527. sei // Разрешаем прерывания
  528. reti // Выход из прерывания
  529.  
  530. ADC_Conv0:
  531. pop temp
  532. mov R14, temp
  533. ldi sys, 1 // sys = 1
  534. mov R15, sys
  535. pop temp
  536. sts TemperatureSensorByte, temp // Сохраняем наши данные с АЦП в ОЗУ
  537. pop temp
  538. sts TemperatureSensorByte+1, temp
  539. ldi temp, 0b01000000 // Настраиваем мультиплексор на ADC0
  540. out ADMUX, temp
  541. mov temp, r14
  542. push temp
  543. rjmp ADC_Conv_exit // Переходим
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement