;******************************** ;* * ;* 周波数カウンタ Ver1.0 * ;* ATtiny2313 * ;* * ;******************************** .INCLUDE "tn2313def.inc" ;ATtiny2313-20PU ;ヒューズ・ビット 既定 設定 ;(拡張) ;SELFPRGEN 1 1 ;自己プログラミング許可 (禁止) ;(上位) ;DWEN 1 1 ;デバッグWIRE許可 (禁止) ;EESAVE 1 1 ;EEPROM内容消去保護 (なし) ;SPIEN 0 0 ;実装書き込み許可 (許可) ;WDTON 1 1 ;ウォッチドッグ タイマ常時許可 (不許可) ;BODLEVEL2 1 1 ;低電圧検出リセット (4.3V許可) ;BODLEVEL1 1 0 ; ;BODLEVEL0 1 0 ; ;RSTDISBL 1 1 ;/RESET入力禁止 (許可) ;(下位) ;CKDIV8 0 1 ;8分周システム クロック (8分周なし) ;CKOUT 1 0 ;システム クロック出力許可 (許可) ;SUT1 1 1 ;起動遅延 (14×CK+4.1ms) ;SUT0 0 0 ; ;CKSEL3 0 1 ;クロック種別 (外部クリスタル発振) ;CKSEL2 1 1 ; ;CKSEL1 0 1 ; ;CKSEL0 0 1 ; ; システム クロック周波数=10.000MHz ;I/Oポート ;PA2/RESET/dW 1 x: /RESET ;PA1/XTAL2 4 I: (10MHzクリスタル) ;PA0/XTAL1 5 I: (10MHzクリスタル) ; ;PB7/SCK/USCK/PCINT7 19 I: (未使用) ;PB6/MISO/DO/PCINT6 18 I: (未使用) ;PB5/MOSI/DI/SDA/PCINT5 17 I: (未使用) ;PB4/OC1B/PCINT4 16 I: (未使用) ;PB3/OC1A/PCINT3 15 I: (未使用) ;PB2/OC0A/PCINT2 14 I: (未使用) ;PB1/AN1/PCINT1 13 I: (未使用) ;PB0/AN0/PCINT0 12 I: (未使用) ; ;PD6/ICP 11 I: (未使用) ;PD5/T1/OC0B 9 I: /FRQ 周波数パルス入力 ;PD4/T0 8 O: /LED 状態表示LED ;PD3/INT1 7 I: (未使用) ;PD2/INT0/XCK/CKOUT 6 I: CLKO システム クロック出力 ;PD1/TXD 3 O: TXD RS-232送信出力 ;PD0/RXD 2 I: RXD RS-232受信入力 .EQU GTIM =80 ;ゲート時間(ms単位: 1〜255:既定=80) .EQU LONT =10 ;ゲートLED点灯時間(ms単位: 1〜69) ; .EQU BRC=10000000/(9600*8)-1 ;USART UBRR値(9600bps@10MHz) ; .EQU CR=$0D ;カーソル復帰コード .EQU LF=$0A ;カーソル改行コード .DSEG ;レジスタ領域 .DEF UD00=R0 ;(未使用) .DEF UD01=R1 ;(未使用) .DEF ZERO=R2 ;定数0 .DEF SSV0=R3 ;タイマ/カウンタ1 オーバーフロー割り込み用SREG保存値 .DEF SSV1=R4 ;タイマ/カウンタ0 比較A一致割り込み用SREG保存値 .DEF UD05=R5 ;(未使用) .DEF UD06=R6 ;(未使用) .DEF UD07=R7 ;(未使用) ; .DEF T1OC=R8 ;タイマ/カウンタ1 オーバーフロー計数値 .DEF BCD0=R9 ;パック化BCD最下位バイト .DEF BCD1=R10 ;パック化BCD第2バイト .DEF BCD2=R11 ;パック化BCD第3バイト .DEF BCD3=R12 ;パック化BCD最上位バイト .DEF TC1L=R13 ;入力パルス数計数値下位 .DEF TC1M=R14 ;入力パルス数計数値中位 .DEF TC1H=R15 ;入力パルス数計数値上位 ; .DEF ACCA=R16 ;通常処理汎用レジスタ .DEF ACCB=R17 ;通常処理汎用レジスタ .DEF ACCC=R18 ;通常処理汎用レジスタ .DEF UD19=R19 ;(未使用) .DEF UD20=R20 ;(未使用) .DEF IJWK=R21 ;割り込み作業用 .DEF T0PS=R22 ;1ms前置計数値 .DEF T0M0=R23 ;ゲート間隔時間(=80ms)計数値 .DEF UD24=R24 ;(未使用) .DEF UD25=R25 ;(未使用) ; ;R26はXLとして使用 ; ;R27はXHとして使用 ; ;R28はYLとして使用 ; ;R29はYHとして使用 ; ;R30はZLとして使用 (未使用) ; ;R31はZHとして使用 (未使用) .DSEG ;SRAM領域 TXBF: .BYTE 16 ;USART送信バッファ .CSEG .ORG $0000 START: RJMP INIT ; 0: RST: プログラム開始(初期化へ) RETI ; 1: INT0: 外部0割り込み RETI ; 2: INT1: 外部1割り込み RETI ; 3: CAPT1: タイマ/カウンタ1 捕獲発生割り込み RETI ; 4: CMP1A: タイマ/カウンタ1 比較A一致割り込み RJMP T1OV ; 5: OVF1: タイマ/カウンタ1 オーバーフロー割り込み RETI ; 6: OVF0: タイマ/カウンタ0 オーバーフロー割り込み RETI ; 7: URX: USART 受信割り込み RETI ; 8: UDE: USART 送信バッファ空き割り込み RETI ; 9: UTX: USART 送信割り込み RETI ;10: ACMP: アナログ比較器割り込み RETI ;11: PCI: ピン変化割り込み RETI ;12: CMP1B: タイマ/カウンタ1 比較B一致割り込み RJMP T0CA ;13: CMP0A: タイマ/カウンタ0 比較A一致割り込み RETI ;14: CMP0B: タイマ/カウンタ0 比較B一致割り込み RETI ;15: USIST: USI 開始条件検出割り込み RETI ;16: USIOV: USI オーバーフロー割り込み RETI ;17: EERDY: EEPROM操作可割り込み RETI ;18: WDTI: ウォッチドッグ割り込み .ORG $0013 ; [ 初期化 ] INIT: SBI ACSR,7 ;アナログ比較器動作禁止 CLR ZERO ;0レジスタ初期化 ; * 電源投入時初期化 * LDI R16,0b00000000 ;ポートA出力(------00)値を取得 OUT PORTA,R16 ;ポートA出力レジスタ設定 LDI R16,0b00000000 ;ポートA方向(------II)値を取得 OUT DDRA,R16 ;ポートA方向レジスタ設定 LDI R16,0b11111111 ;ポートB出力(pppppppp)値を取得 OUT PORTB,R16 ;ポートB出力レジスタ設定 LDI R16,0b00000000 ;ポートB方向(IIIIIIII)値を取得 OUT DDRB,R16 ;ポートB方向レジスタ設定 LDI R16,0b01111111 ;ポートD出力(-pp1pp1p)値を取得 OUT PORTD,R16 ;ポートD出力レジスタ設定 LDI R16,0b00010010 ;ポートD方向(-IIOIIOI)値を取得 OUT DDRD,R16 ;ポートD方向レジスタ設定 ; ( スタック ポインタ初期化 ) LDI R16,RAMEND ;SRAM最終位置アドレス取得 OUT SPL,R16 ;スタック ポインタ初期化 ; ( 変数初期化 ) IVAR: LDI ZH,HIGH(29) ;レジスタ初期化領域最終位置上位取得 LDI ZL,LOW(29) ;レジスタ初期化領域最終位置下位取得 IVAR1: ST Z,ZERO ;対応バイト初期化 DEC ZL ;位置指示子(計数値)を減数 BRPL IVAR1 ;R29〜R0まで継続 ; LDI T0PS,1000/25 ;1ms前置計数値初期化 LDI T0M0,GTIM ;ゲート間隔(=80ms)計数値初期化 ; ( USART初期化 ) LDI R16,HIGH(BRC) ;bpsカウント値上位を取得 OUT UBRRH,R16 ;USARTを9600bpsに設定 LDI R16,LOW(BRC) ;bpsカウント値下位を取得 OUT UBRRL,R16 ;USARTを9600bpsに設定 LDI R16,0b00000010 ;USART制御値取得 OUT UCSRA,R16 ;倍速動作指定 LDI R16,0b00001000 ;USART制御値取得 OUT UCSRB,R16 ;送受信割込み禁止,受信禁止,送信許可 ; ( タイマ/カウンタ0初期化 ) LDI R16,250-1 ;250(25μs)計数値取得 OUT OCR0A,R16 ;比較A値初期化 LDI R16,0b00000010 ;CTC動作指定値取得 OUT TCCR0A,R16 ;CTC動作指定 LDI R16,0b00000001 ;分周なし計時開始値取得 OUT TCCR0B,R16 ;分周なし(100ns)計時開始 ; ( タイマ/カウンタ1初期化 ) LDI R16,0b00000000 ;標準動作指定値取得 OUT TCCR1A,R16 ;標準動作指定 LDI R16,0b00000110 ;T1立ち下がり計数指定値取得 OUT TCCR1B,R16 ;T1立ち下がり計数開始 ; ( 割り込み初期化 ) LDI R16,0b10000001 ;T/C1オーバー,T/C0比較A割り込みのみ許可値取得 OUT TIMSK,R16 ;T/C1オーバー,T/C0比較A割り込みのみ許可 ; SEI ;全割り込み許可 ; [ 主処理 ] MAIN: SBIC PORTD,4 ;ゲート間採取完了でスキップ RJMP MAIN ;ゲート間採取完了まで待機 ; ( 採取計数(24ビット バイナリ)⇒パック化BCD(8桁)変換 ) B3D8: CLR BCD3 ;パック化BCD値最上位初期化 CLR BCD2 ;パック化BCD値第3バイト初期化 CLR BCD1 ;パック化BCD値第2バイト初期化 CLR BCD0 ;パック化BCD値最下位初期化 LDI XH,HIGH(9) ;パック化BCD値基準位置上位取得 LDI R17,24 ;ビット計数値初期化 RJMP B3D3 ;開始へ ; B3D1: LDI XL,LOW(12+1) ;パック化BCD最上位バイト+1値取得 B3D2: LD R16,-X ;パック化BCD対応バイト取得 SUBI R16,-(16-10)/2 ;下位桁、次回10以上か検査(+3) SBRC R16,3 ;下位桁、次回10未満でスキップ ST X,R16 ;次回10以上で、下位桁補正(+3) ; LD R16,X ;パック化BCD対応バイトを取得 SUBI R16,-(16-10)/2*16 ;上位桁、次回10以上か検査(+$30) SBRC R16,7 ;上位桁、次回10未満でスキップ ST X,R16 ;次回10以上で、上位桁補正(+$30) ; CPI XL,LOW(9) ;パック化BCD最下位バイト終了検査 BRNE B3D2 ;パック化BCD最下位バイトまで継続 ; B3D3: LSL TC1L ;バイナリ値対応ビットをキャリー フラグへ移動 ROL TC1M ; ROL TC1H ; ROL BCD0 ;対応ビットをパック化BCD値最下位ビットへ移動 ROL BCD1 ; ROL BCD2 ; ROL BCD3 ; DEC R17 ;バイナリ桁(ビット)計数値減数 BRNE B3D1 ;24桁(ビット)分まで継続 ; ( パック化BCD(8)⇒文字符号変換 * D8A: LDI YH,HIGH(TXBF) ;RS232送信バッファ基準位置上位取得 LDI YL,LOW(TXBF) ;RS232送信バッファ基準位置下位取得 LDI XH,HIGH(12+1) ;パック化BCD最終+1位置上位取得 LDI XL,LOW(12+1) ;パック化BCD最終+1位置下位取得 CLR R18 ;0消去フラグ初期化 LDI R17,8 ;処理BCD桁数取得 D8A1: LD R16,-X ;対応パック化BCD値取得(上位桁用) SWAP R16 ;上位桁を下位桁へ移動 D8A2: ANDI R16,0b00001111 ;対応BCD値のみ有効 CPI R17,4+1 ;0消去有無(1の桁以下)検査 BRCS D8A3 ;0消去無しで分岐 OR R18,R16 ;0消去フラグ更新/検査 BRNE D8A3 ;0消去なしで分岐 ; LDI R16,' ' ;0消去で空白符号置換 RJMP D8A4 ;次へ ; D8A3: ORI R16,'0' ;数値文字符号変換 D8A4: ST Y+,R16 ;文字列バッファへ設定 DEC R17 ;BCD桁計数値減数 BREQ D8A5 ;全桁完了で分岐 ; SBRS R17,0 ;上位桁処理後でスキップ RJMP D8A1 ;下位桁処理後(バイト終了)で分岐 ; LD R16,X ;対応パック化BCD値取得(下位桁用) RJMP D8A2 ;継続へ ; D8A5: ; ( RS232送信バッファ最終作成 ) MKTB: LDI YH,HIGH(TXBF) ;RS232送信バッファ基準位置上位取得 LDI YL,LOW(TXBF) ;RS232送信バッファ基準位置下位取得 LDD R16,Y+2 ;有効桁最上位(100000)桁値取得 STD Y+0,R16 ;送信バッファ先頭に移動 LDD R16,Y+3 ;有効桁第2(10000)桁値取得 STD Y+1,R16 ;送信バッファ第2バイトに移動 LDD R16,Y+4 ;有効桁第3(1000)桁値取得 STD Y+2,R16 ;送信バッファ第3バイトに移動 LDI R16,'.' ;小数点符号取得 STD Y+3,R16 ;送信バッファ第4バイトに小数点符号設定 LDD R16,Y+5 ;有効桁第4(100)桁値取得 STD Y+4,R16 ;送信バッファ第5バイトに移動 LDD R16,Y+6 ;有効桁第5(10)桁値取得 STD Y+5,R16 ;送信バッファ第6バイトに移動 LDD R16,Y+7 ;有効桁第6(1)桁値取得 STD Y+6,R16 ;送信バッファ第7バイトに移動 LDI R16,' ' ;空白符号取得 STD Y+7,R16 ;送信バッファ第8バイトに空白符号設定 LDI R16,'M' ;'M'文字符号取得 STD Y+8,R16 ;送信バッファ第9バイトに'M'文字符号設定 LDI R16,'H' ;'H'文字符号取得 STD Y+9,R16 ;送信バッファ第10バイトに'H'文字符号設定 LDI R16,'z' ;'z'文字符号取得 STD Y+10,R16 ;送信バッファ第11バイトに'z'文字符号設定 LDI R16,CR ;カーソル復帰符号取得 STD Y+11,R16 ;送信バッファ第12バイトにカ^ソル復帰符号設定 ; ( ゲートLED消灯 ) GLOF: CPI T0M0,GTIM-LONT ;ゲートLED点灯時間(=10ms)経過でスキップ BRCC GLOF ;ゲートLED点灯時間経過まで待機 ; SBI PORTD,4 ;ゲートLED消灯(/LED=H) ; ( RS232送信 ) TXJ: LDI XH,HIGH(TXBF) ;RS232送信バッファ基準位置上位取得 LDI XL,LOW(TXBF) ;RS232送信バッファ基準位置下位取得 LDI R17,12 ;送信バイト数計数値初期化 TXJ1: SBIS UCSRA,5 ;送信データ レジスタ空きでスキップ RJMP TXJ1 ;送信データ レジスタ空き待機 ; LD R16,X+ ;対応送信値取得 OUT UDR,R16 ;対応送信値をUSARTへ設定 DEC R17 ;送信バイト数計数値減数 BRNE TXJ1 ;全12バイト送信完了まで継続へ ; RJMP MAIN ;主処理継続へ ; [ 割り込み処理 ] ; * タイマ/カウンタ1 オーバフロー割り込み * T1OV: IN SSV0,SREG ;ステータス レジスタ値一時保存 ; INC T1OC ;入力パルス数計数値上位進行 ; OUT SREG,SSV0 ;ステータス レジスタ値復帰 RETI ;割り込みから復帰 ; * タイマ/カウンタ0 比較A一致割り込み (25.0μs) * T0CA: IN SSV1,SREG ;ステータス レジスタ値一時保存 ; DEC T0PS ;1ms前置計数値減数 BRNE T0CA2 ;1ms未経過で分岐 ; LDI T0PS,1000/25 ;1ms前置計数値再初期化 ; DEC T0M0 ;ゲート間隔(=80ms)計数値減数 BRNE T0CA2 ;ゲート間隔未経過で分岐 ; LDI T0M0,GTIM ;ゲート間隔(=80ms)計数値再初期化 ; IN TC1L,TCNT1L ;入力パルス数計数値下位保存 IN TC1M,TCNT1H ;入力パルス数計数値中位保存 OUT TCNT1H,ZERO ;入力パルス数計数値中位再初期化 OUT TCNT1L,ZERO ;入力パルス数計数値下位再初期化 CPSE TC1M,ZERO ;T/C1オーバーフロー可能性有りでスキップ RJMP T0CA1 ;可能性なしで分岐 ; SEI ;全割り込み許可 NOP ; NOP ; CLI ;全割り込み禁止 T0CA1: MOV TC1H,T1OC ;入力パルス数計数値上位保存 CLR T1OC ;入力パルス数計数値上位再初期化 LDI IJWK,0b10000000 ;TOV1のみ1値取得 OUT TIFR,IJWK ;T/C1オーバーフロー割り込み要求フラグ解除 ; CBI PORTD,4 ;ゲートLED点灯(/LED=L) ; T0CA2: OUT SREG,SSV1 ;ステータス レジスタ値復帰 RETI ;割り込みから復帰 .EXIT