忍者ブログ

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

2025/05/22

dsPIC33CH Curiosity Development Board(カラーLEDの1677万色表示)

次にカラーLEDを1677万色表示させる方法を考えてみます。先ほどの例は各色をON/OFFさせただけでした。絵を描く際パレットに絵の具を混ぜて色を生成しますが、この混ぜ具合を変えると様々な色が出来ることは経験済みだと思います。ソフトウェアでこの混ぜ具合を調整することももちろん可能ですが、今回はデジタル回路で良く使われる手法を使って再現してみましょう。

その手法はPWM(Pulse Width Modulation)と呼ばれ、周期は固定でデューティ比を変化させて変調することで、スイッチング電源やモーター制御など多くの場面で使われております。つまり周期に対してデューティが100%に近づけば 1 = high と同じことになり、逆に0%に近づけば 0 = Low と同じ事になります。フルカラーLEDに対して、それぞれ割合を調整すれば原理的には1677万色が可能です。
 


  ハードウェア構成

dsPIC33E系ではTimerとインプットキャプチャ、アウトプットコンペアは別々のモジュールでしたがdsPIC33CシリーズからSCCPモジュールとして統合されました。今回はSCCPのch3、ch4、ch5をOCM(アウトプットコンペア)として使用します。アウトプットコンペアは単発のパルスや連続パルスを出力する事が可能で、今回はPWMパルスを出力します。 またリマッパブルピンも使用します。リマッパブルピンとは周辺モジュールの入力や出力を自由に割り当てられる機能で「RP」とついているピンに割り当てられます。ただし一部アナログ入力など固定で割り当てられないので注意が必要です。


ソースコード

コンフィグレーション設定やクロック設定の関数に関して記述を省略していますが「dsPIC33CH Curiosity Development Board(準備編)」と同じです。

/*----------------------------------------------------------------------------------*/
/*【INC】インクルードファイル*/
/*----------------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include <libpic30.h>
#include "config.h"
/*----------------------------------------------------------------------------------*/
/*【CONST】定数定義*/
/*----------------------------------------------------------------------------------*/
#define WAIT_TIME       70000L
#define SCCP_PERIOD     0x0100u

const signed long s4g_RGB[13] =
{ 
    0xF9BE01,
    0xF19601, 
    0xEC6C01,
    0xE4012E,
    0xA50082, 
    0x561B85,
    0x034FA4,   
    0x006AB5,
    0x00A3AD,
    0x00A93C,
    0xABCD06, 
    0xFDD902,
    0xF9BE01    /* Dummy */
};
    
/*----------------------------------------------------------------------------------*/
/* Main関数 */
/*----------------------------------------------------------------------------------*/
int main(int argc, char** argv) 
{
    /*----------------------------------------------------------------------------------*/
    /* ローカル変数定義*/
    /*----------------------------------------------------------------------------------*/
        unsigned int u2l_i = 0u;
        unsigned int u2l_L = 128u;
        unsigned long u4l_i = 0x000000u;
        
        signed long s4l_Red = ( s4g_RGB[0u] >> 8u) & 0xFF00u;
        signed long s4l_Green = ( s4g_RGB[0u] >> 0u) & 0xFF00u;
        signed long s4l_Blue = ( s4g_RGB[0u] << 8u) & 0xFF00u;
        
        signed long s4l_Next_Red = ( s4g_RGB[1u] >> 8u) & 0xFF00u;
        signed long s4l_Next_Green = ( s4g_RGB[1u] >> 0u) & 0xFF00u;
        signed long s4l_Next_Blue = ( s4g_RGB[1u] << 8u) & 0xFF00u;
        
        signed long s4l_Delta_Red = (s4l_Next_Red - s4l_Red) >> 7u;
        signed long s4l_Delta_Green = (s4l_Next_Green - s4l_Green)  >> 7u;
        signed long s4l_Delta_Blue = (s4l_Next_Blue - s4l_Blue)  >> 7u;
        
    /*----------------------------------------------------------------------------------*/
    /* クロック初期化*/
    /*----------------------------------------------------------------------------------*/
        vds_Main_Init_Clock_Register();     /* クロック初期化 */
    /*----------------------------------------------------------------------------------*/
    /* GPIO初期化*/
    /*----------------------------------------------------------------------------------*/
        TRISBbits.TRISB14 = 1u;         /* RGB LED REDピンはデジタル入力ピン */
        TRISDbits.TRISD7 = 1u;          /* RGB LED GREENピンはデジタル入力ピン */
        TRISDbits.TRISD5 = 1u;          /* RGB LED BLUEピンはデジタル入力ピン */
    /*----------------------------------------------------------------------------------*/
    /* リマッパブルピン初期化*/
    /*----------------------------------------------------------------------------------*/
        RPOR18bits.RP69R = 0x11u;       /* RGB LED RED [OCM3] */
        RPOR19bits.RP71R = 0x12u;       /* RGB LED GREEN[OCM4] */
        RPOR7bits.RP46R	= 0x13u;        /* RGB LED BLUE [OCM5] */
    /*----------------------------------------------------------------------------------*/
    /*【****】CCP3初期化*/
    /*----------------------------------------------------------------------------------*/
        CCP3CON1L = 0x0000u;
            CCP3CON1Lbits.TMRPS = 3u;   /* クロックプリスケーラ選択(3 = 1:64) */
            CCP3CON1Lbits.MOD = 5u;     /* 動作モード(5 = PWMモード(必須)) */
        CCP3CON1H = 0x0000u;
        CCP3CON2L = 0x0000u;
        CCP3CON2H = 0x0000u;	
            CCP3CON2Hbits.OCAEN = 1u;   /* 出力ON */
        CCP3CON3H = 0x0000u;		
        CCP3PRL	= SCCP_PERIOD;	
        CCP3PRH	= 0x0000u;
        CCP3RB	= 0x0000u;
    /*----------------------------------------------------------------------------------*/
    /* CCP4初期化*/
    /*----------------------------------------------------------------------------------*/
        CCP4CON1L = 0x0000u;
            CCP4CON1Lbits.TMRPS = 3u;   /* クロックプリスケーラ選択(3 = 1:64) */
            CCP4CON1Lbits.MOD = 5u;     /* 動作モード(5 = PWMモード(必須)) */
        CCP4CON1H = 0x0000u;
        CCP4CON2L = 0x0000u;
        CCP4CON2H = 0x0000u;	
            CCP4CON2Hbits.OCAEN = 1u;   /* 出力ON */
        CCP4CON3H = 0x0000u;			
        CCP4PRL	= SCCP_PERIOD;	
        CCP4PRH	= 0x0000u;	
        CCP4RB	= 0x0000u;		
    /*----------------------------------------------------------------------------------*/
    /* CCP5初期化*/
    /*----------------------------------------------------------------------------------*/ 
        CCP5CON1L = 0x0000u;
            CCP5CON1Lbits.TMRPS = 3u;   /* クロックプリスケーラ選択(3 = 1:64) */
            CCP5CON1Lbits.MOD = 5u;     /* 動作モード(5 = PWMモード(必須)) */
        CCP5CON1H = 0x0000u;
        CCP5CON2L = 0x0000u;
        CCP5CON2H = 0x0000u;	
            CCP5CON2Hbits.OCAEN = 1u;   /* 出力ON */
        CCP5CON3H = 0x0000u;		
        CCP5PRL	= SCCP_PERIOD;	
        CCP5PRH	= 0x0000u;		
        CCP5RB	= 0x0000u;		
    /*----------------------------------------------------------------------------------*/
    /* CCP3,4,5の有効化*/
    /*----------------------------------------------------------------------------------*/ 
        CCP3CON1Lbits.CCPON = 1u ;
        CCP4CON1Lbits.CCPON = 1u ;
        CCP5CON1Lbits.CCPON = 1u ;
    /*----------------------------------------------------------------------------------*/
    /* メインルーチン*/
    /*----------------------------------------------------------------------------------*/
        while(1)
        {
        /*------------------------------------------------------------------------------*/
        /* 発光色変更*/
        /*------------------------------------------------------------------------------*/
            u2l_L = 128u;
            while (u2l_L > 0u)
            {
                u2l_L --;
            /*--------------------------------------------------------------------------*/
            /* Dutyレジスタ反映*/
            /*--------------------------------------------------------------------------*/
                CCP3RB = (s4l_Red >> 8u) & 0xFF;
                CCP4RB = (s4l_Green >> 8u) & 0xFF;
                CCP5RB = (s4l_Blue >> 8u) & 0xFF;
            /*--------------------------------------------------------------------------*/
            /* 発光色遷移*/
            /*--------------------------------------------------------------------------*/
                s4l_Red += s4l_Delta_Red;
                s4l_Green += s4l_Delta_Green;
                s4l_Blue += s4l_Delta_Blue;
            /*--------------------------------------------------------------------------*/
            /* 単純ウェイト*/
            /*--------------------------------------------------------------------------*/
                u4l_i = WAIT_TIME;
                while (u4l_i > 0L){u4l_i --;}
            }
        /*------------------------------------------------------------------------------*/
        /* ベース色変更*/
        /*------------------------------------------------------------------------------*/
            u2l_i ++;
            if ( u2l_i > 11u)
            {
                u2l_i = 0u;
            }
            
            /* 現在色ロード */
            s4l_Red = ( s4g_RGB[u2l_i] >> 8u) & 0xFF00u;
            s4l_Green = ( s4g_RGB[u2l_i] >> 0u) & 0xFF00u;
            s4l_Blue = ( s4g_RGB[u2l_i] << 8u) & 0xFF00u;
            
            /* Next色ロード */
            s4l_Next_Red = ( s4g_RGB[u2l_i + 1u] >> 8u) & 0xFF00u;
            s4l_Next_Green = ( s4g_RGB[u2l_i + 1u] >> 0u) & 0xFF00u;
            s4l_Next_Blue = ( s4g_RGB[u2l_i + 1u] << 8u) & 0xFF00u;
            
            /* 差分演算 */
            s4l_Delta_Red = (s4l_Next_Red - s4l_Red) >> 7u;
            s4l_Delta_Green = (s4l_Next_Green - s4l_Green) >> 7u;
            s4l_Delta_Blue = (s4l_Next_Blue - s4l_Blue)  >> 7u;
        }
}



これでメイン側のフルカラーLEDが滑らかに変更されていくと思います。
PR

2020/01/12 dsPIC33C Comment(0)

COMMENT

COMMENT FORM

NAME
MAIL
WEB
TITLE
COMMENT
PASSWORD

プロフィール
 
HN:
ぴくお
性別:
非公開
 
 
カテゴリー
 
 
 
最新記事
 
(10/03)
(09/05)
(08/23)
(08/17)
(08/16)
 
 
RSS
 
 
 
リンク
 
 
 
免責事項
当サイトに掲載の回路図やプログラム等は動作する事を期待して掲載しておりますが、その動作の保証、性能の保証は致しません。 また掲載されているソフトウェアの使用により生じたいかなる損害に関しまして作者は一切責任を負いません。