| CODE |
;*********************************************************************** ;*********************************************************************** ;** DMX ovladac krokoveho motorku pracujici se seriovym ** ;** kanalem UART na mikrokontroleru ATmega8 ** ;*********************************************************************** ;*********************************************************************** .include "m8def.inc" ; ************************************************* ; **Definice konstant a prirazeni nazvu registrum** ; ************************************************* .equ stack_base = $D0 ;pocatecni adresa zasobniku .def temp = r25 ;pomocny registr .def tempu = r24 ;pomocny registr v preruseni UARTu .def kanalh = r19 ;citac prijatych bajtu od startu UARTu (tedy od sig. DMX reset) .def kanall = r18 ;citac prijatych bajtu od startu UARTu (tedy od sig. DMX reset) .def dataRX = r20 ;obsahuje znak prijmuty z UART .def motor = R16 ;counter pro motorek .def speed = R17 ;motorek .def speedm = R21 .def poloha = R22 .def natoceni = R23 .equ c_value = 25535;Compare value for output compare interrupt ;500 cycles@5Mhz = 100us ;---------------------------------------------------------------------------------------------- ; ***************************** ; **Definice vektoru preruseni** ; ***************************** .CSEG .org $000 rjmp main ;obsluha RESET .org OC1Aaddr;Init Output compare A interrupt vector rjmp OC1A .org URXCaddr rjmp prijem_UART ;obsluha ukonceni prijmu znaku z UART ;---------------------------------------------------------------------------------------------- .org $00c ;pocatecni adresa kodu programu ;***************************************************************** ;* ;* OC1A- Timer1 Output compare A interrupt routine ;* ;* ;* DESCRIPTION ;* ;* This interrupt routine load new step motor value from the step ;* motor table in SRAM. The values in the table have two functions, ;* the lower nibble contains the value to output to the step motor. ;* The upper nibble holds the address of the next value. First the ;* step value is output to the port, next the address is moved to ;* the XL register. ;* ;* Number of words :6 + return ;* Number of cycles :7 + return ;* Low registers used :None ;* High registers used :3 (temp,XL,XH) ;*************************************************************** OC1A: in motor,SREG push motor mov motor, speed ;pro speed mensi nez 9 motor stoji cpi motor, 0x0A brlo poloha2 mov natoceni, poloha;maze zmeny pro absolutni polohu (kanalu 1), ;kdyz je motor v pohybu (kanal 0 > 9) cpi motor, 0x7F ;pro mensi nez 126 rotace 1 brlo rotace1 ;rotace jednim smerem pro 10 az 126 (84h) cpi motor, 0x8B ;pro mensi nez 138 brlo uvolni ;STOP s uvolnenym PORTem C ;nastav rychlost pro rotaci2 mov motor, speed ;nastav rychlost subi motor, 0x81 ;nastaveni spravneho rozssahu 10 - xxx) add motor, motor ;nastaveni vetsiho rozptylu (zde 2x) com motor out OCR1AH,motor ldi motor,0xFF ;Load compare low value out OCR1AL,motor dec XL cpi XL, 0x08 brlo rotace ;rotace jednim smerem pro 10 az 126 (84h) ldi XL, 0x07 rotace: ld motor,X ;Load temp with X pointer value out PORTC,motor ;Output lower nibble to step motor konec2: pop motor out SREG,motor reti rotace1: mov motor, speed ;nastav rychlost subi motor, 0x00 ;nastaveni spravneho rozssahu (0 - xxx) add motor, motor ;nastaveni vetsiho rozptylu (zde 2x) com motor out OCR1AH,motor ldi motor,0xFF ;Load compare low value out OCR1AL,motor inc XL cpi XL, 0x08 ;pro mensi nez 126 rotace 1 brlo rotace ;rotace jednim smerem pro 10 az 126 (84h) ldi XL, 0x00 rjmp rotace uvolni: ldi motor, 0x00 out PORTC,motor ;Output lower nibble to step motor rjmp konec2 poloha2: ldi motor, 0x05 out OCR1AH,motor ldi motor,0xFF ;Load compare low value out OCR1AL,motor cp natoceni, poloha ;pro mensi nez 126 rotace 1 brlo zvys ;rotace jednim smerem pro 10 az 126 (84h) cp poloha, natoceni ;pro mensi nez 126 rotace 1 brlo sniz ;rotace jednim smerem pro 10 az 126 (84h) rjmp konec2 zvys: inc natoceni inc XL cpi XL, 0x08 ;pro mensi nez 126 rotace 1 brlo rotace ;rotace jednim smerem pro 10 az 126 (84h) ldi XL, 0x00 rjmp rotace sniz: sbi PORTC, 5 ;kontrolni LED dec natoceni dec XL cpi XL, 0x08 brlo rotace ;rotace jednim smerem pro 10 az 126 (84h) ldi XL, 0x07 rjmp rotace ;---------------------------------------------------------------------------------------------- ; ******************************************************* ; **Rutina provadena pri ukonceni prijmu znaku z UART ** ; ******************************************************* prijem_UART: in dataRX,udr ;preceteni prijateho znaku a ulozani do registru DATARX ; **************************************** ; Zde je zpracovani prijateho znaku in tempu, UCSRA sbrc tempu, FE ;kontrola chyb prijmu (je-li stop bit spravne v 1) rjmp konecb clv ;reseni 512 kanalu pro 8 bitove (256) registry inc kanall brvc dale ldi kanalh, 0x01 ;mozna pozdeji lepe pouzivat "inc kanalh" kvuli star bajtu dale: ;ctu dany kanal (treba 1) ldi tempu, 0x00 cpse kanalh, tempu rjmp konec ldi tempu, 0x02 cpse kanall, tempu rjmp kanal2 mov speed, dataRX ldi tempu, 0x01 ;pri hodnote daneho kanalu vyssi nez 1, rozsvit LED cp dataRX, tempu brlo konec sbi PORTC, 5 ;kontrolni LED nop rjmp konec kanal2: ;nacteny hodnoty z druheho kanalu (adresa 2) ldi tempu, 0x03 cpse kanall, tempu rjmp konec mov poloha, dataRX konec: ; **************************************** reti ;navrat z obsluhy preruseni konecb: cbi ucr,rxen cbi ucr,rxcie ;vypnuti UART clr kanalh clr kanall cbi PORTC, 4 ;kontrolni LED rjmp konec ;--------------------------------------------------------------------------------------------- ; ************************************** ; **Nastaveni registru a ridicich bitu** ; ** Provede se po kazdem RESETu ** ; ************************************** main: ldi r16,high(RAMEND);Intialize stackpointer out SPH,r16 ldi r16,low(RAMEND) out SPL,r16 ldi temp,0x7F ;Set PORTC as output out DDRC,temp ldi temp,0x00 out PORTC,temp ;Write initial value to PORTC sbi ucr,rxen ;pripojeni vstupu UART na pin PD0 ldi temp, 0x00 out ubrrh,temp ldi temp, 0x01 out ubrrl,temp ;nastavena prenosova rychlost na 250000 Bd pri krystalu 4Mhz -> ubrr=0 ;tabulka konstant pro volbu pren. rychlosti je obsazena v dokumentacnim souboru PDF ;xxxxxxxxxxxxxxxxxx KROKOVY MOTOREK xxxxxxxxxxxxxxxxxxxx ldi temp,high(c_value);Load compare high value out OCR1AH,temp ldi temp,low(c_value);Load compare low value out OCR1AL,temp ldi temp,0x00 out TCNT1H,temp ;Clear timer high byte out TCNT1L,temp ;Clear timer low byte out TCCR1A,temp ;Clear timer control reg A ldi temp,0x40 out TIFR,temp ;Clear pending timer interrupt ldi temp, 0x10 out TIMSK, temp ;Enable Timer compare interrupt ldi ZH,high(step*2) ;Init Z pointer to step table in flash ldi ZL,low(step*2) ldi XH,high(0x0100) ;Init X pointer to RAM location ldi XL,low(0x0100) ldi temp,0x10 ;Load counter value load: lpm ;Load step value from flash st X+,R0 ;Store step value in RAM adiw ZL,0x01 ;Increment flash pointer dec temp ;Decrement counter brne load ;Continue until table is loaded ldi XH,high(0x0100) ;Initialize X pointer to RAM location ldi XL,low(0x0100) ldi temp,0xB out TCCR1B,temp ;Clear timer on compare match,CK/1 sei ;DULEZITE globalni povoleni preruseni clr poloha clr natoceni ;---------------------------------------------------------------------------------------------- ; ************************ ; **Hlavni telo programu** ; ************************ loop: cekat_na_0: ;cekam na 0 - zacatek sig. RESET (Break) sbic PIND, 0 rjmp cekat_na_0 ldi temp, 0x10 ;kontroluji, zda-li je 0 alespon 88 us ;stop pri temp = 80h, cyklus trva 1,25 us pri 4 Mhz DMX_reset: ;-> 71 cyklu = 47h sbic PIND, 0 ;Takze start pri temp = 80h - 47h = 39h rjmp cekat_na_0 ;Pri 8 Mhz -> temp = F2, ale je to zdrzeno inc temp ;prerusenimi, volmim 10h brvc DMX_reset cbi ucr,rxen cbi ucr,rxcie ;vypnuti UART clr kanalh clr kanall cbi PORTC, 4 ;kontrolni LED cbi PORTC, 5 ;kontrolni LED cekat_na_1: ;cekam na 1 - zacatek Mark-after-break sbis PIND, 0 ;muzu spustit UART rjmp cekat_na_1 cbi usr, rxc ;maze priznak o prijmu (doufam ze by to mel delat) nop sbi PORTC, 4 ;kontrolni LED sbi ucr,rxen sbi ucr,rxcie ;povoleni volani obsluhy preruseni po dokonceni prijmu znaku loop2: nop nop rjmp loop ;*** Step motor lookup table *** step: .db 0x09, 0x08, 0x0C, 0x04, 0x06, 0x02, 0x03, 0x01 |