PIC

ここは、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タイマー
タイマー:サンプル

SPI

PIC 18F2550を使用したADC128S052とのSPI通信プログラム
SPI通信:サンプル
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:サンプル
A/D取得2:サンプル

PWM

PWMによる可変電圧@18F2550
発振周波数2.9kHz、出力段にLPF(RC 10k/5uF)を入れる
PWM:サンプル

USB(仮想COMポート)

仮想COMポートでPCと通信可能なプログラム。
CCS付属のドライバはXPまでなので、そのままだとWindows7では使えない。色々修正してWindows7でも使用できるようにしたものが以下(自己責任で使用してください)。
src:サンプル
driver:ドライバ(windows7対応)
Windows10以降ではセキュリティが強化されており、上記のドライバはインストールがうまく出来なくなっている。
一応、CCSのサイトからドライバが一覧にあるが、これが使えるかしら。。。
もしくは、以下を試してみる。
driver:ドライバ(windows10対応)


USB(HID)

なぜこれで受信できるかよく分かっていない。PIC->PCの送信のみ。CDCのようにポート指定をしたくない場合などに使える。ドライバもOSが持っているので、気にしなくてよい。PCソフトはプロジェクトごとだと重いので、mainのみ。
src:サンプル
driver:なし(HIDなので自動でインストールされるため)
PCソフト:サンプル


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動かない事例

  1. MCLRに電圧がかかっていない
  2. WDTがONになっている
  3. PWRTE(電源投入直後に72ms間のリセット)が無効になっている
  4. 電源電圧が低い
  5. 低電圧プログラミング(LVP)が有効になっている。
  6. 発振子の設定が合っていない


PIC書き込めない事例

  1. PGM端子がプルダウンされていない
  2. 発振子がプルダウンされていない
  3. MCLR端子に高電圧がかかっていない
  4. おかしなGNDが接続されている
  5. PGC/PGDに何か接続されている


PICトラブル事例

  1. SPIが使用する端子をI/O入力に設定するとspi_writeした時点でフリーズする。
  2. 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!!
}

タグ:

PIC USB
最終更新:2018年04月21日 21:17