トピック関連記事
48時間以内の記事は New Mark で表示されます
TRISAとTRISB
maboさんこんばんは。

F1827お使いということでお聞きしたいことがあります。
TRISAを出力にして、TRISBを入力にした時
何か注意点はありますか?

というのも、タイマー0割込みで、上手くいった下記プログラムを使って、入力側と出力側を入れ替えたのですが、上手く動作しなくなりました。
お気づきの点がありましたら、教えてください。


// タイマー0割込みPIC16F1827 Configuration Bit Settings
//RA6 マッハからの信号 RB3SW ONで5秒間点灯
// '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;

}
}
}

// 割込みサービスルーチン

static void interrupt isr() {
if (RA6 == 0 && event == 0) {//もしRA6が押されていて、イベントが起きていなかったら
event = 1;
}
if(RA6==1&& event==1){//もしRA6が放されていて、イベントがまだやっていたら、enentフラグを0にする
event=0;

} // タイマ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; //全体割り込み許可
}
TR 2018/12/05(Wed) 21:12 No.1307
Re: TRISAとTRISB
TRさん,猛牛ロックさん,こんばんは。

TRさん,すみません,動かなくなった原因はちょっとわかりません。

それに1827使ったの大分前なので,忘れているところも多いのですが,思いついたこと書きます。

まず,event の変数は,mach からの信号で,信号が入るとLEDを点滅させる,というような動作のプログラムでしょうか。

 mach→RA6

 RB3→LED

でしょうか。

コメントには,スイッチの記載もあるようで,スイッチがONで,

machからの信号があった時だけ,LEDを5秒点灯でしょうか。

この辺がちょっ不明です。

この辺分からると私なりのプログラムはか書けそうですが。

ただ,TRさんのプログラムだと,LEDが5秒点灯するようにはなってない気がします。






私が以前はまったのは,ポートの操作を連続して行ったことが原因です。

次のような感じで,ポートの操作を連続でしました。

  RB4=1;
RB6=0;
RB7=0;
RA0=0;

これは,うまく動作しませんでした。対策はLATレジスタを使うか,間に,次のようになにもしない命令をいれるかでした。

  RB4=1;
  asm("nop");→何もしない休みの時間です。
RB6=0;
  asm("nop");
RB7=0;
  asm("nop");
RA0=0;
mabo   2018/12/05(Wed) 23:34 No.1308
Re: TRISAとTRISB
SWをしたらLEDが光る、と言う事なら間違いはありません。

っていうか、このプログラム自体は動いたプログラムで、これをポートABを入れ替える、と言う事ですね?

で、重要な事は、「PICはアナログ入力がデフォルト」という点です。なのでデジタル入力する為には
アナログ機能をオフにする必要があります。
デジタル出力に設定した場合は自動でデジタル出力になる(アナログ入力は1次的に無効)ので問題ないですけど
普通はmain関数の初期設定の部分でアナログ機能をオフにします。
他にも動かないものがあれば、GPIOになっていない、という部分をまず疑った方が良いです。

例えば、ポートA,B入れ替えて、内部プルアップするなら以下のプログラムです。
WPUB(個別の内部プルアップレジスタ)はデフォルトで有効(1)なので操作していません。
なので、他のポートBのピンも内部プルアップ有効状態です。

//上部略
void main(void) {
OSCCON = 0b01011010; // 内部クロック周波数を1MHzに設定
OPTION_REG = 0; //内部プルアップ有効

ANSELA = 0; //アナログ機能無効
ANSELB = 0;

LATA = 0; //ポートAはLOW出力
TRISA = 0x20; //RA6にLED
TRISB = 0xFF; //RB3にSW

while (1) {
LATA6 = !RB3;
}
}
猛牛ロック   2018/12/06(Thu) 01:47 No.1309
Re: TRISAとTRISB
maboさん,有難うございます。

>まず,event の変数は,mach からの信号で,信号が入るとLEDを点滅させる,というような動作のプログラムでしょうか。

 mach→RA6

 RB3→LED

でしょうか。


そうです。


>コメントには,スイッチの記載もあるようで,スイッチがONで,

machからの信号があった時だけ,LEDを5秒点灯でしょうか。


フライス盤のプローブ信号をmach(probeの設定端子 たしか、入力だったと思います。)送るです。


この流れを今回にあてあはめると。

RA6(SW=モーメンタリSW)→RB3(LED)です。


SW ON の時、LED発光する これだけです。
今のプログラムにはLEDが5秒点灯はないです。以下に至る途中は5秒点灯がありました。


>RB4=1;
RB6=0;
RB7=0;
RA0=0;

これは,うまく動作しませんでした。対策はLATレジスタを使うか,間に,次のようになにもしない命令をいれるかでした。

  RB4=1;
  asm("nop");→何もしない休みの時間です。
RB6=0;
  asm("nop");
RB7=0;
  asm("nop");
RA0=0


そうか、LATレジスタか。
TR   2018/12/06(Thu) 07:39 No.1310
Re: TRISAとTRISB
猛牛ロックさん、レスありがとうございます。

F1827の場合、猛牛ロックさんの言われたとおり、TRIS AとBを入れ替えると、
デジタル制御にしなければいけないんですね。
デジタル制御のプログラムを目にはしていたのですが、
F627Aで覚えた流儀でどこまでできるのかと思ってやっていました。
以後注意したいと思います。


タイマー0割込みで、フラグ操作をしました。
使い方としては、
割込みのきっかけを
RB3 == 0 && event == 0 //もしRA6が押されていて、イベントが起きていなかったら
としましたが、
event=RB3として、//SWが押された値がeventとしてフラグ操作をした方がいいのでしょうか?




それと、よく初期値で
端子の設定をALL0にしたりALL1にしたりありますが、
今回は、LATA = 0; //ポートAはLOW出力としましたが、
一般的には、初期値としては、どういった考えを持つのでしょうか?


しかし、自分の場合、F1827がいいのか、F627Aがいいのか迷います。
627Aで十分な感じがします。
627Aの時は、TRISAを入力にし、TRISBを出力にしても、今回のような問題はありませんでした。
やはり、動作速度の問題から、使い分けを考えるべきなのでしょうか?
それ以外にもあったら、簡単でいいから、例などを挙げて教えてください。
例えば、通信にはF1827とか。

追記
今F627Aデータシートを見て分かった。
F627AにはANSELレジスタがない、だからTRISAとTRISBのどちらを入力にしても出力にしても関係ないんだ。
F88は、ANSEL_REGがあったからこそ、ADCができるんだ。
そんなことを考える、F88以上かな。


// タイマー0割込みPIC16F1827 Configuration Bit Settings
//RA6 マッハからの信号 RB3 SW ONで点灯
// '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に設定
OPTION_REG = 0; //内部プルアップ有効
ANSELA = 0; //アナログ機能無効
ANSELB = 0;
LATA = 0; //ポートAはLOW出力
TRISA = 0x20; //RA6にLED
TRISB = 0xFF; //RB3にSW

// タイマ0割込み設定関数の呼び出し
InitInterTimer0();
// 割込み全体の許可
GIE = 1;
event = 0; //初期値イベント無しRB3ロー
// 永久ループ
while (1) {
if (event == 0) {
LATA6 = 0;
}
if (event == 1) {
LATA6 = 1;
}
}
}

// 割込みサービスルーチン

static void interrupt isr() {
if ( RB3 == 0 && event == 0) {//もしRA6が押されていて、イベントが起きていなかったら
event = 1;
}
if(RB3 ==1 && event==1){//もしRA6が放されていて、イベントがまだやっていたら、enentフラグを0にする
event=0;

} // タイマ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; //全体割り込み許可
}
TR   2018/12/06(Thu) 08:35 No.1311
Re: TRISAとTRISB
> SWが押された値がeventとしてフラグ操作をした方がいいのでしょうか?
フラグ操作は「必要に応じて」です。必要以上なら無駄で見通しも悪くなります。
int a=RA0;
int b=!a;
RA1=b;
としても、
RA1=!RA0;
でも同じことです。

if(RB3 == 0 && event == 0)event = 1;
if(RB3 ==1 && event==1)event=0;
こういった処理も意味がある場合と無い場合があります。

if(RB3 == 0 && event == 0){
event = 1;
LAT6=1;
__delay_ms(300);
LAT6=0;
}
if(RB3 ==1)event=0;
のような処理です。これは押されたら1パルス信号を送る(1回光らせる)例です。


例えば、
@SWを押した間は点灯、離したら消灯
ASWを押す度に点灯、消灯切り替え
BSWを押したら秒間点灯(ワンショット)
CSWを押した回数をカウント
で、対処も変わります。
フラグはその形跡が無くなって判断が付かない場合に、自分で印を残します。
@の場合はフラグが無い方が良いです。
A以降はフラグを残さないと判断が付きません。


> 一般的には、初期値としては、どういった考えを持つのでしょうか?
当然使うピンは使う設定にします。使わないピンはプルアップ無しの入力(HI-Z)が良いと思います。
でも、PIC流なら、初期値のアナログ入力、という事かもしれません。
出力にするのは何かとショートさせる危険性もありますからお勧めできません。

> 動作速度の問題から、使い分けを考えるべきなのでしょうか?
いいえ、今ならF1827一択です。
その質問は「WINDOWS 7のPCを買うか、WINDOWS8のPCを買うか?」という質問と似ています。
慣れの問題はありますけど、F1827の方が、価格、性能全てに上回っています。
(凡そ、どのマイコンでも出来ることはそれほど変わりませんけど、ADCの無いマイコンは論外です。
外付けにすれば、より難しくなります。
また、メモリも少なすぎます。まともなプログラムを組めるほどのメモリがありません。)
唯一、薦めるのは、使っていたマイコン(627A)が壊れて、そのプログラムが手元にある場合です。
F1827に慣れればF627Aは全く出番はありません。
更に言えば、F1827も決して新しいマイコンではありません。寧ろベテランの域です。


何か作るものを決めて、進めていった方が良いような気がします。
猛牛ロック   2018/12/06(Thu) 23:58 No.1312

処理 記事No 暗証キー

- JoyfulNote v6.02 -
++ Edited by Hamel ++