看板 TTU-I90B 關於我們 聯絡資訊
剛剛那篇不對,所以我D掉了! 換一篇正確的! 依然是田橋仔的版本……… 不過這樣中間就隔了一篇~"~ 算了…開始了! 其實,到學校跟我討論會比較快…因為實驗五實在是有點長~!!! .include "8515def.inc" rjmp reset .def mscnt=r16 .def temp2=r17 .def temp3=r18 .def scnt=r19 .def mcnt=r20 .def hcnt=r21 .def tempb=r22 .def tempd=r23 .def scndp=r24 .def cnt =r25 ;設定暫存器 .cseg .org 0x06 ;Timer1 溢位中斷向量 intt1: rjmp chk10ms ;跳到chk10ms .cseg .org 0x10 ;若工作頻率8 MHz時,ck=125ns,則預除器256時為32us,而tcnt1為65535-(10*125) ;作計數溢位,則溢位中斷計時為10*125*32uS=10ms,故若中斷則為10ms 計時 ;但對應10ms計時中斷需4ck且執行程式需7ck才會將新值載入tc1 內共11ck ;故需再延時245ck 總共延時245+11=256ck, 作為一個tc1 輸入週期時間作精確的校正 chk10ms: wdr rcall dly53 ldi temp2,high(65537-10*125);TEMP2 為高8 位元(65537-250*125)放入TCNT1H out tcnt1h,temp2;TCNT1 由(65537-250*125) 計數到65537 溢位共計時31249 ldi temp2,low(65537-10*125);TEMP5 為低8 位元(65537-250*125)放入TCNT1L out tcnt1l,temp2;TCNT1 由(65537-125*125) 計數到65537 溢位共計時31249 rcall clock ;呼叫clock副程式計時 reti ;跳回中斷主程 clock: inc mscnt cpi mscnt,100 brne notad clr mscnt inc scnt ;1 秒計時到則令秒暫存器scnt 加1 cpi scnt,60 ;將秒scnt 與60 比較 brne notad clr scnt inc mcnt ;1 分計時到則令分暫存器mcnt 加1 cpi mcnt,60 ;將分mcnt 與60 比較 brne notad ;若加一後不等於60 分則正常不進位而跳回notad clr mcnt ;60 分計時到則清除分mcnt 後令時hscnt 計時加1 inc hcnt ;1 時計時到則令分暫存器hcnt 加1 cpi hcnt,24 ;將時hcnt 與24 比較 brne notad ;若加一後不等於24 時則正常不進位而跳回notad clr hcnt ;24 時計時到則清除時hcnt 後令日dscnt 計時加1 notad: ret ;秒計時加一完成後回主程式 ;上面就是,mscnt=百分之一秒 scnt=秒 mcnt=分 hcnt=時 然後做運算,算總共多少時間! ;總共延時245 個ck 週期時間 dly53: ldi temp2,(53-5)/4 ;1ck dt1: wdr ;1ck dec temp2 ;1ck brne dt1 ;2ck nop ;1ck ret ;4ck ;main program reset: ldi temp2,low(ramend) ;RAMEND 為8515def.inc 內建定義值為025FH out spl,temp2 ;啟始堆疊指標低位元將R16=TEMP=02H 放入SPL=3DH ldi temp2,high(ramend) ;以TEMP=R16<5FH 為資料載入緩衝暫存器 out sph,temp2 ;堆疊指標高位元將R16=TEMP=5FH 放入SPL+1=3EH .equ buffer=0x0100 ;把程式offset 100的地方設為buffer ldi xh,high(buffer) ;x指向buffer起始位置 ldi xl,low(buffer) ldi zh,high(datab*2) ;z指向資料區(datab)起始位置 ldi zl,low(datab*2) ldi temp2,10 ;放10的原因是把資料區(datab)的0~9放到buffer buff: lpm st x+,r0 ld r0,z+ dec temp2 brne buff ;上面就是如何把0~9放到buffer start:wdr ;在使用看門狗計時器前需重設看門狗計時器內含 ;避免在接下來程式前就因WDT 已快計時溢位而重設 ldi temp2,(1<<WDE) ;WDTCR 定址$21 不可位元設定以TEMP 緩衝令WDE=D3=1 out wdtcr,temp2 ;將已設定WDE=1=D3 位元值之TEMP 輸出到WDTCR 內 ;上面是WDR cli ;中斷總開關global interrupt disable ;中斷總開關,cli是關,sei是開 ldi temp2,$ff ;令temp2=ff 用來設定PD,PB 為輸出態 out ddrb,temp2 ;將temp2=FF 輸出到DDRB 設定全為輸出態 out ddrd,temp2 ;將temp2=FF 輸出到DDRD 設定全為輸出態 out ddrc,temp2 ldi temp2,0b00111111 ;temp2=00111111 令PA7-PA6 輸入態PA5-PA0 輸出 out ddra,temp2 ;設定portA,B,C,D是輸入或輸出 sbi porta,6 ;令PortA6=1 提升電阻輸入態 sbi porta,7 ;令PortA7=1 提升電阻輸入態 ;程式是利用portA的6,7 pin來控制,所以要提升...基本上我也不知道為啥~ clr mscnt clr scnt ;令秒暫存器SCNT=00 clr mcnt ;令秒暫存器MCNT=00 clr hcnt ;令秒暫存器HCNT=00 ;清空暫存器,因為一開始是00 out portc,mscnt ldi scndp,0b11111011 ;令6位7-segment led掃描顯示碼起始位置為0011111 ;利用portd的PD2~PD7六根pin來控制六個七段LED顯示器 mov tempb,scnt ;將秒計時搬入tempb 內 ldi temp3,$00 ;00輸到temp3使led計秒的個位數位置小數點不亮起 ;最後面,秒那位的小數點不要亮! rcall btod ;呼叫16進位數轉10進位數的副程式 rcall redsp ;呼叫顯示led的副程式 ;上面四行是秒的 mov tempb,mcnt ;將分計時搬入tempb 內 ldi temp3,$ff ;ff輸到temp3使led計分的個位數位置小數點亮起 rcall btod ;呼叫16進位數轉10進位數的副程式 rcall redsp ;呼叫顯示led的副程式 ;分 mov tempb,hcnt ;將時計時搬入tempb 內 ldi temp3,$ff ;ff輸到temp3使led計時的個位數位置小數點亮起 rcall btod ;呼叫16進位數轉10進位數的副程式 rcall redsp ;呼叫顯示led的副程式 ;時 ldi temp2,$00 ;令TEMP2 暫存器放入00 out tccr1a,temp2 ;將TEMP2=00 內含輸出到TCCR1 內禁止比較器及PWM 動作 out tccr1b,temp2 ;將TEMP2=00 內含輸出到TCCR1 內禁止比較器及PWM 動作 ;一樣的,tccr1b和1a是用來控制timer1,所以要先設定 ldi temp2,high(65535-10*125) ;TEMP2為高8位元(65536-250*125)放入TCNT1H out tcnt1h,temp2 ldi temp2,low(65536-10*125) ;TEMP2為低8位元(65536-250*125)放入TCNT1L out tcnt1l,temp2 ;中斷計時的設定 sei ;中斷總開關sreg=d7=i=1 ;中斷總開關,開=sei ldi temp3,0b10000000 ;令toie1=1 致能中斷 out timsk,temp3 ;將R16 的D1=1 令TOIE0=1 致能中斷 ;timsk也是timer的控制~~p.25 reptw: ;這個副程式是用來顯示的 ldi temp3,00 ;令R16=00 sbi porta,6 ;令portA6=1 提升電阻輸入態 sbi portb,7 ;令portB7=1 提升電阻輸入態 sbis pina,6 ;檢測PA6 輸入是否為0 若pinA6=0 則跳格啟始計時 ldi temp3,03 ;令R16=04 sbis pina,7 ;檢測PA7 輸入是否為0 若pinA6=0 則跳格重新計時 rjmp start ;跳回start 重新開始 out tccr1b,temp3 ;將R16=04 設定TC1 預除256 開始計時其單位時間為32uS ;這就是設定預除器~p.33 mov temp3,mscnt com temp3 out portc,temp3 ldi scndp,0b11111011 ;令6 位數七段LED 掃描顯示碼起始為111110(PD7~PD2) mov tempb,scnt ;將秒計時搬入tempb 內 ldi temp3,$00 ;00輸到temp3使led計秒的個位數位置小數點不亮起 rcall btod ;呼叫16進位數轉10進位數的副程式 rcall redsp ;呼叫顯示led的副程式 mov tempb,mcnt ;將分計時搬入tempb 內 ldi temp3,$ff ;ff輸到temp3使led計分的個位數位置小數點亮起 rcall btod ;呼叫16進位數轉10進位數的副程式 rcall redsp ;呼叫顯示led的副程式 mov tempb,hcnt ;將時計時搬入tempb 內 ldi temp3,$ff ;ff輸到temp3使led計時的個位數位置小數點亮起 rcall btod ;呼叫16進位數轉10進位數的副程式 rcall redsp ;呼叫顯示led的副程式 ;上面控制秒,分,時的轉換和顯示~~ wdr rjmp reptw ;跳回REPTW 顯示日時分秒並等待中斷計時一秒計時 下面就是真正顯示的方式!我覺得還是到學校說吧…用打得太困難啦~~ 不過按照指令一步一步用數字自己代代看,應該可以搞懂! 因為我就是這樣看…!!! redsp: wdr ldi xh,high(buffer) ;x指向buffer起始位置 ldi xl,low(buffer) mov cnt,tempb ;將tempb=個位數的時間值輸到cnt inc cnt ;cnt++ ld r0,-x ;x指標向前一格 jumpb:ld r0,x+ ;x指標向後一格 dec cnt ;cnt-- breq outb ;若cnt=0,則跳到outb,此時x指到所要表示的 ;時間值資料位置的前一格 rjmp jumpb ;跳到jumpb outb: ld r0,x+ ;x指到所要表示的時間值資料位置 mov temp2,r0 ;將r0資料輸入到temp2 sbrc temp3,1 ;如果temp3=00,則不做下一行,從下兩行開始作 ori temp2,$80 ;temp2內的值 or $80使temp2=1xxxxxxx,令7-segment的 ;小數點燈號亮起 out portb,temp2 ;將讀取值之TEMP2 內含輸出到PORTB 顯示 out portd,scndp ;將SCNDP 掃描碼由右邊的PTD2=0 開始移位輸出 rcall delay ;呼叫DELAY 延時副程式令顯示一段時間 sec ;令CF=1 以便作掃描碼移位 rol scndp ;將SCNDP 與CF 作左旋轉令顯示掃描碼向左移位 wdr ldi xh,high(buffer) ;x指向buffer起始位置 ldi xl,low(buffer) mov cnt,tempd ;將tempd=十位數的時間值輸到cnt inc cnt ;cnt++ ld r0,-x ;x指標向前一格在load資料到r0 jumpd:ld r0,x+ ;load資料到r0,x指標再向後一格 dec cnt ;cnt-- breq outd ;若cnt=0,則跳到outd,此時x指到所要表示的時間值資料 ;位置的前一格 rjmp jumpd ;跳到jumpd outd: ld r0,x+ ;x指到所要表示的時間值資料位置 mov temp2,r0 ;將r0資料輸入到temp2 out portb,temp2 ;將讀取值之TEMP2 內含輸出到PORTB 顯示 out portd,scndp ;將SCNDP 掃描碼由右邊的PTD2=0 開始移位輸出 rcall delay ;呼叫DELAY 延時副程式令顯示一段時間 sec ;令CF=1 以便作掃描碼移位 rol scndp ;將SCNDP 與CF 作左旋轉令顯示掃描碼向左移位 ret btod: clr tempd ;令tempd=$00 retrs:subi tempb,10 ;將16進位tempb - 10 brcs negs ;若減十不夠減則cf = 1 進位跳到negs做調整 inc tempd ;若cf = 0昨夠減將十進位置tempd加1 rjmp retrs ;跳回retrs繼續將16進位減10夠減就加1 negs: subi tempb,$f6 ;將10進位tempb減f6即加上10恢復原值 ret ;回主程式 ;上面就是轉換(16進位-->10進位)的程式 ;建議自己代數字試試看~~ delay:ldi temp3,$08 dt3: ldi temp2,$20 dt2: wdr dec temp2 brne dt2 dec temp3 brne dt3 ret datab: .db 0x3f,0x06,0x5b,0x4f .db 0x66,0x6d,0x7d,0x07 .db 0x7f,0x6f,0x77,0x7c ;這邊是放七段顯示器的資料,0~12,其實只有用到0~9 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 218.166.125.121 ※ 編輯: supergothere 來自: 218.166.125.121 (06/06 22:35)
ysun:可不可以用成WORD檔呀 218.34.180.209 06/06
ysun:方便印出ㄇㄟ~~嘻嘻 ^.^" 218.34.180.209 06/06
icemint:你很懶耶~~ 自己複製貼上咩 140.129.37.29 06/06
icemint:要不然就在文章前面按"F"..轉寄回自已信箱 140.129.37.29 06/06
supergothere:=.=我是直接在BBS上面打耶~賺摳摳.. 218.166.125.121 06/06
icemint:◆ 這一篇文章值 9 銀 140.129.37.29 06/07