前提・実現したいこと
PIC16F886を利用してLEDを調光制御しつつシーケンシャルウィンカーのような動作をさせています。
具体的には、下記ポートにそれぞれLEDを接続し、それらを中央(LED7,8)から徐々に明るくさせながら外側(LED1,14)まで順番に点灯させる、といった動作をさせたいと考えております。
また、1つめのLEDが明るくなるまで(0⇒100%点灯)に100msかけるとすると、次に光るLEDは、前のLEDの明るさが50%になったタイミング(50ms)でONにしたいと考えています。
###ポート接続(LEDは上から順番に横並びで並べています)
PORTB0:LED1
PORTB1:LED2
PORTB2:LED3
PORTB3:LED4
PORTB4:LED5
PORTB5:LED6
PORTB6:LED7
PORTB7:LED8
PORTC0:LED9
PORTC1:LED10
PORTC2:LED11
PORTC3:LED12
PORTC4:LED13
PORTC5:LED14
発生している問題・エラーメッセージ
下記のプログラムを実行すると、PORTC側は明るく光るのですが、PORTB1~PORTB5までの5つのポートのみ他より暗く光ってしまいます。 これらはPICの設定の問題でしょうか?それともプログラムの書き方が良くないのでしょうか? LED1つずつを個別にPWM制御しながら、n秒で全点灯や、フェード等を実施するためにはもっと良い書き方があるのでしょうか? ご教授いただければ幸いです。
該当のソースコード
C言語(PIC,MPLABX,XC8)
1#include <stdio.h> 2#include <stdlib.h> 3#define LEDWAIT 20 4#define LEDWAIT1 50 5#define LEDWAIT2 100 6#define LEDWAIT3 500 7#define T0COUT 61 // タイマー0用カウントの初期値(256 - 195 = 61) 8 9// CONFIG1 PIC16f886 10#pragma config FOSC = INTRC_CLKOUT// Oscillator Selection bits (RC oscillator: CLKOUT function on RA6/OSC2/CLKOUT pin, RC on RA7/OSC1/CLKIN) 11#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register) 12#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT enabled) 13#pragma config MCLRE = OFF // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR) 14#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled) 15#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled) 16#pragma config BOREN = OFF // Brown Out Reset Selection bits (BOR enabled) 17#pragma config IESO = OFF // Internal External Switchover bit (Internal/External Switchover mode is disabled) 18#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled) 19#pragma config LVP = OFF // Low Voltage Programming Enable bit (RB3/PGM pin has PGM function, low voltage programming enabled) 20 21// CONFIG2 22#pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V) 23#pragma config WRT = OFF // Flash Program Memory Self Write Enable bits (Write protection off) 24 25// #pragma config statements should precede project file includes. 26// Use project enums instead of #define for ON and OFF. 27 28#include <xc.h> 29#include <htc.h> 30#define _XTAL_FREQ 8000000 31 32//int anodepinB[11] = { 0x07, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x38, 0xC0, 0x00 }; 33//int anodepinC[11] = { 0x00, 0x00, 0x01, 0x0F, 0x7F, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0x0E }; 34 35//int cathodepin[11] = { 0x40, 0x40, 0x40, 0x40, 0x40, 0x43, 0x7F, 0x00, 0x80, 0x80, 0x80 }; 36int cat = 0; 37int Count ; // タイマーの割込み発生回数をカウントする変数 38//int LEDflg ; // LEDのON/OFF状態フラグ 39int LedB6,LedB5,LedB4,LedB3,LedB2,LedB1,LedB0 ; //B6用PWM閾値 40 41 42void PICinit(){ 43 OSCCON = 0b01110000 ; // 内部クロックは8MHz 44 ANSEL = 0b00000000; // ANを全てオフ 45 TRISA = 0b00000000; // RAピンは全て出力 46 TRISB = 0b00000000; // RBピンは全て出力 47 TRISC = 0b00000000; // RC3/RC4は入力 48 PORTA = 0b00000000; //RA出力ピンを初期化(LOW) 49 PORTB = 0b00000000; //RB出力ピンを初期化(LOW) 50 PORTC = 0b00000000; // RC出力ピンを初期化(LOW) 51 OPTION_REG = 0b00000000 ; // デジタルI/Oに内部プルアップ抵抗を使用する 52 53 return; 54} 55 56// タイマー割込みの処理 57void __interrupt() InterTimer( void ) 58{ 59 if (TMR2IF == 1) { // タイマー2の割込み発生か? 60 Count++ ; // 割込み発生の回数をカウントする 61 TMR2IF = 0 ; // タイマー2割込フラグをリセット 62 if (Count < LedB6) { // 割込みを125回カウントすると約1秒 63 RB6 = 1; 64 RB7 = 1; 65 }if(Count < LedB5){ 66 RB5 = 1; 67 RC0 = 1; 68 }if (Count < LedB4) { // 割込みを125回カウントすると約1秒 69 RB4 = 1; 70 RC1 = 1; 71 } 72 if(Count < LedB3){ 73 RB3 = 1; 74 // RC2 = 1; 75 }if(Count < LedB2){ 76 RB2 = 1; 77 RC3 = 1; 78 }if(Count < LedB1){ 79 RB1 = 1; 80 RC4 = 1; 81 }if(Count < LedB0){ 82 RB0 = 1; 83 RC5 = 1; 84 }else{ 85 PORTB = 0x00; 86 PORTC = 0x00; 87 } 88 Count++; 89 if(Count == 100){ 90 Count = 0; 91 } 92 } 93} 94 95int main(void){ 96 PICinit(); //PICを初期化 97 // カソードのループ 98 unsigned short int i; 99 T2CON = 0b00000101 ; // TMR2プリスケーラ値を64倍、ポストスケーラ値は1:1の設定 100 PR2 = 249 ; // タイマーのカウント値を設定 101 TMR2 = 0 ; // タイマー2の初期化 102 Count = 0 ; // 割込み発生の回数カウンターを0にする 103 104 TMR2IF = 0 ; // タイマー2割込フラグを0にする 105 TMR2IE = 1 ; // タイマー2割込みを許可する 106 PEIE = 1 ; // 周辺装置割り込み有効 107 GIE = 1 ; // 全割込み処理を許可する 108 109 //LEDflg = 0 ; // LEDのフラグ状態をOFFとする 110 111 while(1){ 112 113 for(i=0; i<=80;i++){ 114 if (i <= 10){ 115 LedB6 = i*5; 116 LedB5 = 0; 117 LedB4 = 0; 118 LedB3 = 0; 119 LedB2 = 0; 120 LedB1 = 0; 121 LedB0 = 0; 122 }else if (i > 10 && i<= 20){ 123 LedB6 = i*5; 124 LedB5 = (i*5)-50; 125 LedB4 = 0; 126 LedB3 = 0; 127 LedB2 = 0; 128 LedB1 = 0; 129 LedB0 = 0; 130 }else if (i > 20 && i<= 30){ 131 LedB6 = 100; 132 LedB5 = (i*5)-50; 133 LedB4 = (i*5)-100; 134 LedB3 = 0; 135 LedB2 = 0; 136 LedB1 = 0; 137 LedB0 = 0; 138 }else if (i > 30 && i<= 40){ 139 LedB6 = 100; 140 LedB5 = 100; 141 LedB4 = (i*5)-100; 142 LedB3 = (i*5)-150; 143 LedB2 = 0; 144 LedB1 = 0; 145 LedB0 = 0; 146 }else if (i > 40 && i<= 50){ 147 LedB6 = 100; 148 LedB5 = 100; 149 LedB4 = 100; 150 LedB3 = (i*5)-150; 151 LedB2 = (i*5)-200; 152 LedB1 = 0; 153 LedB0 = 0; 154 }else if (i > 50 && i<= 60){ 155 LedB6 = 100; 156 LedB5 = 100; 157 LedB4 = 100; 158 LedB3 = 100; 159 LedB2 = (i*5)-200; 160 LedB1 = (i*5)-250; 161 LedB0 = 0; 162 }else if (i > 60 && i<= 70){ 163 LedB6 = 100; 164 LedB5 = 100; 165 LedB4 = 100; 166 LedB3 = 100; 167 LedB2 = 100; 168 LedB1 = (i*5)-250; 169 LedB0 = (i*5)-300; 170 }else { 171 LedB6 = 100; 172 LedB5 = 100; 173 LedB4 = 100; 174 LedB3 = 100; 175 LedB2 = 100; 176 LedB1 = 100; 177 LedB0 = (i*5)-300; 178 } 179 __delay_ms(10); 180 } 181 }return 0; 182} 183
試したこと
①動作はブレッドボード上で行っておりますが、ブレッドボードの接触不良等ではないことを確認済みです。(ほかのポートにさしても明るいポートとくらいポートは変わらなかったため)
②マイコンの内部プルアップ機能を有効にしているのが原因かと思い、無効にしたりしてみましたがだめでした。
③PORTBをPORTAに変更するときちんと明るく動作しますが、他の接続の関係でピン数が足りないため、PORTBを明るくして対応したいです。
補足情報(FW/ツールのバージョンなど)
MPLABX,Pickit3,xc8コンパイラを利用しています。
回路的には、よくある、マイコン⇒トランジスタ⇒LEDといったスイッチングの回路になっています。すべてのポートに対して回路構成は同じですが、マイコンの各ポートの機能やその設定によっておきてしまっている不具合なのでしょうか?
タイマーと干渉している可能性はあるかも、と思ったのですが私にはわかりませんでした・・・
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。