<紙>さんLOG

「パソコンヲタクの雑記帳」
 PC/Linux系/物理・化学で遊んでいます。
思いついたことを綴っています。

PIC(15)割込

2008年07月05日 | PIC・マイコン
                                              日記@BlogRanking
前回載せた、0.5秒毎のLED点滅プログラムを、
10mS 毎の TMR0 割込による方式に変えてみました。

なお、20MHz発信器では正確に10mSはだせません。9.984mS になります。
以下、SDCC を除く4言語分を載せます。

(段付けのために、先頭に2B空白がある)
(コメントの日本語がエラーに成るものがあるかもしれない)
(config 定義は正しくないかもしれない)

---------------- <mikro BASIC> ------------------------
' chip(16F873A)、clock(20MHz)、config は IDE で設定する。
program test
dim i as byte
sub procedure interrupt
 if INTCON.T0IF = 1 then ' TMR0 interrupt
  ClearBit(INTCON,T0IF) ' Claer T0IF
  TMR0 = 61 ' Next 10mS
  inc(i)
 end if
end sub
'-------------------
main:
 OPTION_REG = 0x87 ' Assign prescaler to TMR0 1:256
 TMR0 = 61 ' (256-61)=195 0.2us*195*256=9.984ms
 INTCON = %10100000 ' Enable TMRO interrupt
 TRISC.0 = 0 ' output
 PORTC.0 = 1 ' on
 i = 0
 while true
  if i > 49 then
   PORTC.0 = 1 - PORTC.0 ' toggle
   i = 0
  end if
 wend
end.


---------------- <Great Cow BASIC> --------------------
#chip 16F873A, 20 ' MHz
#option bootloader
#config HS_OSC, WDT_OFF
Dim i, xx As Byte ' As Byte は省略可。この文自体が省略可。
OPTION_REG = 0x87 ' Assign prescaler to TMR0 1:256
TMR0 = 61 ' (256-61)=195 0.2us*195*256=9.984ms
set INTCON.TMR0IE on ' Enable TMRO interrupt
set INTCON.GIE on
TRISC.0 = 0 ' output
PORTC.0 = 1 ' on
i = 0
do
 if i > 49 then
  xx = PORTC.0 ' toggle
  PORTC.0 = 1 - xx '
  i = 0
 end if
loop
'-------------------
sub Interrupt
 If INTCON.TMR0IF on then ' TMR0 Interrupt occurred
  set INTCON.TMR0IF off ' Clear the interrupt
  TMR0 = 61 ' Reset for Next 10mS
  i = i + 1
 End If
End sub


---------------- <Swordfish BASIC> --------------------
Device = 18F2550
Clock = 24 ' MHz
Config
 PLLDIV=5, CPUDIV=OSC3_PLL4, FOSC=HSPLL_HS, WDT=OFF
Dim TMR0ON As T0CON.7,
 T08BIT As T0CON.6,
 T0CS As T0CON.5,
 T0SE As T0CON.4,
 PSA As T0CON.3,
 TMR0IE As INTCON.5,
 TMR0IF As INTCON.2,
 TMR0 As TMR0L
Dim i As Byte
Interrupt TMR0_Interrupt()
 If TMR0IF = 1 Then // Check if a TMR0 Interrupt occurred
  TMR0IF = 0 // Clear the interrupt
  TMR0 = 22 // Next 10mS
  Inc(i)
 EndIf
End Interrupt
'----------------------
TMR0ON = 0 // Disable TMR0
T08BIT = 1 // Ensure TMR0 is working in 8 Bit mode
T0CS = 0 // Ensure TMR increments from internal clock
T0SE = 0 // Only used if external source is selected
PSA = 0 // Ensure the Clock source uses the Prescaler
T0CON.0 = 1 // Set the Prescaler bits
T0CON.1 = 1 // 1:256
T0CON.2 = 1 // (256-22)=234, 234*1/6*256=9.984mS
TMR0 = 22 // Set the TMR0 register
TMR0IE = 1 // Enable TMR0 Interrupts
Enable(TMR0_Interrupt) // Enable the TMR0 Interrupt Handler
TMR0ON = 1 // Enable TMR0 to increment
TRISC.0 = 0 ' output
PORTC.0 = 1 ' on
i = 0
While true
 If i > 49 then
  Toggle(PORTC.0) ' toggle
  i = 0
 Endif
Wend


---------------- <C18> -----------------------------
#include <p18cxxx.h> // PIC18F2550
#pragma config PLLDIV = 5
/*  その他 20MHz -> 24MHz */
#pragma interrupt ISR // 割込み宣言(優先順位使わない)
#pragma code ISR = 0x08 // 割込みベクタへのjmp命令セット
void Jump_ISR(void){
_asm goto ISR _endasm
}
#define LED0 PORTCbits.RC0 // LED 定義
#pragma udata
unsigned char i;
#pragma code
void main(){
 T0CON = 0b01000111;
   // TMR0ON = 0; ' Disable TMR0
   // T08BIT = 1; ' TMR0 is working in 8 Bit mode
   // T0CS = 0;  ' TMR increments from internal clock
   // T0SE = 0;  ' Only used external source
   // PSA = 0;   ' Ensure the Clock source uses the Prescaler
   // .2 = 1;   ' Prescaler bits
   // .1 = 1;   ' 1:256
   // .0 = 1;   ' (256-22)=234, 234*1/6*256=9.984mS
 TMR0L = 22; // Set the TMR0 register
 INTCONbits.TMR0IE = 1; // Enable TMR0 Interrupts
 T0CONbits.TMR0ON = 1;
 INTCONbits.GIE = 1;
 TRISCbits.TRISC0=0; // output
 LED0 = 1; // on
 i = 0
 while (1){
  if ( i > 49 ){
   if ( LED0 ) LED0=0; else LED0=1;
   i = 0;
  }
 }
}
//----------------------
void ISR(void){ // 割り込み関数
 if(INTCONbits.T0IF){ // タイマ0割り込み?
  INTCONbits.T0IF=0; // タイマ0割り込みフラグを0にする
  TMR0L = 22; // Re-Set the TMR0 register
  i ++ ;
 }
}
できるだけ、各言語の特徴を出したつもりです。

お手数をおかけします。2クリック(投票を)お願いします ⇒ 日記@BlogRanking

最新の画像もっと見る

コメントを投稿

ブログ作成者から承認されるまでコメントは反映されません。