PIC16F1459の基本動作から応用プログラムまでを学びます。

ホーム
16F18313
16F18325
16F18346
16F1619
Curiosity
---
---
    
12F1822
16F1455
16F1459
18F14K50
18F26J50
dsPIC
その他
テスト用基板 - PIC16F1459

PIC16F1459 のプログラムを行うために都合のよいテスト用基板を作成しました。搭載PICにブートローダーを書き込んでおけば、ノートPCだけでプログラムの確認ができます。

テスト基板の動作確認プログラム

このプロジェクトに書かれているプログラムは、上記テスト基板のSW、LED、ボリューム、LCD表示の動作を確認するためのものです。

USB - HID custom  C03_BasicFunc.zip

main.c

// -------------------------------------------------------------------------
// テスト用基板のハード確認用プログラム
//  Notes: 4MHz内部クロック
//     SW1 :RA3,  SW2 :RA5
//     LED1:RC0,  LED2:RC1,  LED3:RC2,  LED4:RC3
//     POT :RA4 (AN3)
//    Language: MPLABX XC8
//    Target:   PIC16F1459
// -------------------------------------------------------------------------

#include <xc.h>
#include <stdio.h>                     // printf のための
#include "bd_confg.h"                  // テスト基板ハードウエア定義
#define _XTAL_FREQ 4000000             // delay_ms(x) のための定義

#pragma config FOSC  = INTOSC, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP  = OFF
#pragma config BOREN = ON, CLKOUTEN = OFF, IESO  = OFF, FCMEN = OFF
#pragma config WRT = OFF, CPUDIV = NOCLKDIV, USBLSCLK = 48MHz, PLLMULT = 4x
#pragma config PLLEN = ENABLED, STVREN = ON, BORV = LO, LPBOR = OFF, LVP = OFF


// MAIN ********************************************************
void main(void){
    char speed;                        // LED点滅のスピード
    OSCCON = 0b00110110;               // 内部クロック4Mhz
    LATC = 0;                          // PORT C クリア
    intSWs();                          // PushSW 初期化
    intLEDs();                         // LED    初期化
    intADC();                          // AD変換 初期化
    intI2CLCD();                       // LCD    初期化
    printf("Speed");                   // LCD 上段に表示
    LCD_posyx(1,0);                    // LCD 下段に表示
    printf("  =");
    while(1){                          // 繰り返しループ
        if(!SW1)LED1=1;                // SW1が押されれば
          else LED1=0;                 //    LED1を点灯
        if(!SW2)LED2=1;                // SW2が押されれば
          else LED2=0;                 //    LED2を点灯
        speed = resADC()>>6;           // AD変換値の上位4Bit取得
        LCD_posyx(1,4);                // LCD下段中央に
        printf("%2d",speed);           // 10進で表示
        speed = 16 - speed;            // LED点滅のスピードに変更
        while(speed--)__delay_ms(20);  // 点滅間隔を待ち
        LED4 = LED3;                   // LED4を点滅
        LED3 = !LED3;                  // LED3を点滅
    }
}
			

bd_confg.h

// -------------------------------------------------------------------------//  Notes: 4MHz内部クロック
//     SW1  RA3,  SW2  RA5
//     LED1 RC0,  LED2 RC1,  LED3 RC2,  LED4 RC3
//     POT  RA4 (AN3)
//    Language: MPLABX XC8
//    Target:   PIC16F1459
// -------------------------------------------------------------------------

#include <xc.h>
#include <stdio.h>
#ifndef _XTAL_FREQ
#define _XTAL_FREQ 4000000      // delay_ms(x) のための定義
#endif
// board_config --------------------------------------------------------
// Push SW -------------------------------------------------------------
#define intSWs()  TRISA5=1
#define SW1       RA3
#define SW2       RA5
// LED ------------------------------------------------------------------
#define intLEDs() TRISC&=0xF0
#define LED1      LATC0
#define LED2      LATC1
#define LED3      LATC2
#define LED4      LATC3
// ADC ------------------------------------------------------------------
void intADC(void);
unsigned int resADC(void);

// I2C LCD --------------------------------------------------------------
//  調整用定数
#define CONTRAST  0x28                  // for 3.3V
// #define CONTRAST  0x18               // for 5.0V

void intI2CLCD(void);                   // 初期化
void i2cByteWrite(char, char, char);    // i2c byte送信
void i2cTxData(char);                   // i2c SSPBUF セット
void LCD_dat(char);                     // 1文字表示
void LCD_cmd(char);                     // コマンド出力
void LCD_clr(void);                     // 全消去
void LCD_posyx(char,char);              // カーソル位置指定

			

bd_confg.c

// -------------------------------------------------------------------------//  Notes: 4MHz内部クロック
//     SW1  RA3,  SW2  RA5
//     LED1 RC0,  LED2 RC1,  LED3 RC2,  LED4 RC3
//     POT  RA4 (AN3)
//    Language: MPLABX XC8
//    Target:   PIC16F1459
// -------------------------------------------------------------------------

#include <xc.h>
#include <stdio.h>
#include "bd_confg.h"
// board_config --------------------------------------------------------

// ADC ------------------------------------------------------------------
void intADC(void){
    TRISAbits.TRISA4 = 1;       // RA4(AN3)は入力に設定
    ANSELAbits.ANSA4 = 1;       // RA4(AN3)はアナログに設定
    ADCON2 = 0b00000000;        // AD変換はプログラムの命令で開始
    ADCON1 = 0b11000000;        // 右詰め出力, AD変換クロックFosc/4
                                // 正基準電圧 VDD
    ADCON0 = 0b00001101;        // アナログ入力 AN3(RA4),ADC ON
}
unsigned int resADC(void) {
    __delay_ms(5);              // ADチャージ時間
    GO = 1;                     // AD変換開始
    while(GO);                  // AD変換終了待ち
    return ADRES;               // AD結果16ビットで取得
}
// I2C LCD --------------------------------------------------------------
//********************************************************************
// I2C 関連
//********************************************************************
//-------- i2cで1byteデータを送信する -----------------------
//  以下の引数が必要
//  addr : Slaveのアドレス
//  cont : Slaveへ制御コード
//  data : 送信するデータ
//  NACKやBus衝突などの対応は行っていない
// -----------------------------------------------------------
void i2cByteWrite(char addr, char cont, char data){
    SEN = 1;                       // Start condition 開始
    while(SEN);                    // Start condition 確認
    i2cTxData(addr);               // アドレス送信
    i2cTxData(cont);               // 制御コード送信
    i2cTxData(data);               // データ送信
    SSP1IF = 0;                    // 終了フラグクリア
    PEN = 1;                       // Stop condition 開始
    while(PEN);                    // Stop condition 確認
}
//-------- SSPBUFに1文字保存し送信終了を待つ -----------------
void i2cTxData(char data){
    SSP1IF = 0;                    // 終了フラグクリア
    SSPBUF = data;                 // データセット
    while(!SSP1IF);                // 送信終了待ち
}
//********************************************************************
// LCD 関連
//********************************************************************
//-------- 初期化 --------------------------------------
void intI2CLCD(void){
    ANSELB &= 0b01010000;          // RB7,RB5をデジタルI/Oにする
    TRISB  |= 0b10100000;          // PortBを入力I/Oにする
    WPUB   |= 0b10100000;          // RB7,RB5を弱プルアップ
    nWPUEN  = 0;                   // 弱プルアップをONにする
    SSPCON3 = 0;
    SSPCON2 = 0;
    SSPCON1 = 0b00101000;          // I2Cマスターモード指定
    SSPSTAT = 0b10000000;          // Slew rate for 100 kHz
    SSPADD  = 9;                   // I2Cクロック周波数100KHz for 4MHz
    __delay_ms(100);
    LCD_cmd(0x38);                 // 8bit 2行 表示命令モード
    LCD_cmd(0x39);                 // 8bit 2行 拡張命令モード
    LCD_cmd(0x14);                 // OSC  BIAS 設定1/5
                                   // コントラスト設定
    LCD_cmd(0x70 + (CONTRAST & 0x0F));
    LCD_cmd(0x5C + (CONTRAST >> 4));
    LCD_cmd(0x6B);                 // Ffollwer
    __delay_ms(100);
    __delay_ms(100);
    LCD_cmd(0x38);                 // 表示命令モード
    LCD_cmd(0x0C);                 // Display On
    LCD_cmd(0x01);                 // Clear Display
}
//-------- 1文字表示
void LCD_dat(char chr){
    i2cByteWrite(0x7C, 0x40, chr);
    __delay_us(50);                // 50μsec
}
//-------- コマンド出力
void LCD_cmd(char cmd){
    i2cByteWrite(0x7C, 0x00, cmd);
    if(cmd & 0xFC)                 // 上位6ビットに1がある命令
        __delay_us(50);            // 50usec
    else
        __delay_ms(2);             // 2msec ClearおよびHomeコマンド
}
//-------- 全消去 ------------------------------------------------
void LCD_clr(void){
    LCD_cmd(0x01);                 //Clearコマンド出力
}
//-------- カーソル位置指定 --------------------------------------
void LCD_posyx(char ypos, char xpos){
    unsigned char pcode;
    switch(ypos & 0x03){           // 縦位置を取得
        case 0: pcode=0x80;break;  // 1行目
        case 1: pcode=0xC0;break;  // 2行目
    }
    LCD_cmd(pcode += xpos);        // 横位置を加える
}

// **************** printf Routen *****************************
// LCD で printf関数が使用できるようにするため putch を設定する
void putch(char data) {
        LCD_dat(data);             // LCD への一文字表示関数
}

			

ブートローダー の書込み

このテスト基板に、PICkit などのプログラマーを使わず、PCだけで作成したアプリケーションプログラムを書き込むには、ブートローダープログラムがPICにあらかじめセットされている必要があります。 このブートローダをPICにセット(書き込む)には、残念ながらPICkitなどのプログラマーを使用しなければなりません。 しかし、一度セットしてしまえば、後は、PCのUSB経由で、PICにいろいろなアプリケ―ションプログラムを書込みその動作を確認することが可能になります。
 PICkitなどのプログラマーで、下記プロジェクトを書き込んでください。 このプロジェクトには、ブートローダープログラムだけではなく、テスト基板の機能を確認する上述の「テスト基板の動作確認プログラム」も含まれています。

C03_Bootloader16F1459IntlOscWtDemo.zip

<手順>

  1. テスト基板に、PICkit3 を接続します。
  2. テスト基板とPCをUSBケーブルで接続します。
  3. 基板の電源SWをONとし、電源を供給します。
  4. MPLAB X を起動し、上記プロジェクトで、ブートローダーを書き込みます。
  5. 基板の電源SWをOFFとし、PICkit3を取り外します。
  6. 再度、電源SWをONにすれば、「テスト基板の動作確認プログラム」が動作します。
    (SW、LED、LCD表示の動作確認ができます)
  7. SW1を押しながら電源SWをONにすると、
    ブートローダーのアプリケーションプログラムの更新モードで動作します。
    (PCアプリ HIDBootloader (Windows).exeを起動すれば、希望のPICプログラムを書き込むことができます)

ブートローダー用アプリの書込み

ここのホームページで作成したPIC16F1459のブートローダー用アプリケーションプログラムを以下のフォルダーにまとめてあります。

HEXfilesForBootLoader.zip

<手順>

  1. テスト基板から、PICkit3 を取り外します。
  2. テスト基板とPCをUSBケーブルで接続します。
  3. PCの HIDBootloader (Windows).exe を起動します。
    「Device not detected」というメッセージが表示されます。
  4. SW1を押しながら電源SWをONにすると、ブートローダーアプリケーションが更新モードで動作します。
    HIDBootloader (Windows)には、「Device attached」と表示されます。 
  5. 「HEXfilesForBootLoader」のHEXファイルを読み込み、PICに書き込みます
  6.  HIDBootloader (Windows)の「Reset Device」ボタンをクリックするか、基板の電源SWを一度OFFにし再度ONにすれば「Device Detachedと表示されブートローダが切り離され、PICに今書き込んだアプリケーションプログラムが起動します。