PIC18F26K22でLEDちかちか 味見

 2013-08-21
これまで8pinのPICで遊んだりしていましたが、そろそろpin数の多いPICも遊んでみましょうと、
取り出したるは遙か昔(?)に買ってあったPIC18F26K22です。

 
PIC18F26K22は64KByteのFlashを持ち、どんなタコなコードでも食べてくれそうな頼もしい石である。
その他の大まかな機能としては、3.8KByteのRAM、1KByteのEEPROM、ADCは19ch、8bitタイマが3ch、16bitタイマが4ch、あとはCCPやSPI,I2C等が載っています。


まずはこのPIC18F26K22を使って、HelloWorld的な「LEDちかちか」をやってやります。
ただし、デフォルトの設定のままホイホイとPORTを弄るだけでは能がありませんので、これまで使ったことのないPLLを使ってみます。

LED一粒でちかちかさせてもいいのですが、折角なのでPORTAの8bit分のLEDを接続しました。
LEDを除けば、PIC本体と電源のパスコン一つだけです。さすがですね。PICの左下のほうにすこし配線してあるのはプログラム書込み用のICSPです。
DSC_2126.jpg 実験用

PIC18F26K22は内蔵オシレータを3つ持っているらしい。16MHzのHFINTOSCと500KHzのMFINTOSC、それから31.25kHzのLFINTOSCです。どのクロックもCPUの動作クロックとして使用出来ます。その他、それらを分周した16,8,4,2,1MHz、500,250,31.25KHzが使用可能です。
内蔵以外だと水晶やセラロック、弛緩発振などいくつか使えますが、その分pinを使用するので今回は内蔵オシレータを使います。とりあえず最高速の16MHzにします。

そしてさらにPLLも掛けます。今回のPLLは4逓倍固定ですので面倒なPLLの設定は不要です。「PLLを使いますよ」という経路を選択してやればそれでいいのです。楽ちん。
PICは4サイクルで1命令なので、PLLも4逓倍のほうがわかりやすいみたいですね。

pic18f26k22_clk.jpg ←今回の経路(赤字) 4箇所のレジスタ(青字)で指定します

まぁこう書いてしまうと簡単ですが、実はFOSCの設定値で小一時間ハマっておりました。
ユーザーマニュアルには FOSC=0b1000 で内部OSCを使うとなっているのでそのようにプログラムにぶち込んだんです。
#pragma config FOSC = 0b1000

これだと動きませんでしたねハハハ。ライブラリのマニュアルを参照すると、どこぞで定義されたのかもしれないよくわからないシンボルで定義してよ、と書いてありました。その通りにしたらすんなり動いた。はぁ~。最初のうちはこういうのがあるからねぇ~。 ユーザーマニュアルに書いてあったのは何なんだ。
下記のようにするといいです。
#pragma config FOSC  = INTIO67



遠回りといえども理解するには実際やってみるのが一番なので、ユーザーマニュアルを観ながらレジスタを一つ一つ確認していく方法でズンドコ書いていきました。
まぁ躓いたのはFOSCの部分で他はマニュアル見ながら普通にいけました。

#include <xc.h>

#pragma config FCMEN = OFF // not use Fail-Safe Clock Monitor
#pragma config IESO = OFF // not use Internal-External swithover mode
#pragma config PRICLKEN=ON // Primary Clock is always enabled
#pragma config PLLCFG= ON // PLL is ON
#pragma config FOSC = INTIO67 // INTOSCIO ( use INTOSC )
#pragma config BORV = 250 // Vbor set 2.5V
#pragma config PWRTEN= ON // USE Power-up Timer
#pragma config WDTPS = 32768 // WDT postscaler 1:32768
#pragma config WDTEN = OFF // WDT hardware disabled
#pragma config MCLRE = INTMCLR // use RE3 input
#pragma config P2BMX = PORTC0 // CCP2MUX is on RC0(wtf?)
#pragma config T3CMX = PORTC0 // T3CKI is on RC0(wtf?)
#pragma config HFOFST= OFF // wait for HFINTOSC is stable
#pragma config CCP3MX= PORTC6 // CCP3 in/out is multiplexed with RC6(wtf?)
#pragma config PBADEN= OFF // ANSELB resets to 0(PORTB set as GPIO on reset)
#pragma config DEBUG = OFF // USE RB6,7 as GPIO
#pragma config LVP = ON // Single-Supply ICSP enabled
#pragma config STVREN= ON // Stack Full/Underflow Reset enable
#pragma config CP3 = OFF // NOT USE CodeProtection
#pragma config CP2 = OFF // NOT USE CodeProtection
#pragma config CP1 = OFF // NOT USE CodeProtection
#pragma config CP0 = OFF // NOT USE CodeProtection
#pragma config CPD = OFF // NOT USE DataProtection
#pragma config CPB = OFF // NOT USE BootblockProtection
#pragma config WRT3 = OFF // NOT USE WriteProtection
#pragma config WRT2 = OFF // NOT USE WriteProtection
#pragma config WRT1 = OFF // NOT USE WriteProtection
#pragma config WRT0 = OFF // NOT USE WriteProtection
#pragma config WRTD = OFF // NOT USE WriteDataProtection
#pragma config WRTB = OFF // NOT USE WriteBootblockProtection
#pragma config WRTC = OFF // NOT USE WriteConfigurationregisterProtection

#define WAIT_MS 500

int sysinit();
int wait_ms(unsigned int);

/*
*
*/
int main() {
unsigned char cnt=0;
sysinit();

if(0){
cnt=0xff;
while(1){
cnt=(cnt<<1)+1;
if(cnt==0xff){ PORTA=cnt;wait_ms(1500);cnt=0xfe; }
PORTA=cnt;
wait_ms(500);
}
}else{
cnt=0x0;
while(1){
cnt=(cnt<<1);
if(cnt==0x00){ PORTA=cnt;wait_ms(1500);cnt=0x01; }
PORTA=cnt;
wait_ms(500);
}
}

return (EXIT_SUCCESS);
}

int sysinit(){
//setting CLK
OSCCONbits.IRCF = 0b111; // INTOSC 16MHz
OSCCONbits.SCS = 0b00; // USE PLL
OSCTUNEbits.PLLEN = 0b1; // PLL enable

//setting PORTA
PORTA=0x0; //PORTA init
ANSELA=0x0; //NOT USE ANALOGINPUT
CM1CON0=0x0; //NOT USE CMP1
CM2CON0=0x0; //NOT USE CMP2
VREFCON1=0x0; //NOT USE VREF(setting to Vref=Vdd,Vss)
VREFCON2=0x0; //NOT USE VREF
HLVDCON=0x0A; //set default(HLVDL=0b1010, HLVD=3.65V)
SLRCON=0x1F; //set default(PORTA,B,C slew at a limited rate)
SRCON0=0x0; //NOT USE SR latch
SSP1CON1=0x0; //NOT USE SPI
T0CS=0b0; //NOT USE T0CKI as TMR0 CLK source
TRISA=0x0; //PORTA set all output

//setting PORTB
PORTB=0x0; //PORTB init
ANSELB=0x0; //NOT USE ANALOGINPUT
ECCP2AS&=0b1100;//NOT USE CCP2
CCP2CON=0; //NOT USE CCP2
ECCP3AS&=0b1100;//NOT USE CCP3
CCP3CON=0; //NOT USE CCP3
INTCON=0; //DISABLE INT
INTCON2=0; //DISABLE INT
INTCON3=0; //DISABLE INT
IOCB=0; //DISABLE INT
T1GCON=0; //NOT USE TMR1
T3CON=0; //NOT USE TMR3
T5GCON=0; //NOT USE TMR5
TRISB=0; //PORTB set all output
WPUB=0; //DISABLE pullup

//setting PORTC
PORTC=0x0; //PORTC init
ANSELC=0x0; //NOT USE ANALOGINPUT
ECCP1AS&=0b1100;//NOT USE CCP1
CCP1CON=0; //NOT USE CCP1
CTMUCONH=0; //NOT USE CTMU
RCSTA1=0; //Serial port disabled
T1CON=0; //NOT USE TMR1
T3CON=0; //NOT USE TMR3
T3GCON=0; //NOT USE TMR3
T5CON=0; //NOT USE TMR5
TRISC=0; //PORTB set all output

return(EXIT_SUCCESS);
}

int wait_ms(unsigned int wait){
unsigned int cnt=0;
unsigned int i =0;
for(cnt=0; cnt <= wait ; cnt++){
for(i=0; i <= WAIT_MS; i++){ ; }
}
}

sysinit()でとりあえず今回使うPORT周辺のレジスタを叩いています。
初期値のママで問題ないものも多いですが、とりあえずマニュアルで「こいつら関係してるから注意な」と書かれていたレジスタを列挙してあります。

具体的な動作としては、ポートAを8bit使ってbitwalkさせています。
if文の切り替えでその反転もできるように書きました。

下の動画の途中で反転させたコードをPICkit3で書き込んで動作させています。





なんとかPLL動かせてよかったよかった。

 
コメント












管理者にだけ表示を許可する
トラックバック
トラックバックURL:
http://wbbwbb.blog83.fc2.com/tb.php/129-7800972d
≪ トップページへこのページの先頭へ  ≫