picマイコンの使い方

PICマイコンの8bitマイコンから32bitマイコンまで使いこなすぞ! 周辺機能やアセンブラ、C言語を使いこなすぞ。ARMには負けないぞ! 頼みの綱はPIC32MZだ!たのしみだなー

TIMER

【PIC32MX370F512H】タイマーを使ってみる。


◆今回はPIC32MX370F512Hのタイマーを使ってみます!
2種類のタイマーがあり、
・タイマーAは16bitタイマー。
・タイマーBは16/32bitいずれかを選択できるタイマー。T32bitで選択
今回はタイマーAの16bitタイマーを使ってみます。


1)参照
リファレンスマニュアルDS61105F_JPを参照しました。
設定は16bitPICとほとんど変わりありません。
以前作成した記事

【dsPIC33FJ128MC802】タイマー機能を使ってみる。
をそのまま流用しました。

2)クロックについて
・クロックのソースはシステムクロックではなくペリフェラルクロックなので注意が必要です。
今回はコンフィグレーションで「システムクロックの1/2設定」としました。
 FPBDIV = DIV_2


3)T1CONレジスタ

ほとんどのbitは「0」でOKです。

①TimerONbitの設定:タイマ有効

「T1CONbits.ON = 1」

1でタイマが有効となります。

②TCKPSbitの設定:タイマ入力クロックのプリスケール

「 T1CONbits.TCKPS = 0b00;」

00は「1:1」となります。





4)プログラム

10msec毎にポートDのbit9をパタパタさせます。

システムクロックは、外付けセラロック10MHzを1/2で5MHzを入力し

PLLで24倍して100MHzにしてます。

2014/9/21:訂正)

システムクロックは内部発振8MHzを1/2で4MHz入力して

PLLで24倍だから96MHz。

タイマークロックソースはペリフェラルクロックを用います。

ペリフェラルクロックはシステムクロックを1/2しましたので48MHzとなります。

#include <stdio.h>
#include <plib.h>
#include <p32xxxx.h>
#include <stdlib.h>
#include "my_header.h"
//== configuration
//== OSC:8MHz SYSCLK:80MHz= OSC_8/PLLI_2=4MHz*MUL_20 ====================
#pragma config FNOSC=FRCPLL //Oscillator_selection_bits(FNOSC)
#pragma config POSCMOD=OFF //secondary_Oscillator_Enable(FSOSCEN)
//#pragma config FNOSC=PRIPLL //Oscillator_selection_bits(FNOSC)
//#pragma config POSCMOD=XT //secondary_Oscillator_Enable(FSOSCEN)
#pragma config FPLLMUL=MUL_24 //PLL_Multiplier(FPLLMUL)
#pragma config FPLLIDIV=DIV_2 //PLL_input_driver(FPLLIDIV)
#pragma config FPLLODIV=DIV_1 //PLL_output_clock_divider(FPLLODIV)
#pragma config FPBDIV=DIV_2 //Peripheral_clock_divisor(FPBDIV)
#pragma config FSRSSEL = PRIORITY_7 //shadow_register_set_priority_select(FSRSSEL)
#pragma config PMDL1WAY = OFF //peripheral_module_disable_configuration(PMDL1WAY)
#pragma config IOL1WAY = OFF //peripheral_pin_select_configuration(IOL1WAY)
#pragma config FSOSCEN = OFF //secondary_oscillator_enable(FSOCEN)
#pragma config IESO = OFF //internal_external_switch_over(IESO)
#pragma config OSCIOFNC = OFF //CLKO_output_signal_active_on_the_OSCO_pin(OSCIOFNC)
#pragma config FCKSM = CSDCMD //clock_switching_and_monitor_selection(FCKSM)
#pragma config WINDIS = OFF //watchdog_timer_is_in_non-window_mode(WINDIS)
#pragma config FWDTEN=OFF //watchdog_timer_window_enable(FWDTEN)
#pragma config DEBUG = OFF //debugger_is_disable(DEBUG)
#pragma config JTAGEN = OFF //JTAG_disable
#pragma config ICESEL=ICS_PGx3 //ICE_ICD_Comm_channel_select(ICESEL)
#pragma config PWP = OFF //program_flash_write_protect(PWP)
#pragma config BWP = OFF //boot_flash_write_protect_bit(BMP)
#pragma config CP = OFF //code_protect(CP)
//== function_prototype ====================================================

//== array_initialize ==================================================
unsigned char string_box1[15] = "abcdefg¥r¥n" ;
unsigned char rev_data[] = "----¥r¥n"; //UART_receive_string
unsigned char tes_d[49000];
//== main_function ====================================================
int main(void) {
//== OSC =================================================
SYSTEMConfigPerformance(96000000); //system_clock_96MHz
//== JTAG ================================================
//DEVCFG0bits.JTAGEN = 0; //JtagDisable
CFGCONbits.JTAGEN = 0; //JtagPortDisable
//== PORT ================================================
TRISB = 0x00000000;
TRISC = 0x00000000;
TRISD = 0x00000000;
TRISE = 0x00000000;
TRISF = 0x00000000;
TRISG = 0x00000000;
ANSELB = 0x00000000;
ANSELC = 0x00000000;
ANSELD = 0x00000000;
ANSELE = 0x00000000;
ANSELF = 0x00000000;
ANSELG = 0x00000000;
//== T1CON ===============================================
T1CON = 0x00000000; //Clear
T1CONbits.TON = 0; //<15>Timer1_OFF
T1CONbits.TSIDL = 1; //<13>Idelmode:SleepStop
T1CONbits.TGATE = 0; //<7>Gatetime:OFF
T1CONbits.TCKPS = 0B00; //PS1:1
T1CONbits.TCS = 0; //ClockSource:INT
IEC0bits.T1IE = 0; //Interrupt:disable
IPC1bits.T1IP = 0; //InterruptLevel:0
//== Interrupt ENABLE ===========================================
//INTCONbits.MVEC = 1; //Multi_Vector
//asm volatile("ei"); //Enable_Interrup
//== preprocessing ==============================================
//== while ======================================================
while(1)
{
LATDbits.LATD9 = !LATDbits.LATD9;
delay_ms(10);
}//while(1)
}//int main(void)

//== delay_us ==============================================================
void delay_us(unsigned int usec)
{
TMR1 = 0; //TMR1=0
T1CONbits.TON = 1; //Timer1_start
PR1 = 47; //
unsigned int i;
for(i=0; i<usec; i++)
{
while(!IFS0bits.T1IF); //Timer1Interrupt(IFS0bits.T1IF==0)
IFS0bits.T1IF = 0; //InterruptFlagDown
}//for(i=0; i<usec; i++)
}//void delay_us(unsigned int usec)
//== delay_ms ==============================================================
void delay_ms(unsigned int msec)
{
unsigned int i;
for(i=0; i<msec; i++)
{
delay_us(1000); //call:1000usec
}//for
}//void delay_ms(unsigned int msec)

//== end ==============================================================







5)出力波形の確認

PIC32MX370F512Hでタイマ


ピンク色の波形が出力波形です。

ちゃんと10msec毎に出力が切り替わってます。

一応成功みたい。








【PIC24EP64GP202】実質35Mips!?


PIC24EP64GP202を70Mipsで使ってみたけど
実質35Mipsで動作しているようです・・・
以前40Mipsの動作確認したFJ/HJファミリと比較したいと思います。



1)1命令1サイクル!?
マイクロチップのサイトにあるリファレンスマニュアルを参照しました。
①dsPIC33E/PIC24Eファミリリファレンスマニュアル セクション2.CPU:DS70359B_JP
page31の2.8.1:「1命令ワード(word)/1命令サイクル(cycle)」を見てみると・・・
badde6ba.png
あれ!?3つの命令に6サイクルもかかっている!?
ってことは、1命令に2サイクル掛ってるじゃないか!?
全然70Mipsじゃないね!?
実質35Mipsってことになるよ。。。
前回の記事ポートをパタパタしても33MHzだったんだね。

つづいてFJ/Hファミリーは・・・
②dsPIC33FJファミリリファレンスマニュアル セクション2.CPU:DS70204B_JP
page30の2.8.1:「1命令ワード(word)/1命令サイクル(cycle)」を見てみると・・・
0edd779b.png
3つの命令に3サイクルかかっているので
1命令1サイクルですね。安心して40Mipsであることがわかりますね。

2)まとめ
誰か!お前間違っていると言ってくれ!
70Mipsで動かしたよって情報あったらお願いします。

【PIC24EP64GP202】70Mipsで使ってみたけど・・・


◆PIC24EP64GP202を70Mipsで使ってみます。
dsPIC33FJ/PIC24HJファミリに非常に近いのでコードや回路はそのまんま流用できそうです。



0)調達
チップワンストップさんで購入しました。
・型番:PIC24EP64GP202-I/SP
実験のしやすいDIPタイプにしました。
・金額:¥533円
価格的には非常にやすいです。

1)参考資料
マイクロチップのサイトからリファレンスマニュアルをダウンロードしました。
①dsPIC33E/PIC24Eファミリリファレンスマニュアル セクション7.オシレータ:DS70580B_JP
page25:「7.37 MHz内部FRCにPLLを併用する場合のサンプルコード」を参照しました。
サンプルコードは60mipsですが、70MIPSに変更しました。
②dsPIC33FJ128MC802を40mipsで動かした時の記事がそのまま流用できます。
詳細はこちらから。
レジスタの扱いや式をまとめてあります。

2)開発環境
MPLAB-IDEではダメそう・・・
プロジェクトのターゲットデバイスには「PIC24EP64GP202」がちゃんとありますが
「p24EP64GP202.h」(ヘッダーファイル)がサポートフォルダには入っていません。
厄介なことにMPLAB-IDEではPIC24EP64GP202は開発できないようです。
どうしてもMPLAB-Xは使いたくなかったんですが・・・
(年をとると新しいことがやりづらくなるんだよね)
とはいってもしょうがないのでMPLAB-Xをインストールしてプロジェクト立ち上げ!

3)ソース
サンプルコードは60mipsですが、70MIPSに変更しました。
具体的には
・60mips「PLLFBDbits.PLLDIV=63」
 ↓
・70mips「PLLFBDbits.PLLDIV=73」
動作確認としてPORTBのbit6をパタパタ4回やってみました。
//=========================================================
// TEST
//=========================================================
//== include ============================================
#include <p24Exxxx.h>
#include <stdio.h>

//== define =============================================================

//== configuration ======================================================
//== FGS ==================================================
#pragma config GWRP=OFF //User program memory is not write-protected
#pragma config GCP=OFF //General Segment Code protect is Disabled
//== FOSCSEL ==============================================
#pragma config FNOSC=FRCPLL //Internal Fast RC (FRC) w/ PLL
#pragma config IESO=OFF //Start-up device with user-selected oscillator source
//== FOSC =================================================
#pragma config FCKSM=CSECMD //Both Clock Switching and Fail-Safe Clock Monitor are disabled
#pragma config IOL1WAY=ON // Allow Only One Re-configuration
#pragma config OSCIOFNC=ON //OSC2 pin has digital I/O function
#pragma config POSCMD=NONE //Primary Oscillator Disabled
//== FWDT ===============================================
#pragma config FWDTEN=OFF //Watchdog timer enabled/disabled by user software
//== FPOR ================================================
#pragma config WDTWIN=WIN25 //WDT Window is 50% of WDT period
#pragma config ALTI2C1=OFF //I2C1 mapped to SDA1/SCL1 pins
#pragma config ALTI2C2=OFF //I2C2 mapped to SDA2/SCL2 pins
//== FICD ===========================================
#pragma config ICS=PGD3 //PGD3_use
#pragma config JTAGEN=OFF //jtag=off
//== interrupt_function_prototype ================================================

//== StringBox ===================================================================


//== main ==================================================================
int main(void)
{
//== Fcy=Fosc/2=7.37M*((PLLFBD+2)/(N2*N1))/2=69.09MHz ================
PLLFBDbits.PLLDIV = 73; //<8:0>M=PLLFBD+2
CLKDIVbits.DOZE = 0b000; //<14:12>Fcy*1
CLKDIVbits.FRCDIV = 0b000; //<10:8>FRC*1
CLKDIVbits.PLLPOST = 0; //<7:6>N2=2
CLKDIVbits.PLLPRE = 0; //<4:0>N1=2
OSCTUNbits.TUN = 0b00000; //<5:0>FRC+0MHz
__builtin_write_OSCCONH(0x01);
__builtin_write_OSCCONL(0x01);
while(OSCCONbits.COSC != 0b001);
while(OSCCONbits.LOCK != 1); //wait for PLL Lock
//== AD_PORT ==========================================================
ANSELA = 0x0000;
ANSELB = 0x0000;
//=== TRISA ===========================================================
TRISA = 0x0000; //initial_
//== TRISB =============================================================
TRISB = 0x0000; //input:
//== while(1) ==============================================================
while(1)
{
//== FRONT_DEBUG =======================================================
asm("BSET LATB, #6");
asm("BCLR LATB, #6");
asm("BSET LATB, #6");
asm("BCLR LATB, #6");
asm("BSET LATB, #6");
asm("BCLR LATB, #6");
asm("BSET LATB, #6");
asm("BCLR LATB, #6");
//== BACK_DEBUG =======================================================
}//while(1)
}//int main(void)


//========================================================================

//=================================================================================


4)オシロの波形
あれ!?1サイクル33.33MHz(70/2≒35MHz)だと!?
次回は「PIC24EPは実質35mipsじゃないか!?」となります。
bd4339b4.png


5)回路図
c1edb830.png


【dsPIC33FJ128MC802】タイマー機能を使ってみる。(LEDピカピカ)


◆dsPIC33FJ128MC802でタイマー機能を使ってみます。
delay関数の元になってもらいたいと思います。



1)タイマー機能
リファレンスマニュアル70205C参考にトライしました。
dsPIC33FJ128MC802は、それぞれA,B,Cの3種類のタイマー機能をもってます。
Aタイプ:TIMER1
Bタイプ:TIMER2、TIMER4
Cタイプ:TIMER3、TIMER5
いずれも16bitタイマーですが、BとCは連結し32bitにすることが出来ます。
32bitタイマーの組み合わせは下記の通りです。
・TIMER2+TIMER3
・TIMER4+TIMER5

2)レジスター設定
制御レジスターTxCON、カウンタレジスタTMRx、周期レジスタPRxの3つを設定します。
PR1とTMR1が一致したらT1IFbitがセットされことを利用したいと思います。

・T1CON1レジスタの設定
・PS(プリスケーラー)を1:1で設定しました。
長い時間をカウントさせたい場合はより多くの分周が必要になりますね。

・TMR1レジスタの設定
TMR1には0を代入しました。

・PR1レジスタの設定
周期レジスターPR1に代入する値を検討したいと思います。
生成したい時間1μsecまでTMR1には何カウントしてもらえばよいのでしょうか?
39.61MPISの場合、1サイクルにかかる時間は「0.025μsec」なので
1μsec=0.025μsec×PS×カウント数  という式が導けますね。
変形して・・・
カウント数=(1μsec/0.025μsec×1)-1※
(※カウンターは「0」からなので-1する。)
これをPR1に代入します。

3)プログラム例
プログラムの例はこちら↓
1sec毎にLEDがピカピカです。

//=========================================================
// TEST
//=========================================================
//== ヘッダファイル ============================================
#include <p33fj128mc802.h>
#include <stdio.h>

//== define ===========================================================

//== configuration ======================================================
_FBS(BSS_NO_FLASH & BWRP_WRPROTECT_OFF);
_FGS(GSS_OFF & GCP_OFF & GWRP_OFF);
_FOSCSEL(FNOSC_FRCPLL & IESO_OFF);
_FOSC(FCKSM_CSDCMD & IOL1WAY_ON & OSCIOFNC_ON & POSCMD_NONE);
_FWDT(FWDTEN_OFF);
_FPOR(FPWRT_PWR128 & ALTI2C_OFF);
_FICD(JTAGEN_OFF & ICS_PGD1);
//== interrupt_function_prototype ================================================

//== MyTimer =====================================================================
void delay_us(unsigned int usec); //Timer1を利用したusec関数
void delay_ms(unsigned int msec); //msec関数
//== main ==================================================================
int main(void)
{
//== クロックの設定 ======================================================
//== Fcy=Fosc/2=7.37M*((PLLFBD+2)/(N2*N1))/2=39.61MHz ================
CLKDIVbits.PLLPOST = 0; //N2=2
CLKDIVbits.PLLPRE = 0; //N1=2
PLLFBDbits.PLLDIV = 41; //M=PLLFBD+2
//== ウォッチドック設定 ====================================================
RCONbits.SWDTEN = 0; //OFF
//== AD切り替え ==========================================================
AD1PCFGL = 0xffff; //全digital
//=== TRISA ===========================================================
TRISA = 0x0000; //initial_
//== TRISB =============================================================
TRISB = 0x0000; //input:

//== TIMER1設定 =========================================================
T1CONbits.TON = 0; //15_Timer1_OFF
T1CONbits.TSIDL = 1; //13_アイドルモード:Sleep中は停止
T1CONbits.TGATE = 0; //6_ゲート積算時間:OFF
T1CONbits.TCKPS = 0B00; //5-4_PS1:1
T1CONbits.TCS = 0; //2_クロックソース:内部
IEC0bits.T1IE = 0; //割り込み拒否
IPC0bits.T1IP = 0; //優先レベル0
//== 前処理 ======================================================

//== while文 ===========================================================
while(1)
{
//== 前段デバック =======================================================
LATAbits.LATA3 = !LATAbits.LATA3;
delay_ms(1000);
//== 前段デバック =======================================================
}//while(1)
}//int main(void)


//== delay_us関数 =================================================================
void delay_us(unsigned int usec)
{
TMR1 = 0; //TMR1=0
T1CONbits.TON = 1; //Timer1_start
PR1 = 39; //PR1値:((目的値1usec)/(1サイクル:0.0025usec*PS)-1)=39
unsigned int i;
for(i=0; i<usec; i++)
{ //タイマーフラグ待ち
while(!IFS0bits.T1IF); //Timer1一致フラグチェック(IFS0bits.T1IF==0)
IFS0bits.T1IF = 0; //一致フラグ下ろす
}//for(i=0; i<usec; i++)
}//void delay_usec();
//== delay_ms関数 ==================================================================
void delay_ms(unsigned int msec)
{
unsigned int i;
for(i=0; i<msec; i++)
{
delay_us(1000); //call:1000usec
}//for
}//void delay_ms

//=================================================================================




4)回路図はこちら
RA3にLEDをつければピカピカですね。
3e3e90a7.png

TIMER0の書き留め事項

TIMER0について

・TMR0の初期値

→フラグがたつと割り込む。

でなにかする。


ギャラリー
  • 【PIC32MZ2048ECH144-I/PH】PIC32MZ2048ECH144を買いました!
  • 【PIC32MX370F512H】タイマーを使ってみる。
  • 【dsPIC33FJ128MC802】PMP接続のDMA転送でaitendoの1.44インチ液晶TFT(ZY-FGD)を使ってみる。その3
  • 【dsPIC33FJ128MC802】PMP接続のDMA転送(連続転送)でaitendoの液晶を使ってみる。
  • 【dsPIC33FJ128MC802】PMP接続のDMA転送(連続転送)でaitendoの液晶を使ってみる。
  • 【dsPIC33FJ128MC802】PMP接続のDMA転送(連続転送)でaitendoの液晶を使ってみる。
  • 【dsPIC33FJ128MC802】PMP接続のDMA転送(連続転送)でaitendoの液晶を使ってみる。
  • 【dsPIC33FJ128MC802】aitendoの1.44インチ液晶TFT(ZY-FGD)をPMP接続で使ってみる!
  • 【dsPIC33FJ128MC802】aitendoの1.44インチ液晶TFT(ZY-FGD)をPMP接続で使ってみる!
メッセージはこちちらからお願いします。

名前
メール
本文
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

ブログパーツ
  • SEOブログパーツ
にほんブログ村 その他趣味ブログ 電子工作へ
にほんブログ村
アクセスカウンタ
アクセスランキング