ラベル PIC18F2550 の投稿を表示しています。 すべての投稿を表示
ラベル PIC18F2550 の投稿を表示しています。 すべての投稿を表示

2010年12月6日月曜日

TIMER0を使ってリモコン信号を解析

基本情報は、赤外線リモコンの受信 

リーダー部の前半の9msを判断する。
TIMER0を割り込み無しで、カウンタとして使って判断する。
今回は次の信号との間の34msも調べてみたいと思います。

48MHzでプリスケーラ値は1:8を使えばカウント出来るはず、

リモコンの信号で割り込み+RS232C通信-USB Device - HID - Keyboard-PIC18F2550


割り込みとRS232C通信を追加してみる-USB Device - HID - Keyboard-PIC18F2550
の記事のスイッチを赤外線リモコン受光モジュール(PL-IRM-2161-C438)に変えただけです。
PIC側のファームウェアは同じです、
ハイパーターミナルを見ていると、割り込みはかかっているみたいです。

割り込みとRS232C通信を追加してみる-USB Device - HID - Keyboard-PIC18F2550

RS232C通信 の記事と
INTポートにスイッチを付けて割り込み-高優先割込  の記事をコピーペーストすれば簡単に実装出来ました。


Keyboard.zip
ダウンロード

スイッチをBS(バックスペース)キーにする-USB Device - HID - Keyboard-PIC18F2550

キーコードを調べます。
USB HID toPS/2 Scan Code Translation Table
によると、バックスペースは、2A のようです。

void Keyboard(void)
{
 static unsigned char key = 4; 

 //Check if the IN endpoint is not busy, and if it isn't check if we want to send 
 //keystroke data to the host.
    if(!HIDTxHandleBusy(lastINTransmission))
    {
        if(Switch3IsPressed())
        {
         //Load the HID buffer
         hid_report_in[0] = 0;
         hid_report_in[1] = 0;
         hid_report_in[2] = key++;
         hid_report_in[3] = 0;
         hid_report_in[4] = 0;
         hid_report_in[5] = 0;
         hid_report_in[6] = 0;
         hid_report_in[7] = 0;
            //Send the 8 byte packet over USB to the host.
            lastINTransmission = HIDTxPacket(HID_EP, (BYTE*)hid_report_in, 0x08);
 

とりあえずkey++の場所に0x2Aと記入すれば動きます。

ビルドして書き込んで動作確認-USB Device - HID - Keyboard

USB Device - HID - Keyboard フォルダ内のFirmware フォルダ内の
USB Device - HID - Keyboard- C18 - PICDEM FSUSB.mcp を無修正で書き込みできます。

RB5に接続されているスイッチを押すと下記のように表示されます。
1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ

ボタンでマウス移動させてみる-USB Device - HID - Mouse

参考資料
詳細:TB055


上、下、右、左、右クリック、左クリックに対応

MOUSE.zip
ダウンロード

2010年12月3日金曜日

ビルドして書き込む-USB Device - HID - Custom Demos

Microchip Solutionsのインストールフォルダから
USB Device - HID - Custom Demos
-Generic HID - Firmware
--USB Device - HID - Simple Custom Demo - C18 - PICDEM FSUSB.mcp
上記のファイルがそのまま利用出来ますが、
HardwareProfile - PICDEM FSUSB.hの
LEDのポートの部分を変更します。


PnP(プラグアンドプレイ)なので自動的にドライバをインストールしてくれます。
マック用のPCソフトウェアも用意してあります。

2010年12月2日木曜日

TIMER0による割り込み-PIC18F2550


RC0ポートに繋がっているLEDは通常の処理で点滅、
RC1ポートに繋がっているLEDは割り込みが発生する度に点滅

/*
概要:タイマ0を使った割り込みを使ってみる

HID - Bootloaderを使った書き込み

マイコン:PIC18F2550

ファイル名:nain.c

開発環境:MPLAB C18

*/

#include <p18f2550.h>
#include <delays.h>
#include <timers.h>
void high_isr (void);
void low_isr (void);

// リセットベクタ  
#pragma code reset_vector=0x1000
extern void _startup(void);
void remapped_reset(void) { 
 _asm goto 
  _startup 
 _endasm
}

#pragma code

// 高優先割込み関連の記述 ====
#pragma code high_vector=0x1008
void high_interrupt (void) {
 _asm
  GOTO high_isr
 _endasm
}
#pragma code

#pragma interrupt high_isr
void high_isr (void) {
/* ここに高優先割込み処理を記述する */
 INTCONbits.TMR0IF = 0;  // タイマ0割り込みフラグを0にする
    WriteTimer0(18660); 
    LATCbits.LATC1 = !LATCbits.LATC1;//RC1のLED点滅点<->灯点滅                                 

}

// 低優先割込み関連の記述 ====
#pragma code low_vector=0x1018
void low_interrupt (void) {
 _asm
  GOTO low_isr
 _endasm
}
#pragma code

#pragma interruptlow low_isr
void low_isr (void) {
/* ここに低優先割込み処理を記述する */

    
}

void main(void) {
        TRISC=0;            // ポートCをすべて出力ピンにする

        OpenTimer0(
   TIMER_INT_ON &  //割込み:ON
   T0_16BIT &      //16 bit モードに設定  vs  8bit モード( T0_8BIT )
   T0_SOURCE_INT & //内部クロック使用
   T0_PS_1_128     //128ビットプリスケーラ  1/8 vs 1/1 1/2 1/4 1/8 1/16 1/32 1/64 1/128 1/256 
        );
        
  WriteTimer0(18660);//48MHzで0.5s
  
  RCONbits.IPEN = 0;      //割込み優先順位制御:OFF (RCON レジスタのIPENビット = 0)
  INTCONbits.TMR0IE = 1;  //タイマ0割込み許可
  INTCONbits.PEIE = 1;    //周辺割込み許可 
                          //INTCONレジスタの b6ビット : 低位割込み許可/禁止(割り込み優先順位制御     有りの場合)  
  INTCONbits.GIE = 1;     //全割込み許可
                          //INTCONレジスタの b7ビット : 高位割込み許可/禁止(割り込み優先順位制御  有りの場合)
        while(1)
        {                       //通常の処理
         
         PORTCbits.RC0=1;  //RC0ポートのLED点滅        
         Delay10KTCYx(0);  //0=>256 48MHzで213.3 ms
         PORTCbits.RC0=0;
         Delay10KTCYx(0);
        }
}

2010年12月1日水曜日

INTポートにスイッチを付けて割り込み-高優先割込-PIC18F2550


RB2/INT2に繋がっているスイッチを押すと割り込みが発生。
割り込みでRC1のLEDを点滅させる

/*
概要:外部割込みINT2を使ってみる

HID - Bootloaderを使った書き込み

マイコン:PIC18F2550

ファイル名:nain.c

開発環境:MPLAB C18

*/

#include <p18f2550.h>
#include <delays.h>
#include <portb.h>

void high_isr (void);
void low_isr (void);

// リセットベクタ  
#pragma code reset_vector=0x1000
extern void _startup(void);
void remapped_reset(void) { 
 _asm goto 
  _startup 
 _endasm
}

#pragma code

// 高優先割込み関連の記述 ====
#pragma code high_vector=0x1008
void high_interrupt (void) {
 _asm
  GOTO high_isr
 _endasm
}
#pragma code

#pragma interrupt high_isr
void high_isr (void) {
/* ここに高優先割込み処理を記述する */
                                 
        INTCON3bits.INT2IE = 0;   //外部割込みINT2の禁止
  INTCONbits.PEIE = 0;      //低位割込み禁止
  INTCONbits.GIE = 0;       //全割込み禁止
     
        INTCON3bits.INT2IF = 0;   // INT2の割込みフラグをリセット       

  LATCbits.LATC1 = !LATCbits.LATC1;//RC1のLED点滅点<->灯点滅
 
        INTCON3bits.INT2IE = 1;   //外部割込みINT2の許可
  INTCONbits.PEIE = 1;      //低位割込み許可
        INTCONbits.GIE = 1;       //全割込み許可
}

// 低優先割込み関連の記述 ====
#pragma code low_vector=0x1018
void low_interrupt (void) {
 _asm
  GOTO low_isr
 _endasm
}
#pragma code

#pragma interruptlow low_isr
void low_isr (void) {
/* ここに低優先割込み処理を記述する */

}

void main(void) {
        TRISB = 0b00000100;     // B portのRB2を入力モードに その他を出力モードに設定
        TRISC=0;                // ポートCをすべて出力ピンにする

        OpenRB2INT(PORTB_CHANGE_INT_ON &    //ポートRB2の外部割込みON
                   FALLING_EDGE_INT &       //立下りエッジでON
                   PORTB_PULLUPS_OFF        //Bポートの抵抗プルアップOFF
                                );
        RCONbits.IPEN = 1;      //割込み優先順位制御ON  (0:優先順位制御OFF)
        INTCON3bits.INT2IP = 1; //INT2の割り込みを高位割込みにセット(0:低位割込み)
        INTCON3bits.INT2IE= 1;  //INT2割込みの許可
  INTCONbits.PEIE = 1;    //低位割込み許可
        INTCONbits.GIE = 1;     //全割込み許可

        LATCbits.LATC1 = 1;    //電源投入でRC1のLED消灯

        while(1)
        {                       //通常の処理
         
         PORTCbits.RC0=1; //RC0ポートのLED点滅        
         Delay10KTCYx(0); //0=>256 48MHzで213.3 ms
         PORTCbits.RC0=0;
         Delay10KTCYx(0);
        }
}

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日日曜日

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日水曜日

ビルドして動作確認-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 用のファームウェがそのまま利用出来ました。