PCからPICマイコンをUSB制御してLチカしてみる

pic24fj64gb002_usb_Lchika-Title800x450

PICマイコンの中にはUSBインターフェイスを持っていてUSBデバイスとして使えたりOTG機能でHOST側として使えるものがあります。今回その中でPIC24FJ64GB002を使ってPCとUSB経由で接続しUSBデバイスとして扱ったときの動作をLチカを使って確認したいと思います。

動作確認環境は以下になります。

  • PIC : PIC24FJ64GB002
  • プログラマー ; PICKit4
  • PC OS : Linux Mint 20 Cinnamon
  • MPLAB X IDE : v5.40
  • コンパイラー : XC16 (v1.6)

接続は、ブレッドボードを使って以下のようにしました。

PIC_USB_LchikaW

PICの動作としては、PCとPICのUSBポート(D+/D-)がUSBでつながっていない状態のときは、LEDが点灯状態のままで点滅しません。PCとPICのUSBポート(D+/D-)がUSBでつながった状態になったら初期状態ではLEDのON/FFの切り替え時間が500msで点滅します。

PCよりPICをSerialポートとしてopenしmsオーダの数字を文字列で送信するとそのタイミングでLEDの点滅スピードが変わります。

“0”〜”9″以外の文字列を送信した場合はそのままLoopBackします。

SerialポートをCloseしてもLEDの点滅スピードは維持したままです。

この動作をさせるファームウェアのソースは以下のソースは以下のようになります。USB関連のソースはMCCを使ってGenerateしましたのでここではmain.cのみ掲載します。

#include "mcc_generated_files/system.h"
/**
 
 BCD USB Specification : 0x0200
 Vender ID             : 0x04D8
 Product ID            : 0x000A
 BCD Device release    : 0x0100
 
*/
#include "mcc_generated_files/usb/usb.h"

#define FCY 16000000UL // Fosc(32MHz)/2(16MIPS)                                                                         
#include <libpic30.h>

char USB_In_Buffer[64] ;
char USB_Out_Buffer[64] ;

volatile int Delaytm = 500;

void usb_trx_test()
{
    uint8_t numBytesRead;
    uint8_t i,k;
    int ibuf = 0;
    int idelaytm = 0;
    uint8_t num_f = 0;
    if((USBDeviceState < ADR_PENDING_STATE) || (USBSuspendControl==1))
	{
	}
	else if (USBDeviceState < CONFIGURED_STATE || (USBSuspendControl==1))
	{
	}
    else
    {
        if( USBUSARTIsTxTrfReady() == true)
        {
            LATBbits.LATB2 = 0;
            __delay_ms(Delaytm);
            LATBbits.LATB2 = 1;
            __delay_ms(Delaytm);
        }
        
        numBytesRead = getsUSBUSART(USB_Out_Buffer,64) ; 
        if(numBytesRead > 0)
        {
            ibuf = 0;
            idelaytm = 0;
            for (i=0 ; i<numBytesRead ; i++) {
                num_f = 0;
                // A -- Z
                if (USB_Out_Buffer[i] >= 0x41 && USB_Out_Buffer[i] <= 0x5a )
                {
                    num_f = 1;
                }
                // a -- z
                else if (USB_Out_Buffer[i] >= 0x61 && USB_Out_Buffer[i] <= 0x7a )
                {
                    num_f = 1;
                }
                // 0 -- 9
                else if (USB_Out_Buffer[i] >= 0x30 && USB_Out_Buffer[i] <= 0x39 )
                {
                    ibuf = (int)USB_Out_Buffer[i]-0x30;
                    for ( k = (numBytesRead-1); k > 0 ; k--)
                    {
                        ibuf = ibuf * 10;
                    }
                    idelaytm = idelaytm + ibuf;
                }
                
                if ( num_f == 1 )
                {
                   USB_In_Buffer[i] = USB_Out_Buffer[i] ;                                                                                                     
                }
            }                                                                                                                                                 
            putUSBUSART(USB_In_Buffer,numBytesRead) ;
            if ( idelaytm > 0 )
            {
                Delaytm = idelaytm;
            }            
        }
        CDCTxService() ;
    }
}

int main(void)
{
    // initialize the device
    SYSTEM_Initialize();
    U1BRG = 103;
    LATBbits.LATB2 = 1;

    
    while (1)
    {
        // Add your application code
        usb_trx_test();

    }

    return 1;
}
/**
 End of File
*/

上記のファームウェアをPICに書き込んだのちPCとPICをUSBで接続します。

ターミナルを開いてpython3を起動します。で以下のスクリプトを入力していきLEDの点滅時間が変わるのを確認します。”ttyACM1″のところは使用するPC(Linux)の環境によって異なりますので事前にdmesgコマンドで調べておきます。3行目のser.write ….の数字が設定したいLEDのON/OFF切り替え時間になります。

>>> import serial
>>> ser=serial.Serial("/dev/ttyACM1", 9600, timeout=1)
>>> ser.write(bytes('200', 'utf-8'))
>>> ser.close()

動作確認を動画にしたものが以下になります。

中川電子技研

この投稿へのコメント

コメントはありません。

コメントを残す

メールアドレスが公開されることはありません。

この投稿へのトラックバック

トラックバックはありません。

トラックバック URL