中国からの部品が届きました♪。

USB-TTLシリアル変換器の二種類(FT232RLPL2303HX)、中華製Arduino Nano V3CANモジュールの4点が届きました~?。

そしてArduinoにLチカのスケッチをArduinoでhexファイル化したらAVR-GCCで書いたhexファイルより4倍の容量に・・・。

DigLchika_PB5_ino.hexがArduino ICEでビルドしたhexファイル( 948byte )?。全く同じ制御をAVR-GCC( AVR STUDIO)でビルドしたDigLchika_PB5.hex( 176byte )?。

更にArduinoのanalogWrite関数は周辺機能であるタイマーのPWM機能を使って作動させているので、決まったデジタルポート(OCxA/B端子)以外では使えない?。

これでは話にならないので?Arduinoのボード上に接続されているD13(PB5)のLEDから、じわっとLEDを光らせる関数をAVR STUDIOで作ってみました?。

とても低次元なプログラムなのでPwmLchika_PB5.hex( 410byte )の容量で収まりました??。

中華製Arduino Nano V3のUSB-シリアル変換ICは【 CH340G 】というICが使われているため、専用のドライバーをインストールする必要があります。

ウインドウズ用はこちらからダウンロードしてArduinoのUSBケーブルを接続する前にドライバーをインストールしておきます。

FT232RLのUSBーTTLシリアル変換モジュールのウインドウズ用はドライバーはこちらです。

PL2303のUSB-TTLシリアル変換モジュールのドライバーは秋月電子でダウンロードできます。

以下はAVR STUDIO(AVR-GCC)でのコードです。

/* ----------------------------------------------------------------  /
 * Lチカプログラム
 * ----------------------------------------------------------------  /
 * CPU:     AVR ATMEGA328P(Arduino NANO V3 CPU Board)
 * C Compiler: GCC WINAVR
 * File:    main.c
 * Author:  March
 * Created: 2017/10/27
 * URL:     http://super-evolution.ml/
 * ---------------------------------------------------------------- */
#define F_CPU (16000000UL)
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/wdt.h>

/* ----------------------------------------- */
/* Define                                    */
/* ----------------------------------------- */
// #define nop( )               asm volatile("nop")
#define	sbi( PORT, BIT )        ( PORT |=  _BV( BIT ) )
#define	cbi( PORT, BIT )        ( PORT &= ~_BV( BIT ) )

#define WDTRESET                wdt_reset( );
#define WDTEN                   wdt_enable( WDTO_500MS )
//#define WDTDI                 wdt_disable( )

#define	LED_DDR                 DDRB
#define	LED_DDR_NUM             DDD5
#define	LED_PORT                PORTB
#define	LED_PORT_NUM            PORTB5

#define	LED_PORT_ON             sbi( LED_PORT, LED_PORT_NUM )
#define	LED_PORT_OFF            cbi( LED_PORT, LED_PORT_NUM )

/* ----------------------------------------- */
/* Variabal                                  */
/* ----------------------------------------- */
volatile uint8_t		LedPwmCount100us		= 0;
volatile uint8_t		LedPwmCount100usFrzq	= 100;
volatile uint8_t		LedPwmCount100usDuty	= 0;

/* ---------------------------------------------------------------- */
/* Interrupt Program Code                                           */
/* ---------------------------------------------------------------- */

/* -------------------------------------------- */
/* タイマー0 100ms割込                          */
/* -------------------------------------------- */
ISR( TIMER0_COMPA_vect, ISR_BLOCK )
{
    // Watch Dog Timer Reset
    WDTRESET;

    if( LedPwmCount100us > LedPwmCount100usFrzq ){
        LedPwmCount100us = 0;
        if( LedPwmCount100usDuty == 0 ){ LED_PORT_OFF; }
        else{ LED_PORT_ON; }
    } else if( LedPwmCount100us > LedPwmCount100usDuty ){
        LED_PORT_OFF;
    }
    LedPwmCount100us++;

    return;
}

/* ---------------------------------------------------------------- */
/* Program Code                                                     */
/* ---------------------------------------------------------------- */

/* ----------------------------------------------- */
/* AllPorts PWM Control Program                    */
/* ----------------------------------------------- */
static void Timer0PwmAllPort( uint8_t value )
{
    // 割り込み禁止
    cli( );
    LedPwmCount100usDuty = value;
    // 割り込み許可
    sei( );

    return;
}


/* ----------------------------------------------- */
/* Zinwari PWM Control Program                     */
/* ----------------------------------------------- */
static void ZinwariLedControl(
        uint8_t value, uint16_t steptime, uint16_t MaxMintime )
{
    static int8_t data = 0, singflg = 0;

    if( singflg == 0 ){
        if( data >= value ){ singflg = 1; }
        else{ data++; }
    } else{
        if( data <= 0 ){ singflg = 0; }
        else{ data--; }
    }

    // PWM設定
    Timer0PwmAllPort( data );
    // 待機時間
    if( data == 0 ){ _delay_ms( MaxMintime ); }
    else if( data == value ){ _delay_ms( MaxMintime ); }
    else{ _delay_ms( steptime ); }

    return;
}


/* ----------------------------------------- */
/*  Cpu Init Program                         */
/* ----------------------------------------- */
void Cpu_init( void )
{
    /* DDRB Setting                                 /
     *            +--------[ 7. OSC2      ]: 0
     *            |+-------[ 6. OSC1      ]: 0
     *            ||+------[ 5. non       ]: INPUT
     *            |||+-----[ 4. non       ]: INPUT
     *            ||||+----[ 3. non       ]: INPUT
     *            |||||+---[ 2. non       ]: INPUT
     *            ||||||+--[ 1. non       ]: INPUT
     *            |||||||+-[ 0. non       ]: INPUT */
    //DDRB    = 0b00000000;
    //PORTB   = 0b00000000;
    
    /* DDRC Setting                                  /
     *            +--------[ 7. --------- ]: 0
     *            |+-------[ 6. Reset     ]: INPUT
     *            ||+------[ 5. non       ]: INPUT
     *            |||+-----[ 4. non       ]: INPUT
     *            ||||+----[ 3. non       ]: INPUT
     *            |||||+---[ 2. non       ]: INPUT
     *            ||||||+--[ 1. non       ]: INPUT
     *            |||||||+-[ 0. non       ]: INPUT */
    //DDRC     = 0b00000000;
    //PORTC    = 0b00000000;
    
    /* DDRD Setting                                 /
     *            +--------[ 7. non       ]: INPUT
     *            |+-------[ 6. non       ]: INPUT
     *            ||+------[ 5. non       ]: INPUT
     *            |||+-----[ 4. non       ]: INPUT
     *            ||||+----[ 3. non       ]: INPUT
     *            |||||+---[ 2. non       ]: INPUT
     *            ||||||+--[ 1. TxD       ]: OUTPUT
     *            |||||||+-[ 0. RxD       ]: INPUT */
    //DDRD    = 0b00000000;
    //PORTD   = 0b00000000;

    /* DIDR0 Setting                               /
     *             +--------[ 7. -----  ]:
     *             |+-------[ 6. -----  ]: 0
     *             ||+------[ 5. ACD5D  ]: 0
     *             |||+-----[ 4. ACD4D  ]: 0
     *             ||||+----[ 3. ACD3D  ]: 0
     *             |||||+---[ 2. ACD2D  ]: 0
     *             ||||||+--[ 1. ACD1D  ]: 0
     *             |||||||+-[ 0. ACD0D  ]: 0      */
    DIDR0      = 0b00000000;

    // LED Port OUTPUT
    sbi( LED_DDR, LED_DDR_NUM );

    // TIMER0 WaitTimer 10KHz(100us)設定
    TCNT0      = 0x00;
    OCR0A      = (25-1);		// FREQ値
    TCCR0A     = 0b00000010;		// 比較一致タイマ/カウンタ解除(CTC)動作
    TIFR0      = 0b00000010;		// TIMER0 FLG=0
    TIMSK0     = 0b00000010;		// TIMER0 割り込み許可
    TCCR0B     = 0b00000011;		// TIMER0 START(4us) / 64
    
    return;
}


/* ----------------------------------------- */
/* Main Program                              */
/* ----------------------------------------- */
int main( void )
{
    // 各初期化
    Cpu_init( );
    // 割り込み許可
    sei( );
    // Watch Dog Timer On
    WDTEN;
    
    // Loop
    while( 1 )
    {
        // ジワットLED点滅
        ZinwariLedControl(
            100,	// 最大PWM値(最大100%)
            12,		// 1ステップの変化時間 ms
            500		// LO&最大PWM値時の一定保持時間 ms
        );
    }
}

自作ECU(インジェクション)、オートクルーズ、マルチ温度計などに比べるとめっちゃしょぼいコードですが、何か役に立つかなっと記載・・・?。