概要
PIC16F88とMPLAB XC8 C Compilerを使用した開発例として,可変抵抗でLEDの輝度を制御するプログラムを紹介します. この開発例では,PIC16F88のA/D変換モジュールとCCPモジュールのPWMモードを使用しています. 開発環境は下記のとおりです.
PIC | PIC16F88-I/P |
---|---|
MPLAB X IDE | MPLAB X IDE v2.15 |
MPLAB XC8 | MPLAB XC8 C Compiler v1.32 |
PICkit 2 | MPLAB X IDEを使用して書込み |
回路
回路図
PICkit 2を使用してICSP (In Circuit Serial Programming)と電源供給を行うことを前提とした回路です. 今回は,これをブレッドボード上に組んで動作を確認しました.
電源はPICkit 2から5.0Vを供給しています. 内蔵クロックを使用するため,外部発振子は不要です. AN0に可変抵抗を接続し,RB3に電流制限用抵抗 330Ωを経由してLEDを接続しています.
回路部品
下表は使用部品表です.
番号 | 部品名 | 型番 | 数量 | 参考単価 |
---|---|---|---|---|
U1 | PICマイコン | Microchip PIC16F88-I/P | 1 | 200円 |
LED1 | LED | 各社 各色 | 1 | 10円 |
VR1 | 可変抵抗 | 各社 30kΩ B | 1 | 40円 |
R1 | 炭素皮膜抵抗 | 各社 1/4W 10kΩ | 1 | 1円 |
R2 | 炭素皮膜抵抗 | 各社 1/4W 330Ω | 1 | 1円 |
その他 | リード線など | 適量 |
プログラム
main.c
下記はソースファイル「main.c」です.参考になれば幸いです.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | #include <xc.h> #define _XTAL_FREQ 8000000 // 8MHz #define PR2_DATA 0xFF #define T2_DIV_BY_1 0b00000000 #define CCP_PWM 0b00001100 // 16F88 // CONFIG1 #pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTRC oscillator; port I/O function on both RA6/OSC2/CLKO pin and RA7/OSC1/CLKI pin) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled) #pragma config MCLRE = ON // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is MCLR) #pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled) #pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming) #pragma config CPD = OFF // Data EE Memory Code Protection bit (Code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off) #pragma config CCPMX = RB3 // CCP1 Pin Selection bit (CCP1 function on RB3) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) // CONFIG2 #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled) #pragma config IESO = OFF // Internal External Switchover bit (Internal External Switchover mode disabled) // プロトタイプ宣言 void setADCChannel(unsigned char channel); unsigned int readADCValue( void ); void initPWM1(unsigned char pr2, unsigned char t2ckps); void setPWM1Duty(unsigned int duty); void main( void ) { unsigned int duty1; OSCCON = 0b01110000; // 内蔵クロックの周波数を8MHzに設定 PORTA = 0x00; // PORTAを初期化 PORTB = 0x00; // PORTBを初期化 TRISA = 0b00000001; // PORTAの入出力設定 TRISB = 0b00000000; // PORTBの入出力設定 ANSEL = 0b00000001; // AN0を有効化 ADCON0 = 0b01000001; // Fosc/16, ADON ADCON1 = 0b11000000; // 右詰め, AVdd, AVss duty1 = 0; initPWM1(PR2_DATA, T2_DIV_BY_1); // CCP1をPWMモードに設定 // PWM周波数は約7.8kHz(計算式は下記) // PWM Frequency = 1 / ((PR2_DATA + 1) * 4 * (1 / _XTAL_FREQ)) setPWM1Duty(duty1); // デューティ値を初期化(10bit, 0-1023) while (1){ setADCChannel(0); // A/D変換対象チャンネルを設定 __delay_us(50); // アクィジション時間(50マイクロ秒) duty1 = readADCValue(); // A/D変換値を取得 setPWM1Duty(duty1); // A/D変換値をデューティ値に設定 } } /* * A/D変換対象チャンネル設定関数 * * 引数: * unsigned char channel A/D変換対象チャンネル * * 復帰値: * なし */ void setADCChannel(unsigned char channel) { ADCON0 &= 0b11000111; // CHS<2:0>を初期化 ADCON0 |= (channel << 3); } /* * A/D変換値取得関数 * * 引数: * なし * * 復帰値: * unsigned int A/D変換値(10bit, 0-1023) */ unsigned int readADCValue( void ) { GO_nDONE = 0b1; while (GO_nDONE); return ((ADRESH << 8) + ADRESL); } /* * CCP1モジュール PWM初期設定関数 * * 引数: * unsigned char pr2 PR2設定値 * unsigned char t2ckps プリスケーラ設定値 * * 復帰値: * なし */ void initPWM1(unsigned char pr2, unsigned char t2ckps) { PR2 = pr2; CCP1CON = CCP_PWM; setPWM1Duty(0); T2CON = t2ckps; T2CON |= 0x04; } /* * CCP1モジュール PWMデューティ値設定関数 * * 引数: * unsigned char pr2 PR2設定値 * unsigned char t2ckps プリスケーラ設定値 * * 復帰値: * なし */ void setPWM1Duty(unsigned int duty) { CCPR1L = duty >> 2; CCP1CON &= 0b11001111; CCP1CON |= 0b00110000 & (duty << 4); } |
0 件のコメント:
コメントを投稿