2010年11月30日火曜日

Delay10KTCYx()

#include <delays.h>

例: Delay10KTCYx(200)
引数は0-255
0は256で計算する。

引数の選択方法:1秒必要な時
8MHz で動作している場合
1/8,000,000=0.125μs
1命令4サイクルなので
0.125x4=0.5μs
1x1,000,000/0.5=2,000,000 =2,000k回
必要 引数は200を選択

例:48MHzで1秒必要な場
200 msを5回繰り返す

1命令1/48*4=0.083=1/12μs
200 msは
200x1,000/(1/12)=2,400,000=2,400k回

Delay10KTCYx(240);
Delay10KTCYx(240);
Delay10KTCYx(240);
Delay10KTCYx(240);
Delay10KTCYx(240);

2010年11月29日月曜日

出力データをグラフで表示してみる-3軸加速度センサー編-PIC18F2550

KXM52-1050モジュールを秋月電子通商で購入したので、とりあえず動作確認してみました。



LM60を使った温度計作成 の記事で紹介しているプログラムを流用しています。

PIC側プログラム
3D.zip
ダウンロード
のmain.c を
C:\インストールフォルダ\USB Device - WinUSB - Generic Driver Demo\WinUSB Simple Demo - Firmware\USB Device - WinUSB - Generic Driver - C18 - PICDEM FSUSB.mcp
のmain.c と入れ替えてビルドして下さい

PC側プログラム
受信データをとりあえず表示するだけで、他は何も考慮していません。
3D-PC.zip
ダウンロード
プログラムを流用しているので、わざわざAD変換した値から電圧を求めてグラフを描いてますが、
AD変換した値でグラフを描いた方がシンプルでいいと思います。
目盛も意味はありません、見やすいようずらして表示してあります。

2010年11月28日日曜日

ブートローダーで書き込むプログラム

#include <p18cxxx.h> 
 
#define REMAPPED_RESET_VECTOR_ADDRESS            0x1000
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS    0x1008
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS    0x1018
     
     extern void _startup (void);        // See c018i.c in your C18 compiler dir
     #pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS
     void _reset (void)
     {
         _asm goto _startup _endasm
     }
         
         
 void main (void)
 {
   TRISA = 0x00;
   TRISD = 0x08;
   /* Reset the LEDs */
   PORTA = 0;
   /* Light the LEDs */
   PORTA = 0x3F;
   while (1)
   {
       LATAbits.LATA0=PORTDbits.RD3;
   }  
 }
 

LM60を使った温度計作成

リアルタイムで値を表示-WinUSB - Generic Driver Demo-PIC18F2550 の記事を参考に
温度計を繋げてみました。

基準電圧には、LM336Z-2.5の2.409VをRA3/AN3 に繋げてみました。


参考にPIC側、PC側のファイルを置いておきます。
プログラムソースには必要無い部分も含まれています。
PIC側プロジェクトファイル
TEMP.zip
ダウンロード

PC側プロジェクトファイ
WinUSB_TEMP.zip
ダウンロード

温度センサーも基準電圧ダイオードもデータシートの図は下から見た図でした、
最初は上から見た図と勘違いしていて、温度は上がるはずなのに逆に下がったり、
計算した温度が出なかったり大変でした。

2010年11月26日金曜日

リアルタイムで値を表示-WinUSB - Generic Driver Demo-PIC18F2550

 AD変換とRS232C通信を追加-WinUSB - Generic Driver Demo-PIC18F2550 の記事は、
ボタンをクリックして値を取得していましたが、
タイマーを利用してリアルタイムで値を取得して表示してみたいと思います。

Connect ボタンをクリックするとリアルタイムで表示し始めます。
インターバルは1秒に設定しています。

回路図とPIC側のファームウェアは、
AD変換とRS232C通信を追加-WinUSB - Generic Driver Demo-PIC18F2550 の記事で紹介している物と同じです。

PC側のソフトはTimer コントロールを追加して、
プロパティーでインターバルの時間を設定して、Enabled = true;にする。
Timer コントロールのイベント処理部分は
ボタンをクリックした時の、処理をそのままコピーする感じです。

PC側プロジェクトファイル
WinUSB Simple Demo - PC Application - MS VC++ 2005 Express02.zip
ダウンロード

AD変換とRS232C通信を追加-WinUSB - Generic Driver Demo-PIC18F2550

サンプルのWinUSB - Generic Driver Demoに
強引にAD変換とRS232C通信を追加してみました。





PIC側プロジェクトファイル
WinUSB.zip
ダウンロード

PC側プロジェクトファイル
WinUSB Simple Demo - PC Application - MS VC++ 2005 Express.zip
ダウンロード

PC側のプロジェクトファイルをビルドするには、
VWindows Driver Kit (WDK)をインストールする必要があります。
インクルードファイルの準備 を一読すると良いかもしれません。

USBで接続しているので、RS232C通信は必要無いと思いますが、
動作確認の為にあえて加えてみました。

細かいところまで作り込んでいません。
RA3/AN3 ポートは電源電圧を基準電圧に使用しているので必要ありません。

2010年11月24日水曜日

16進,10進,8進,2進数の変換

ウインドウズのアクセサリに入っている電卓を使用しています。


ビルドして動作確認-WinUSB - Generic Driver Demo-PIC18F2550


USB Device - WinUSB - Generic Driver Demo フォルダの中の
WinUSB Simple Demo - Firmware フォルダの中の
USB Device - WinUSB - Generic Driver - C18 - PICDEM FSUSB.mcp を開きます。

LEDをボタンで点滅させるので、
HardwareProfile - PICDEM FSUSB.h を修正します。

    /** LED ************************************************************/
    #define mInitAllLEDs()      LATC &= 0xF0; TRISC &= 0xF0;
   
    #define mLED_1              LATCbits.LATC0
    #define mLED_2              LATCbits.LATC1
    #define mLED_3              LATCbits.LATC2
    //#define mLED_4              LATCbits.LATC3

修正が終わったらビルドして書き込みます。


USB Device - WinUSB - Generic Driver Demo フォルダの
SimpleWinUSBDemo.exe を起動させます。
Connect ボタンを押してPICと接続します、
Toggle LED(s) ボタンをクリックすると、点灯<->消灯 します。
Get Pushbotton Stateボタンを押すと、RB5に接続されているスイッチの状態を表示します。
スイッチを押しながらボタンをクリックするとState: Pressed と表示される。

2010年11月23日火曜日

プログラムを見てみる-PIC18F2550-MCHPUSB - Generic Driver Demo

ファイル名:main.c
main関数
  InitializeSystem();//初期設定
    ADCON1 |= 0x0F;                 // すべてのピンをデジタルに設定
    UserInit();                           //UserInit()関数の読み込み user.cにある

繰返し部分
  ProcessIO();                         //user.cにある

ファイル名: user.c
UserInit関数
   mInitPOT();                        //HardwareProfile - PICDEM FSUSB.にある

   T0CON = 0b10010111;         //Timer0 のインターバル(1秒毎)

ProcessIO()関数
  ServiceRequests();//データの送信

ServiceRequests();

ファイル名:HardwareProfile - PICDEM FSUSB.h
/** POT ************************************************************/
#define mInitPOT()   {
TRISAbits.TRISA0=1;    //RA0 1:入力
ADCON0=0x01;     //ADCON0レジスタ bit0:1 A/D変換使用開始
ADCON2=0x3C;          //ADCON2レジスタbit2-0(100)  4Tosc(時間)  ~2.50MHz(オシレータ周波数)
//bit5-3(111)  20TAD(アクィジション時間)
ADCON2bits.ADFM = 1;//A/D変換結果の格納 ADFM=1:右詰め
}

複雑すぎてビギナーの私には厳しい。

2010年11月21日日曜日

A/D変換-C18プログラミング-PIC18F2550

未完成



/*
概要:A/D変換値をRS232C通信で送信

HID - Bootloaderを使った書き込み

マイコン:PIC18F2550

ファイル名:RS232C.c

開発環境:MPLAB C18

*/

#include <p18f2550.h>
#include <usart.h>
#include <stdio.h>
#include <adc.h>
#include <stdlib.h>
#include <delays.h>

// リセットベクタ  
#pragma code reset_vector=0x1000

extern void _startup(void);
void remapped_reset(void) { _asm goto _startup _endasm}

#pragma code

void main (void){
char ad_value[10] = "AD=";
char v_value[10] = "Volt=";
char str2[8] ="\r\n";

int ADread;  //AD変換値
char buf_ad[3]; //一時的に保存
double press; //電圧値整形前
int One_digit; //電圧値の整数部分
int v_m;  //小数点以下2桁
 
 TRISA = 0b00001001;     //RA0,A/D input RA3 Vref input
 TRISB = 0;              //all output
 TRISC = 0;        //all output
 
 LATC = 0;    //ポートCの出力ラッチCすべてに0:OFFを出力
 
 ADCON0 = 0b00000001; //bit0=1 AD変換開始
       //bit3,4,5の000でAN0を一つのだけのポートに指定
 ADCON1 = 0b00011101; //アナログ入力ポートの使い方の設定
       //bit4,5の0,1でVss、AN3/Vref+
       //bit0,1,2,3の1101でAN0,AN1がアナログ他はデジタル
 ADCON2 = 0b10110110; //bit0,1,2 の110で64Tosc
       //bit3,4,5の110で16TAD
 
 T0CON = 0b10000110;     //Timer0 の設定
       //bit0,1,2 110 プリスケーラ使用時の倍率指定256
       //bit3=0 プリスケーラ使用有無 使用する 
       //bit4=0 立ち上がり 
       //bit5=0 TMR0クロックソース選択 命令サイクル 
       //bit6=0 16ビットモード 
       //bit7=1 TMR0有効
 
 
 INTCONbits.TMR0IE = 1;  // Timer0 Interrupt Enable
 
 RCONbits.IPEN = 1;      // Interruput Priority Enable
 INTCON2bits.TMR0IP = 0; // Timer0 Interrupt is Low Priority
 
 INTCONbits.GIEH = 1; //INTCONの7bit目
       //高位割込み許可
 INTCONbits.GIEL = 1; //INTCONの6bit目
       //低位割込み許可
 
 while(BusyADC());       //AD変換が終わるまで待つ

 // configure USART  
 OpenUSART(USART_TX_INT_OFF & //送信割込みの禁止  
 USART_RX_INT_OFF &       //受信割込みの禁止  
 USART_ASYNCH_MODE &      //非同期(調歩)モード  
 USART_EIGHT_BIT &      //8ビットモード  
 USART_CONT_RX &        //連続受信モード  
 USART_BRGH_LOW,        //低速ボーレート  
 77);             //SPBRGレジスタ 9600 bps  

 while (1)
 {
  ConvertADC();   //start A/D
  ADread = ReadADC();     //AD変換値読込み int
  itoa(ADread,buf_ad); //型変換 
  putsUSART(ad_value); //
  putsUSART(buf_ad);  //rs232c通信で送信
  putsUSART(str2);  //改行
  putsUSART(v_value);
  press = ADread * 0.005;//電圧値を取得
  One_digit = press;  //電圧値の整数部分
  itoa(One_digit,buf_ad); //型変換 
  putsUSART(buf_ad);  //送信
  WriteUSART('.');  //コンマの送信
  v_m = press*100 - One_digit*100;//小数点以下2桁取得
  itoa(v_m,buf_ad);  //型変換 
  putsUSART(buf_ad);  //送信
  putsUSART(str2);  //改行
  
  Delay10KTCYx(200);  //wait about 0.8sec

 }
 
 CloseUSART();
}

LM60を使った温度計作成準備

温度センサーのM60BIZ(TO-92)を秋月電子通商で購入したので、
温度計を作成したいと思います。

データシートに書かれている値をエクセルの散布図でグラフにしてみました。
温度(T) 出力電圧Vo
125℃ 1205mV
100℃ 1049mV
25℃ 580mV
0℃ 424mV
-25℃ 268mV
-40℃ 174mV

上の表は、+Vs(入力電圧)が+2.7Vの時の表のようです。

出力電圧の計算式も書いてありました。
Vo(出力電圧)=(+6.25mV/℃xT℃)+424mV
出力電圧から温度を求めるには、
T℃=(Vo-424mV)/(+6.25mV/℃)

例:125℃、1205mVの時
 +125℃=(+1205mV-424mV)/(+6.25mV/℃)  //分かりにくい
124.96=(1205-424)/6.25

例:1℃
1℃=430.25mV....

正確なAD変換の値を取得するには基準電圧が必要という事で、
LM336Z-2.5 を入手しました。

10ビットのA/D変換では0から1023の値が得られるので、
意味があるか分かりませんが、2.5Vを1023等分した場合のグラフも描いてみました。
2500mV/1023=2.444
 A/D変換の値X2.444で出力電圧(mV)が得られる。

1.温度センサー 出力電圧のA/D変換値を求める
2. A/D変換値から出力電圧を求める。
3. 出力電圧から温度を求める
こんな感じでいいのだろうか?

LM336Z-2.5 を基準電圧に使った温度計の製作例があったのでLM336Z-2.5を選択したのですが、
A/D変換の精度を出すためには下記の条件が必要のようです。
VrefH - VrefL > 3V
VrefL=GND(0V)に設定したとしても高い方の基準電圧(Vrefh)と低い方の基準電圧の(Vrefl)の差が3V 以上にはならないような気がする。

LM336Z-5.0を選択した方が良かったかもしれない。

2010年11月20日土曜日

RS232C通信-PIC18F2550

LED やスイッチ、可変抵抗器は必要ありません。




/*
概要:とりあえずRS232C通信
ブートローダーを使った書き込み

マイコン:PIC18F2550

ファイル名:RS232C.c

開発環境:MPLAB C18

*/

#include <p18f2550.h>
#include <usart.h>
#include <stdio.h>

// リセットベクタ  
#pragma code reset_vector=0x1000

extern void _startup(void);
void remapped_reset(void) { _asm goto _startup _endasm}

#pragma code

void main (void)
{
 char Mes[10]="Start!!\r\n";
 
 // configure USART
 OpenUSART(USART_TX_INT_OFF & //送信割込みの禁止
 USART_RX_INT_OFF &    //受信割込みの禁止
 USART_ASYNCH_MODE &   //非同期(調歩)モード
 USART_EIGHT_BIT &   //8ビットモード
 USART_CONT_RX &    //連続受信モード
 USART_BRGH_LOW,    //低速ボーレート
 77);       //SPBRGレジスタ 9600 bps
 
 TRISC = 0b11111101;                 //RC7(RX): input mode   RC6(TX): output mode
 
 while (1)
 {
  putsUSART(Mes);
 }
 
 CloseUSART();
}

SPBRGレジスタの計算方法
FOSC = HSPLL_HS//48MHz
通信速度:9600bps
USART_BRGH_LOW:64
48*1,000,000/9,600/64-1=77.125

RS232C.zip
ダウンロード

ビルドして書き込んで動作確認-PIC18F2550-MCHPUSB - Generic Driver Demo

PIC18F4550 用のファームウェをそのまま無修正で利用出来ました。
RA0/AN0 ポートに可変抵抗器を接続しました。



ビルドして書き込んで動作確認-PIC18F2550-CDC - Basic Demo

PIC18F4550 用のファームウェがそのまま利用出来ました。



LEDとスイッチ部分の修正

HardwareProfile - PICDEM FSUSB.h にLED とスイッチを接続するポートの指定が書いてあります。

LED接続ポートの変更
修正前のソース
    /** LED ************************************************************/
    #define mInitAllLEDs()      LATD &= 0xF0; TRISD &= 0xF0;
   
    #define mLED_1              LATDbits.LATD0
    #define mLED_2              LATDbits.LATD1
    #define mLED_3              LATDbits.LATD2
    #define mLED_4              LATDbits.LATD3

修正後のソース
    /** LED ************************************************************/
    #define mInitAllLEDs()      LATC &= 0xF0; TRISC &= 0xF0;
   
    #define mLED_1              LATCbits.LATC0
    #define mLED_2              LATCbits.LATC0
    #define mLED_3              LATCbits.LATC1
    #define mLED_4              LATCbits.LATC2

下線部の部分(D->C)を修正
ポートが少ないのでmLED_1 mLED_2を一緒にしています。

スイッチ接続ポートの設定部分は変更なしでそのまま
RB4,RB5に接続しておけば大丈夫だと思います。

はじめに-PIC18F2550

PIC18F4550(USB内蔵)コーナーの
PIC18F4550 USBマイコンボード(秋月電子通商製)で遊ぶ も参考になります。

2010年11月19日金曜日

ビルドして書き込む-USB Device - HID - Mouse-PIC18F2550


PIC18F4550 用のプログラムがそのまま使えます。
RB5ポートに接続されているスイッチを押すと回転が止まります。

ブートローダーで書き込むプログラムの作成-PIC18F2550


/*
概要:ブートローダーを使ったプログラムで書き込むためのプログラム
マイコン:PIC18F2550

ファイル名:LED001.c

RC0:LED
*/
#include <p18f2550.h>
#include <delays.h>

// リセットベクタ  
#pragma code reset_vector=0x1000

extern void _startup(void);
void remapped_reset(void) { _asm goto _startup _endasm}

#pragma code

void main(void) {
  TRISCbits.TRISC0=0;   // RC0 is output (LED)
  
  while(1) {
    PORTCbits.RC0=1;   // RC0=ON 
    Delay10KTCYx(250);
    PORTCbits.RC0=0;   // RC0=ON 
    Delay10KTCYx(250); 
  }
}

LED001.c ファイルの他にrm18f2550 - HID Bootload.lkr ファイルを用意する必要があります。
rm18f2550 - HID Bootload.lkr ファイルはrm18f4550 - HID Bootload.lkr のコードを修正して、
ファイル名を変更したものです。
変更箇所は一か所です。
FILES p18f4550.lib

FILES p18f2550.lib

PIC18F2550-LED.zip
ダウンロード

コンフィギュレーションは ブートローダが制御しているのでプログラムで指定する事はできませんん。
作成するプログラムは0x1000から記述する必要があります。

割り込み制御について、PICは割り込みが発生すると0x0008または0x0018にある割り込みベクタへプログラムカウンタを移動させます。
この領域はブートローダが制御する領域なので、この領域を使用したプログラムを作成することはできません。
割り込みが発生すると、ブートローダは0x1008または0x1018にジャンプする命令を実行します。
作成するプログラムでは、割り込みの制御を0x1008と0x1018に記述しておく必要があります。

// リセットベクタ
#pragma code 0x1000

// エントリポイント
void main() {
 // 任意の処理
}

// 高優先割り込みベクタ
#pragma code ih_vect = 0x1008
void ih_vect_method() {
 _asm
  GOTO ISR_HIGH
 _endasm
}

// 低優先割り込みベクタ
#pragma code il_vect = 0x1018
void il_vect_method() {
 _asm
  GOTO ISR_LOW
 _endasm
}

#pragma code
#pragma interrupt ISR_HIGH
#pragma interruptlow ISR_LOW save = WREG,BSR,STATUS

PIC18F2550に書き込む-PICkit 2


LEDは通電確認用

PIC18F4550との比較


PIC18F2550のピン配置


ブートローダーの書き込み

USBフレームワークのPIC18F4550 用のブートローダーがそのまま使えました。

2010年11月18日木曜日

PWM機能でLEDの明るさ制御


RB0ポートかRB3ポートのどちらかを選択して利用出来ます。
Device Flags:で指定します。


/*
概要:PWM機能でLEDの明るさ制御

使用マイコン:16F886

使用ポート:RB0/INT/CCP1

発振器: Clock: 8.0MHz 内蔵発振

Device Flags:
 _CP_OFF    _CCP1_BR0   _DEBUG_OFF  _WRT_ENABLE_OFF
_CPD_OFF _LVP_OFF    _BODEN_OFF _MCLRE_OFF
_PWRTE_ON _WDT_OFF    _INTRC_IO
IESO_ON__CFG2   _FCMEN_ON__CFG2

MikroC v8.2.0.0
*/


void main() {

 unsigned short int i;

 OSCCON = 0b01110000; //内蔵発振器 8MHz使用に設定

 // A/D Pref // ANALOG=1, DIGITAL=0 
 ANSEL = 0b00000000;

 TRISA = 0b11111111;  //すべてインプット
 TRISB = 0b00000000;  //すべてアウトプット

 //ポートの初期化
 PORTA = 0b00000000;
 PORTB = 0b00000000;

 //PWM mode//
 PWM_Init(5000);   //Initialize PWM module at 5KHz:
 PWM_Start();   // start PWM

 while (1) {
  for (i = 0; i < 256; i++){
  PWM_Change_Duty(i);
  Delay_ms(50);
 }

 }
}

PWM_Change_Duty(i); iが0の時0% 127の時50% 255の時100%とマニュアルには書いてありました。

2010年11月17日水曜日

A/D変換+RS232C通信




RA3ポートは基準電圧です。本来なら電源電圧に接続しないで、正確に出力された電源に接続するべきでしょう。
電源電圧を基準電圧に使うならRA3ポートを使って電源電圧に接続しないで、
プログラムで基準電圧に電源電圧を利用する設定をすればいいでしょう。
ADCON1.VCFG1 = 0; //基準電圧は電源電圧
ADCON1.VCFG0 = 0;

/*
概要:A/D変換した値をRS-232c通信でパソコンに送信

PIC16F88

A/D: RA1 (10KΩ半固定抵抗で分圧しアナログ値を生成)
基準電圧入力ポート:RA3
RS-232通信用:RB2/RX RB5:TX

Clock: 8.0MHz 内蔵発振器使用

Device Flags:
_CP_OFF  _CCP1_RB3  _DEBUG_OFF  _WRT_ENABLE_OFF
_CPD_OFF  _LVP_OFF  _BODEN_OFF  _MCLR_OFF  _PWRTE_ON
_WDT_OFF  _INTRC_IO  _IESO_ON__CFG2  _FCMEN_ON__CFG2

MikroC v8.2.0.0
*/
 void main() {
 //使用変数の定義
 float volt,press,calc,adc_value;
 char inter, deci;

 PORTA = 0b00000000; //PORTAの初期化
 PORTB = 0b00000000; //PORTBの初期化

 OSCCON = 0b01110000; //内臓クロック8MHzに設定

 //A/D変換clock設定 0.125us*16倍=2.0us at 8MHz > 1.6us
 //Fosc=8MHz 8/2/8
 ADCON0.ADCS1=0;  //01 Fosc/8
 ADCON0.ADCS0=1;
 ADCON1.ADCS2=1;     //1:Foscを1/2にする

 ADCON1.VCFG1 = 1; //基準電圧入力ポートをRA3に設定
 ADCON1.VCFG0 = 0;   //Vref+  Vss

 // A/D利用PORTの設定 // ANALOG=1, DIGITAL=0 //
 ANSEL = 0b00000010; //RA3のみアナログ使用

 TRISA = 0b00001010; //RA1,RA3のみ1:入力に設定、他は0:出力
 //マイコンの初期化終わり

 usart_init(9600);

 do {
  //アナログデータの取得 10bit(0~1023)
  adc_value = ADC_Read(1); //RA1値をアナログデジタル変換(0~1023)
  press = adc_value*0.005; //AD変換した値を電圧に 0.005=基準電圧(5v)/1023 pressは小数点未満二桁
  inter = (int) press;        //小数点未満の切り捨て
  deci= (int) (press*10.0) - inter*10;//小数点未満の一桁目を取得
  usart_write('V');
  usart_write('O');
  usart_write('L');
  usart_write('T');
  usart_write('=');
  usart_write(inter | 0x30);
  usart_write('.');
  usart_write(deci | 0x30);
  usart_write('V');
  usart_write(13);        //1310改行コード
  usart_write(10);
  delay_ms(1000);
 } while(1);
}

USB機能内蔵PIC24一覧

PIC24FJ32GB002
PIC24FJ32GB004
PIC24FJ64GB002
PIC24FJ64GB004
PIC24FJ64GB106
PIC24FJ64GB108
PIC24FJ64GB110
PIC24FJ128DA106
PIC24FJ128DA110
PIC24FJ128DA206
PIC24FJ128DA210
PIC24FJ128GA008
PIC24FJ128GB106
PIC24FJ128GB108
PIC24FJ128GB110
PIC24FJ128GB206
PIC24FJ128GB210
PIC24FJ192GB106
PIC24FJ192GB108
PIC24FJ192GB110
PIC24FJ256DA106
PIC24FJ256DA110
PIC24FJ256DA206
PIC24FJ256DA210
PIC24FJ256GB106
PIC24FJ256GB108
PIC24FJ256GB110
PIC24FJ256GB206
PIC24FJ256GB210

2010年11月15日月曜日

RS232C通信-PCソフトを作成してLED点灯

PIC18F4550 USBマイコンボード(秋月電子通商製)で遊ぶ
のコーナーのCDC - Basic Demo の 
ボタンでLEDの点灯・消灯 で作ったソフトを流用して作成しました。


パソコン側ソフト:pic-pc.zip
ダウンロード

PIC側ソフト:rs232c-pic-pc.zip
ダウンロード

RS232C通信-コマンドでLED点滅

とりあえずRS232C通信 で作成したプログラムを修正して、
コマンドを送ってLEDを点滅させるプログラムに変更したいと思います。

/*
概要:RS232C通信-コマンドでLED点滅

対象PIC  :PIC16F88
クロック :内蔵8MHz
コンパイラ:mikroC Version: 8.2.0.0

電源:5V

コンフィグレーションフラグ:
_CP_OFF  _CCP1_RB3  _DEBUG_OFF  _WRT_ENABLE_OFF
_CPD_OFF  _LVP_OFF  _BODEN_OFF  _MCLR_OFF  _PWRTE_ON
_WDT_OFF  _INTRC_IO  _IESO_ON__CFG2  _FCMEN_ON__CFG2


*/

void main() {

    unsigned short int com;


 PORTA = 0b00000000;  //PortBの中初期化
 PORTB = 0b00000000;  //PortBの中初期化

 OSCCON = 0b01110000; //8MHzを指定

 ANSEL = 0b00000000;  //すべてデジタルポート

 TRISA = 0b00000000;
 TRISB = 0b00000100;    //B2/RXを入力に,B5/TXを出力

 Usart_Init(9600);      //通信速度の設定

 do {

        if (Usart_Data_Ready()) {
            com = Usart_Read(); //受信データの読込
        }

        switch(com) {
            case 'a':
                PORTA.F0 = 1; //RB5 ON
                break;
            case 'b':
                PORTA.F0 = 0; //RB5 OFF
                break;
        }
    } while(1);

}

とりあえずRS232C通信

使うのは2,3,5,7,8番ピン
7番ピンと8番ピンは直結します。
パソコンからの送信要求(7番ピン)に対し、
無条件に送信可(8番ピン)を返すようにするためです。
5番ピンはグランドに接続します。
2番ピンと3番ピンだけが、PICから制御する信号線になります。


aを永遠に送り続けるだけのプログラム
/*
概要:取り合えすRS232C通信

対象PIC  :PIC16F88
クロック :内蔵8MHz
コンパイラ:mikroC Version: 8.2.0.0

電源:5V

コンフィグレーションフラグ:
_CP_OFF  _CCP1_RB3  _DEBUG_OFF  _WRT_ENABLE_OFF
_CPD_OFF  _LVP_OFF  _BODEN_OFF  _MCLR_OFF  _PWRTE_ON
_WDT_OFF  _INTRC_IO  _IESO_ON__CFG2  _FCMEN_ON__CFG2


*/

void main() {
 PORTA = 0b00000000;  //PortBの中初期化
 PORTB = 0b00000000;  //PortBの中初期化

 OSCCON = 0b01110000; //8MHzを指定

 ANSEL = 0b00000000;  //すべてデジタルポート

 TRISA = 0b00000000;
 TRISB = 0b00000100;    //B2/RXを入力に,B5/TXを出力

 Usart_Init(9600);      //通信速度の設定

 do {
    Usart_Write('a'); //RS232C通信でPCへ送信
 } while(1);

} 





mikroC のメニューバーのTools から USART Terminal を開いて接続してたところ


ハイパーターミナルで表示した場合

電源を入れた直後の接続しか正常に常時出来ません。
接続と切断を繰り返すと別な文字が表示されたりします。

2010年11月12日金曜日

赤外線リモコンの受信

概要:赤外線リモコンの信号受信
使用PIC:PIC16F88
赤外線リモコン受信モジュール:PL-IRM-2161-C438(秋月電子通商で購入)
使用リモコン:NECのテレビリモコン

参考サイト
PICとMikroCのTVリモコン信号の受信機 のコーナーは非常に参考になりました。
リモコンのフォーマットは 秋月電子通商のダウンロードコーナーの資料も大いに役立ちます。
手元にNECのテレビリモコンがあってラッキーでした。



タイマTMR0を使用しての時間の計測
内部クロックの周期は(1/4MHz)*4=1usとなる。
TMR0は8bitのカウンタであるため,
TMR0は,256us(1us * 256)までの時間を計測することができる。
これではリーダー部の9msを計測できないのでプリスケーラを設定する。

プリスケーラ1/64に設定
(1/4MHz)*4*64=64us=0.0664ms
TMR0は,16.384ms(64us * 256)までの時間を計測することができるようになる.
0.064msから16.384ms の間の時間を計測できる。

リーダ部の9ms を計測したい場合に必要なタイマーカウント、
9ms = 0.064ms * x
x = 9ms/0.064ms
x = 140.625 = 141回
/**
概要:TVリモコン信号(赤外線)受信器
(ボタンと押している間だけLED点灯、ボタンをはなすとLED消灯)

Device Flags: _BODEN_OFF _BOREN_OFF _CP_OFF _PWRTE_ON _WDT_OFF
       _LVP_OFF _MCLRE_OFF _INTRC_OSC_NOCLKOUT

PICとMikroCさん(http://kuri6005.sakura.ne.jp/pic/)のソースを
PIC16F88  内蔵4MHzに変更
RB0:赤外線リモコン受信モジュール PL-TRM2161-C438 二個で100円
LED: RB2, RB3, RB4, RB5 動作確認用
電源:乾電池2本(3V)
コンパイラ:MikroC 8.2.0.0
*/
unsigned short int flag = 0;
unsigned short int custom_a = 0;
unsigned short int custom_b = 0;
unsigned short int data_a = 0;
unsigned short int data_b = 0;
unsigned short int old_F2 = 0;
unsigned short int old_F3 = 0;
unsigned short int old_F4 = 0;
unsigned short int old_F5 = 0;

void interrupt() {            //割込み関数
    unsigned short int i, b;

    if(INTCON.INTF) {         //割込み種がRB0/INT割込みの場合
        INTCON.INTE = 0;      //RB0/INT割込みの禁止

        //リーダ部の確認        時間の計測にはタイマー0を割込みなしで使用
        TMR0 = 0;            //timer0リセット、タイマーは常に動作
        
        while(PORTB.F0 == 0);   //0Vの状態をカウント、5Vになるまでループ
                                //カウンタの比較
        if(TMR0 < 120) {       // < 141 (=9.0ms * 4MHz/4 /64) 誤差を見越して120
            flag = 1;           //120より少なかったらヘッダではないので受信を終了し、
            return;             //メインルーチンに戻り、受信待ち状態にします
        }                       //120以上であれば次に進みます。

                   //リーダー部の残りの部分を判定
        TMR0 = 0;            //timer0リセット
        while(PORTB.F0 == 1);   //5Vの状態をカウント
        if(TMR0 < 27) {        // < 35 (=2.250ms * 4MHz/4 /64)
            flag = 1;
            return;
        }else if(TMR0 < 60) { // < 71 (=4.5ms * 4MHz/4 /64)
            //リピートリーダを受信した時
            PORTB.F2 = old_F2;
            PORTB.F3 = old_F3;
            PORTB.F4 = old_F4;
            PORTB.F5 = old_F5;
            Delay_ms(96);
            flag = 1;
            return;
        }
        //リーダー部の確認終了

        //custom codeの取得
        custom_a = 0;
        for (i = 0; i < 8; i++) {   //繰返し0-7になるまで
            TMR0 = 0;         //timer0リセット
            while(PORTB.F0 == 0);     //0Vの期間をカウント
            while(PORTB.F0 == 1);     //5Vの期間をカウント
            if(TMR0 < 27)       // < 18 (=1.125ms * 4MHz/4 /64) 誤差を見越して27(35より小さい値)
                b = 0;
            else                // < 35 (=2.250ms * 4MHz/4 /64)
                b = 1;
            custom_a |= (b << i);     //custom_aと(b << i)の論理和をcustom_aに代入する
                     //bを左にiビットずらす
        }
        custom_b = 0;
        for (i = 0; i < 8; i++) {
            TMR0 = 0; //timer0リセット
            while(PORTB.F0 == 0);
            while(PORTB.F0 == 1);
            if(TMR0 < 27) // < 18 (=1.125ms * 4MHz/4 /64)
                b = 0;
            else          // < 35 (=2.250ms * 4MHz/4 /64)
                b = 1;
            custom_b |= (b << i);
        }
        //custom codeの取得終了

        //data codeの取得
        data_a = 0;
        for (i = 0; i < 8; i++) {
            TMR0 = 0; //timer0リセット
            while(PORTB.F0 == 0);
            while(PORTB.F0 == 1);
            if(TMR0 < 27) // < 18 (=1.125ms * 4MHz/4 /64)
                b = 0;
            else          // < 35 (=2.250ms * 4MHz/4 /64)
                b = 1;
            data_a |= (b << i);
        }

    data_b = 0;
        for (i = 0; i < 8; i++) {
            TMR0 = 0; //timer0リセット
            while(PORTB.F0 == 0);
            while(PORTB.F0 == 1);
            if(TMR0 < 27) // < 18 (=1.125ms * 4MHz/4 /64)
                b = 0;
            else          // < 35 (=2.250ms * 4MHz/4 /64)
                b = 1;
            data_b |= (b << i);
        }
        //while(PORTB.F0 == 0); //ストップビット受信

        //data_aとdata_bの各ビットを反転しその結果が同じか比較
        if (data_a == ~data_b) {  //data誤りのチェックOKの場合
            switch (data_a) {
                case 0x11:     //2チャンネルのボタンが押されている場合
                    PORTB.F2 = 1;   //RB2ポートのLEDを点灯する。
                    PORTB.F3 = 0;
                    PORTB.F4 = 0;
                    PORTB.F5 = 0;
                    break;

                case 0x13:      //4チャンネルのボタンが押されている場合
                    PORTB.F2 = 0;
                    PORTB.F3 = 1;
                    PORTB.F4 = 0;
                    PORTB.F5 = 0;
                    break;

                case 0x15:      //6チャンネルのボタンが押されている場合
                    PORTB.F2 = 0;
                    PORTB.F3 = 0;
                    PORTB.F4 = 1;
                    PORTB.F5 = 0;
                    break;

                case 0x17:      //8チャンネルのボタンが押されている場合
                    PORTB.F2 = 0;
                    PORTB.F3 = 0;
                    PORTB.F4 = 0;
                    PORTB.F5 = 1;
                    break;

                default:
                    PORTB.F2 = 0;
                    PORTB.F3 = 0;
                    PORTB.F4 = 0;
                    PORTB.F5 = 0;
                    break;
            }
            old_F2 = PORTB.F2;
            old_F3 = PORTB.F3;
            old_F4 = PORTB.F4;
            old_F5 = PORTB.F5;
        }
    }
    Delay_ms(40);
    flag = 1;
}

void main() {
    //使用変数の定義
    unsigned short int i;

    PORTB  = 0b00000000;  //PORTBの中身をきれいにする
  OSCCON = 0b01100000;  //内臓クロック4MHzに設定
    TRISB  = 0b00000001;  //RB0を1:入力、他は0:出力に設定

    //PIC稼働確認(LED点滅)
    for (i=0; i < 5; i++) {
        PORTB = 0b11111110;
        Delay_ms(50);
        PORTB = 0b00000000;;
        Delay_ms(50);
    }

    //timer0プリスケーラ64回に設定
    OPTION_REG = 0b10000101;

    INTCON.INTE = 1;    //RB0/INT割込みの許可
    INTCON.GIE = 1;    //全体割込み許可

    do {
        if(flag == 1) {
            flag = 0;
            PORTB.F2 = 0;
            PORTB.F3 = 0;
            PORTB.F4 = 0;
            PORTB.F5 = 0;
            INTCON.INTE = 1; //RB0/INT割込みの許可
        }
    }while(1);
}

参考:5Vになるまでと表現していますが、実際には、受信センサーからの出力される電圧です。

電源関係

よく使う電源

単三乾電池2つ直列接続 3V・1500mAh

USBバス電源 4.75 - 5.25 V(ホスト側)・500mA

クロック設定

設定例:
OSCCON = 0b01110000;        // クロックを8Mhzに設定する。


概要:USB Device - HID - Mouse

ファームゥエアは、USB Device - HID - Mouse フォルダの HID - Mouse - Firmware フォルダの中の USB Device - HID - Mouse - C18 - PICDEM FSUSB.mcp を開いてビルドして書き込みます。

書き込んでUSB ケーブルで繋げると自動的にドライバをインストールして、
マウスのポインターがグルグル回りだします。
RB5に繋がっているスイッチを押すと停止し、もう一度押すと動き出します。

2010年11月11日木曜日

TMR0

概要:短い期間でのインターバルタイマーなどに利用できる。

タイマー0は8ビットのタイマーカウンタ で、
1命令サイクル毎に+1されます。(プリスケーラで変更できます)
最初に設定した値からカウントアップが始まります。

最大256のプリスケーラを併用すると65,535までのクロックをカウントすることができる
プリスケーラとは、カウント周波数を遅くする回路のこと。
クロックは外部入力と内部発生を選択することができる
TMR0(タイマーカウンタ)のカウント値がFFH(255)から00Hに戻る(オーバフロー)時TMR0割込みが発生する。
基本的にはアップカウンタ

カウント開始からFFHを過ぎて割り込みが発生するまでのインターバル時間を調整するために、
TMR0に初期値を書き込む操作を行ないます。

TMR0の初期値とプリスケーラ値の設定によって割り込み発生までに必要なカウント値が決まります。

タイマーカウンタTMR0はSFR(スペシャルファンクションレジスタ)として読み書きが可能で、プリスケーラ値やクロックの外部/内部の選択、および外部クロック時の立上り/立下りタイミングの設定などの、TMR0の動作設定はOPTIONレジスタによって行ないます。

内部クロック
周期 = 1/システムクロック周波数 x 4
システムクロックが20MHzの場合は、1/20MHz x 4 = 0.2μSということになります。

TMR0のカウントアップ周期 = 内部クロック周期 x プリスケーラ設定値
実際のタイマーカウンタTMR0は、
プリスケーラを経由した後のクロック周期でカウントアップされます。
プリスケーラは1:2~1:256の8段階から選択できますので、
上記の通りシステム クロックが20MHzの場合、
プリスケーラが1:2の時は0.4μS、
1:256の時は51.2μSのカウントアップ周期となります。

システムクロックが20MHzの場合、TMR0を使ったタイマー動作では、51.2μS x 255カウント = 13.056mS が計測できる最長時間ということになります。

TMR0に200がセットされていると、56命令サイクル(255-200+1)でTMR0割込みが発生します。
クロックとして20MHzを使用していますので、1命令サイクルは0.2μSです。
プリスケーラが1:2の時は0.4μS
22.4μS(0.4μS×56サイクル)でTMR0割込みが発生します。

16ビットタイマーの場合
8ビットタイマーは256カウントが限界でした。
16ビットタイマーは256x256で65,536カウントが限界になります。

クロックとサイクル

クロックは、OSC1,OSC2ピンに接続する発振子の周波数により決定されます。
10MHzの発振子を使用している場合、
1秒当たりのクロック数は、  
10MHz  = 10,000,000 = 0.1μS(マイクロ秒)
となり、
1クロックの時間は  
1秒/10,000,000 = 0.0000001秒 = 0.1μS(マイクロ秒)
となります。

(参考)
ミリ(m)は10の−3乗
マイクロ(μ)は10の−6乗
ナノ (n)は10の−9乗

PICマイコンには、35個の命令があります。
全ての命令は4クロックで実行されます。
4クロックを1サイクルと呼びます。

1つの命令は、4クロック(1サイクル)で実行されますので、
1命令は、 0.4μS 必要です。

(参考)
必要な待ち時間などを設定する場合の計算
0.5秒の待ち時間を設定したい場合に必要なサイクルは、
0.5S/0.4μS = 1,250,000命令(サイクル) となります。


2010年11月10日水曜日

LEDの点滅

/*
概要:A/D変換値を液晶ディスプレイ(LCD)に表示 データ4bit接続

対象PIC  :PIC16F88
クロック :内蔵8MHz
コンパイラ:mikroC Version: 8.2.0.0

Led  :RA0

電源:5V

コンフィグレーションフラグ:
* _CP_OFF  _CCP1_RB3  _DEBUG_OFF  _WRT_ENABLE_OFF
* _CPD_OFF  _LVP_OFF  _BODEN_OFF  _MCLR_OFF  _PWRTE_ON
* _WDT_OFF  _INTRC_IO  _IESO_ON__CFG2  _FCMEN_ON__CFG2


*/
void main() {

     PORTA = 0b00000000; //PORTAの初期化
     PORTB = 0b00000000; //PORTBの初期化
     OSCCON = 0b01110000; //内臓クロック8MHzに設定

    // A/D利用PORTの設定 // ANALOG=1, DIGITAL=0
    ANSEL = 0b00000000; //全てデジタル使用

    TRISA = 0b00000000; //PORTA 全て出力に設定

    do {
        //RA0 のLDEを点滅させる
        PORTA.F0 = 1;
        Delay_ms(1000);
        PORTA.F0 = 0;
        Delay_ms(1000);
    } while(1);
}

マイコンを使うきっかけ

マイコンを使うきっかけは、
離れた所からパソコンのマウス操作をテーブル等が無くても出来るようにしたいと思ったからです。

予定
使ってないリモコンを使ってパソコンを操作する。

2010年11月9日火曜日

LCDに文字を表示


mikroC で用意されているライブラリを使用しています。
可変抵抗器VRは10KΩの炭素被膜抵抗器に置き換える事も可能です。

/*
概要:A/D変換値を液晶ディスプレイ(LCD)に表示 データ4bit接続

対象PIC  :PIC16F88
クロック :内蔵8MHz
コンパイラ:mikroC Version: 8.2.0.0

LCD制御 :R/W:RB0  RS:RB2  E:RB3
LCDデータ:DB4:RB4 DB5:RB5 DB6:RB6 DB7:RB7 

電源:5V

コンフィグレーションフラグ:
 _CP_OFF  _CCP1_RB3  _DEBUG_OFF  _WRT_ENABLE_OFF
 _CPD_OFF  _LVP_OFF  _BODEN_OFF  _MCLR_OFF  _PWRTE_ON
 _WDT_OFF  _INTRC_IO  _IESO_ON__CFG2  _FCMEN_ON__CFG2
*/
void main()
{

    PORTA = 0b00000000; //PORTAの初期化
    PORTB = 0b00000000; //PORTBの初期化
    OSCCON = 0b01110000; //内臓クロック8MHzに設定

    // A/D利用PORTの設定 // ANALOG=1, DIGITAL=0 //
    ANSEL = 0b00000000; //全てデジタル使用

    //PORTの設定 0:出力 1:入力
    TRISA = 0b00000000; //PORTA 全て出力に設定
    TRISB = 0b00000000; //PORTB 全て出力に設定
    //マイコンの初期化終わり

    Lcd_Config(&PORTB,2,3,0,7,6,5,4); //LCDのピン接続設定
    Lcd_Init(&PORTB); //LCD初期化

    Lcd_Cmd(LCD_CURSOR_OFF); //カーソル非表示

    Lcd_Out(1, 1, "hello sc1602bslb");//LCD上段文字列表示
    Lcd_Out(2, 1, "pic16f88"); //LCD下段文字列表示

}

タブがスペースに変換されるのを解除

メニューバーのTools->Options... を選択します。
Open options dialog... ボタンをクリックします。
Options タブを選択します。
 Tab to spaces のチェックを外します。

PIC16F88に書き込む

PIC16F88に書き込むには、ちょと細工をしないと書き込めないようです。
書き込みソフトのPICkit 2 v2.61で書き込む場合、
連続して、書き込み出来ない時などは、
一旦他のディバイスを選択してから、
PIC16F88のディバイスを選択し直せば、書き込みが成功したりします。

ディバイスの読み込み(Read)は出来るが、書き込みが出来なかったりする時は、
http://www.microchip.com/forums/tm.aspx?m=242087 にあるように、
VDD PICkit 2 をOn にして3.0にしてReadボタンを押して、
アドレス0番に2800と入力して、Write ボタンを押す。
VDDを5.0にして、 Eraseボタンを押して完了。(この部分は飛ばしても良かったです。)
書き込むファイルを読み込んで書き込むと成功したりします。

2010年11月8日月曜日

背景、コメントの斜体・色の変更

メニューバーのTools->Options... を選択します。
 コメントが斜体だと見にくいので、Itakic を解除しました
また、緑だと 設定値の緑と同じで見にくいので色を変更しました。

コンフィグレーション一覧

コンフィグレーション指定サンプル
__CONFIG _CONFIG1, _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF & _BODEN_ON & _LVP_OFF & _CPD_OFF & _DEBUG_OFF


_CONFIG1             備考
_CP_ALL コードプロテクション。読み込み禁止。
プロテクト オン

_CP_OFF
プロテクト オフ

_CCP1_BR0 CCP1ピンの選択 RB0
_CCP1_RB3 CCP1ピンの選択 RB3
_DEBUG_OFF デバッグ機能を使うかどうか
_DEBUG_ON ONにするとRB6とRB7はデバッガ用になってIOに使えない。
_WRT_ENABLE_OFF Writeプロテクション。書き込み禁止。
_WRT_ENABLE_512

_WRT_ENABLE_1052

_CPD_ON Data EE Memoryのコードプロテクション。読み込み禁止。
_CPD_OFF

_LVP_ON Low-Voltage Programming の設定。
_LVP_OFF ONにするとRB3はPGMピンになる。
_BODEN_ON ブラウンアウトリセットの設定。
_BODEN_OFF

_MCLR_ON MCLRを使うかどうか。ONにするとRA5はMCLR。
_MCLR_OFF OFFにするとRA5として使えて、内部的にMCLRはVddと直結する。
_PWRTE_OFF パワーアップタイマー。
_PWRTE_ON

_WDT_ON ウォッチドッグタイマー。
_WDT_OFF

_EXTRC_CLKOUT
外部RC発振モード OSC2ピンはクロック出力

_EXTRC_IO
外部RC発振モード OSC2ピンはRA6として汎用入出力

_INTRC_CLKOUT RA6(15番ピン)に(内部周波数)/4 Hz が出力される
_INTRC_IO 内臓クロックを使って、クロック用の足をIOに使う。
_EXTCLK
外部発振器モード OSC2ピンはRA6として汎用

_HS_OSC 4MHz~20MHz(水晶振動子orセラミック振動子)
_XT_OSC 4MHz以下(水晶振動子orセラミック振動子)
_LP_OSC 100KHz以下(水晶振動子,省電力モード)

_CONFIG_2
備考
_IESO_ON__CFG2 外部クロックが安定するまでは内蔵クロックを使う。
_IESO_OFF__CFG2

_FCMEN_ON__CFG2 外部クロックが途切れたときは内蔵クロックを使う。
_FCMEN_OFF__CFG2

PIC16F88のピン配置


切断ボタンの追加

USBデバイス用のハンドルとの切断は
BOOL CloseHandle(
  HANDLE hObject   // オブジェクトのハンドル
);
とする。
msdn:http://msdn.microsoft.com/ja-jp/library/cc429605.aspx
How to Access a USB Device by Using WinUSB Functions

ボタンを追加して、クリックイベントに下記ソースを追加
private: System::Void button3_Click(System::Object^  sender, System::EventArgs^  e) {
            bool MatchFound = false;

   MatchFound = CloseHandle(MyDeviceHandle);

   if(MatchFound == true)  //切断に成功した場合
   {
    
    ToggleLED_btn->Enabled = false; 
    GetPushbuttonState_btn->Enabled = false;
    StateLabel->Enabled = false;
    label1->Text = "接続状態:未接続";
   }     

   }

接続ボタンを2度押した場合には、切断ボタンが効かなくなった、
なぜだろう?
とりあえず、2度押し出来ないようにしました。

PC側ソフトの内容を分析

電圧の取得は
.NET Framework SDK 2.0 のクラス ライブラリ の
BackgroundWorker クラス を使用して、
グローバル変数の ADCValue に値を入れている。

ライブラリの詳細: http://msdn.microsoft.com/ja-jp/library/system.componentmodel.backgroundworker%28VS.80%29.aspx#

プログレスバーの表示は、
Timer クラス を使用して、
タイマーで指定した間隔でプログレスバーに値を表示しています。
ライブラリの詳細:http://msdn.microsoft.com/ja-jp/library/system.windows.forms.timer.aspx

vc++のタイマーのインターバル指定
8m秒 を指定したい時 8
8秒 を指定したい時 8000


2010年11月7日日曜日

RBO,RB1でLED点滅

WinUSB - Generic Driver Demo を参考にしてカスタマイズ

PC側ソフトはボタンを2つ追加して、クリックされた時に
0x82、0x83 のコマンドを送るようにしただけです。
private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
  ULONG BytesWritten = 0;
  unsigned char OutputPacketBuffer[64];

  OutputPacketBuffer[0] = 0x82; 
  WinUsb_WritePipe(MyWinUSBInterfaceHandle, 0x01, &OutputPacketBuffer[0], 64, &BytesWritten, NULL);  

  }
private: System::Void button2_Click(System::Object^  sender, System::EventArgs^  e) {
  ULONG BytesWritten = 0;
  unsigned char OutputPacketBuffer[64];
  OutputPacketBuffer[0] = 0x83; 
  WinUsb_WritePipe(MyWinUSBInterfaceHandle, 0x01, &OutputPacketBuffer[0], 64, &BytesWritten, NULL);  

   }

PIC側ソフトはコマンドに応じた処理を追加しただけです。
case 0x82: 
     TRISB = 0xFC;   // RB0,1 output
     LATBbits.LATB0 = 1;
     LATBbits.LATB1 = 1;
                break;
case 0x83:
     TRISB = 0xFC;   // RB0,1 output
     LATBbits.LATB0 = 0;
     LATBbits.LATB1 = 0;
                break;        

フリーカーソルを解除

メニューバーのTools->Options... の Open options dialog... ボタンをクリックします。
Editor Options ダイアログが開きます。
Options タブを選択し、
Scroll past end of line をクリックします。

PIC12F629の概要

ピン配置

A/D 変換機能搭載してない

コメントの日本語表示

mikroC をC:\Program Files にインストールした場合、
普通にダブルクリックで起動させたら、設定の変更が出来ないようなので、
管理者として開きます。
アイコンの上で右クリックして、管理者として実行 をクリックします。



Font ボタンをクリックします。

日本語フォントを選択し、文字セットを日本語にし、OKをクリックします。

他のウィザードもOKをクリックして閉じます。
Preferences でOKをクリックした時に、メッセージが表示されて、設定が反映されない場合は、
mikroC を管理者権限で実行させて下さい。

コメントで日本語が利用出来るようになりました。