PIC

「PIC」の編集履歴(バックアップ)一覧はこちら

PIC」(2018/04/21 (土) 21:17:14) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

ここは、PIC18F2550/4550の覚書ページ。環境は以下を想定している。PIC18FはそこそこのCPUパワーに多数のペリフェラルが付いており使いやすい。また、秋月等で販売されており、低価格で入手性も良い。 開発環境:CSS-C(C言語) ライタ:PIC Programmerv4 Beta ほとんどは、CSSに付属しているサンプル(Example)で実現できる(サンプルが優秀で使いやすい)。 ---- *PIC16F883のRB I/Oポート問題 RB5を入力設定にしたのに常に0にしかならない。 よくよく調べるとRB6,RB7しか反応せず(1を入力すると1を返す)、RB0~RB5は無反応であることが分かった。 原因は、RB0~RB5がアナログ入力になっていたこと。 CCSでは、AN7までしかサポートしていない?ためか、ADCの設定をDISにしてもRB0~RB5はDISにならない。 直接レジスタを叩いてDISにする必要がある。 #BYTE ANSELH = 0x189 ANSELH = 0x00; *PIC18F2550/4550 *タイマー1kHz PIC 18F2550を使用した1kHzタイマー タイマー:[[サンプル>http://www13.atwiki.jp/usonx?cmd=upload&act=open&pageid=13&file=foucault.c]] *SPI PIC 18F2550を使用したADC128S052とのSPI通信プログラム SPI通信:[[サンプル>http://www13.atwiki.jp/usonx?cmd=upload&act=open&pageid=13&file=pic_spi.zip]] PICでSPIの極性(モード)を変更したい場合、CCSコンパイラでは変更する関数が用意されていないため、直接レジスタを叩く必要がある。0x14はレジスタアドレス、4はbit(0オリジン)である。レジスタアドレスはPICのデータシートに書いてある。叩き方としては、 #BIT CKP = 0x14.4 CKP = 0; と思ったら用意されていたでござる。 #define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H) #define SPI_MODE_1 (SPI_L_TO_H) #define SPI_MODE_2 (SPI_H_TO_L) #define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H) setup_spi(SPI_MASTER | SPI_MODE_0); SPIとTIMER1を同時に使用しようとしたら、急にSPI通信のところで処理が停止してしまう現象が起きた。原因を探っていくと、SPIの初期化をした後に汎用ピンの初期化(set_tris_cとか)をしており、これが原因だった模様。処理順を逆にしたら正常に動作した。 *A/Dコンバータ 18F2550のA/D取得。ADC以外も色々書いてあるけども。 A/D取得1:[[サンプル>http://www13.atwiki.jp/usonx?cmd=upload&act=open&pageid=13&file=adc.c]] A/D取得2:[[サンプル>http://www13.atwiki.jp/usonx?cmd=upload&act=open&pageid=13&file=CH.c]] *PWM PWMによる可変電圧@18F2550 発振周波数2.9kHz、出力段にLPF(RC 10k/5uF)を入れる PWM:[[サンプル>http://www13.atwiki.jp/usonx?cmd=upload&act=open&pageid=13&file=pwm.c]] *USB(仮想COMポート) 仮想COMポートでPCと通信可能なプログラム。CCS付属のドライバはXPまでなので、そのままだとWindows7では使えない。色々修正してWindows7でも使用できるようにしたものが以下(自己責任で使用してください)。 src:[[サンプル>http://www13.atwiki.jp/usonx?cmd=upload&act=open&pageid=13&file=ex_usb_serial.c]] driver:[[ドライバ(windows7対応)>http://www13.atwiki.jp/usonx?cmd=upload&act=open&pageid=13&file=driver.zip]] Windows10以降ではセキュリティが強化されており、上記のドライバはインストールがうまく出来なくなっている。 一応、CCSのサイトから[[ドライバ>http://www.ccsinfo.com/downloads.php]]が一覧にあるが、これが使えるかしら。。。 もしくは、以下を試してみる。 driver:[[ドライバ(windows10対応)>https://img.atwikiimg.com/www13.atwiki.jp/usonx/attach/13/189/NT%2C2000%2CXP%2CVISTA%2C7%2C8%2C10.zip]] *USB(HID) なぜこれで受信できるかよく分かっていない。PIC->PCの送信のみ。CDCのようにポート指定をしたくない場合などに使える。ドライバもOSが持っているので、気にしなくてよい。PCソフトはプロジェクトごとだと重いので、mainのみ。 src:[[サンプル>http://www13.atwiki.jp/usonx?cmd=upload&act=open&pageid=13&file=ex_usb_hid.c]] driver:なし(HIDなので自動でインストールされるため) PCソフト:[[サンプル>http://www13.atwiki.jp/usonx?cmd=upload&act=open&pageid=13&file=MFC_USBHIDDlg.cpp]] ---- *PIC 18F2550@CDC PIC 18F2550のUSB接続のF/W(ファームウェア) CDC形式 #define __USB_PIC_PERIF__ 1 #if !defined(__PCH__) #error USB CDC Library requires PIC18 #endif #if __USB_PIC_PERIF__ #include <18F2550.h> //configure a 20MHz crystal to operate at 48MHz #fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN //#fuses USBDIV, PLL1, CPUDIV1, PROTECT, NOCPD, noBROWNOUT,HSPLL,NOWDT,nolvp, VREGEN #use delay(clock=48000000) #else //use the National USBN960x peripheral #include <18F452.h> #fuses HS,NOWDT,NOPROTECT,NOLVP #use delay(clock=20000000) #endif //endif check to see which peripheral to use #if __USB_PIC_PERIF__ && defined(__PCH__) #define USB_CON_SENSE_PIN PIN_B2 #endif // Includes all USB code and interrupts, as well as the CDC API #include <usb_cdc.h> #rom int 0xf00000={1,2,3,4} void main() { BYTE i, j, address, value; usb_cdc_init(); usb_init(); while(!usb_cdc_connected()) {} do { usb_task(); if (usb_enumerated()) { printf(usb_cdc_putc, "\r\n\nEEPROM:\r\n"); // Display contents of the first 64 for(i=0; i<=3; ++i) { // bytes of the data EEPROM in hex for(j=0; j<=15; ++j) { printf(usb_cdc_putc, "%2x ", read_eeprom( i*16+j ) ); } printf(usb_cdc_putc, "\n\r"); } printf(usb_cdc_putc, "\r\nLocation to change: "); address = gethex_usb(); printf(usb_cdc_putc, "\r\nNew value: "); value = gethex_usb(); write_eeprom( address, value ); } } while (TRUE); } ---- *PIC動かない事例 + MCLRに電圧がかかっていない + WDTがONになっている + PWRTE(電源投入直後に72ms間のリセット)が無効になっている + 電源電圧が低い + 低電圧プログラミング(LVP)が有効になっている。 + 発振子の設定が合っていない ---- *PIC書き込めない事例 + PGM端子がプルダウンされていない + 発振子がプルダウンされていない + MCLR端子に高電圧がかかっていない + おかしなGNDが接続されている + PGC/PGDに何か接続されている ---- *PICトラブル事例 + SPIが使用する端子をI/O入力に設定するとspi_writeした時点でフリーズする。 + 16F883はCCSがADCをAN7?までしかサポートしていない? ---- *CCSでのビットシフト unsigned char a = 0xab; unsigned char b = 0xcd; long c; c = a << 8 | b; とすると、bは0x00cdとなってしまう。 これは、a<<8とするとaは1byteであることから0x00となってしまう。 回避するには、 c = a; c = a << 8 | b; とする。一度2byteの器に移し替え、ビットシフトを行う必要がある。 CCSでは、short型が2byteない? ucharを結合する場合は、longを使用した方がよい ----- *PIC18FのUSB機能をOFFに、USB端子をI/Oピンとして使用する 18F系のPICではノミナルで、USB機能がENAとなっている。しかし、場合によってはD+/-端子をI/Oピンとして使用したい時があり、その場合はUSB機能をDISにする必要がある。下記のようにレジスタを設定する。 #include "./sample.h" #byte UCON=0xF6D #bit USBEN=UCON.3 #byte UCFG=0xF6F #bit UTRDIS=UCFG.3 // USB Tranceiver Disable flg #byte RCSTA=0xFAB #bit SPEN=RCSTA.7 void main() { USBEN = 0; SPEN = 0; UTRDIS=1; setup_adc_ports(NO_ANALOGS|VSS_VDD); setup_adc(ADC_OFF); setup_spi(FALSE); setup_wdt(WDT_OFF); setup_timer_0(RTCC_INTERNAL); setup_timer_1(T1_DISABLED); setup_timer_2(T2_DISABLED,0,1); setup_comparator(NC_NC_NC_NC); setup_vref(FALSE); setup_oscillator(False); // TODO: USER CODE!! } ----
ここは、PIC18F2550/4550の覚書ページ。環境は以下を想定している。PIC18FはそこそこのCPUパワーに多数のペリフェラルが付いており使いやすい。また、秋月等で販売されており、低価格で入手性も良い。 開発環境:CSS-C(C言語) ライタ:PIC Programmerv4 Beta ほとんどは、CSSに付属しているサンプル(Example)で実現できる(サンプルが優秀で使いやすい)。 ---- *PIC16F883のRB I/Oポート問題 RB5を入力設定にしたのに常に0にしかならない。 よくよく調べるとRB6,RB7しか反応せず(1を入力すると1を返す)、RB0~RB5は無反応であることが分かった。 原因は、RB0~RB5がアナログ入力になっていたこと。 CCSでは、AN7までしかサポートしていない?ためか、ADCの設定をDISにしてもRB0~RB5はDISにならない。 直接レジスタを叩いてDISにする必要がある。 #BYTE ANSELH = 0x189 ANSELH = 0x00; *PIC18F2550/4550 *タイマー1kHz PIC 18F2550を使用した1kHzタイマー タイマー:[[サンプル>http://www13.atwiki.jp/usonx?cmd=upload&act=open&pageid=13&file=foucault.c]] *SPI PIC 18F2550を使用したADC128S052とのSPI通信プログラム SPI通信:[[サンプル>http://www13.atwiki.jp/usonx?cmd=upload&act=open&pageid=13&file=pic_spi.zip]] PICでSPIの極性(モード)を変更したい場合、CCSコンパイラでは変更する関数が用意されていないため、直接レジスタを叩く必要がある。0x14はレジスタアドレス、4はbit(0オリジン)である。レジスタアドレスはPICのデータシートに書いてある。叩き方としては、 #BIT CKP = 0x14.4 CKP = 0; と思ったら用意されていたでござる。 #define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H) #define SPI_MODE_1 (SPI_L_TO_H) #define SPI_MODE_2 (SPI_H_TO_L) #define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H) setup_spi(SPI_MASTER | SPI_MODE_0); SPIとTIMER1を同時に使用しようとしたら、急にSPI通信のところで処理が停止してしまう現象が起きた。原因を探っていくと、SPIの初期化をした後に汎用ピンの初期化(set_tris_cとか)をしており、これが原因だった模様。処理順を逆にしたら正常に動作した。 *A/Dコンバータ 18F2550のA/D取得。ADC以外も色々書いてあるけども。 A/D取得1:[[サンプル>http://www13.atwiki.jp/usonx?cmd=upload&act=open&pageid=13&file=adc.c]] A/D取得2:[[サンプル>http://www13.atwiki.jp/usonx?cmd=upload&act=open&pageid=13&file=CH.c]] *PWM PWMによる可変電圧@18F2550 発振周波数2.9kHz、出力段にLPF(RC 10k/5uF)を入れる PWM:[[サンプル>http://www13.atwiki.jp/usonx?cmd=upload&act=open&pageid=13&file=pwm.c]] *USB(仮想COMポート) 仮想COMポートでPCと通信可能なプログラム。 CCS付属のドライバはXPまでなので、そのままだとWindows7では使えない。色々修正してWindows7でも使用できるようにしたものが以下(自己責任で使用してください)。 src:[[サンプル>http://www13.atwiki.jp/usonx?cmd=upload&act=open&pageid=13&file=ex_usb_serial.c]] driver:[[ドライバ(windows7対応)>http://www13.atwiki.jp/usonx?cmd=upload&act=open&pageid=13&file=driver.zip]] Windows10以降ではセキュリティが強化されており、上記のドライバはインストールがうまく出来なくなっている。 一応、CCSのサイトから[[ドライバ>http://www.ccsinfo.com/downloads.php]]が一覧にあるが、これが使えるかしら。。。 もしくは、以下を試してみる。 driver:[[ドライバ(windows10対応)>https://img.atwikiimg.com/www13.atwiki.jp/usonx/attach/13/189/NT%2C2000%2CXP%2CVISTA%2C7%2C8%2C10.zip]] *USB(HID) なぜこれで受信できるかよく分かっていない。PIC->PCの送信のみ。CDCのようにポート指定をしたくない場合などに使える。ドライバもOSが持っているので、気にしなくてよい。PCソフトはプロジェクトごとだと重いので、mainのみ。 src:[[サンプル>http://www13.atwiki.jp/usonx?cmd=upload&act=open&pageid=13&file=ex_usb_hid.c]] driver:なし(HIDなので自動でインストールされるため) PCソフト:[[サンプル>http://www13.atwiki.jp/usonx?cmd=upload&act=open&pageid=13&file=MFC_USBHIDDlg.cpp]] ---- *PIC 18F2550@CDC PIC 18F2550のUSB接続のF/W(ファームウェア) CDC形式 #define __USB_PIC_PERIF__ 1 #if !defined(__PCH__) #error USB CDC Library requires PIC18 #endif #if __USB_PIC_PERIF__ #include <18F2550.h> //configure a 20MHz crystal to operate at 48MHz #fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN //#fuses USBDIV, PLL1, CPUDIV1, PROTECT, NOCPD, noBROWNOUT,HSPLL,NOWDT,nolvp, VREGEN #use delay(clock=48000000) #else //use the National USBN960x peripheral #include <18F452.h> #fuses HS,NOWDT,NOPROTECT,NOLVP #use delay(clock=20000000) #endif //endif check to see which peripheral to use #if __USB_PIC_PERIF__ && defined(__PCH__) #define USB_CON_SENSE_PIN PIN_B2 #endif // Includes all USB code and interrupts, as well as the CDC API #include <usb_cdc.h> #rom int 0xf00000={1,2,3,4} void main() { BYTE i, j, address, value; usb_cdc_init(); usb_init(); while(!usb_cdc_connected()) {} do { usb_task(); if (usb_enumerated()) { printf(usb_cdc_putc, "\r\n\nEEPROM:\r\n"); // Display contents of the first 64 for(i=0; i<=3; ++i) { // bytes of the data EEPROM in hex for(j=0; j<=15; ++j) { printf(usb_cdc_putc, "%2x ", read_eeprom( i*16+j ) ); } printf(usb_cdc_putc, "\n\r"); } printf(usb_cdc_putc, "\r\nLocation to change: "); address = gethex_usb(); printf(usb_cdc_putc, "\r\nNew value: "); value = gethex_usb(); write_eeprom( address, value ); } } while (TRUE); } ---- *PIC動かない事例 + MCLRに電圧がかかっていない + WDTがONになっている + PWRTE(電源投入直後に72ms間のリセット)が無効になっている + 電源電圧が低い + 低電圧プログラミング(LVP)が有効になっている。 + 発振子の設定が合っていない ---- *PIC書き込めない事例 + PGM端子がプルダウンされていない + 発振子がプルダウンされていない + MCLR端子に高電圧がかかっていない + おかしなGNDが接続されている + PGC/PGDに何か接続されている ---- *PICトラブル事例 + SPIが使用する端子をI/O入力に設定するとspi_writeした時点でフリーズする。 + 16F883はCCSがADCをAN7?までしかサポートしていない? ---- *CCSでのビットシフト unsigned char a = 0xab; unsigned char b = 0xcd; long c; c = a << 8 | b; とすると、bは0x00cdとなってしまう。 これは、a<<8とするとaは1byteであることから0x00となってしまう。 回避するには、 c = a; c = a << 8 | b; とする。一度2byteの器に移し替え、ビットシフトを行う必要がある。 CCSでは、short型が2byteない? ucharを結合する場合は、longを使用した方がよい ----- *PIC18FのUSB機能をOFFに、USB端子をI/Oピンとして使用する 18F系のPICではノミナルで、USB機能がENAとなっている。しかし、場合によってはD+/-端子をI/Oピンとして使用したい時があり、その場合はUSB機能をDISにする必要がある。下記のようにレジスタを設定する。 #include "./sample.h" #byte UCON=0xF6D #bit USBEN=UCON.3 #byte UCFG=0xF6F #bit UTRDIS=UCFG.3 // USB Tranceiver Disable flg #byte RCSTA=0xFAB #bit SPEN=RCSTA.7 void main() { USBEN = 0; SPEN = 0; UTRDIS=1; setup_adc_ports(NO_ANALOGS|VSS_VDD); setup_adc(ADC_OFF); setup_spi(FALSE); setup_wdt(WDT_OFF); setup_timer_0(RTCC_INTERNAL); setup_timer_1(T1_DISABLED); setup_timer_2(T2_DISABLED,0,1); setup_comparator(NC_NC_NC_NC); setup_vref(FALSE); setup_oscillator(False); // TODO: USER CODE!! } ----

表示オプション

横に並べて表示:
変化行の前後のみ表示: