48時間以内の記事は で表示されます
自分には原因不明
>それともどこかに掲載されたプログラム&スケッチを試したのですか?
スケッチとはなんでしたっけ?
同じ配線で試しました。
RB3につないであるLEDと抵抗があります。
そのLEDと抵抗込みの電圧に差があります。
自分のは明るい。猛牛ロックさんはすべて書いてなかったけど、
以下は、猛牛ロックさんが書いてなかった部分を書き足したものです。
// 花丸 タイマー0割込みPIC16F1827 Configuration Bit Settings
//RA6 マッハからの信号 RA6 SW ONの間中RB3 点灯、 RA6 SW offでRB3 点滅
// 'C' source line config statements
#include <xc.h>
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF // PLL Enable (4x PLL disabled)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = HI // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
// __delay_ms(), __delay_us()関数が使用する
#define _XTAL_FREQ 4000000
volatile int event;
// プロトタイプ宣言
void InitInterTimer0(void);
// メイン関数
void main(void) {
OSCCON = 0b01101010; // 内部クロック周波数を4MHzに設定
// 電圧レベルの初期設定
PORTA = 0x00;
PORTB = 0x00;
// 入出力設定
TRISA = 0b01000000;
TRISB = 0x00;
// タイマ0割込み設定関数の呼び出し
InitInterTimer0();
// 割込み全体の許可
GIE = 1;
// 永久ループ
while (1) {
LATB3 = !RA6;//意味はRA6の内容を反転(論理否定)させたものをLATB3に代入します。
//つまり、RA6が1ならLATB3を0にする。RA6が0ならLATB3を1にする。
}
}
// 割込みサービスルーチン
static void interrupt isr() {
static unsigned int ms = 0;
if (ms < 3000)LATB3 = 1;
else LATB3 = 0;
ms++;
if (ms == 6000) ms = 0;
//msの初期化//カウントアップ、6s(6000)でリセット
// タイマ0割込みフラグをクリア
T0IF = 0;
}
// タイマ0割込み設定関数
void InitInterTimer0(void) {
OPTION_REG = 0b000000000; //プリスケラ000 5ビット=0内部クロック使用 WDTは使わない
TMR0 = -250; //直ぐにセットする
INTCONbits.TMR0IF = 0; //TMR0フラグクリアー
INTCONbits.TMR0IE = 1; //TMR0割り込み許可
INTCONbits.GIE = 1; //全体割り込み許可
}
スケッチとはなんでしたっけ?
同じ配線で試しました。
RB3につないであるLEDと抵抗があります。
そのLEDと抵抗込みの電圧に差があります。
自分のは明るい。猛牛ロックさんはすべて書いてなかったけど、
以下は、猛牛ロックさんが書いてなかった部分を書き足したものです。
// 花丸 タイマー0割込みPIC16F1827 Configuration Bit Settings
//RA6 マッハからの信号 RA6 SW ONの間中RB3 点灯、 RA6 SW offでRB3 点滅
// 'C' source line config statements
#include <xc.h>
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF // PLL Enable (4x PLL disabled)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = HI // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
// __delay_ms(), __delay_us()関数が使用する
#define _XTAL_FREQ 4000000
volatile int event;
// プロトタイプ宣言
void InitInterTimer0(void);
// メイン関数
void main(void) {
OSCCON = 0b01101010; // 内部クロック周波数を4MHzに設定
// 電圧レベルの初期設定
PORTA = 0x00;
PORTB = 0x00;
// 入出力設定
TRISA = 0b01000000;
TRISB = 0x00;
// タイマ0割込み設定関数の呼び出し
InitInterTimer0();
// 割込み全体の許可
GIE = 1;
// 永久ループ
while (1) {
LATB3 = !RA6;//意味はRA6の内容を反転(論理否定)させたものをLATB3に代入します。
//つまり、RA6が1ならLATB3を0にする。RA6が0ならLATB3を1にする。
}
}
// 割込みサービスルーチン
static void interrupt isr() {
static unsigned int ms = 0;
if (ms < 3000)LATB3 = 1;
else LATB3 = 0;
ms++;
if (ms == 6000) ms = 0;
//msの初期化//カウントアップ、6s(6000)でリセット
// タイマ0割込みフラグをクリア
T0IF = 0;
}
// タイマ0割込み設定関数
void InitInterTimer0(void) {
OPTION_REG = 0b000000000; //プリスケラ000 5ビット=0内部クロック使用 WDTは使わない
TMR0 = -250; //直ぐにセットする
INTCONbits.TMR0IF = 0; //TMR0フラグクリアー
INTCONbits.TMR0IE = 1; //TMR0割り込み許可
INTCONbits.GIE = 1; //全体割り込み許可
}
Re: 自分には原因不明
これは駄目です。
2つのプログラムを無理やり付けても動作しません。
ベースに
LATB3 = !RA6;
がありますから、これを削除すれば3秒毎の点灯/消灯です。
これが付けば、殆どはRA6のスイッチと連動した動作になります。
・SW(RA6)を押したらLED(RB3)が光る
・LED(RB3)を点滅させる
というプログラムをどう両立させようと思ったのですか?
私には目的動作が判りません。
追記
SWを押しっぱなしにすれば、逆に殆ど点灯していて、3秒ごとにちょっと薄くなると思います。
プログラムをちゃんと追えれば、どういった事になっているか判ると思います。
2つのプログラムを無理やり付けても動作しません。
ベースに
LATB3 = !RA6;
がありますから、これを削除すれば3秒毎の点灯/消灯です。
これが付けば、殆どはRA6のスイッチと連動した動作になります。
・SW(RA6)を押したらLED(RB3)が光る
・LED(RB3)を点滅させる
というプログラムをどう両立させようと思ったのですか?
私には目的動作が判りません。
追記
SWを押しっぱなしにすれば、逆に殆ど点灯していて、3秒ごとにちょっと薄くなると思います。
プログラムをちゃんと追えれば、どういった事になっているか判ると思います。
無題ー1
前スレの続きです。
TRさん,猛牛ロックさん,こんばんは。
便利な機能があるんですね。自動で,インデントがつけられるんですね。
こうするとバグも見つけやすくなりますかね。
TRさん,私も初めてわかりました。下記に記事があります。
https://picalittle.blog.fc2.com/blog-entry-25.html
TRさん,猛牛ロックさん,こんばんは。
便利な機能があるんですね。自動で,インデントがつけられるんですね。
こうするとバグも見つけやすくなりますかね。
TRさん,私も初めてわかりました。下記に記事があります。
https://picalittle.blog.fc2.com/blog-entry-25.html
Re: 無題ー1
皆さん いろいろとありがとうございます」。
mainn関数内に以下を足したら、
動作しました。
__delay_ms(5000);//5秒まつ
RB3=0;
event=0;
event=0をつけて、eventが0~1~0と回るようにしたら、
SWとRB3がつながりました。
やった〜
22:23追記
押している間だけ点灯させるには、
main関数内の最後に以下を足せば、SW ONの間だけ
RB3が点灯します。
これで、さっぱりとしました。
if (event == 1&& RA6 == 1) {
RB3 = 0;
event = 0;
mainn関数内に以下を足したら、
動作しました。
__delay_ms(5000);//5秒まつ
RB3=0;
event=0;
event=0をつけて、eventが0~1~0と回るようにしたら、
SWとRB3がつながりました。
やった〜
22:23追記
押している間だけ点灯させるには、
main関数内の最後に以下を足せば、SW ONの間だけ
RB3が点灯します。
これで、さっぱりとしました。
if (event == 1&& RA6 == 1) {
RB3 = 0;
event = 0;
Re: 無題ー1
タイマー割り込みですけど、この機種だとタイマー2,4,6あたりを使うのが良いです。
まぁ、取りあえず、タイマー0と言う事で書きます。
マイコンのクロック周波数が4MHzだとします。で、タイマーのクロック元は1/4クロック=1サイクルを選択します。
つまり、1MHz=1usです。
次に割り込み間隔を1msにします。この辺りが標準的だと思います。SWの読み取りやダイナミック点灯など、大体これでいけます。
となると、カウント値1000になるので、そのままだと8ビットカウンタがオーバーします。なのでプリスケーラの出番です。
1:4を選択すれば、250カウントで1ms、1:8なら125カウントで1msです。
で、タイマー0だと、比較一致が無く、オーバーフロー(カウンタ溢れ)しかありません。なので自分で設定します。
割り込みの最初でTMR0=156;とすれば、156から数え始め、100カウント目の256の時に再び割り込みに入ります。
なので、1:4ならTMR0=6;(256-250)、1:8ならTMR0=131;(256-125)にする事になります。
ただ、ちょっと解りずらいので、マイナスの数を使うのが良いです。つまり、TMR0=-250;です。
マイナスは「あと250カウントしたら0になる」という意味です。時計の「○分前」というのと同じです。
具体的には下のような感じです。何回割り込みに入ったかで正確な時間を測ります。
//上部略
// タイマ0割込み設定関数
void InitInterTimer0(void) {
//割り込み設定
OPTION_REG = 1; //1:4
TMR0IE = 1; //TMR0割り込み許可
GIE = 1; //全体割り込み許可
}
//TMR0の割り込み1ms
void interrupt isr() {
TMR0=-250;//直ぐにセットする
T0IF = 0;
static unsigned int ms=0;
if(ms<3000)LATB3=1;
else LATB3=0;
ms=(ms+1)%6000;//カウントアップ、6s(6000)でリセット
}
// メイン関数
void main(void) {
OSCCON = 0b01101010; //内蔵発振器 4MHz使用に設定
//ピン初期設定
LATB = 1<<3;
TRISB = 0;
InitInterTimer0();
while (1) {}
}
ただし、正確に言えば、TMR=-250;とした時にプリスケーラもリセットされます。
なので、その分完璧ではありません。256でオーバーフローさせて、それを数えて算出すれば完璧です。
けれども、その誤差よりも、内蔵クロックの誤差の方が大きいのであまり問題にはなりません。
で、タイマー2,4,6は比較器が付いています。この間やったPWMの周期を決めるPR2と全くおなじです。
それで上限を249とすることで、TMRレジスタを直接操作することなく、1msにすることが出来ます。
あれ?書き込み器は直ったのですか?
動いたのは良かったですけど、押している間なら
while(1){
LATB3=!RA6;
}
で済むと思うんだけど…
でも、そういった事を多くするのが重要です。
>SOURCE→FORMAT
そのまま上部のメニューからの操作です。
※今日は土曜出勤でした。
まぁ、取りあえず、タイマー0と言う事で書きます。
マイコンのクロック周波数が4MHzだとします。で、タイマーのクロック元は1/4クロック=1サイクルを選択します。
つまり、1MHz=1usです。
次に割り込み間隔を1msにします。この辺りが標準的だと思います。SWの読み取りやダイナミック点灯など、大体これでいけます。
となると、カウント値1000になるので、そのままだと8ビットカウンタがオーバーします。なのでプリスケーラの出番です。
1:4を選択すれば、250カウントで1ms、1:8なら125カウントで1msです。
で、タイマー0だと、比較一致が無く、オーバーフロー(カウンタ溢れ)しかありません。なので自分で設定します。
割り込みの最初でTMR0=156;とすれば、156から数え始め、100カウント目の256の時に再び割り込みに入ります。
なので、1:4ならTMR0=6;(256-250)、1:8ならTMR0=131;(256-125)にする事になります。
ただ、ちょっと解りずらいので、マイナスの数を使うのが良いです。つまり、TMR0=-250;です。
マイナスは「あと250カウントしたら0になる」という意味です。時計の「○分前」というのと同じです。
具体的には下のような感じです。何回割り込みに入ったかで正確な時間を測ります。
//上部略
// タイマ0割込み設定関数
void InitInterTimer0(void) {
//割り込み設定
OPTION_REG = 1; //1:4
TMR0IE = 1; //TMR0割り込み許可
GIE = 1; //全体割り込み許可
}
//TMR0の割り込み1ms
void interrupt isr() {
TMR0=-250;//直ぐにセットする
T0IF = 0;
static unsigned int ms=0;
if(ms<3000)LATB3=1;
else LATB3=0;
ms=(ms+1)%6000;//カウントアップ、6s(6000)でリセット
}
// メイン関数
void main(void) {
OSCCON = 0b01101010; //内蔵発振器 4MHz使用に設定
//ピン初期設定
LATB = 1<<3;
TRISB = 0;
InitInterTimer0();
while (1) {}
}
ただし、正確に言えば、TMR=-250;とした時にプリスケーラもリセットされます。
なので、その分完璧ではありません。256でオーバーフローさせて、それを数えて算出すれば完璧です。
けれども、その誤差よりも、内蔵クロックの誤差の方が大きいのであまり問題にはなりません。
で、タイマー2,4,6は比較器が付いています。この間やったPWMの周期を決めるPR2と全くおなじです。
それで上限を249とすることで、TMRレジスタを直接操作することなく、1msにすることが出来ます。
あれ?書き込み器は直ったのですか?
動いたのは良かったですけど、押している間なら
while(1){
LATB3=!RA6;
}
で済むと思うんだけど…
でも、そういった事を多くするのが重要です。
>SOURCE→FORMAT
そのまま上部のメニューからの操作です。
※今日は土曜出勤でした。
Re: 無題ー1
猛牛ロックさんこんにちは。
自作書き込み基板は、1827用に、以下の内容で再作成します。
コメお願いします。
方針
PORTA
出力端子
つなぎ方
PICの端子〜LED〜抵抗〜GND
PORTB
入力端子(全ビットプルアップ)
つなぎ方
DC5V〜抵抗〜LED〜PICの端子〜SW〜なし
それと、猛牛ロックさんプログラムを拝見させていただきました。
有難うございます。
聞きたい点を ← の後に羅列しましたので、ご教授願います。
/上部略
// タイマ0割込み設定関数
void InitInterTimer0(void) {
//割り込み設定
OPTION_REG = 1; //1:4 ←端折っていますか?OPTIN_REG=00000001では?
TMR0IE = 1; //TMR0割り込み許可
GIE = 1; //全体割り込み許可
}
//TMR0の割り込み1ms
void interrupt isr() {
TMR0=-250;//直ぐにセットする
T0IF = 0;←タイマー0が入ると1が立つので、ここで初期化する
static unsigned int ms=0; ← static静的なという意味があるようですが、どういった意味合いになりますか?
if(ms<3000)LATB3=1;
else LATB3=0;
ms=(ms+1)%6000;//カウントアップ、6s(6000)でリセット ←ふつうは割込み作業を終えたら、ここで、T0IF=0;//タイマ0による割り込みフラグリセットと記述すると思いますが、この行の意味は何ですか?
}
// メイン関数
void main(void) {
OSCCON = 0b01101010; //内蔵発振器 4MHz使用に設定
//ピン初期設定
LATB = 1<<3;←1のbit列を3bit左にシフトという意味と思いますが何故こういったことをするのですか?
TRISB = 0;
InitInterTimer0();
while (1) {}
追記
PORTBは、PIC内部でプルアップです。
自作書き込み基板は、1827用に、以下の内容で再作成します。
コメお願いします。
方針
PORTA
出力端子
つなぎ方
PICの端子〜LED〜抵抗〜GND
PORTB
入力端子(全ビットプルアップ)
つなぎ方
DC5V〜抵抗〜LED〜PICの端子〜SW〜なし
それと、猛牛ロックさんプログラムを拝見させていただきました。
有難うございます。
聞きたい点を ← の後に羅列しましたので、ご教授願います。
/上部略
// タイマ0割込み設定関数
void InitInterTimer0(void) {
//割り込み設定
OPTION_REG = 1; //1:4 ←端折っていますか?OPTIN_REG=00000001では?
TMR0IE = 1; //TMR0割り込み許可
GIE = 1; //全体割り込み許可
}
//TMR0の割り込み1ms
void interrupt isr() {
TMR0=-250;//直ぐにセットする
T0IF = 0;←タイマー0が入ると1が立つので、ここで初期化する
static unsigned int ms=0; ← static静的なという意味があるようですが、どういった意味合いになりますか?
if(ms<3000)LATB3=1;
else LATB3=0;
ms=(ms+1)%6000;//カウントアップ、6s(6000)でリセット ←ふつうは割込み作業を終えたら、ここで、T0IF=0;//タイマ0による割り込みフラグリセットと記述すると思いますが、この行の意味は何ですか?
}
// メイン関数
void main(void) {
OSCCON = 0b01101010; //内蔵発振器 4MHz使用に設定
//ピン初期設定
LATB = 1<<3;←1のbit列を3bit左にシフトという意味と思いますが何故こういったことをするのですか?
TRISB = 0;
InitInterTimer0();
while (1) {}
追記
PORTBは、PIC内部でプルアップです。
Re: 無題ー1
猛牛ロックさん,TRさん,こんばんは,
猛牛ロックさんのプログラムは,いつもながら感心させられます。
TRさんの疑問点ですが,分かる範囲で書きます。
詳しくは猛牛ロックさんがコメントくださると思います。
まず,
ms=(ms+1)%6000
は,msをプラス1して6000で割ったあまりをmsに入れてますので,
if(ms<6000){ms++;}
else{ms=0;}
と同じ意味だと思います。こうすれば,msのオーバーフローを気にしなくていいので,いい方法だと思います。
割り込みに入ってくる回数をカウントして,6秒を作ってます。
それから,
LATB = 1<<3
ですが,クロック数が多くとれるPICでは,レジスタの操作が思うようにできないことがあります。
これを解決するために作られたのがLATレジスタです。
私も以前,これ使ったことあります。3ビット分シフトするので,
LATB.B3=1
と同じ意味だと思います。
働き的には,
RB3=1
としてもいいのですが,RB3とかのレジスタの操作を続けて行うと,思った動作をしなくなります。
こんな時にLATレジスタを使うと大丈夫なようです。
下記に記載があります。
http://www.microtechnica.tv/faq/faq.cgi?kate=mikroC&faq=16
間違ってるかもしれませんが,間違いは,多分,猛牛ロックだんがコメントくださると思います。
猛牛ロックさんのプログラムは,いつもながら感心させられます。
TRさんの疑問点ですが,分かる範囲で書きます。
詳しくは猛牛ロックさんがコメントくださると思います。
まず,
ms=(ms+1)%6000
は,msをプラス1して6000で割ったあまりをmsに入れてますので,
if(ms<6000){ms++;}
else{ms=0;}
と同じ意味だと思います。こうすれば,msのオーバーフローを気にしなくていいので,いい方法だと思います。
割り込みに入ってくる回数をカウントして,6秒を作ってます。
それから,
LATB = 1<<3
ですが,クロック数が多くとれるPICでは,レジスタの操作が思うようにできないことがあります。
これを解決するために作られたのがLATレジスタです。
私も以前,これ使ったことあります。3ビット分シフトするので,
LATB.B3=1
と同じ意味だと思います。
働き的には,
RB3=1
としてもいいのですが,RB3とかのレジスタの操作を続けて行うと,思った動作をしなくなります。
こんな時にLATレジスタを使うと大丈夫なようです。
下記に記載があります。
http://www.microtechnica.tv/faq/faq.cgi?kate=mikroC&faq=16
間違ってるかもしれませんが,間違いは,多分,猛牛ロックだんがコメントくださると思います。
Re: 無題ー1
maboさん、拙い質問ですみません。
8ビットなので、レジスタに1ずつ加算されていき8ビットの最大値(255)を超えたとき(256になった時)に割り込みが発生します。
とよく目にします。
このことと関係があります。
1MHzの動作速度だと、1/1Mzで1μs/回
1回の振動の時間が1μsだと思います。
この1μsの時間で、1回のカウントができると考えてよろしいのでしょうか?
255というのは、255μsかかるのでしょうか?
8ビットなので、レジスタに1ずつ加算されていき8ビットの最大値(255)を超えたとき(256になった時)に割り込みが発生します。
とよく目にします。
このことと関係があります。
1MHzの動作速度だと、1/1Mzで1μs/回
1回の振動の時間が1μsだと思います。
この1μsの時間で、1回のカウントができると考えてよろしいのでしょうか?
255というのは、255μsかかるのでしょうか?
Re: 無題ー1
> OPTION_REG = 1; //1:4 ←端折っていますか?OPTIN_REG=00000001では?
同じです。「1」も「0b00001」も「0x000001」でもどれも整数の1です。
この辺りは全然気を使っていません。データシートみて端だけ1だったのでそうしただけです。
> T0IF = 0;←タイマー0が入ると1が立つので、ここで初期化する
現実的には割り込み内に全部の事が終わっていれば割り込み最後でも同じ事です。
私は最初にクリアするのが好みです。
で、「タイマー0が入ると」とは「タイマー0割り込みに入ると」ということですよね?
最初はタイマーが0になると、という意味かと思いました。
> static unsigned int ms=0; ← static静的なという
前にも説明したと思いますけど、これは重要です。
staticが無ければこの関数に入ると毎回ms=0;が実行されます。つまりカウントアップできません。
staticをつけると継続されます。下の方でカウントアップしていますけど、その数値が維持されます。
つまり、「ms=0」は初回のみ行われます。
> ms=(ms+1)%6000;//カウントアップ、6s(6000)でリセット ←ふつうは
コメント通りですけど。
2行に分けます。
ms=ms+1; //カウントアップです。毎回、自分(ms)に1を加えたものを、代入します
ms=ms%6000; //「%」は割った余りのことです。今回はif(ms>=6000)ms=ms-6000;と同じ意味です。
この辺りも好きに書けば良い事です。自分の好みで書いてください。
> LATB = 1<<3;←1のbit列を3bit左にシフトという意味と思いますが何故こういったことをするのですか?
特別な意味はありません。何となくそう手が動いただけです。8でも0b1000でも0x8でも良いです。
重要なのはLATB3だけ1、残りを0、にすることです。
> PORTBは、PIC内部でプルアップです。
ホントだ。OPTION_REG間違いましたね。
OPTION_REG=0x81;
でした。
デフォルトで、全部1で、内部プルアップも1で無効なんですね。
この辺りも判り難いですね。まぁデータシートで確認するだけですけど。
<<追記>>
データシートのプルアップの欄で
2: The weak pull-up device is automatically disabled if the pin is in configured as an output.
と、出力設定時には自動で内部プルアップは無効になる、と書いてあります。
なので、今回は
OPTION_REG = 1;
でも出力にしているので、内部プルアップは無効です。まぁ、使わない場合は
OPTION_REG |=0x80;
とした方が良いでしょうけど。
> 1MHzの動作速度だと、1/1Mzで1μs/回
> 1回の振動の時間が1μsだと思います。
> この1μsの時間で、1回のカウントができると考えてよろしいのでしょうか?
> 255というのは、255μsかかるのでしょうか?
4MHzクロック=1MHzサイクルの場合に
・クロック源を1/4駆動クロック(つまり1サイクル)を選択
・プリスケーラを無効
にした場合は1MHz=1usでタイマーがカウントアップされます。
0から255までなら255usですけど、1回転なら更に1カウントした時です。
0b11111111(255)から1を足すと0b100000000(256)です。一番左の1は8ビットのカウント外ですから消えます。
(割り込みを有効にしていれば、その消える1が利用されて割り込みになります)
※言っている事に間違いはありません
<追記>
書き込み器の回路を見ました。
RA5は入力のみです。そして、LEDを付けてプルダウンさせればリセットしっ放しになります。
RB6、RB7にLEDを付けて正常に書き込みできるかは判りません。
ブレッドボードで試してからにした方が良いです。
※無難なのはスイッチのみを付ける事です
同じです。「1」も「0b00001」も「0x000001」でもどれも整数の1です。
この辺りは全然気を使っていません。データシートみて端だけ1だったのでそうしただけです。
> T0IF = 0;←タイマー0が入ると1が立つので、ここで初期化する
現実的には割り込み内に全部の事が終わっていれば割り込み最後でも同じ事です。
私は最初にクリアするのが好みです。
で、「タイマー0が入ると」とは「タイマー0割り込みに入ると」ということですよね?
最初はタイマーが0になると、という意味かと思いました。
> static unsigned int ms=0; ← static静的なという
前にも説明したと思いますけど、これは重要です。
staticが無ければこの関数に入ると毎回ms=0;が実行されます。つまりカウントアップできません。
staticをつけると継続されます。下の方でカウントアップしていますけど、その数値が維持されます。
つまり、「ms=0」は初回のみ行われます。
> ms=(ms+1)%6000;//カウントアップ、6s(6000)でリセット ←ふつうは
コメント通りですけど。
2行に分けます。
ms=ms+1; //カウントアップです。毎回、自分(ms)に1を加えたものを、代入します
ms=ms%6000; //「%」は割った余りのことです。今回はif(ms>=6000)ms=ms-6000;と同じ意味です。
この辺りも好きに書けば良い事です。自分の好みで書いてください。
> LATB = 1<<3;←1のbit列を3bit左にシフトという意味と思いますが何故こういったことをするのですか?
特別な意味はありません。何となくそう手が動いただけです。8でも0b1000でも0x8でも良いです。
重要なのはLATB3だけ1、残りを0、にすることです。
> PORTBは、PIC内部でプルアップです。
ホントだ。OPTION_REG間違いましたね。
OPTION_REG=0x81;
でした。
デフォルトで、全部1で、内部プルアップも1で無効なんですね。
この辺りも判り難いですね。まぁデータシートで確認するだけですけど。
<<追記>>
データシートのプルアップの欄で
2: The weak pull-up device is automatically disabled if the pin is in configured as an output.
と、出力設定時には自動で内部プルアップは無効になる、と書いてあります。
なので、今回は
OPTION_REG = 1;
でも出力にしているので、内部プルアップは無効です。まぁ、使わない場合は
OPTION_REG |=0x80;
とした方が良いでしょうけど。
> 1MHzの動作速度だと、1/1Mzで1μs/回
> 1回の振動の時間が1μsだと思います。
> この1μsの時間で、1回のカウントができると考えてよろしいのでしょうか?
> 255というのは、255μsかかるのでしょうか?
4MHzクロック=1MHzサイクルの場合に
・クロック源を1/4駆動クロック(つまり1サイクル)を選択
・プリスケーラを無効
にした場合は1MHz=1usでタイマーがカウントアップされます。
0から255までなら255usですけど、1回転なら更に1カウントした時です。
0b11111111(255)から1を足すと0b100000000(256)です。一番左の1は8ビットのカウント外ですから消えます。
(割り込みを有効にしていれば、その消える1が利用されて割り込みになります)
※言っている事に間違いはありません
<追記>
書き込み器の回路を見ました。
RA5は入力のみです。そして、LEDを付けてプルダウンさせればリセットしっ放しになります。
RB6、RB7にLEDを付けて正常に書き込みできるかは判りません。
ブレッドボードで試してからにした方が良いです。
※無難なのはスイッチのみを付ける事です
Re: 無題ー1
//TMR0の割り込み1ms
void interrupt isr() {
TMR0=-250;//直ぐにセットする
T0IF = 0;
static unsigned int ms=0;←msの初期値=0
if(ms<3000)LATB3=1;←3秒間LATB3が点灯
else LATB3=0; ←3秒を超えたらLATB3が消灯
ms=(ms+1)%6000;//カウントアップ、6s(6000)でリセット ←は,ms初期値0に1msを足し、6000で割ったあまりを更に最初のmsを捨てて、新たなmsに1を足して、また6000で割った値を、、、
これを6000msまでつづけるとすると、一つ上の行は3秒間LATB3が点灯となっているので、3秒間点灯後の残り3秒は、LATB3がoffとなり、その後また、main関数に戻るということですか?
、、、、と考えると意味が分かりません。
もう少し詳しく教えてください。
RB6、RB7にLEDを付けて正常に書き込みできるかは判りません。
ブレッドボードで試してからにした方が良いです。← 出力端子RB3に、LEDと180Ωを付け、且つプルダウン10kΩ付けながら書き込みました。
テスト結果は、RB6とRB7の両方とも点灯しました。
※無難なのはスイッチのみを付ける事です← 入力端子の設定の場合を懸念しているのかな〜?
出力端子は、ハイでもローでも電位を固定できるといわれていますが、短絡事故防止の為にプルダウン抵抗をつけた方が良いと思いますが、
出力端子の場合、書き込んでいる最中は、プルダウン抵抗をしない方が良いという意味でしょうか?
>現実的には割り込み内に全部の事が終わっていれば割り込み最後でも同じ事です。
私は最初にクリアするのが好みです。
void interrupt isr()関数で割込み作業を実施してしまえば、割込み作業の前でも後でもので良いので、
タイマー0の割込み作業実施後に立ったT0IF のフラグを0にリセットして、
次回の割込み作業に備えるってことですよね。
※
1827は、PORTAのRA5の為にPORTA側を一体で出力端子にできないんですね!?
ということは、IN OUTそれぞれ8ピンづつとしたい場合は、
PORBの内、1ピンだけ入力設定で使うことになるのでしょうか?
追記
1827ですが、PORTA側を入力端子に使った場合、考えられる不都合としては、
割込みの場合、IOCAN3 = 1; 割込み種類別の有効化の設定を行い といった、作業ができないくらいでしょうか?
static 分かりました。 0にせずに、記録をとどめ、次の作業にその記録を次の機会に使える
といった意味ですね。
void interrupt isr() {
TMR0=-250;//直ぐにセットする
T0IF = 0;
static unsigned int ms=0;←msの初期値=0
if(ms<3000)LATB3=1;←3秒間LATB3が点灯
else LATB3=0; ←3秒を超えたらLATB3が消灯
ms=(ms+1)%6000;//カウントアップ、6s(6000)でリセット ←は,ms初期値0に1msを足し、6000で割ったあまりを更に最初のmsを捨てて、新たなmsに1を足して、また6000で割った値を、、、
これを6000msまでつづけるとすると、一つ上の行は3秒間LATB3が点灯となっているので、3秒間点灯後の残り3秒は、LATB3がoffとなり、その後また、main関数に戻るということですか?
、、、、と考えると意味が分かりません。
もう少し詳しく教えてください。
RB6、RB7にLEDを付けて正常に書き込みできるかは判りません。
ブレッドボードで試してからにした方が良いです。← 出力端子RB3に、LEDと180Ωを付け、且つプルダウン10kΩ付けながら書き込みました。
テスト結果は、RB6とRB7の両方とも点灯しました。
※無難なのはスイッチのみを付ける事です← 入力端子の設定の場合を懸念しているのかな〜?
出力端子は、ハイでもローでも電位を固定できるといわれていますが、短絡事故防止の為にプルダウン抵抗をつけた方が良いと思いますが、
出力端子の場合、書き込んでいる最中は、プルダウン抵抗をしない方が良いという意味でしょうか?
>現実的には割り込み内に全部の事が終わっていれば割り込み最後でも同じ事です。
私は最初にクリアするのが好みです。
void interrupt isr()関数で割込み作業を実施してしまえば、割込み作業の前でも後でもので良いので、
タイマー0の割込み作業実施後に立ったT0IF のフラグを0にリセットして、
次回の割込み作業に備えるってことですよね。
※
1827は、PORTAのRA5の為にPORTA側を一体で出力端子にできないんですね!?
ということは、IN OUTそれぞれ8ピンづつとしたい場合は、
PORBの内、1ピンだけ入力設定で使うことになるのでしょうか?
追記
1827ですが、PORTA側を入力端子に使った場合、考えられる不都合としては、
割込みの場合、IOCAN3 = 1; 割込み種類別の有効化の設定を行い といった、作業ができないくらいでしょうか?
static 分かりました。 0にせずに、記録をとどめ、次の作業にその記録を次の機会に使える
といった意味ですね。
Re: 無題ー1
> もう少し詳しく教えてください。
変数ms自体は、最後の計算部分で1が足されます。(ms+1)つまり、カウントアップです。
更に%6000としているので、MAX6000(5999)のカウンタ/タイマーです。
> 3秒間点灯後の残り3秒は、LATB3がoffとなり、その後また、main関数に戻る
大きな勘違いをしています。毎回すぐにmain関数に戻ります。3秒も居ません。
msはタイマー0割り込みに入った回数をカウントしています。
1回入るとmsが1増えます。6000回この関数に入ると%6000の部分が効いて0になります。
毎回余りの計算はしていますけど、6000(以上)になった時だけ効果が有効になります。
タイマー割り込み関数自体は直ぐに終わるようにします。
> ※無難なのはスイッチのみを付ける事です← 入力端子の設定の場合を懸念しているのかな〜?
いいえ、単純に書き込めるかどうかです。書き込めたのなら良いです。
書き込み端子ですから、PICKIT3からの信号によって、ピン先がHIGH⇔LOWがちゃんと振れるかどうかの問題です。
> 短絡事故防止の為にプルダウン抵抗をつけた方が良いと思いますが
いいえ。短絡事故防止なら繋がないか、或いは入力にするのが一番です。プルダウン抵抗は何の役にも立ちません。電気が漏れているだけです。
付ける必要があるのはその出力先が制御端子、つまり、別のICの入力だった場合です。その時はHIGH/LOW区別するために付ける場合があります。
でもプルアップの方が多いです。
> 出力端子の場合、書き込んでいる最中は、プルダウン抵抗をしない方が良いという意味でしょうか?
書き込んでいる最中は全て入力端子です。書き込み器の出力が弱い場合は書き込み器内部抵抗と、回路に付けたプルダウン抵抗/プルアップ抵抗の
分圧した値がピン先の電圧になるので、変なものを付ければ誤動作して書き込めません。
なにも付けなければ書き込み器の電圧がそのままピン先の電圧になります。
> 1827は、PORTAのRA5の為にPORTA側を一体で出力端子にできないんですね!?
今まで使っていたPICも同様かと思いますけど、MCLRピンは出力能力が無いので出力できない、というだけの話です。
PICの場合はどれも同じ様にMCLRのピンは入力のみなんじゃないかな?
> PORTA側を入力端子に使った場合、考えられる不都合としては
ポートBなら内部プルアップがあるのでスイッチを付けるだけです。これはスイッチを押さない限りは何も接続していない、というのと同じです。
つまり、ピン先にピンヘッダでも付けておいてからスイッチに向かえばどちらにでも通用します。
ポートAは内部プルアップが無いので、外部プルアップ/ダウンが必要です。となるとSW入力に固定されます。
つまりは、外部割り込みに関わらず、SW入力以外の事は出来ない、という事になります。勿論、ジャンパーやdipスイッチ等で
切り離し可能にする方法もあります。
変数ms自体は、最後の計算部分で1が足されます。(ms+1)つまり、カウントアップです。
更に%6000としているので、MAX6000(5999)のカウンタ/タイマーです。
> 3秒間点灯後の残り3秒は、LATB3がoffとなり、その後また、main関数に戻る
大きな勘違いをしています。毎回すぐにmain関数に戻ります。3秒も居ません。
msはタイマー0割り込みに入った回数をカウントしています。
1回入るとmsが1増えます。6000回この関数に入ると%6000の部分が効いて0になります。
毎回余りの計算はしていますけど、6000(以上)になった時だけ効果が有効になります。
タイマー割り込み関数自体は直ぐに終わるようにします。
> ※無難なのはスイッチのみを付ける事です← 入力端子の設定の場合を懸念しているのかな〜?
いいえ、単純に書き込めるかどうかです。書き込めたのなら良いです。
書き込み端子ですから、PICKIT3からの信号によって、ピン先がHIGH⇔LOWがちゃんと振れるかどうかの問題です。
> 短絡事故防止の為にプルダウン抵抗をつけた方が良いと思いますが
いいえ。短絡事故防止なら繋がないか、或いは入力にするのが一番です。プルダウン抵抗は何の役にも立ちません。電気が漏れているだけです。
付ける必要があるのはその出力先が制御端子、つまり、別のICの入力だった場合です。その時はHIGH/LOW区別するために付ける場合があります。
でもプルアップの方が多いです。
> 出力端子の場合、書き込んでいる最中は、プルダウン抵抗をしない方が良いという意味でしょうか?
書き込んでいる最中は全て入力端子です。書き込み器の出力が弱い場合は書き込み器内部抵抗と、回路に付けたプルダウン抵抗/プルアップ抵抗の
分圧した値がピン先の電圧になるので、変なものを付ければ誤動作して書き込めません。
なにも付けなければ書き込み器の電圧がそのままピン先の電圧になります。
> 1827は、PORTAのRA5の為にPORTA側を一体で出力端子にできないんですね!?
今まで使っていたPICも同様かと思いますけど、MCLRピンは出力能力が無いので出力できない、というだけの話です。
PICの場合はどれも同じ様にMCLRのピンは入力のみなんじゃないかな?
> PORTA側を入力端子に使った場合、考えられる不都合としては
ポートBなら内部プルアップがあるのでスイッチを付けるだけです。これはスイッチを押さない限りは何も接続していない、というのと同じです。
つまり、ピン先にピンヘッダでも付けておいてからスイッチに向かえばどちらにでも通用します。
ポートAは内部プルアップが無いので、外部プルアップ/ダウンが必要です。となるとSW入力に固定されます。
つまりは、外部割り込みに関わらず、SW入力以外の事は出来ない、という事になります。勿論、ジャンパーやdipスイッチ等で
切り離し可能にする方法もあります。
Re: 無題ー1
猛牛ロックさんへ
>msが1増えます。6000回この関数に入ると%6000の部分が効いて0になります。
毎回余りの計算はしていますけど、6000(以上)になった時だけ効果が有効になります。
そうか、msは、割込み回数のカウンターで、ms関数により、msに入った値の上限を6千としたわけか、了解。
char等ビット数の関係があるからですね。
>なにも付けなければ書き込み器の電圧がそのままピン先の電圧になります。
今回、キットで遊ぼう野ボードが壊れたのを契機に、
書込みができて、且つ、テストのし易いテスト用ボード兼用を作ろうとしています。
そうなると、INもOUTもSWを付けておいて、PICとPIC3だけがつながる状態にすれば、いいですね?
自分の場合、手パ用にPIC16F627Aを使っていますが、
INとOUTそれぞれ、8ピンずつ分けています。
なので、627Aに代わるPICも8ピンずつ使えないとまずい。
1827のRA5は、入力専用ですので、RA5の1ピン分を入力側(RB0〜RB8)の中から、
出力として使える、お勧めのピンはどれですか?
お勧めがあれば、入力用のRA5に代わるピンとしたいと思います。
追記16:23
猛牛ロックさんのプログラムの動作確認
RA6はSWONで点灯
RB3は、RA6のSWに関係なく3秒間隔で点灯
//ピン初期設定
LATB = 1 << 3;
これだけで、どうしてRA6のSWに連携するのですか?
>msが1増えます。6000回この関数に入ると%6000の部分が効いて0になります。
毎回余りの計算はしていますけど、6000(以上)になった時だけ効果が有効になります。
そうか、msは、割込み回数のカウンターで、ms関数により、msに入った値の上限を6千としたわけか、了解。
char等ビット数の関係があるからですね。
>なにも付けなければ書き込み器の電圧がそのままピン先の電圧になります。
今回、キットで遊ぼう野ボードが壊れたのを契機に、
書込みができて、且つ、テストのし易いテスト用ボード兼用を作ろうとしています。
そうなると、INもOUTもSWを付けておいて、PICとPIC3だけがつながる状態にすれば、いいですね?
自分の場合、手パ用にPIC16F627Aを使っていますが、
INとOUTそれぞれ、8ピンずつ分けています。
なので、627Aに代わるPICも8ピンずつ使えないとまずい。
1827のRA5は、入力専用ですので、RA5の1ピン分を入力側(RB0〜RB8)の中から、
出力として使える、お勧めのピンはどれですか?
お勧めがあれば、入力用のRA5に代わるピンとしたいと思います。
追記16:23
猛牛ロックさんのプログラムの動作確認
RA6はSWONで点灯
RB3は、RA6のSWに関係なく3秒間隔で点灯
//ピン初期設定
LATB = 1 << 3;
これだけで、どうしてRA6のSWに連携するのですか?
Re: 無題ー1
> char等ビット数の関係があるからですね。
今回は直接的に点滅周期の6秒です。大まかな1分、10分、1時間とかのサイクルにする場合もあります。
> 手パ用にPIC16F627Aを使っていますが
汎用ならピンフレームを付けておくだけで良いと思います。
専用ならその回路に近いものを作る事になります。けれども汎用性は失われます。
> お勧めがあれば、入力用のRA5に代わるピンとしたいと思います。
今現在思い浮かびません。TRさんが今後使いたい機能を考えて選択した方が良いです。
> LATB = 1 << 3;
> これだけで、どうしてRA6のSWに連携するのですか?
それでは連動しません。単にLATBレジスタを「8」にしただけです。
私が言ったのは
> while(1){
> LATB3=!RA6;
> }
です。タイマー割り込み関数でも、メインループでも、
LATB3=!RA6;
を入れて、あと何もしなければ連動します。
意味はRA6の内容を反転(論理否定)させたものをLATB3に代入します。
つまり、RA6が1ならLATB3を0にする。RA6が0ならLATB3を1にする。
今回は直接的に点滅周期の6秒です。大まかな1分、10分、1時間とかのサイクルにする場合もあります。
> 手パ用にPIC16F627Aを使っていますが
汎用ならピンフレームを付けておくだけで良いと思います。
専用ならその回路に近いものを作る事になります。けれども汎用性は失われます。
> お勧めがあれば、入力用のRA5に代わるピンとしたいと思います。
今現在思い浮かびません。TRさんが今後使いたい機能を考えて選択した方が良いです。
> LATB = 1 << 3;
> これだけで、どうしてRA6のSWに連携するのですか?
それでは連動しません。単にLATBレジスタを「8」にしただけです。
私が言ったのは
> while(1){
> LATB3=!RA6;
> }
です。タイマー割り込み関数でも、メインループでも、
LATB3=!RA6;
を入れて、あと何もしなければ連動します。
意味はRA6の内容を反転(論理否定)させたものをLATB3に代入します。
つまり、RA6が1ならLATB3を0にする。RA6が0ならLATB3を1にする。
Re: 無題ー1
猛牛ロックさん 、レスありがとうございます。
プログラムを以下の通り整理ました。
動作は、
RA6 SW ONの間中RB3 点灯、 RA6 SW offでRB3 3秒間点滅
今回も色々と有難うございます。
タイマー0割込みについて、理解を深められました。
特に、SW ONの場合、必要な割込み間隔から、TM0の初期値を決める です。
キットで遊ぼうの教科書にはない事です。
薫陶として、保存しておきます。
LATB3 = !RA6;
この話は、以前「=」と「==」の違いを教えられていたので、話を聞いているうちにわかっていました。
同様のことで
RB3=~RB3もありますね。
RA5の代わりのピンは、おいおい考えるにしても、とりあえず、写真を見ると、
PIC3の書き込み時に使用するRB7をRA5の代わりとして入力用に使います。
// 花丸 タイマー0割込みPIC16F1827 Configuration Bit Settings
//RA6 マッハからの信号 RA6 SW ONの間中RB3 点灯、 RA6 SW offでRB3 点滅
// 'C' source line config statements
#include <xc.h>
// CONFIG1
略
// __delay_ms(), __delay_us()関数が使用する
#define _XTAL_FREQ 4000000
#define On 1
#define Off 0
volatile int event;
// プロトタイプ宣言
void InitInterTimer0(void);
// メイン関数
void main(void) {
OSCCON = 0b01101010; // 内部クロック周波数を4MHzに設定
// 電圧レベルの初期設定
PORTA = 0x00;
PORTB = 0x00;
// 入出力設定
TRISA = 0b01000000;
TRISB = 0x00;
// タイマ0割込み設定関数の呼び出し
InitInterTimer0();
// 割込み全体の許可
GIE = 1;
// 永久ループ
while (1) {
LATB3 = !RA6;
}
}
// 割込みサービスルーチン
static void interrupt isr() {
static unsigned int ms = 0;
if (ms < 3000)LATB3 = 1;
else LATB3 = 0;
ms = (ms + 1) % 6000; //カウントアップ、6s(6000)でリセット
// タイマ0割込みフラグをクリア
T0IF = 0;
}
// タイマ0割込み設定関数
void InitInterTimer0(void) {
OPTION_REG = 0b000000000; //プリスケラ000 5ビット=0内部クロック使用 WDTは使わない
TMR0 = -250; //直ぐにセットする
INTCONbits.TMR0IF = 0; //TMR0フラグクリアー
INTCONbits.TMR0IE = 1; //TMR0割り込み許可
INTCONbits.GIE = 1; //全体割り込み許可
}
プログラムを以下の通り整理ました。
動作は、
RA6 SW ONの間中RB3 点灯、 RA6 SW offでRB3 3秒間点滅
今回も色々と有難うございます。
タイマー0割込みについて、理解を深められました。
特に、SW ONの場合、必要な割込み間隔から、TM0の初期値を決める です。
キットで遊ぼうの教科書にはない事です。
薫陶として、保存しておきます。
LATB3 = !RA6;
この話は、以前「=」と「==」の違いを教えられていたので、話を聞いているうちにわかっていました。
同様のことで
RB3=~RB3もありますね。
RA5の代わりのピンは、おいおい考えるにしても、とりあえず、写真を見ると、
PIC3の書き込み時に使用するRB7をRA5の代わりとして入力用に使います。
// 花丸 タイマー0割込みPIC16F1827 Configuration Bit Settings
//RA6 マッハからの信号 RA6 SW ONの間中RB3 点灯、 RA6 SW offでRB3 点滅
// 'C' source line config statements
#include <xc.h>
// CONFIG1
略
// __delay_ms(), __delay_us()関数が使用する
#define _XTAL_FREQ 4000000
#define On 1
#define Off 0
volatile int event;
// プロトタイプ宣言
void InitInterTimer0(void);
// メイン関数
void main(void) {
OSCCON = 0b01101010; // 内部クロック周波数を4MHzに設定
// 電圧レベルの初期設定
PORTA = 0x00;
PORTB = 0x00;
// 入出力設定
TRISA = 0b01000000;
TRISB = 0x00;
// タイマ0割込み設定関数の呼び出し
InitInterTimer0();
// 割込み全体の許可
GIE = 1;
// 永久ループ
while (1) {
LATB3 = !RA6;
}
}
// 割込みサービスルーチン
static void interrupt isr() {
static unsigned int ms = 0;
if (ms < 3000)LATB3 = 1;
else LATB3 = 0;
ms = (ms + 1) % 6000; //カウントアップ、6s(6000)でリセット
// タイマ0割込みフラグをクリア
T0IF = 0;
}
// タイマ0割込み設定関数
void InitInterTimer0(void) {
OPTION_REG = 0b000000000; //プリスケラ000 5ビット=0内部クロック使用 WDTは使わない
TMR0 = -250; //直ぐにセットする
INTCONbits.TMR0IF = 0; //TMR0フラグクリアー
INTCONbits.TMR0IE = 1; //TMR0割り込み許可
INTCONbits.GIE = 1; //全体割り込み許可
}
Re: 無題ー1
maboさんこんばんは。
No1287について
>ms=(ms+1)%6000
は,msをプラス1して6000で割ったあまりをmsに入れてますので,
if(ms<6000){ms++;}
else{ms=0;}
この方が分かりやすいですね。
msの初期化だったんですね。
有難うございました。
追記
大分以前、猛牛ロックさんが、下記のことを言っていました。
今やっとその意味を深く理解できました。
当時はいっぱい、いっぱいでしたよ。
イコンの動作として説明してください。
つまり、「エンドミルがタッチプローブに接触したら」→「入力ピンがLになったら」です。
それが出来るようになったら、次にその動作がプログラムでどう配置すれば実現できるか
考えてください。
No1287について
>ms=(ms+1)%6000
は,msをプラス1して6000で割ったあまりをmsに入れてますので,
if(ms<6000){ms++;}
else{ms=0;}
この方が分かりやすいですね。
msの初期化だったんですね。
有難うございました。
追記
大分以前、猛牛ロックさんが、下記のことを言っていました。
今やっとその意味を深く理解できました。
当時はいっぱい、いっぱいでしたよ。
イコンの動作として説明してください。
つまり、「エンドミルがタッチプローブに接触したら」→「入力ピンがLになったら」です。
それが出来るようになったら、次にその動作がプログラムでどう配置すれば実現できるか
考えてください。
Re: 無題ー1
> if(ms<6000){ms++;}
> else{ms=0;}
意味合いはあっていますけど、実際にはちょっと違います。置き換えるなら
ms++;
if(ms==6000) ms=0;
や、
ms+;
if(ms>=6000)ms-=6000;
とかです。
前者は5999でやってきた時に6000です。
6000でやってきた時に0です。(ms++はされずにms=0だけ実行される)
つまり、6001でループします。
時計の一番上(12時、24時、60分)に来たときは、その時点で0時や0分に置き換わらなければいけません。
必ずインクリメントしなければならない部分は無条件でms++;、そして、6000だったら0です。
一行で書けば
if(++ms==6000)ms=0;//或いはif(++ms>=6000)ms=0;
です。ただし、場合によっては4ms毎に割り込みに入る場合もあります。また0スタートでは無い場合もあります。
そして、誤って、別の場所で6000を超えた場合(例えば時計の時刻合わせをしようとしてこの変数を弄ったり)や、初期化忘れ等に
大きな不具合に繋がります。
そう言った事を
ms=(ms+4)%6000;
のように書く方が、安全性が高いような気がします。
考え方は変数の型と同じです。%6000で、6000でループするカウンタ(範囲が0〜5999の変数)です。
繰り上がり(桁あふれ)の分は消えます。
但しデクリメントは注意が必要です。
ms=(ms-1)%6000;
ではなく
ms=(ms+5999)%6000;
みたいな処理です。ちょっと見通しが悪いです。
> else{ms=0;}
意味合いはあっていますけど、実際にはちょっと違います。置き換えるなら
ms++;
if(ms==6000) ms=0;
や、
ms+;
if(ms>=6000)ms-=6000;
とかです。
前者は5999でやってきた時に6000です。
6000でやってきた時に0です。(ms++はされずにms=0だけ実行される)
つまり、6001でループします。
時計の一番上(12時、24時、60分)に来たときは、その時点で0時や0分に置き換わらなければいけません。
必ずインクリメントしなければならない部分は無条件でms++;、そして、6000だったら0です。
一行で書けば
if(++ms==6000)ms=0;//或いはif(++ms>=6000)ms=0;
です。ただし、場合によっては4ms毎に割り込みに入る場合もあります。また0スタートでは無い場合もあります。
そして、誤って、別の場所で6000を超えた場合(例えば時計の時刻合わせをしようとしてこの変数を弄ったり)や、初期化忘れ等に
大きな不具合に繋がります。
そう言った事を
ms=(ms+4)%6000;
のように書く方が、安全性が高いような気がします。
考え方は変数の型と同じです。%6000で、6000でループするカウンタ(範囲が0〜5999の変数)です。
繰り上がり(桁あふれ)の分は消えます。
但しデクリメントは注意が必要です。
ms=(ms-1)%6000;
ではなく
ms=(ms+5999)%6000;
みたいな処理です。ちょっと見通しが悪いです。
Re: 無題ー1
猛牛ロックさんこんばんは。
丁寧にも説明してくださってありがとうございます。
>ms++;
if(ms==6000) ms=0;
この式もようやく見慣れてきました。
{}を端折っているんですよね。
キットで遊ぼうの教科書にはないので、端折っていると感じます。
実際は、端折っても正解なんでしょうけど。
そして、ようやく分かってきた事で、
ハイインピーダンス状態ってありますね。
写真のやつ。
よく見てやっとわかりました。
マイコンのi/oて、電源ONの直後は、一斉に入力端子になるそうですね!
だから、プルアップかプルダウンの抵抗を付けて
安定させるわけですね。
ハイインピーダンスって言葉を調べると、1でも0でもない状態なんだそうです。
どっちつかずで、不安定状態をいうようですね。
テスターの検知棒が何も触れていない状態と同じなんだそうです。
それと、猛牛ロックさんが、過日言っていた中に、16F627Aの端子の説明をしていました。
F627AもF1827と端子の使われ方が同じですということ、
具体的には、PORTAが出力端子、PORTBが入力端子でした。
そこでなんですが、自分の今のフライス盤制御のレベルなら、PORTAを全て入力とし、
PORTBを全て出力としても問題ないように思えます。
実際、素人の自分は、PORTAを全て入力とし、PORTBを全て出力とした方が分かりやすいんですよね。
現況を踏まえて、このような使い方をしてもいいでしょうかね〜?
丁寧にも説明してくださってありがとうございます。
>ms++;
if(ms==6000) ms=0;
この式もようやく見慣れてきました。
{}を端折っているんですよね。
キットで遊ぼうの教科書にはないので、端折っていると感じます。
実際は、端折っても正解なんでしょうけど。
そして、ようやく分かってきた事で、
ハイインピーダンス状態ってありますね。
写真のやつ。
よく見てやっとわかりました。
マイコンのi/oて、電源ONの直後は、一斉に入力端子になるそうですね!
だから、プルアップかプルダウンの抵抗を付けて
安定させるわけですね。
ハイインピーダンスって言葉を調べると、1でも0でもない状態なんだそうです。
どっちつかずで、不安定状態をいうようですね。
テスターの検知棒が何も触れていない状態と同じなんだそうです。
それと、猛牛ロックさんが、過日言っていた中に、16F627Aの端子の説明をしていました。
F627AもF1827と端子の使われ方が同じですということ、
具体的には、PORTAが出力端子、PORTBが入力端子でした。
そこでなんですが、自分の今のフライス盤制御のレベルなら、PORTAを全て入力とし、
PORTBを全て出力としても問題ないように思えます。
実際、素人の自分は、PORTAを全て入力とし、PORTBを全て出力とした方が分かりやすいんですよね。
現況を踏まえて、このような使い方をしてもいいでしょうかね〜?
Re: 無題ー1
猛牛ロックさん,TRさん,こんばんは。
猛牛ロックさん,またまた,詳しい解説ありがとうございます。
結構プログラム作ってたので,表現された式が,
どんな意味なのかわなんとなく理解できます。
でも,自分で作るとなると,やはり,細かい部分で,?
なことがいっぱいです。
特にループ等では,境界値?の付近の理解がいまいちで,
1回余計に数えたり,少なかったりというミスをよくします。
その点猛牛ロックさんは,私にいわせれば,場数をふんでらヤルのでしょうね。
いつも感心させられます。
TRさんは,何か目的がありになってのプログラムでしょうか。
CNCの周辺機器でもお作りでしょうか。
猛牛ロックさん,またまた,詳しい解説ありがとうございます。
結構プログラム作ってたので,表現された式が,
どんな意味なのかわなんとなく理解できます。
でも,自分で作るとなると,やはり,細かい部分で,?
なことがいっぱいです。
特にループ等では,境界値?の付近の理解がいまいちで,
1回余計に数えたり,少なかったりというミスをよくします。
その点猛牛ロックさんは,私にいわせれば,場数をふんでらヤルのでしょうね。
いつも感心させられます。
TRさんは,何か目的がありになってのプログラムでしょうか。
CNCの周辺機器でもお作りでしょうか。
Re: 無題ー1
> 同様のことで
> RB3=~RB3もありますね。
ですけど、ここで、「~」で通用するかは解りません。
通用するとしても使わない方が良いです。
反転させるなら論理否定「!」が良いです。
※「!1」は0です。「!0」は厳密には「0以外の数」(真)ですが、現実には「1」です。
けれども「~0」は8ビットで処理されれば255ですし、「~1」も8ビットの処理なら254です。
!は思ったように動作するだろう確信がありますけど、~に関しては「不明」です。
場合によってはコンパイラに怒られる可能性もあります。
> 実際は、端折っても正解なんでしょうけど。
C言語は段落や改行、スペース等は自由に入れられます。全て1行で書いても良いわけです。
なので、その範囲がどこまでなのかの判断は不可欠です。
ifやelseやwhile等、どれも対象はその後の1命令です。「{}」は範囲拡張の為のものです。
また、説明時には「{}」があった方が説明し易い、という事情もあります。
不安になったら自動整形して確認して下さい。
> テスターの検知棒が何も触れていない状態と同じなんだそうです。
というよりもテスター(電圧計)の検知棒そのものです。
で、「何も触れていない状態」ではなく、触れてもその回路に何も影響を起こさない(ほど高い抵抗値)、ということです。
測ろうとして触れた途端に電圧が変わってしまえば、まともに測定できない、ということです。
> このような使い方をしてもいいでしょうかね〜?
どのように使うかは製作者の自由です。
それぞれのピンの機能等を確認して、不都合が起こらない様に配置すれば良いです。
> RB3=~RB3もありますね。
ですけど、ここで、「~」で通用するかは解りません。
通用するとしても使わない方が良いです。
反転させるなら論理否定「!」が良いです。
※「!1」は0です。「!0」は厳密には「0以外の数」(真)ですが、現実には「1」です。
けれども「~0」は8ビットで処理されれば255ですし、「~1」も8ビットの処理なら254です。
!は思ったように動作するだろう確信がありますけど、~に関しては「不明」です。
場合によってはコンパイラに怒られる可能性もあります。
> 実際は、端折っても正解なんでしょうけど。
C言語は段落や改行、スペース等は自由に入れられます。全て1行で書いても良いわけです。
なので、その範囲がどこまでなのかの判断は不可欠です。
ifやelseやwhile等、どれも対象はその後の1命令です。「{}」は範囲拡張の為のものです。
また、説明時には「{}」があった方が説明し易い、という事情もあります。
不安になったら自動整形して確認して下さい。
> テスターの検知棒が何も触れていない状態と同じなんだそうです。
というよりもテスター(電圧計)の検知棒そのものです。
で、「何も触れていない状態」ではなく、触れてもその回路に何も影響を起こさない(ほど高い抵抗値)、ということです。
測ろうとして触れた途端に電圧が変わってしまえば、まともに測定できない、ということです。
> このような使い方をしてもいいでしょうかね〜?
どのように使うかは製作者の自由です。
それぞれのピンの機能等を確認して、不都合が起こらない様に配置すれば良いです。
Re: 無題ー1
maboさん、おはようございます。
>TRさんは,何か目的がありになってのプログラムでしょうか。
CNCの周辺機器でもお作りでしょうか。
いえいえ、特に計画等はありません。
ただ、以前、教えて頂いたフライス盤プルグラムを自分のものにしなくてはいけないと思ったので、
学習しています。
PIC3書き込みボードを考え直しましたので、アップします。
今回は、PIC3からの繋ぎも反映しました。
キットで遊ぼうの配線図をもとに、プルアップ抵抗をなくしたりしています。
発光LEDとそれに係る抵抗があればいいようです。
それから、周期を求めるエクセルを作りました。
追記
入力端子(内部でプルアップ)の設定で、
SW OFFで、端子は、ハイでしょうか?
※
3秒間隔で点滅をするRB3は大変暗いです。
おかしいのでは??
>TRさんは,何か目的がありになってのプログラムでしょうか。
CNCの周辺機器でもお作りでしょうか。
いえいえ、特に計画等はありません。
ただ、以前、教えて頂いたフライス盤プルグラムを自分のものにしなくてはいけないと思ったので、
学習しています。
PIC3書き込みボードを考え直しましたので、アップします。
今回は、PIC3からの繋ぎも反映しました。
キットで遊ぼうの配線図をもとに、プルアップ抵抗をなくしたりしています。
発光LEDとそれに係る抵抗があればいいようです。
それから、周期を求めるエクセルを作りました。
追記
入力端子(内部でプルアップ)の設定で、
SW OFFで、端子は、ハイでしょうか?
※
3秒間隔で点滅をするRB3は大変暗いです。
おかしいのでは??
Re: 無題ー1
F1827のデータシート(DS4139D)の371ページに5V駆動時の出力特性が載っています。添付図
その下に3.0V駆動の特性もありますけど、そうすると全然弱くなります。
で、これを見てわかるように、あまり多くの電流を流す能力はありません。
そして、このグラフの出力がヘタる分は、損失=発熱になります。
言いたいことは、もう少し抵抗を大きくした方が無難です。
状態を確認する為ですから1kΩとかが良いと思います。
また、言っている事が逆になるのですが、、このグラフから言えるのは、青色LED(VF3.0として)なら、抵抗は繋がなくても19mA程度しか流れません。
赤色(VF2.0Vとして)でも22mA程度なので抵抗は付けなくても良い事になります。
更に言えば、いままで、出力操作で
if(RA0==1)RA0=0;
else RA0=1;
のような反転させる記述をしましたけど、HIGH出力で25mA位流しているとグラフでは1V程度です。
なので、読み込みはLOWになります。、
つまり、反転はしないで、HIGH出力のままになります。
(自分の理解ではそうした仕組みになっていると思います。試したわけではありません。)
> 入力端子(内部でプルアップ)の設定で、
> SW OFFで、端子は、ハイでしょうか?
そうです。
> 3秒間隔で点滅をするRB3は大変暗いです。
> おかしいのでは??
何かがおかしいのでしょうね。エスパーすれば、出力ではなく、プルアップ入力で光らせているのでは?
その下に3.0V駆動の特性もありますけど、そうすると全然弱くなります。
で、これを見てわかるように、あまり多くの電流を流す能力はありません。
そして、このグラフの出力がヘタる分は、損失=発熱になります。
言いたいことは、もう少し抵抗を大きくした方が無難です。
状態を確認する為ですから1kΩとかが良いと思います。
また、言っている事が逆になるのですが、、このグラフから言えるのは、青色LED(VF3.0として)なら、抵抗は繋がなくても19mA程度しか流れません。
赤色(VF2.0Vとして)でも22mA程度なので抵抗は付けなくても良い事になります。
更に言えば、いままで、出力操作で
if(RA0==1)RA0=0;
else RA0=1;
のような反転させる記述をしましたけど、HIGH出力で25mA位流しているとグラフでは1V程度です。
なので、読み込みはLOWになります。、
つまり、反転はしないで、HIGH出力のままになります。
(自分の理解ではそうした仕組みになっていると思います。試したわけではありません。)
> 入力端子(内部でプルアップ)の設定で、
> SW OFFで、端子は、ハイでしょうか?
そうです。
> 3秒間隔で点滅をするRB3は大変暗いです。
> おかしいのでは??
何かがおかしいのでしょうね。エスパーすれば、出力ではなく、プルアップ入力で光らせているのでは?
Re: 無題ー1
RB3の電圧が非常に低いです。テスターで測れません。
で、自分の以下のプログラムだとRB3に電圧は、
4.72V。こうなると、プログラムの違いといわざるをえないのでは?
// 自分作 タイマー0割込みPIC16F1827 Configuration Bit Settings
//RA6 マッハからの信号 RB3SW ONの間中、RB3点灯
// 'C' source line config statements
#include <xc.h>
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF // PLL Enable (4x PLL disabled)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = HI // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
// __delay_ms(), __delay_us()関数が使用する
#define _XTAL_FREQ 1000000
#define On 1
#define Off 0
volatile int event;
// プロトタイプ宣言
void InitInterTimer0(void);
// メイン関数
void main(void) {
OSCCON = 0b01011010; // 内部クロック周波数を1MHzに設定
// 電圧レベルの初期設定
PORTA = 0x00;
PORTB = 0x00;
// 入出力設定
TRISA = 0b01000000;
TRISB = 0x00;
// タイマ0割込み設定関数の呼び出し
InitInterTimer0();
// 割込み全体の許可
GIE = 1;
event = 0; //初期値イベント無しRB3ロー
// 永久ループ
while (1) {
if (event == 0) {
RB3 = 0;
}
if (event == 1) {
RB3 = 1;
}
if (event == 1 && RA6 == 1) {//もしイベントがOnのままで、SWがOffなら、
RB3 = 0;
event = 0;
}
}
}
// 割込みサービスルーチン
static void interrupt isr() {
if (RA6 == 0 && event == 0) {//もしRA6が押されていて、イベントが起きていなかったら
event = 1;
}
// タイマ0割込みフラグをクリア
T0IF = 0;
}
// タイマ0割込み設定関数
void InitInterTimer0(void) {
OPTION_REG = 0b000000000; //プリスケラ000 5ビット=0内部クロック使用 WDTは使わない
TMR0 = 0x00;
INTCONbits.TMR0IF = 0; //TMR0フラグクリアー
INTCONbits.TMR0IE = 1; //TMR0割り込み許可
INTCONbits.GIE = 1; //全体割り込み許可
}
で、自分の以下のプログラムだとRB3に電圧は、
4.72V。こうなると、プログラムの違いといわざるをえないのでは?
// 自分作 タイマー0割込みPIC16F1827 Configuration Bit Settings
//RA6 マッハからの信号 RB3SW ONの間中、RB3点灯
// 'C' source line config statements
#include <xc.h>
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF // PLL Enable (4x PLL disabled)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = HI // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
// __delay_ms(), __delay_us()関数が使用する
#define _XTAL_FREQ 1000000
#define On 1
#define Off 0
volatile int event;
// プロトタイプ宣言
void InitInterTimer0(void);
// メイン関数
void main(void) {
OSCCON = 0b01011010; // 内部クロック周波数を1MHzに設定
// 電圧レベルの初期設定
PORTA = 0x00;
PORTB = 0x00;
// 入出力設定
TRISA = 0b01000000;
TRISB = 0x00;
// タイマ0割込み設定関数の呼び出し
InitInterTimer0();
// 割込み全体の許可
GIE = 1;
event = 0; //初期値イベント無しRB3ロー
// 永久ループ
while (1) {
if (event == 0) {
RB3 = 0;
}
if (event == 1) {
RB3 = 1;
}
if (event == 1 && RA6 == 1) {//もしイベントがOnのままで、SWがOffなら、
RB3 = 0;
event = 0;
}
}
}
// 割込みサービスルーチン
static void interrupt isr() {
if (RA6 == 0 && event == 0) {//もしRA6が押されていて、イベントが起きていなかったら
event = 1;
}
// タイマ0割込みフラグをクリア
T0IF = 0;
}
// タイマ0割込み設定関数
void InitInterTimer0(void) {
OPTION_REG = 0b000000000; //プリスケラ000 5ビット=0内部クロック使用 WDTは使わない
TMR0 = 0x00;
INTCONbits.TMR0IF = 0; //TMR0フラグクリアー
INTCONbits.TMR0IE = 1; //TMR0割り込み許可
INTCONbits.GIE = 1; //全体割り込み許可
}
無題
初めてのプログラム
皆さんこんばんは。
初めてプログラムを作ってみました。
タイマー0割り込みをつかって、
RB3を常時点燈、RA6に信号が入ったら、RB3を消灯
しかし、RB3がSW ONでいきなりつきません。
どこが悪いのかご指摘願います。
宜しくお願いします。
RA6はプルアップ、RB3はプルダウンです。
/*タッチプローブ*/
// PIC16F1827 Configuration Bit Settings
//RA6 マッハからの信号
// 'C' source line config statements
#include <xc.h>
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF // PLL Enable (4x PLL disabled)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = HI // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
// __delay_ms(), __delay_us()関数が使用する
#define _XTAL_FREQ 8000000
#define On 1
#define Off 0
//プロトタイプ宣言
void InitInterTimer0 (void);
void interrupt isr ( void )
{//TMR0の割り込み処理
if(RA6==Off )
{
RB3=Off;
INTCONbits.TMR0IF=0;//タイマ0割り込みが入った際、TMR0IFが1になるので、0で初期化
INTCONbits.TMR0IE=1;//タイマー0を有効化
}
}
// メイン関数
void main (void){
OSCCON = 0b01101001;//内蔵発振器 8MHz使用に設定
PORTA = 0x00;// 電圧レベルの初期設定
PORTB = 0x00;
// 入出力設定
TRISA = 0b00110000;//RA5は入力専用・RA6は入力,他は出力
TRISB = 0b00000000;//RB3はLED用出力
//初期設定
RB3=On;
RA6=On;
InitInterTimer0 ();
INTCONbits.GIE=1;
while(1){
RB3=On;
}
}
//タイマ0割込み設定関数
void InitInterTimer0 (void)
{//割り込み設定
OPTION_REG=0b100000000;//プリスケラ000 5ビット=0内部クロック使用 WDTは使わない
TMR0=0x00;
INTCONbits.TMR0IF=0; //TMR0フラグクリアー
INTCONbits.TMR0IE=1;//TMR0割り込み許可
INTCONbits.GIE=1;//全体割り込み許可
}
皆さんこんばんは。
初めてプログラムを作ってみました。
タイマー0割り込みをつかって、
RB3を常時点燈、RA6に信号が入ったら、RB3を消灯
しかし、RB3がSW ONでいきなりつきません。
どこが悪いのかご指摘願います。
宜しくお願いします。
RA6はプルアップ、RB3はプルダウンです。
/*タッチプローブ*/
// PIC16F1827 Configuration Bit Settings
//RA6 マッハからの信号
// 'C' source line config statements
#include <xc.h>
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF // PLL Enable (4x PLL disabled)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = HI // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
// __delay_ms(), __delay_us()関数が使用する
#define _XTAL_FREQ 8000000
#define On 1
#define Off 0
//プロトタイプ宣言
void InitInterTimer0 (void);
void interrupt isr ( void )
{//TMR0の割り込み処理
if(RA6==Off )
{
RB3=Off;
INTCONbits.TMR0IF=0;//タイマ0割り込みが入った際、TMR0IFが1になるので、0で初期化
INTCONbits.TMR0IE=1;//タイマー0を有効化
}
}
// メイン関数
void main (void){
OSCCON = 0b01101001;//内蔵発振器 8MHz使用に設定
PORTA = 0x00;// 電圧レベルの初期設定
PORTB = 0x00;
// 入出力設定
TRISA = 0b00110000;//RA5は入力専用・RA6は入力,他は出力
TRISB = 0b00000000;//RB3はLED用出力
//初期設定
RB3=On;
RA6=On;
InitInterTimer0 ();
INTCONbits.GIE=1;
while(1){
RB3=On;
}
}
//タイマ0割込み設定関数
void InitInterTimer0 (void)
{//割り込み設定
OPTION_REG=0b100000000;//プリスケラ000 5ビット=0内部クロック使用 WDTは使わない
TMR0=0x00;
INTCONbits.TMR0IF=0; //TMR0フラグクリアー
INTCONbits.TMR0IE=1;//TMR0割り込み許可
INTCONbits.GIE=1;//全体割り込み許可
}
Re: 無題
プログラムの方はまだちゃんと見ていませんけど、回路図をみると、RB3は
・LOW出力で点灯
・HIGH出力で消灯
・入力時(プルアップ無)で弱点灯
という回路になっています。
※LEDを光らせるのにプルする必要はありません。
・LOW出力で点灯
・HIGH出力で消灯
・入力時(プルアップ無)で弱点灯
という回路になっています。
※LEDを光らせるのにプルする必要はありません。
Re: 無題
TRさん,猛牛ロックさん,こんばんは。
TRさん,頑張ってますね。
私の環境でも通りますので,シンタックスエラーはないようです。
これが一番やっかいなんです。
ここからは,自分のやりたいことが表現?されているか,
一つ一つつぶす作業だと思います。
回路については,ちょと私は,分からないところがあるのですが,正しいものとしてプログラムだけ見ました。
忘れてしまっている部分も多いので,なんともいえないのですが,
TRさんのプログラムだと,
RA6=On
の時の処理が割り込み処理に書かれてないように思います。次のようにしてはどうでしょうか。
void interrupt isr ( void ){//TMR0の割り込み処理
if(RA6==Off ){
RB3=Off;
}
if(RA6==On ){
RB3=On;
}
INTCONbits.TMR0IF=0;//タイマ0割り込みが入った際、 TMR0IFが1になるので、0で初期化
INTCONbits.TMR0IE=1;//タイマー0を有効化
}
こうした上で,main の
while(1){
RB3=On;
}
を
while(1){
}
のようにしてみてはどうでしょうか。実際にやってみないので,動くかはは分かりません。
それと,このままだとLEDがちらつくかも。
スイッチが押された時に,一度だけLEDをONにする,
それと,LEDをOffにするのは,LEDがOnの時だけにする,
等の判断をいれないと,同じ処理を何度も繰り返すことに
なると思います。
TRさん,頑張ってますね。
私の環境でも通りますので,シンタックスエラーはないようです。
これが一番やっかいなんです。
ここからは,自分のやりたいことが表現?されているか,
一つ一つつぶす作業だと思います。
回路については,ちょと私は,分からないところがあるのですが,正しいものとしてプログラムだけ見ました。
忘れてしまっている部分も多いので,なんともいえないのですが,
TRさんのプログラムだと,
RA6=On
の時の処理が割り込み処理に書かれてないように思います。次のようにしてはどうでしょうか。
void interrupt isr ( void ){//TMR0の割り込み処理
if(RA6==Off ){
RB3=Off;
}
if(RA6==On ){
RB3=On;
}
INTCONbits.TMR0IF=0;//タイマ0割り込みが入った際、 TMR0IFが1になるので、0で初期化
INTCONbits.TMR0IE=1;//タイマー0を有効化
}
こうした上で,main の
while(1){
RB3=On;
}
を
while(1){
}
のようにしてみてはどうでしょうか。実際にやってみないので,動くかはは分かりません。
それと,このままだとLEDがちらつくかも。
スイッチが押された時に,一度だけLEDをONにする,
それと,LEDをOffにするのは,LEDがOnの時だけにする,
等の判断をいれないと,同じ処理を何度も繰り返すことに
なると思います。
Re: 無題
猛牛ロックさんへ
>・LOW出力で点灯 → これは分かります。
・HIGH出力で消灯 → これも分かります。
・入力時(プルアップ無)で弱点灯 これがわかりませんので、教えてください。
という回路になっています。
※LEDを光らせるのにプルする必要はありません。 ここも教えてください。
追記
PICのI/Oってよくわからないのですが、
ひょっとして、RB3のプルダウン抵抗は、RB3に何もつながっていない場合は、10kオームの抵抗は必要だけど、
LEDをつける場合は、逆に、電圧が、180kオームとLEDと10キロΩによって分圧されるということですか?
>・LOW出力で点灯 → これは分かります。
・HIGH出力で消灯 → これも分かります。
・入力時(プルアップ無)で弱点灯 これがわかりませんので、教えてください。
という回路になっています。
※LEDを光らせるのにプルする必要はありません。 ここも教えてください。
追記
PICのI/Oってよくわからないのですが、
ひょっとして、RB3のプルダウン抵抗は、RB3に何もつながっていない場合は、10kオームの抵抗は必要だけど、
LEDをつける場合は、逆に、電圧が、180kオームとLEDと10キロΩによって分圧されるということですか?
Re: 無題
プログラムを一通り見ました。
> #define On 1
> #define Off 0
回路的にはSWもLEDもアクティブローです。
あと、通常のPICは
PORTレジスタは読み取り用、
LATレジスタは出力用
となります。使い分けた方が良いです。
> while(1){
>
> RB3=On;
> }
これだと、仮にタイマー割り込みで消灯したとしても気が付きません。
すぐに点灯します。
タイマー割り込みをするなら、割り込みがかかる周期を把握した方が良いです。
普通は、キッチリとした時間が欲しいからタイマー割り込みを使うのです。
> PORTA = 0x00;// 電圧レベルの初期設定
> PORTB = 0x00;
> //初期設定
> RB3=On;
> RA6=On;
2回初期設定しても意味がありません。
また、RA6=Onと入力ピンに代入しても意味がありません。
> 入力時(プルアップ無)で弱点灯
入力時(プルアップ無)はハイインピーダンスです。
つまり、PICとは繋がっていないのと同じ状態です。
5V---150Ω---LED---10kΩ---GND
という回路ですから、0.3mA程度流れる筈です。
部屋を暗くすれば十分に光っているのが判る筈ですけど。
> ※LEDを光らせるのにプルする必要はありません。
入力時にプルをするのは、未接続時には、いろんな電圧値を示す為です。
例えば、SW-5Vと繋ぐなら、SWオンのときはHIGHレベルになります。でも
未接続だと、SWオフの時はHIGHの時もあればLOWになる時もあります。
なので、押していない時の識別の為に、押した時と逆側にプルします。
出力時は、HIGH/LOWいずれにしても、どちらかをを出力します。
LEDの場合は直接的に駆動させるだけです。プル抵抗は無駄な電気を使うだけです。
ただし、トランジスタを使う場合はPICが駆動されない(電源が入っていない)時や入力の場合に
つまり、上記で言う未接続相当の時に、トランジスタのゲート或いはベースがトランジスタをオンにしてしまう電圧に
なる場合があります。そういった誤動作を防ぐためにプルします。
追記します。
MABOさんのが正しい処理です。LEDがちらつくこともありません。
ただし、main関数で
while(1){
}
として、タイマー割り込みで
if(RA6==Off ){
RB3=Off;
}
if(RA6==On ){
RB3=On;
}
とするなら、最初からmain関数で
while(1){
if(RA6==On ) RB3=On;
else RB3=Off;
}
とすれば良いです。タイマー割り込みを使う意義がありません。
更に追記します。
押す度にオンとオフを繰り返すようなプログラムなら、フラグ処理が必要です。
また、チャタリング現象の考慮も必要になります。
あと、
if(RA6==Off ){
RB3=Off;
}
if(RA6==On ){
RB3=On;
}
は、短くすると
RB3=RA6;
でも良いはずです。
> #define On 1
> #define Off 0
回路的にはSWもLEDもアクティブローです。
あと、通常のPICは
PORTレジスタは読み取り用、
LATレジスタは出力用
となります。使い分けた方が良いです。
> while(1){
>
> RB3=On;
> }
これだと、仮にタイマー割り込みで消灯したとしても気が付きません。
すぐに点灯します。
タイマー割り込みをするなら、割り込みがかかる周期を把握した方が良いです。
普通は、キッチリとした時間が欲しいからタイマー割り込みを使うのです。
> PORTA = 0x00;// 電圧レベルの初期設定
> PORTB = 0x00;
> //初期設定
> RB3=On;
> RA6=On;
2回初期設定しても意味がありません。
また、RA6=Onと入力ピンに代入しても意味がありません。
> 入力時(プルアップ無)で弱点灯
入力時(プルアップ無)はハイインピーダンスです。
つまり、PICとは繋がっていないのと同じ状態です。
5V---150Ω---LED---10kΩ---GND
という回路ですから、0.3mA程度流れる筈です。
部屋を暗くすれば十分に光っているのが判る筈ですけど。
> ※LEDを光らせるのにプルする必要はありません。
入力時にプルをするのは、未接続時には、いろんな電圧値を示す為です。
例えば、SW-5Vと繋ぐなら、SWオンのときはHIGHレベルになります。でも
未接続だと、SWオフの時はHIGHの時もあればLOWになる時もあります。
なので、押していない時の識別の為に、押した時と逆側にプルします。
出力時は、HIGH/LOWいずれにしても、どちらかをを出力します。
LEDの場合は直接的に駆動させるだけです。プル抵抗は無駄な電気を使うだけです。
ただし、トランジスタを使う場合はPICが駆動されない(電源が入っていない)時や入力の場合に
つまり、上記で言う未接続相当の時に、トランジスタのゲート或いはベースがトランジスタをオンにしてしまう電圧に
なる場合があります。そういった誤動作を防ぐためにプルします。
追記します。
MABOさんのが正しい処理です。LEDがちらつくこともありません。
ただし、main関数で
while(1){
}
として、タイマー割り込みで
if(RA6==Off ){
RB3=Off;
}
if(RA6==On ){
RB3=On;
}
とするなら、最初からmain関数で
while(1){
if(RA6==On ) RB3=On;
else RB3=Off;
}
とすれば良いです。タイマー割り込みを使う意義がありません。
更に追記します。
押す度にオンとオフを繰り返すようなプログラムなら、フラグ処理が必要です。
また、チャタリング現象の考慮も必要になります。
あと、
if(RA6==Off ){
RB3=Off;
}
if(RA6==On ){
RB3=On;
}
は、短くすると
RB3=RA6;
でも良いはずです。
Re: 無題
猛牛ロックさん,TRさん,こんにちは。
猛牛ロックさん,適切なアドバイス,ありがとうございます。
いつものことながら見識の深さにおどろかされます。
TRさん,書き込みいただいたプログラム,うまく動いたでしょうか。
私も,割り込み処理等の動作確認で,TRさんの書かれたようなLEDチカのプログラムよくつかいました。
X IDEには,シュミレーターもついていて,それを動かせば,各値等の確認できるようですが,実際にLED等で,確かめた方が私にはてっとりばやいです。
タイマーフラグのクリアーやらレジスターの再設定等,TRさんが書かれたプログラムのように書いて,
思った動作をしないで,悩んだことも多々あります。
この辺は,きっと,場数なんでしょうかね。
猛牛ロックさん,適切なアドバイス,ありがとうございます。
いつものことながら見識の深さにおどろかされます。
TRさん,書き込みいただいたプログラム,うまく動いたでしょうか。
私も,割り込み処理等の動作確認で,TRさんの書かれたようなLEDチカのプログラムよくつかいました。
X IDEには,シュミレーターもついていて,それを動かせば,各値等の確認できるようですが,実際にLED等で,確かめた方が私にはてっとりばやいです。
タイマーフラグのクリアーやらレジスターの再設定等,TRさんが書かれたプログラムのように書いて,
思った動作をしないで,悩んだことも多々あります。
この辺は,きっと,場数なんでしょうかね。
Re: 無題
みなさんこんばんは。
猛牛ロックさんいつもありがとうございます。
maboさんも、いろいろとご指導に感謝します。
タイマー0割込みですが、キットで遊ぼうの域からは脱していません。
今のところ、以下のプログラムです。
最初は、入力SWから、出力端子の操作ができるかと思ったのですが、ダメでした。
外部割込みなら行けそうですが、
外部割込みをやってみます。
それと、入力端子を使っての出力端子の操作は、1827で出来るのでしょうか、
というのも、ツールラボさんの記事を見ていたら、IOCAN3 = 1;
IOCANレジスタなんですね、これは、PORTA3番ピンに機能があって、この機能を使えば
簡単に入力端子のHiでプログラムを組めるようです。
ツールラボさんは、1823でしたっけ、、、。
それとハイインピーダンスの件、ありがとうございます。
I/Oピンの仕組みはまだよくわかっていないです。
でも想像した通り、180オーム-LED-10kオームで分圧されてしまうようですね。
常時RB3を点灯させ、
タイマー0割込みで、RB4を点滅させています。
// PIC16F1827 Configuration Bit Settings
// 'C' source line config statements
#include <xc.h>
// CONFIG1
省略
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
// __delay_ms(), __delay_us()関数が使用する
#define _XTAL_FREQ 1000000
#define On 1
#define Off 0
// プロトタイプ宣言
void InitInterTimer0 (void);
// メイン関数
void main (void)
{
OSCCON = 0b01011010; // 内部クロック周波数を1MHzに設定
// 電圧レベルの初期設定
PORTA = 0xFF;
PORTB = 0xFF;
// 入出力設定
TRISA = 0x20;
TRISB = 0x00;
// タイマ0割込み設定関数の呼び出し
InitInterTimer0();
// 割込み全体の許可
GIE = 1;
// 永久ループ
while(1)
{
RB3 =1;
}
}
// 割込みサービスルーチン
static void interrupt isr()
{
RB4 =1;
__delay_ms(3000);
RB4=0;
__delay_ms(3000);
// タイマ0割込みフラグをクリア
T0IF = 0;
}
// タイマ0割込み設定関数
void InitInterTimer0 (void)
{
OPTION_REG=0b000000000;//プリスケラ000 5ビット=0内部クロック使用 WDTは使わない
TMR0=0x00;
INTCONbits.TMR0IF=0; //TMR0フラグクリアー
INTCONbits.TMR0IE=1;//TMR0割り込み許可
INTCONbits.GIE=1;//全体割り込み許可
}
猛牛ロックさんいつもありがとうございます。
maboさんも、いろいろとご指導に感謝します。
タイマー0割込みですが、キットで遊ぼうの域からは脱していません。
今のところ、以下のプログラムです。
最初は、入力SWから、出力端子の操作ができるかと思ったのですが、ダメでした。
外部割込みなら行けそうですが、
外部割込みをやってみます。
それと、入力端子を使っての出力端子の操作は、1827で出来るのでしょうか、
というのも、ツールラボさんの記事を見ていたら、IOCAN3 = 1;
IOCANレジスタなんですね、これは、PORTA3番ピンに機能があって、この機能を使えば
簡単に入力端子のHiでプログラムを組めるようです。
ツールラボさんは、1823でしたっけ、、、。
それとハイインピーダンスの件、ありがとうございます。
I/Oピンの仕組みはまだよくわかっていないです。
でも想像した通り、180オーム-LED-10kオームで分圧されてしまうようですね。
常時RB3を点灯させ、
タイマー0割込みで、RB4を点滅させています。
// PIC16F1827 Configuration Bit Settings
// 'C' source line config statements
#include <xc.h>
// CONFIG1
省略
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
// __delay_ms(), __delay_us()関数が使用する
#define _XTAL_FREQ 1000000
#define On 1
#define Off 0
// プロトタイプ宣言
void InitInterTimer0 (void);
// メイン関数
void main (void)
{
OSCCON = 0b01011010; // 内部クロック周波数を1MHzに設定
// 電圧レベルの初期設定
PORTA = 0xFF;
PORTB = 0xFF;
// 入出力設定
TRISA = 0x20;
TRISB = 0x00;
// タイマ0割込み設定関数の呼び出し
InitInterTimer0();
// 割込み全体の許可
GIE = 1;
// 永久ループ
while(1)
{
RB3 =1;
}
}
// 割込みサービスルーチン
static void interrupt isr()
{
RB4 =1;
__delay_ms(3000);
RB4=0;
__delay_ms(3000);
// タイマ0割込みフラグをクリア
T0IF = 0;
}
// タイマ0割込み設定関数
void InitInterTimer0 (void)
{
OPTION_REG=0b000000000;//プリスケラ000 5ビット=0内部クロック使用 WDTは使わない
TMR0=0x00;
INTCONbits.TMR0IF=0; //TMR0フラグクリアー
INTCONbits.TMR0IE=1;//TMR0割り込み許可
INTCONbits.GIE=1;//全体割り込み許可
}
Re: 無題
> でも想像した通り、180オーム-LEDる-10kオームで分圧されてしまうようですね。
いいえ、単なる直列回路です。入力時は、
5V-10180オーム-LED-GND
と同じと言う事です。
HIGH出力時は、LEDは5Vと5V(HIGH)に挟まれているので、LEDには電気が流れませんけど、10kΩには電気が流れます。
つまり、無駄です。
LOW出力時には5V-LED-LOWと流れるのでLEDは光ります。10kΩの方には電気は流れません。
いずれにしても、10kΩは付ける意味がありません。
> 入力SWから、出力端子の操作ができるかと思ったのですが
言っている意味が解りません。
プログラムのどこからでも出力端子は操作できます。
RB3をLOWにしたいと言う事でしょうか?
それなら
RB3=0;
と書けばLOWになります。
> IOCANレジスタなんですね、
F1827の基本的な構成として、入力がポートB、出力がポートAに割り当てられています。
まぁ、絶対的なものではありませんけど。
で、同じもの(INT/IOC)は1827にもありますけど、ポートBです。
で、今回のプログラムですけど、悪い例です。
タイマー割り込みは正確な時間を作り出します。
しかし、このプログラムでは__delay_ms(3000);で、正確な時間の取得を壊しています。
なぜなら、タイマー割り込みの間隔を超えているからです。
また、タイマー割り込みを使う意味も全くありません。
タイマー割り込みを使うもう一つの利点はdelay関数を使わないプログラムにする、という点です。
まずは、タイマー割り込みの時間(間隔)を把握しましょう。
1msや10msにしても良いですし、中途半端な値でも駄目ではありません。
駆動周波数とプリスケーラ、タイマー値から、算出(設定)してください。
それがタイマー0の単位時間です。単位時間内に収まる処理にする必要があります。
※基本的には、周辺機能(タイマーや外部割り込み等)は使わずにGPIO操作を覚えた方が良いです。
まずはGPIO操作で、壁にぶつかるまで押し通した方が良いです。
今は分散してしまっていて、見通し悪いプログラムになっていて、自分で原因を見つけるのが困難になっています。
CONFIGやクロック設定などは、どっかからのコピーで良いですけど、ピン操作(初期設定)からは、
どう制御しているのか、100%自信をもって書いてください。
理解せずに動いても意味がありません。
逆に、理解していないものを書いてはいけません。
自分の理解と共に、出来る範囲を増やす事です。
特に動かないのを、何故そうなったか理解しようとせずに、他の機能に移るのは止めるべきです。
動かないのは、目の前に覚えるべきことがあるからです。
そこを乗り越えてはじめて、1つスキルが上がるのです。
いいえ、単なる直列回路です。入力時は、
5V-10180オーム-LED-GND
と同じと言う事です。
HIGH出力時は、LEDは5Vと5V(HIGH)に挟まれているので、LEDには電気が流れませんけど、10kΩには電気が流れます。
つまり、無駄です。
LOW出力時には5V-LED-LOWと流れるのでLEDは光ります。10kΩの方には電気は流れません。
いずれにしても、10kΩは付ける意味がありません。
> 入力SWから、出力端子の操作ができるかと思ったのですが
言っている意味が解りません。
プログラムのどこからでも出力端子は操作できます。
RB3をLOWにしたいと言う事でしょうか?
それなら
RB3=0;
と書けばLOWになります。
> IOCANレジスタなんですね、
F1827の基本的な構成として、入力がポートB、出力がポートAに割り当てられています。
まぁ、絶対的なものではありませんけど。
で、同じもの(INT/IOC)は1827にもありますけど、ポートBです。
で、今回のプログラムですけど、悪い例です。
タイマー割り込みは正確な時間を作り出します。
しかし、このプログラムでは__delay_ms(3000);で、正確な時間の取得を壊しています。
なぜなら、タイマー割り込みの間隔を超えているからです。
また、タイマー割り込みを使う意味も全くありません。
タイマー割り込みを使うもう一つの利点はdelay関数を使わないプログラムにする、という点です。
まずは、タイマー割り込みの時間(間隔)を把握しましょう。
1msや10msにしても良いですし、中途半端な値でも駄目ではありません。
駆動周波数とプリスケーラ、タイマー値から、算出(設定)してください。
それがタイマー0の単位時間です。単位時間内に収まる処理にする必要があります。
※基本的には、周辺機能(タイマーや外部割り込み等)は使わずにGPIO操作を覚えた方が良いです。
まずはGPIO操作で、壁にぶつかるまで押し通した方が良いです。
今は分散してしまっていて、見通し悪いプログラムになっていて、自分で原因を見つけるのが困難になっています。
CONFIGやクロック設定などは、どっかからのコピーで良いですけど、ピン操作(初期設定)からは、
どう制御しているのか、100%自信をもって書いてください。
理解せずに動いても意味がありません。
逆に、理解していないものを書いてはいけません。
自分の理解と共に、出来る範囲を増やす事です。
特に動かないのを、何故そうなったか理解しようとせずに、他の機能に移るのは止めるべきです。
動かないのは、目の前に覚えるべきことがあるからです。
そこを乗り越えてはじめて、1つスキルが上がるのです。
Re: 無題
猛牛ロックさん,TRさん,こんばんは。
猛牛ロックさん,今日もありがとうございます。
TRさん,新しいプログラムですね。
割り込みの中で,
__delay_ms(3000);
をお使いのようですが,好みからいったら,割り込みに入った回数をカウントして,LEDのOnとOffを交互にすればいいように思いますが,どうでしょうか。
static void interrupt isr(){
if(Count<一定数){Count++;}
Else{ Count=0;RB4=RB4~;}
T0IF = 0;
}
間違ってるかもしれませんが,上記のようにすれば,いいかもですね。
それから,
RB3
ですけど,1回だけOnにすれば,いいので,
RB3 =1;
while(1)
{
}
みたいにWhileの外にだした方いいと思います。
Whileの中にあると,RB3を1にする動作を繰り返すことになります。
今日は,ちょっと,下記を参考にシュミレートをいろいろやってみました
http://www.geocities.jp/zattouka/GarageHouse/micon/MPLABX/Simulator1.htm
猛牛ロックさん,今日もありがとうございます。
TRさん,新しいプログラムですね。
割り込みの中で,
__delay_ms(3000);
をお使いのようですが,好みからいったら,割り込みに入った回数をカウントして,LEDのOnとOffを交互にすればいいように思いますが,どうでしょうか。
static void interrupt isr(){
if(Count<一定数){Count++;}
Else{ Count=0;RB4=RB4~;}
T0IF = 0;
}
間違ってるかもしれませんが,上記のようにすれば,いいかもですね。
それから,
RB3
ですけど,1回だけOnにすれば,いいので,
RB3 =1;
while(1)
{
}
みたいにWhileの外にだした方いいと思います。
Whileの中にあると,RB3を1にする動作を繰り返すことになります。
今日は,ちょっと,下記を参考にシュミレートをいろいろやってみました
http://www.geocities.jp/zattouka/GarageHouse/micon/MPLABX/Simulator1.htm
Re: 無題
>F1827の基本的な構成として、入力がポートB、出力がポートAに割り当てられています。
・・・・・・
で、同じもの(INT/IOC)は1827にもありますけど、ポートBです。
そうか!
データシートを見るとありました。
写真の赤枠!
1827の場合、ピンに入った信号を読み取る場合、読み取れる選択肢は、
bit0〜bit7までの全てですね! オー、沢山ある。
RB6に割り込み有効化
IOCIE = 1;
IOCBN3 = 1;
GIE = 1;
常時動作
RB6 割り込み無効化
GIE = 0;
IOCIE = 0;
IOCBN3 = 0;
割り込み処理プログラム
void interrupt isr(void)
{
略
}
これで、常時動作の最中にRB3にLo信号が入れば、割込みができると思いますが。
>単位時間内に収まる処理にする必要があります。
サブルーチンの作業時間は、タイマー割り込みの時間(間隔)内にするということですか?
今は、
サブルーチンは、割込みが始まって、RB4 =点灯〜3秒据え置き〜RB4消灯〜3秒据え置き
そして、メイン関数内のRB3点灯させています。
サブルーチン内の割込み開始から割込み作業終了の間の時間(点灯3秒+消灯3秒)をタイマー割込み時間(間隔)内にするのですか?
タイマー割込み時間(間隔)内にする作業の種類にするということですか?
例
タイマー割込み時間(間隔)内にRA6がハイかローかの確認作業など
>※基本的には、周辺機能(タイマーや外部割り込み等)は使わずにGPIO操作を覚えた方が良いです。
まずはGPIO操作で、壁にぶつかるまで押し通した方が良いです。
自分は、進みます。
これからも宜しくご指導願います
Re: 無題
maboさん,こんにちは。
>割り込みの中で,
__delay_ms(3000);
をお使いのようですが,好みからいったら,割り込みに入った回数をカウントして,LEDのOnとOffを交互にすればいいように思いますが,どうでしょうか。
static void interrupt isr(){
if(Count<一定数){Count++;}
Else{ Count=0;RB4=RB4~;}
T0IF = 0;
}
プログラム全体を見させていただけませんか?
>それから,
RB3
ですけど,1回だけOnにすれば,いいので,
RB3 =1;
while(1)
{
}
みたいにWhileの外にだした方いいと思います。
Whileの中にあると,RB3を1にする動作を繰り返すことになります。
分かりました。
>今日は,ちょっと,下記を参考にシュミレートをいろいろやってみました
http://www.geocities.jp/zattouka/GarageHouse/micon/MPLABX/Simulator1.htm
シュミレーターの使い方なんですね。
機会があったら、見ようかと思います。ありがとうございました。
>割り込みの中で,
__delay_ms(3000);
をお使いのようですが,好みからいったら,割り込みに入った回数をカウントして,LEDのOnとOffを交互にすればいいように思いますが,どうでしょうか。
static void interrupt isr(){
if(Count<一定数){Count++;}
Else{ Count=0;RB4=RB4~;}
T0IF = 0;
}
プログラム全体を見させていただけませんか?
>それから,
RB3
ですけど,1回だけOnにすれば,いいので,
RB3 =1;
while(1)
{
}
みたいにWhileの外にだした方いいと思います。
Whileの中にあると,RB3を1にする動作を繰り返すことになります。
分かりました。
>今日は,ちょっと,下記を参考にシュミレートをいろいろやってみました
http://www.geocities.jp/zattouka/GarageHouse/micon/MPLABX/Simulator1.htm
シュミレーターの使い方なんですね。
機会があったら、見ようかと思います。ありがとうございました。
Re: 無題
TRさん,猛牛ロックさんおはようございます。
TRさん,プログラムの全体ですが,
1268のTRさんのプログラムで,割り込みの部分だけを
入れ替えて,main の方で,RB3を外にだせばいいと思います。
割り込みのなかで,
T0IF = 0;
を使ってますが,もしかして,コンパイル通らないかもですね。
T0IF = 0→INTCONbits.TMR0IF=0
でしょうか。
カウントの定数は,オーバーフローしない範囲で,
好みでいいと思います。
定数を多くすれば,点滅の間隔が長くなります。
この間隔は,割り込みの時間等を考えれば,割り出せるのでしょうが,私は,適当なことが多かったです。
ただ,タイマーのプログラムで使った時は,だいたい正確な時間になるように,トライアンドエラーで調整しました。
TRさん,プログラムの全体ですが,
1268のTRさんのプログラムで,割り込みの部分だけを
入れ替えて,main の方で,RB3を外にだせばいいと思います。
割り込みのなかで,
T0IF = 0;
を使ってますが,もしかして,コンパイル通らないかもですね。
T0IF = 0→INTCONbits.TMR0IF=0
でしょうか。
カウントの定数は,オーバーフローしない範囲で,
好みでいいと思います。
定数を多くすれば,点滅の間隔が長くなります。
この間隔は,割り込みの時間等を考えれば,割り出せるのでしょうが,私は,適当なことが多かったです。
ただ,タイマーのプログラムで使った時は,だいたい正確な時間になるように,トライアンドエラーで調整しました。
Re: 無題
皆さん方のご指摘を踏まえて、下記の通りプログラムを変えました。
常時は、フラグによりRB3をハイにしたりローにしたりの動作です。
割込み時には、エベントフラグが0なら、強制的に
イベントフラグを1にさせます。
しかし、XIDEのバージョンの関係かどうかわかりませんが
@にエラーが出ています。
以前のNo1268ではそんなことがなかったのに( 一一)
プログラムが悪いのでしょうか?
// PIC16F1827 Configuration Bit Settings
//RA6 マッハからの信号
// 'C' source line config statements
#include <xc.h>
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF // PLL Enable (4x PLL disabled)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = HI // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
// __delay_ms(), __delay_us()関数が使用する
#define _XTAL_FREQ 1000000
#define On 1
#define Off 0
int event;
// プロトタイプ宣言
void InitInterTimer0 (void);
// メイン関数
void main (void)
{
OSCCON = 0b01011010; // 内部クロック周波数を1MHzに設定
// 電圧レベルの初期設定
PORTA = 0x00;
PORTB = 0x00;
// 入出力設定
TRISA = 0x00;
TRISB = 0x00;
// タイマ0割込み設定関数の呼び出し
InitInterTimer0();
// 割込み全体の許可
GIE = 1;
event=0;//初期値イベント無しRB3ロー
// 永久ループ
while(1)
{
if(event==1)
{
RB3=0;
}
if(event=1){
RB3=1;
}
// 割込みサービスルーチン
@static void interrupt isr()
{
if(RA6==0 && event==0){//もしRA6が押されていて、イベントが起きていなかったら
event=1;
}
// タイマ0割込みフラグをクリア
T0IF = 0;
}
// タイマ0割込み設定関数
void InitInterTimer0 (void)
{
OPTION_REG=0b000000000;//プリスケラ000 5ビット=0内部クロック使用 WDTは使わない
TMR0=0x00;
INTCONbits.TMR0IF=0; //TMR0フラグクリアー
INTCONbits.TMR0IE=1;//TMR0割り込み許可
INTCONbits.GIE=1;//全体割り込み許可
}
常時は、フラグによりRB3をハイにしたりローにしたりの動作です。
割込み時には、エベントフラグが0なら、強制的に
イベントフラグを1にさせます。
しかし、XIDEのバージョンの関係かどうかわかりませんが
@にエラーが出ています。
以前のNo1268ではそんなことがなかったのに( 一一)
プログラムが悪いのでしょうか?
// PIC16F1827 Configuration Bit Settings
//RA6 マッハからの信号
// 'C' source line config statements
#include <xc.h>
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF // PLL Enable (4x PLL disabled)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = HI // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
// __delay_ms(), __delay_us()関数が使用する
#define _XTAL_FREQ 1000000
#define On 1
#define Off 0
int event;
// プロトタイプ宣言
void InitInterTimer0 (void);
// メイン関数
void main (void)
{
OSCCON = 0b01011010; // 内部クロック周波数を1MHzに設定
// 電圧レベルの初期設定
PORTA = 0x00;
PORTB = 0x00;
// 入出力設定
TRISA = 0x00;
TRISB = 0x00;
// タイマ0割込み設定関数の呼び出し
InitInterTimer0();
// 割込み全体の許可
GIE = 1;
event=0;//初期値イベント無しRB3ロー
// 永久ループ
while(1)
{
if(event==1)
{
RB3=0;
}
if(event=1){
RB3=1;
}
// 割込みサービスルーチン
@static void interrupt isr()
{
if(RA6==0 && event==0){//もしRA6が押されていて、イベントが起きていなかったら
event=1;
}
// タイマ0割込みフラグをクリア
T0IF = 0;
}
// タイマ0割込み設定関数
void InitInterTimer0 (void)
{
OPTION_REG=0b000000000;//プリスケラ000 5ビット=0内部クロック使用 WDTは使わない
TMR0=0x00;
INTCONbits.TMR0IF=0; //TMR0フラグクリアー
INTCONbits.TMR0IE=1;//TMR0割り込み許可
INTCONbits.GIE=1;//全体割り込み許可
}
Re: 無題
maboさんへ
>1268のTRさんのプログラムで,割り込みの部分だけを
入れ替えて,main の方で,RB3を外にだせばいいと思います。
それでも、良いと思います。
>割り込みのなかで,
T0IF = 0;
を使ってますが,もしかして,コンパイル通らないかもですね。
T0IF = 0→INTCONbits.TMR0IF=0
でしょうか。
それは、XIDEのバージョンの関係でコンパイルできなくなります。
今自分は、コンパイルできなくなるのでV3.65を使っています。
V3.65なら、T0IF = 0 でとおります。
猛牛ロックさんが、割込み時間を気にしているのは、
SWによってLEDの操作を考えていると思います。
本来のタイマー0割込みの使い方をしろと言っていると思います。
自分はそう、解釈し新しいプログラムをNo1274に掲載しました。
>1268のTRさんのプログラムで,割り込みの部分だけを
入れ替えて,main の方で,RB3を外にだせばいいと思います。
それでも、良いと思います。
>割り込みのなかで,
T0IF = 0;
を使ってますが,もしかして,コンパイル通らないかもですね。
T0IF = 0→INTCONbits.TMR0IF=0
でしょうか。
それは、XIDEのバージョンの関係でコンパイルできなくなります。
今自分は、コンパイルできなくなるのでV3.65を使っています。
V3.65なら、T0IF = 0 でとおります。
猛牛ロックさんが、割込み時間を気にしているのは、
SWによってLEDの操作を考えていると思います。
本来のタイマー0割込みの使い方をしろと言っていると思います。
自分はそう、解釈し新しいプログラムをNo1274に掲載しました。
Re: 無題
TRさん,猛牛ロックさん,こんにちは
TRさん,新しいプログラムですね。
今回は,スイッチ(RA6経由)でLED(RB3)をつける
というプログラムで,スイッチの判断を割り込みで検出するということでしょうか。
これを発展させば,チャタリングの除去等もできますね。
一カ所だけあきらかな間違いがあります。
while(1)
{
if(event==1)
{
RB3=0;
}
if(event=1){
RB3=1;
}
の if(event=1) の部分で,
if(event==0)
でしょうかね。
@のエラーはちょっと不明です。
TRさん,新しいプログラムですね。
今回は,スイッチ(RA6経由)でLED(RB3)をつける
というプログラムで,スイッチの判断を割り込みで検出するということでしょうか。
これを発展させば,チャタリングの除去等もできますね。
一カ所だけあきらかな間違いがあります。
while(1)
{
if(event==1)
{
RB3=0;
}
if(event=1){
RB3=1;
}
の if(event=1) の部分で,
if(event==0)
でしょうかね。
@のエラーはちょっと不明です。
Re: 無題
maboさんこんにちは。
ご指摘ありがとうございます。
早速直しました(笑い
エラー表示をグーグル翻訳すると ↓
main.c:62:警告:(2025)ローカル変数 "isr"の修飾子 "interrupt"は許可されておらず無視されています
しかし、No1268ではそんなことがなかったのに(参った
ご指摘ありがとうございます。
早速直しました(笑い
エラー表示をグーグル翻訳すると ↓
main.c:62:警告:(2025)ローカル変数 "isr"の修飾子 "interrupt"は許可されておらず無視されています
しかし、No1268ではそんなことがなかったのに(参った
Re: 無題
TRさん,もしかして空白の問題かも。
isr()→isr ()
X IDEのディターでは,()と関数名の間に空白があるようです。
isr()→isr ()
X IDEのディターでは,()と関数名の間に空白があるようです。
Re: 無題
ちょっと成形すれば、buildは出来ますよ。
「}」は付けましたか?
SOURCE→FORMATで成形してみた方が良いです。すぐに判ります。
ただし、実行しても何も変化はしない気がします。
<追記します。>
プログラム的には
> PORTA = 0x00;
> PORTB = 0x00;
> // 入出力設定
> TRISA = 0x00;
> TRISB = 0x00;
で、RA3はLOW出力です。※RA6もまたLOW出力です。
タイマー割り込みがかかると
> if (RA6 == 0 && event == 0) {//もしRA6が押されていて、イベントが起きていなかったら
> event = 1;
> }
で、eventが1になります。
※初期化はint event;ではなく、volatile int event;にした方が良いです。
そして、メイン関数の永久ループで、
if (event == 1) {
RB3 = 0;
}
と、元々LOW出力のピンをLOW出力にします。
ちょっと、どうしたいのか、プログラム以前に、目的とする動作が判りません。
どういったプログラムが書きたかったのでしょうか?
元々HIGH出力のRB3を、一度スイッチが押されたらLOW出力に固定したい、という事ですか?
それとも、毎回押す度にトグル動作、とかでしょうか?
「}」は付けましたか?
SOURCE→FORMATで成形してみた方が良いです。すぐに判ります。
ただし、実行しても何も変化はしない気がします。
<追記します。>
プログラム的には
> PORTA = 0x00;
> PORTB = 0x00;
> // 入出力設定
> TRISA = 0x00;
> TRISB = 0x00;
で、RA3はLOW出力です。※RA6もまたLOW出力です。
タイマー割り込みがかかると
> if (RA6 == 0 && event == 0) {//もしRA6が押されていて、イベントが起きていなかったら
> event = 1;
> }
で、eventが1になります。
※初期化はint event;ではなく、volatile int event;にした方が良いです。
そして、メイン関数の永久ループで、
if (event == 1) {
RB3 = 0;
}
と、元々LOW出力のピンをLOW出力にします。
ちょっと、どうしたいのか、プログラム以前に、目的とする動作が判りません。
どういったプログラムが書きたかったのでしょうか?
元々HIGH出力のRB3を、一度スイッチが押されたらLOW出力に固定したい、という事ですか?
それとも、毎回押す度にトグル動作、とかでしょうか?
Re: 無題
猛牛ロックさんこんばんは。
>「}」は付けましたか?
つけ忘れていました。
つけたら、エラー表示がなくなりビルトもできました。
これなら、動作しますかね?
動作
SW On(プルアップRA6がLo)→ RB3がハイ
RB3は、プルアップもプルダウンもなしで、RB3からLED〜180Ω〜GND
SWは、押している時間だけSWが入るタイプです。
でなんですが、、、、
実は、PICの差し込みを間違えて自作の書き込み機が壊れたようです。
>SOURCE→FORMATで成形してみた方が良いです。すぐに判ります。
この方法を教えてください。
色々とすみません。宜しくお願いします。
>「}」は付けましたか?
つけ忘れていました。
つけたら、エラー表示がなくなりビルトもできました。
これなら、動作しますかね?
動作
SW On(プルアップRA6がLo)→ RB3がハイ
RB3は、プルアップもプルダウンもなしで、RB3からLED〜180Ω〜GND
SWは、押している時間だけSWが入るタイプです。
でなんですが、、、、
実は、PICの差し込みを間違えて自作の書き込み機が壊れたようです。
>SOURCE→FORMATで成形してみた方が良いです。すぐに判ります。
この方法を教えてください。
色々とすみません。宜しくお願いします。
interrupt関数
みなさんこんばんは。
F1827で、以下のプログラム(もとは、猛牛ロックさん作成)ですが、大変重宝しています。
F1827でコンパイルするとエラーが出ます。
IDXは、interrupt関数に!が出ています。
原因を分かったらご教授願います。
/*間欠*/
// PIC16F1827 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF // PLL Enable (4x PLL disabled)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = HI // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#define KanketuTime 2
#define DousaTime 1
#define On 0
#define Off 1
// __delay_ms(), __delay_us()関数が使用する
#define _XTAL_FREQ 4000000
int Start;
// プロトタイプ宣言
void InitInterTimer0 (void);
void WaitTime (int cnt);
// メイン関数
void main (void){
OSCCON = 0b01101010;//内蔵発振器 4MHz使用に設定
PORTA = 0x00;// 電圧レベルの初期設定
PORTB = 0xFF;
// 入出力設定
TRISA = 0b01010000;//RA5は入力専用・RA6は入力他は出力
TRISB = 0b00000000;//RB0は入力
//初期設定
RA2=Off;//MACH
RA6=Off;
Start=0;
// タイマ0割込み設定関数の呼び出し
InitInterTimer0();
// 割込み全体の許可
GIE = 1;
int Buzer=0;//
// 永久ループ
while(1){
if(Start==1){//スタートフラグが1なら動作開始
RA2=On;
Buzer=On;
Second(DousaTime);
//RA2=Off;
//Second(KanketuTime);
}
if(Start==0){
if(Buzer==On){
Second(KanketuTime);
RA2=Off;
Buzer=Off;
}
}
}
}
static void interrupt isr()
{//TMR0の割り込み処理(割り込みサブルーチン)
if(INTCONbits.TMR0IF==1){//割り込みがあったら
TMR0 =0 ; // タイマー0の初期化
if(RA6==0){//MACHからの信号をしらべて0(Low)だったらスタートのフラグを1にする
if(Start==0){
Start=1;
}
}
if(RA6==1){//MACHからの信号をしらべて1(High)だったらスタートのフラグを0にして
if(Start==1){
Start=0;
//RA2=Off;//機器の動作を強制的に止める。
}
}
INTCONbits.TMR0IF=0;
TMR0=0;
}
}
// タイマ0割込み設定関数
void InitInterTimer0 (void)
{//割り込み設定
OPTION_REG=0b000000000;//プリスケラ? 2 5ビット=0 WDTは使わない
TMR0=0; //TMR0カウンターを0に
INTCONbits.TMR0IF=0; //TMR0フラグクリアー
INTCONbits.TMR0IE=1;//TMR0割り込み許可
INTCONbits.GIE=1;//全体割り込み許可
}
// 待ち時間関数}
void Second(int sec){
while(sec >0){
sec--;
__delay_ms(10);
}
}
F1827で、以下のプログラム(もとは、猛牛ロックさん作成)ですが、大変重宝しています。
F1827でコンパイルするとエラーが出ます。
IDXは、interrupt関数に!が出ています。
原因を分かったらご教授願います。
/*間欠*/
// PIC16F1827 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF // PLL Enable (4x PLL disabled)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = HI // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#define KanketuTime 2
#define DousaTime 1
#define On 0
#define Off 1
// __delay_ms(), __delay_us()関数が使用する
#define _XTAL_FREQ 4000000
int Start;
// プロトタイプ宣言
void InitInterTimer0 (void);
void WaitTime (int cnt);
// メイン関数
void main (void){
OSCCON = 0b01101010;//内蔵発振器 4MHz使用に設定
PORTA = 0x00;// 電圧レベルの初期設定
PORTB = 0xFF;
// 入出力設定
TRISA = 0b01010000;//RA5は入力専用・RA6は入力他は出力
TRISB = 0b00000000;//RB0は入力
//初期設定
RA2=Off;//MACH
RA6=Off;
Start=0;
// タイマ0割込み設定関数の呼び出し
InitInterTimer0();
// 割込み全体の許可
GIE = 1;
int Buzer=0;//
// 永久ループ
while(1){
if(Start==1){//スタートフラグが1なら動作開始
RA2=On;
Buzer=On;
Second(DousaTime);
//RA2=Off;
//Second(KanketuTime);
}
if(Start==0){
if(Buzer==On){
Second(KanketuTime);
RA2=Off;
Buzer=Off;
}
}
}
}
static void interrupt isr()
{//TMR0の割り込み処理(割り込みサブルーチン)
if(INTCONbits.TMR0IF==1){//割り込みがあったら
TMR0 =0 ; // タイマー0の初期化
if(RA6==0){//MACHからの信号をしらべて0(Low)だったらスタートのフラグを1にする
if(Start==0){
Start=1;
}
}
if(RA6==1){//MACHからの信号をしらべて1(High)だったらスタートのフラグを0にして
if(Start==1){
Start=0;
//RA2=Off;//機器の動作を強制的に止める。
}
}
INTCONbits.TMR0IF=0;
TMR0=0;
}
}
// タイマ0割込み設定関数
void InitInterTimer0 (void)
{//割り込み設定
OPTION_REG=0b000000000;//プリスケラ? 2 5ビット=0 WDTは使わない
TMR0=0; //TMR0カウンターを0に
INTCONbits.TMR0IF=0; //TMR0フラグクリアー
INTCONbits.TMR0IE=1;//TMR0割り込み許可
INTCONbits.GIE=1;//全体割り込み許可
}
// 待ち時間関数}
void Second(int sec){
while(sec >0){
sec--;
__delay_ms(10);
}
}
Re: interrupt関数
> !が出ています。
元のプログラムと見比べてみてください。
何が変わっているのか。
場所は「!」が付いているので判っているんですよね?
更にコンパイルすればエラーメッセージが出ると思います。
元のプログラムと見比べてみてください。
何が変わっているのか。
場所は「!」が付いているので判っているんですよね?
更にコンパイルすればエラーメッセージが出ると思います。
Re: interrupt関数
猛牛ロックさんありがとうございます。
自分なりに、データシートを見たりして、プログラむ見直しをしたりして、
現在は以下の通りですが、
エラーの表示は、
interrupt関数に「!」の表示はそのままです。
でも何度見ても、エラーには思えないプログラム内容です。
エラー原因をわかりましたら、教えてください。
宜しくお願いします。
エラー表示も添えておきます。
なお、グーグル翻訳では、翻訳しきれませんでした。
エラー表示内容
make -f nbproject/Makefile-default.mk SUBPROJECTS= .build-conf
make[1]: Entering directory 'C:/Users/TOSHI/MPLABXProjects/LESSON_C.X'
make -f nbproject/Makefile-default.mk dist/default/production/LESSON_C.X.production.hex
make[2]: Entering directory 'C:/Users/TOSHI/MPLABXProjects/LESSON_C.X'
"C:\Program Files (x86)\Microchip\xc8\v2.00\bin\xc8-cc.exe" -mcpu=16F1827 -c -fno-short-double -fno-short-float -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -Wa,-a -DXPRJ_default=default -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-osccal -mno-resetbits -mno-save-resetbits -mno-download -mno-stackcall -std=c99 -gdwarf-3 -mstack=compiled:auto:auto -o build/default/production/main.p1 main.c
main.c:71:6: error: variable has incomplete type 'void'
void interrupt isr(){//TMR0<82><U+030A><84><82><U+835E><82><U+074F><88><97><9D>
^
main.c:71:15: error: expected ';' after top level declarator
void interrupt isr(){//TMR0<82><U+030A><84><82><U+835E><82><U+074F><88><97><9D>
^
;
2 errors generated.
make[2]: *** [build/default/production/main.p1] Error 1
(908) exit status = 1
nbproject/Makefile-default.mk:106: recipe for target 'build/default/production/main.p1' failed
make[2]: Leaving directory 'C:/Users/TOSHI/MPLABXProjects/LESSON_C.X'
nbproject/Makefile-default.mk:90: recipe for target '.build-conf' failed
make[1]: Leaving directory 'C:/Users/TOSHI/MPLABXProjects/LESSON_C.X'
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
BUILD FAILED (exit value 2, total time: 1s)
//*****************************
//* 間欠タイマー
//* 16F627A
//* XC8 V1.35
//* No481
//* RA6←MACHからの入力想定
//* RA2←制御機器へ
//*****************************
#include <xc.h>
#define _XTAL_FREQ 4000000 //delay用宣言
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// CONFIG
#pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTOSC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = OFF // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD)
#pragma config BOREN = OFF // Brown-out Detect Enable bit (BOD disabled)
#pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EE Memory Code Protection bit (Data memory code protection off)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
#define KanketuTime 2
#define DousaTime 1
#define On 0
#define Off 1
// __delay_ms(), __delay_us()関数が使用する
#define _XTAL_FREQ 4000000
int Start;
//関数宣言
void Second(int sec);
// プロトタイプ宣言
void InitInterTimer0 (void);
// メイン関数
void main (void){
OSCCON = 0b01101010;//内蔵発振器 4MHz使用に設定
PORTA = 0x00;// 電圧レベルの初期設定
PORTB = 0xFF;
// 入出力設定
TRISA = 0b01010000;//RA5は入力専用・RA6は入力他は出力
TRISB = 0b00000000;//RB0は入力
//初期設定
RA2=Off;//MACH
RA6=Off;
Start=0;
int Buzer=0;//
void InitInterTimer0 (void);
GIE=1;//全体割り込み許可
// 永久ループ
while(1){
if(Start==1){//スタートフラグが1なら動作開始
RA2=On;
Buzer=On;
Second(DousaTime);
//RA2=Off;
//Second(KanketuTime);
}
if(Start==0){
if(Buzer==On){
Second(KanketuTime);
RA2=Off;
Buzer=Off;
}
}
TMR0=0;
TMR0IF=0;
}
}
void interrupt isr(){//TMR0の割り込み処理
if(TMR0IF==1){//割り込みがあったら
if(RA6==0){//MACHからの信号をしらべて0(Low)だったらスタートのフラグを1にする
if(Start==0){
Start=1;
}
}
if(RA6==1){//MACHからの信号をしらべて1(High)だったらスタートのフラグを0にして
if(Start==1){
Start=0;
//RA2=Off;//機器の動作を強制的に止める。
}
}
TMR0=0;
TMR0IF=0;
}
}
// タイマ0割込み設定関数
void InitInterTimer0 (void)
{
//割り込み設定
OPTION_REG=0b000000000;//プリスケラ? 2 5ビット=0 WDTは使わない
INTCONbits.TMR0IF=0; //TMR0フラグクリアー
INTCONbits.TMR0IE=1;//TMR0割り込み許可
INTCONbits.GIE=1;//全体割り込み許可
}
// 待ち時間関数}
void Second(int sec){
while(sec >0){
sec--;
__delay_ms(10);
}
}
自分なりに、データシートを見たりして、プログラむ見直しをしたりして、
現在は以下の通りですが、
エラーの表示は、
interrupt関数に「!」の表示はそのままです。
でも何度見ても、エラーには思えないプログラム内容です。
エラー原因をわかりましたら、教えてください。
宜しくお願いします。
エラー表示も添えておきます。
なお、グーグル翻訳では、翻訳しきれませんでした。
エラー表示内容
make -f nbproject/Makefile-default.mk SUBPROJECTS= .build-conf
make[1]: Entering directory 'C:/Users/TOSHI/MPLABXProjects/LESSON_C.X'
make -f nbproject/Makefile-default.mk dist/default/production/LESSON_C.X.production.hex
make[2]: Entering directory 'C:/Users/TOSHI/MPLABXProjects/LESSON_C.X'
"C:\Program Files (x86)\Microchip\xc8\v2.00\bin\xc8-cc.exe" -mcpu=16F1827 -c -fno-short-double -fno-short-float -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -Wa,-a -DXPRJ_default=default -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-osccal -mno-resetbits -mno-save-resetbits -mno-download -mno-stackcall -std=c99 -gdwarf-3 -mstack=compiled:auto:auto -o build/default/production/main.p1 main.c
main.c:71:6: error: variable has incomplete type 'void'
void interrupt isr(){//TMR0<82><U+030A><84><82><U+835E><82><U+074F><88><97><9D>
^
main.c:71:15: error: expected ';' after top level declarator
void interrupt isr(){//TMR0<82><U+030A><84><82><U+835E><82><U+074F><88><97><9D>
^
;
2 errors generated.
make[2]: *** [build/default/production/main.p1] Error 1
(908) exit status = 1
nbproject/Makefile-default.mk:106: recipe for target 'build/default/production/main.p1' failed
make[2]: Leaving directory 'C:/Users/TOSHI/MPLABXProjects/LESSON_C.X'
nbproject/Makefile-default.mk:90: recipe for target '.build-conf' failed
make[1]: Leaving directory 'C:/Users/TOSHI/MPLABXProjects/LESSON_C.X'
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
BUILD FAILED (exit value 2, total time: 1s)
//*****************************
//* 間欠タイマー
//* 16F627A
//* XC8 V1.35
//* No481
//* RA6←MACHからの入力想定
//* RA2←制御機器へ
//*****************************
#include <xc.h>
#define _XTAL_FREQ 4000000 //delay用宣言
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// CONFIG
#pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTOSC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = OFF // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD)
#pragma config BOREN = OFF // Brown-out Detect Enable bit (BOD disabled)
#pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EE Memory Code Protection bit (Data memory code protection off)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
#define KanketuTime 2
#define DousaTime 1
#define On 0
#define Off 1
// __delay_ms(), __delay_us()関数が使用する
#define _XTAL_FREQ 4000000
int Start;
//関数宣言
void Second(int sec);
// プロトタイプ宣言
void InitInterTimer0 (void);
// メイン関数
void main (void){
OSCCON = 0b01101010;//内蔵発振器 4MHz使用に設定
PORTA = 0x00;// 電圧レベルの初期設定
PORTB = 0xFF;
// 入出力設定
TRISA = 0b01010000;//RA5は入力専用・RA6は入力他は出力
TRISB = 0b00000000;//RB0は入力
//初期設定
RA2=Off;//MACH
RA6=Off;
Start=0;
int Buzer=0;//
void InitInterTimer0 (void);
GIE=1;//全体割り込み許可
// 永久ループ
while(1){
if(Start==1){//スタートフラグが1なら動作開始
RA2=On;
Buzer=On;
Second(DousaTime);
//RA2=Off;
//Second(KanketuTime);
}
if(Start==0){
if(Buzer==On){
Second(KanketuTime);
RA2=Off;
Buzer=Off;
}
}
TMR0=0;
TMR0IF=0;
}
}
void interrupt isr(){//TMR0の割り込み処理
if(TMR0IF==1){//割り込みがあったら
if(RA6==0){//MACHからの信号をしらべて0(Low)だったらスタートのフラグを1にする
if(Start==0){
Start=1;
}
}
if(RA6==1){//MACHからの信号をしらべて1(High)だったらスタートのフラグを0にして
if(Start==1){
Start=0;
//RA2=Off;//機器の動作を強制的に止める。
}
}
TMR0=0;
TMR0IF=0;
}
}
// タイマ0割込み設定関数
void InitInterTimer0 (void)
{
//割り込み設定
OPTION_REG=0b000000000;//プリスケラ? 2 5ビット=0 WDTは使わない
INTCONbits.TMR0IF=0; //TMR0フラグクリアー
INTCONbits.TMR0IE=1;//TMR0割り込み許可
INTCONbits.GIE=1;//全体割り込み許可
}
// 待ち時間関数}
void Second(int sec){
while(sec >0){
sec--;
__delay_ms(10);
}
}
Re: interrupt関数
TRさん,猛牛ロックさん,こんばんは。
ちょっとご無沙汰してました。
TRさん,自分で試してないので,?ですが,
多分,プロトタイプの宣言ををしてないからかなと推測します。
static void interrupt isr()
の関数がプロトタイプの宣言をしてなくて,
main関数より後にでてくるからだと思います。
多分コンパイラーは,プログラムの先頭から解釈していきますが,
main関数のなかで,プロトタイプの宣言をしてない関数に出会う,
あるいは,main関数より前に書いてない関数に出会うと,
関数の参照ができなくて,エラーがでます。
プロトタイプの宣言,面倒なので,サブ関数をメインの前に,
記述するといいかもです。
確か,私の流儀では,そうしてました。
ちょっとご無沙汰してました。
TRさん,自分で試してないので,?ですが,
多分,プロトタイプの宣言ををしてないからかなと推測します。
static void interrupt isr()
の関数がプロトタイプの宣言をしてなくて,
main関数より後にでてくるからだと思います。
多分コンパイラーは,プログラムの先頭から解釈していきますが,
main関数のなかで,プロトタイプの宣言をしてない関数に出会う,
あるいは,main関数より前に書いてない関数に出会うと,
関数の参照ができなくて,エラーがでます。
プロトタイプの宣言,面倒なので,サブ関数をメインの前に,
記述するといいかもです。
確か,私の流儀では,そうしてました。
Re: interrupt関数
No.1249は私の環境ではその部分にはエラーは出ません。
No.1251はMABOさんの言う通り、関数宣言でしょう。
但し、チラッと見ただけですけど、1827用のプログラムになっていないようですし、
内容的にも劣化しているように思います。
No.1251はMABOさんの言う通り、関数宣言でしょう。
但し、チラッと見ただけですけど、1827用のプログラムになっていないようですし、
内容的にも劣化しているように思います。
Re: interrupt関数
みなさんこんにちは。
maboさんへ
>プロトタイプの宣言,面倒なので,サブ関数をメインの前に,
記述するといいかもです。
やってみましたが、同じエラーが出ました。
猛牛ロックさんへ
>No.1249は私の環境ではその部分にはエラーは出ません。
そうでしたか〜。
と思って、
IDXにおいて、PICをF627Aに選択して、ビルトしましたが
同じエラーが出ました。
もう、自分レベルにはどうしようもありません。
AM11:51 追記
猛牛ロックさんの 環境 という話から、やむを得ず、
MPLAB のバージョンを変更したら、コンパイルできました。
IDXが3.36
コンパイラが1.42です。
自分には、こんな方法しか思いつきませんでした(泣く
でも、皆さんのおかげで、猛牛ロックさんが考えたプログラムを
自分風にアレンジして、しかも、1827、、違うか1823?の日本語バージョンで
書き込みに成功できて、うれしいです。
感謝申し上げます。
Config、AD、PWM、割り込み、タイマー0 そのほかにも
制御文、等々 学習を深められましたm(__)m
maboさんへ
>プロトタイプの宣言,面倒なので,サブ関数をメインの前に,
記述するといいかもです。
やってみましたが、同じエラーが出ました。
猛牛ロックさんへ
>No.1249は私の環境ではその部分にはエラーは出ません。
そうでしたか〜。
と思って、
IDXにおいて、PICをF627Aに選択して、ビルトしましたが
同じエラーが出ました。
もう、自分レベルにはどうしようもありません。
AM11:51 追記
猛牛ロックさんの 環境 という話から、やむを得ず、
MPLAB のバージョンを変更したら、コンパイルできました。
IDXが3.36
コンパイラが1.42です。
自分には、こんな方法しか思いつきませんでした(泣く
でも、皆さんのおかげで、猛牛ロックさんが考えたプログラムを
自分風にアレンジして、しかも、1827、、違うか1823?の日本語バージョンで
書き込みに成功できて、うれしいです。
感謝申し上げます。
Config、AD、PWM、割り込み、タイマー0 そのほかにも
制御文、等々 学習を深められましたm(__)m
Re: interrupt関数
> IDXが
何度か書いていますけど、これってMPLAB X IDEですよね?せめてXIDEにして欲しいです。
> コンパイラが1.42です。
一度バージョンを2.?に上げましたよね?書式がちょっと変わったのかもしれません。
その辺りはコンパイラのマニュアルを見る必要があります。
基本的に、コンパイラの仕様に従うしかありません。
それは初心者でもベテランでも同様です。
で、学習ですけど、私の思うには人のコードを書き換えても上達しません。
まずはデジタル入出力を使った、簡単なものから始めた方が良いです。
※本文にあたる部分が10行以下のもの。
取り敢えず重要な事は
・C言語の書式を覚える。(宣言、初期化、関数、引数、戻り値、変数の型)
・GPIOを操作出来るようになる。(入出力を正しく操作)
・if文、while文(for文)を覚える。
・変数を使えるようになる(フラグ、カウント)
といった事です。
レジスタを詳しく覚える事は、時間の無駄が大きいです。
レジスタを操作すること自体は重要な事ですけど、逆に言えば、適切に設定するだけの事です。
最低限の事だけにしておいた方が良いです。
何度か書いていますけど、これってMPLAB X IDEですよね?せめてXIDEにして欲しいです。
> コンパイラが1.42です。
一度バージョンを2.?に上げましたよね?書式がちょっと変わったのかもしれません。
その辺りはコンパイラのマニュアルを見る必要があります。
基本的に、コンパイラの仕様に従うしかありません。
それは初心者でもベテランでも同様です。
で、学習ですけど、私の思うには人のコードを書き換えても上達しません。
まずはデジタル入出力を使った、簡単なものから始めた方が良いです。
※本文にあたる部分が10行以下のもの。
取り敢えず重要な事は
・C言語の書式を覚える。(宣言、初期化、関数、引数、戻り値、変数の型)
・GPIOを操作出来るようになる。(入出力を正しく操作)
・if文、while文(for文)を覚える。
・変数を使えるようになる(フラグ、カウント)
といった事です。
レジスタを詳しく覚える事は、時間の無駄が大きいです。
レジスタを操作すること自体は重要な事ですけど、逆に言えば、適切に設定するだけの事です。
最低限の事だけにしておいた方が良いです。
Re: interrupt関数
TRさん,猛牛ロックさん,こんばんは。
TRさん,私の環境でコンパイルしてみました。
X IDE 5.03→5.05の最新でした。
X C8 2.00
の最新の環境です。
TRさんのアップした最初のプログラムです。
若干変更しました。まず,プロトタイプの宣言で,
// プロトタイプ宣言
void InitInterTimer0 (void);
void WaitTime (int);
void Second(int);
のようにvoid Second(int);を付け加えました。
それから,ブログの方に掲載しますが,若干の変更をしたら,
コンパイル通りました。
新しい,コンパイラーは,文法にシビアなようです。
それと,xc.h の読み取りのバグがあるようです。
http://mabo52.sakura.ne.jp/files/newmain.c
TRさん,私の環境でコンパイルしてみました。
X IDE 5.03→5.05の最新でした。
X C8 2.00
の最新の環境です。
TRさんのアップした最初のプログラムです。
若干変更しました。まず,プロトタイプの宣言で,
// プロトタイプ宣言
void InitInterTimer0 (void);
void WaitTime (int);
void Second(int);
のようにvoid Second(int);を付け加えました。
それから,ブログの方に掲載しますが,若干の変更をしたら,
コンパイル通りました。
新しい,コンパイラーは,文法にシビアなようです。
それと,xc.h の読み取りのバグがあるようです。
http://mabo52.sakura.ne.jp/files/newmain.c
Re: interrupt関数
Re: interrupt関数
TRさん,猛牛ロックさん,こんにちは。
今回のプログラム16F1827だったんですね。
以前,猛牛ロックさんにご紹介いただいて,私も使いました。
ただ,クロックが早くなる分,いままで動いていたプログラムが動かなくなったり,
88〜1827への移植に苦労したりました。
LATレジスタ使ったり,間にNOPのアセンブラーいれたり,見よう見まねでやりました。
http://kuri6005.sakura.ne.jp/pic/index.php?%C8%AF%B8%F7%A5%C0%A5%A4%A5%AA%A1%BC%A5%C9%28LED%29%A4%CE%C5%C0%CC%C7%2816F1827%20XC8%29
http://mitt.la.coocan.jp/pic/pic1320_06.html
http://www.microtechnica.tv/faq/faq.cgi?kate=mikroC&faq=16
あたりにその記事があります。私のブログでも,
http://mabo52.sakura.ne.jp/index.php?e=970#cmt257
に関連の記事書いてます。
なんかもういろいろ忘れています。
今回のプログラム16F1827だったんですね。
以前,猛牛ロックさんにご紹介いただいて,私も使いました。
ただ,クロックが早くなる分,いままで動いていたプログラムが動かなくなったり,
88〜1827への移植に苦労したりました。
LATレジスタ使ったり,間にNOPのアセンブラーいれたり,見よう見まねでやりました。
http://kuri6005.sakura.ne.jp/pic/index.php?%C8%AF%B8%F7%A5%C0%A5%A4%A5%AA%A1%BC%A5%C9%28LED%29%A4%CE%C5%C0%CC%C7%2816F1827%20XC8%29
http://mitt.la.coocan.jp/pic/pic1320_06.html
http://www.microtechnica.tv/faq/faq.cgi?kate=mikroC&faq=16
あたりにその記事があります。私のブログでも,
http://mabo52.sakura.ne.jp/index.php?e=970#cmt257
に関連の記事書いてます。
なんかもういろいろ忘れています。
PIC3ボード製作
みなさんこんばんは。
猛牛ロックさんもF1827を所有という事ですね!
お〜と言う感じ。
自分もすでにポチット行きました。
さてさて、
心機一転でPICを始めることにしました。
最初に、PIC3が安定して書き込みできる環境づくりということで、
外部給電によるPIC3用ボードを作ることにしました。
先ず悩んでいる点があります。
それは、PIC端子の処置です。
プルダウンかプルアップかです。
自分は、プルダウンで行こうかとおもいます。
そこでなんですが、将来、出力端子にした時の事を想定して、写真の様に抵抗2本と
LEDを繋いでみました。
実験では動作しましたが、写真の様な繋ぎ方は、どうなんでしょうか?
アブノーマルでしょうか?
猛牛ロックさんもF1827を所有という事ですね!
お〜と言う感じ。
自分もすでにポチット行きました。
さてさて、
心機一転でPICを始めることにしました。
最初に、PIC3が安定して書き込みできる環境づくりということで、
外部給電によるPIC3用ボードを作ることにしました。
先ず悩んでいる点があります。
それは、PIC端子の処置です。
プルダウンかプルアップかです。
自分は、プルダウンで行こうかとおもいます。
そこでなんですが、将来、出力端子にした時の事を想定して、写真の様に抵抗2本と
LEDを繋いでみました。
実験では動作しましたが、写真の様な繋ぎ方は、どうなんでしょうか?
アブノーマルでしょうか?
Re: PIC3ボード製作
学習ボートは使わないのですか?
あれには外部給電端子もついているので作る必要は無いと思います。
> 自分は、プルダウンで行こうかとおもいます。
それは自由ですけど、参考とするプログラムにはプルアップが多いと思いますよ。
で、大抵は内部プルアップを使います。
※今のマイコンは個別に内部プルアップ出来ます。なので、あまり外には配線しません。
回路図は意図が解りません。
あれには外部給電端子もついているので作る必要は無いと思います。
> 自分は、プルダウンで行こうかとおもいます。
それは自由ですけど、参考とするプログラムにはプルアップが多いと思いますよ。
で、大抵は内部プルアップを使います。
※今のマイコンは個別に内部プルアップ出来ます。なので、あまり外には配線しません。
回路図は意図が解りません。
Re: PIC3ボード製作
こんにちは。
>学習ボートは使わないのですか?
あれには外部給電端子もついているので作る必要は無いと思います。
キットで遊ぼうのぼーどですか、
あのボードは、書き込みが不安定で使い物になりません。
購入当初も、電圧を4.75Vにしたりして、なんで5Vじゃダメなのと思ったりしていました。
そんな中、最近(MPLABのバージョンを最新にした。)は、書き込みが出来なくなり、壊れたと思い買い換えました。
それで、試しにと思って、書き込み専用ボードで書き込んでみると
安定して書きこめるようになりました。
PIC3の電流をLEDの方へ回すには限りがあるようです。
なので、書き込みとLEDなどへ回す電気とを分離して、書き込み専用のボードを作ることにしました。
プログラムをやっていて思っていたのですが、
例えば、
入力のSWをONで、出力LEDをHiとしますよね。
この場合、プルアップとプルダウンでの、
端子をHiにしたりLoにしたりの設定が分かりずらいと思っていました。
統一したらいいのにと思っていました。
PICの事が少しは分かってきたので、新たな視線で考えることにしました。←大袈裟(笑
写真は、今のプランです。LEDは、将来の事です。今は作りませんので、除いて見て下さい。
MCLAの端子は入力専用であり、且つ書き込み時には、PIC3に繋がっていなければならない。
書き込みが出来て、且つMCLAの機能を端子を持たせなければなりません。
プルアップにしました。
これなら、両方の機能を持たせられます。
そうなると、統一した方が分かり易いので、RA側は、全てプルアップに統一となりました。
プルアップの場合、SWがONで、端子は、Loとなる。
出力側は、プルダウン。
入力側が、SwがONの時、出力側端子はLEDがOn。この方がイメージが合う。
この時の端子の電位は
入力側はLoで出力側もLo(電流は、PICに流れる。)
イメージが合うんですよね。
追記
PICの電源にコンデンサを忘れました。
>学習ボートは使わないのですか?
あれには外部給電端子もついているので作る必要は無いと思います。
キットで遊ぼうのぼーどですか、
あのボードは、書き込みが不安定で使い物になりません。
購入当初も、電圧を4.75Vにしたりして、なんで5Vじゃダメなのと思ったりしていました。
そんな中、最近(MPLABのバージョンを最新にした。)は、書き込みが出来なくなり、壊れたと思い買い換えました。
それで、試しにと思って、書き込み専用ボードで書き込んでみると
安定して書きこめるようになりました。
PIC3の電流をLEDの方へ回すには限りがあるようです。
なので、書き込みとLEDなどへ回す電気とを分離して、書き込み専用のボードを作ることにしました。
プログラムをやっていて思っていたのですが、
例えば、
入力のSWをONで、出力LEDをHiとしますよね。
この場合、プルアップとプルダウンでの、
端子をHiにしたりLoにしたりの設定が分かりずらいと思っていました。
統一したらいいのにと思っていました。
PICの事が少しは分かってきたので、新たな視線で考えることにしました。←大袈裟(笑
写真は、今のプランです。LEDは、将来の事です。今は作りませんので、除いて見て下さい。
MCLAの端子は入力専用であり、且つ書き込み時には、PIC3に繋がっていなければならない。
書き込みが出来て、且つMCLAの機能を端子を持たせなければなりません。
プルアップにしました。
これなら、両方の機能を持たせられます。
そうなると、統一した方が分かり易いので、RA側は、全てプルアップに統一となりました。
プルアップの場合、SWがONで、端子は、Loとなる。
出力側は、プルダウン。
入力側が、SwがONの時、出力側端子はLEDがOn。この方がイメージが合う。
この時の端子の電位は
入力側はLoで出力側もLo(電流は、PICに流れる。)
イメージが合うんですよね。
追記
PICの電源にコンデンサを忘れました。
Re: PIC3ボード製作
確かに、プルダウン入力とアクティブハイでの出力は、感覚と一緒になります。
けれども、実際の素子や回路の状況でそれが変わるのは仕方がないことです。
それを避けるためには
#define Led_On 0
#define Led_Off 1
#define Sw_On 1
#define Sw_Off 0
等のように間違わないように、また書き換えも楽になるように工夫します。
> あのボードは、書き込みが不安定で使い物になりません。
それはボードのせいでは無いと思います。
それなりの数の購入者が居て、利用されているボードですから、
「書き込みが不安定」という反響がなければ、特にボードには問題は無いと推測します。
勿論、故障と言う事はあるでしょうけど。
「安定した書き込み」を第一に考えるなら、https://www.aliexpress.com/item//32949836067.html
のようなセッティングの楽な物を使う方が良いような気がします。
※これは配線だけを合わせるものです。それだけで多くの人が書き込んでいる実績があります。
第三者の視点で見ると、TRさんが作ろうとしているボードよりも、上記の2つのボードの方が信頼性が高いと言わざるを得ません。
けれども、実際の素子や回路の状況でそれが変わるのは仕方がないことです。
それを避けるためには
#define Led_On 0
#define Led_Off 1
#define Sw_On 1
#define Sw_Off 0
等のように間違わないように、また書き換えも楽になるように工夫します。
> あのボードは、書き込みが不安定で使い物になりません。
それはボードのせいでは無いと思います。
それなりの数の購入者が居て、利用されているボードですから、
「書き込みが不安定」という反響がなければ、特にボードには問題は無いと推測します。
勿論、故障と言う事はあるでしょうけど。
「安定した書き込み」を第一に考えるなら、https://www.aliexpress.com/item//32949836067.html
のようなセッティングの楽な物を使う方が良いような気がします。
※これは配線だけを合わせるものです。それだけで多くの人が書き込んでいる実績があります。
第三者の視点で見ると、TRさんが作ろうとしているボードよりも、上記の2つのボードの方が信頼性が高いと言わざるを得ません。
Re: PIC3ボード製作
キットで遊ぼうのボードで書き込みをしましたが、
やはり駄目でした。
自分のボードは故障していると思われます。
PIC3が故障しているようではないです。
今のところ、自作暫定ボードで書き損じはないので、
自作をやってみます。
やはり駄目でした。
自分のボードは故障していると思われます。
PIC3が故障しているようではないです。
今のところ、自作暫定ボードで書き損じはないので、
自作をやってみます。
Re: PIC3ボード製作
みなさんこんばんは。
お陰様で、書き込み専用ボード完成しました。
あたりまえでしょうけど、一発で書き込みが出来ました。
でも、キットで遊ぼうのボードでは、その当たり前が出来ませんでした
写真は、自作ボードで書き込んだ後の、書きこめたかどうかのテストです。
壊れていたキットで遊ぼうのボードは、最後の御奉公です。
11/26追記
No1246について
ボードが出来たので、内容を拝見しました。
間欠のプログラムを思い出しました ↓
#define On 1
#define Off 0
#define 略
#define 略
#define vacuum RA3 //掃除機出力
略
// 待ち時間関数
略
}
// メイン関数
void main (void){
略
// 永久ループ
while(1){
略
if(MODE==0||(MODE==3&&MACH_sig==0)){//OFF
略
vacuum=Off;
関連付けさせるには、#defaineを2つ必要なんですね。
プログラムにたけている人は違いますね。
お陰様で、書き込み専用ボード完成しました。
あたりまえでしょうけど、一発で書き込みが出来ました。
でも、キットで遊ぼうのボードでは、その当たり前が出来ませんでした
写真は、自作ボードで書き込んだ後の、書きこめたかどうかのテストです。
壊れていたキットで遊ぼうのボードは、最後の御奉公です。
11/26追記
No1246について
ボードが出来たので、内容を拝見しました。
間欠のプログラムを思い出しました ↓
#define On 1
#define Off 0
#define 略
#define 略
#define vacuum RA3 //掃除機出力
略
// 待ち時間関数
略
}
// メイン関数
void main (void){
略
// 永久ループ
while(1){
略
if(MODE==0||(MODE==3&&MACH_sig==0)){//OFF
略
vacuum=Off;
関連付けさせるには、#defaineを2つ必要なんですね。
プログラムにたけている人は違いますね。
- JoyfulNote v6.02 -
++ Edited by Hamel ++