---
---
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 |
<手順>
ここのホームページで作成したPIC16F1459のブートローダー用アプリケーションプログラムを以下のフォルダーにまとめてあります。
HEXfilesForBootLoader.zip |
<手順>