/* **************************************************************************** * PIC to Pi ユーティリティー * * Raspberry Pi GPIO access ルーチン * * [pi_gpio.h] * [pi_gpio.c] * * (gcc -c pi_gpio.c -o gpio.o) * * void mode_set_3208(void); MCP3208で使用するpinのモードset * set_adc_channel(ch); adc_channelをselectする * * (uint32_t)data = read_adc_mcp3208(void);selectされたchから読み込む(12bit) * * 2013.2.9 shellvalley ******************************************************************************* 関数名 <注意> 1. [wiringPiSetup()]をmaink関数で実行すること 2. pin番号はwiringPi-pin番号であり、PaspberryPiのgpioPin番号ではない <gpioモードset> pinMode(pin,INPUT); 指定pinを入力モードにする pinMode(pin,OUTPUT); 指定pinを出力モードにする 例:pinMode(GPIO7,OUTPUT); // mode_set_3208(); MCP3208で使用するpinのモードset <gpio入出力関数> output_bit(pin,bit); 指定pinに0 or 1を出力する output_high(pin); 指定pinに1を出力する output_low(pin) 指定pinに0を出力する 例:output_bit(GPIO7,data); input_bit(pin); 例:input_bit(MISO); <A-D変換関数 IC:MCP3208に対するspi制御> set_adc_channel(ch); adc_channelをselectする (uint32_t)data = read_adc_mcp3208(void);selectされたchから読み込む(12bit) ########【pin番号とRaspberryPiのpinとの対応】################################### +-----------------------+-----------------------+------------------------------+ | RaspberryPi | w iringPi | | | pin番号 | pin番号 | Name | | (ハード) | (ソフト) | | +-----------------------+-----------------------+------------------------------+ | 1 | - | 3.3V | | 2 | - | 5v | | 3 | 8 | SDA | | 4 | - | (DNC) | | 5 | 9 | SCL | | 6 | - | 0v:GND | | 7 | 7 | GPIO7 | | 8 | 15 | TxD | | 9 | - | (DNC) | | 10 | 16 | RxD | | 11 | 0 | GPIO0 | | 12 | 1 | GPIO1 | | 13 | 2 | GPIO2 | | 14 | - | (DNC) | | 15 | 3 | GPIO3 | | 16 | 4 | GPIO4 | | 17 | - | (DNC) | | 18 | 5 | GPIO5 | | 19 | 12 | MOSI(MasterOutSleveIn) | | 20 | - | (DNC) | | 21 | 13 | MISO(MasterInSleveOut) | | 22 | 6 | GPIO6 | | 23 | 14 | SCLK | | 24 | 10 | CE0 | | 25 | - | (DNC) | | 26 | 11 | CE1 | +-----------------------+-----------------------+------------------------------+ ######## A-Dコンバータ MCP3204/3208 (SPI 接続) ################################ ・デバイスとの通信を開始するにはCS ラインをLow にする。 ・CS ピンがLow の時にデバイスの電源が入れられた場合、通信を開始するには High にしてからLow に戻すことが必要。 ・CS Low とDIN High で受け取る最初のクロックは開始ビットを形成。 ・SGL/DIFF ビットが開始ビットに続き、シングルエンドまたは差動入力モードを 使って変換を行うかどうかを決める。 ・3つのビット(D0、D1、D2) は、入力チャンネル構成を選択するのに使われる。 ・デバイスは、開始ビットを受け取った後、クロックの4 番目の上昇部で アナログ入力のサンプリングを開始する。 ・サンプリング期間は開始ビットに続く5番目のクロックの下降部で終了する。 +-----------+---+---+---+---------------+-----------------------+ |制御bit選択| | | | 入力構成 | チャンネル選択 | |SINGLE/DIFF|D2 |D1 |D0 | | | +-----------+---+---+---+---------------+-----------------------+ | 1 |0 |0 |0 |シングルエンド |CH0 | | 1 |0 |0 |1 |シングルエンド |CH1 | | 1 |0 |1 |0 |シングルエンド |CH2 | | 1 |0 |1 |1 |シングルエンド |CH3 | | 1 |1 |0 |0 |シングルエンド |CH4 | | 1 |1 |0 |1 |シングルエンド |CH5 | | 1 |1 |1 |0 |シングルエンド |CH6 | | 1 |1 |1 |1 |シングルエンド |CH7 | | 0 |0 |0 |0 |差動 |CH0 = IN+ CH1 = IN- | | 0 |0 |0 |1 |差動 |CH0 = IN CH1 = IN+ | | 0 |0 |1 |0 |差動 |CH2 = IN+ CH3 = IN- | | 0 |0 |1 |1 |差動 |CH2 = IN CH3 = IN+ | | 0 |1 |0 |0 |差動 |CH4 = IN+ CH5 = IN- | | 0 |1 |0 |1 |差動 |CH4 = IN CH5 = IN+ | | 0 |1 |1 |0 |差動 |CH6 = IN+ CH7 = IN- | | 0 |1 |1 |1 |差動 |CH6 = IN CH7 = IN+ | +-----------+---+---+---+---------------+-----------------------+ ############################################################################### */ // ############################################################################ // ############################################################################ //[pi_gpio.h] // ############################################################################ // ############################################################################ #define SDA0 8 // rsp board pin:03(SDA0) pull-upされている #define SCL0 9 // rsp board pin:05(SCL0) pull-upされている #define GPIO7 7 // rsp board pin:07(GPIO7) #define TXD 15 // rsp board pin:08(TxD) #define RXD 16 // rsp board pin:10(RxD) #define GPIO0 0 // rsp board pin:11(GPIO0) #define GPIO1 1 // rsp board pin:12(GPIO1) #define GPIO2 2 // rsp board pin:13(GPIO2) #define GPIO3 3 // rsp board pin:15(GPIO3) #define GPIO4 4 // rsp board pin:16(GPIO4) #define GPIO5 5 // rsp board pin:18(GPIO5) #define MOSI 12 // rsp board pin:19(MOSI) #define MISO 13 // rsp board pin:21(MISO) #define GPIO6 6 // rsp board pin:22(GPIO6) #define SCLK 14 // rsp board pin:23(SCLK) #define CE0 10 // rsp board pin:24(CE0) #define CE1 11 // rsp board pin:26(CE1) #define pin_03 8 // rsp board pin:03 #define pin_05 9 // rsp board pin:05 #define pin_07 7 // rsp board pin:07 #define pin_08 15 // rsp board pin:08 #define pin_10 16 // rsp board pin:10 #define pin_11 0 // rsp board pin:11 #define pin_12 1 // rsp board pin:12 #define pin_13 2 // rsp board pin:13 #define pin_15 3 // rsp board pin:15 #define pin_16 4 // rsp board pin:16 #define pin_18 5 // rsp board pin:18 #define pin_19 12 // rsp board pin:19 #define pin_21 13 // rsp board pin:21 #define pin_22 6 // rsp board pin:22 #define pin_23 14 // rsp board pin:23 #define pin_24 10 // rsp board pin:24 #define pin_26 11 // rsp board pin:26 // ########################################################################### // ### RaspberryPI <-> PIC ccsc compiler ##################################### // ########################################################################### #define output_bit(pin,bit) digitalWrite(pin,bit) #define output_high(pin) digitalWrite(pin,1) #define output_low(pin) digitalWrite(pin,0) #define input_bit(pin) digitalRead(pin) #define Wait_time 500 #define set_adc_channel(ch) MCP3208_adc_ch=ch; static uint8_t MCP3208_adc_ch=ch; // ######## MCP3208 A-Dコンバータで使用 ###################################### #define spi_clk_1 output_bit(SCLK,1);usleep(Wait_time); #define spi_clk_0 output_bit(SCLK,0);usleep(Wait_time); // ########################################################################### // ########################################################################### //[pi_gpio.c] // ########################################################################### // ########################################################################### // // ######## include file ##################################################### #include <wiringPi.h> #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <unistd.h> #include "pi_gpio.h" // ######## MCP3208 A-Dコンバータで使用 ###################################### #define spi_clk_1 output_bit(SCLK,1);usleep(Wait_time); #define spi_clk_0 output_bit(SCLK,0);usleep(Wait_time); // ######## MCP3208 A-Dコンバータで使用 ###################################### static uint8_t MCP3208_adc_ch; static uint32_t SPI_IN_work[11]; static uint8_t SPI_d2,SPI_d1,SPI_d0; // spi contorol data // ########################################################################### static uint32_t read_adc_3208(void); static void spi_data_input(uint8_t); /* static void mode_set_3208(void); // ########################################################################### void mode_set_3208(void){ pinMode(MOSI , OUTPUT); // rsp board pin:19(MOSI)SPI-MasterOutSleveIn pinMode(MISO , INPUT); // rsp board pin:21(MISO)SPI-MasterInSleveOut pinMode(SCLK , OUTPUT); // rsp board pin:23(SCLK)SPI-CLK pinMode(CE0 , OUTPUT); // rsp board pin:24(CE0)SPI-CS } */ // ########################################################################### // #####AD変換データ12bit read ############################################# void spi_data_input(uint8_t no){ int16_t i; SPI_IN_work[no] = 0; for(i = 0 ; i < 11 ; i++){ spi_clk_1; spi_clk_0; SPI_IN_work[no] |= input_bit(MISO); SPI_IN_work[no] <<= 1; // B11 read } SPI_IN_work[no] |= input_bit(MISO); usleep(Wait_time); } // ########################################################################### int compare_int(const void *a, const void *b){ return *(int*)b - *(int*)a; } // ########################################################################### // ########################################################################### // 6回read => sort => topと2番目の差が0x20以下なら1番目を返すを返す // 6回でもNGならばretryの2回目をとっておき、5回retryしてもNGならば、sortして1番目を返す // ########################################################################### uint32_t read_adc_mcp3208(void){ uint32_t i,j,work[10]; int16_t retry = 5; if((MCP3208_adc_ch & 0x04)!=0)SPI_d2 = 1; else SPI_d2 = 0; if((MCP3208_adc_ch & 0x02)!=0)SPI_d1 = 1; else SPI_d1 = 0; if((MCP3208_adc_ch & 0x01)!=0)SPI_d0 = 1; else SPI_d0 = 0; while(1){ for(i = 0 ; i < 6 ; i++){ // test output_bit(CE0 ,0); // CE0 : 1 output_bit(MOSI ,1); // シングルエンド モード usleep(Wait_time); usleep(Wait_time); spi_clk_1; if(SPI_d2 != 0) output_bit(MOSI ,1); // adc ch d2 else output_bit(MOSI ,0); // adc ch d2 spi_clk_0; spi_clk_1; spi_clk_0; spi_clk_1; if(SPI_d1 != 0) output_bit(MOSI ,1); // adc ch d1 else output_bit(MOSI ,0); // adc ch d1 spi_clk_0; spi_clk_1; if(SPI_d0 != 0) output_bit(MOSI ,1); // adc ch d0 else output_bit(MOSI ,0); // adc ch d0 spi_clk_0; spi_clk_1; output_bit(MOSI ,0); spi_clk_0; usleep(Wait_time); // A to D start usleep(Wait_time); spi_clk_1; spi_clk_0; spi_clk_1; spi_clk_0; spi_data_input(i); // data input spi_clk_1; output_bit(CE0 ,1); // CE0 : 1 spi_clk_0; usleep(Wait_time); usleep(Wait_time); usleep(Wait_time); usleep(Wait_time); } qsort(SPI_IN_work,6,sizeof(uint32_t),compare_int); j = SPI_IN_work[0] - SPI_IN_work[1]; // j = SPI_IN_work[1] - SPI_IN_work[2]; if(j < 0x20)return(SPI_IN_work[0]); // if(j < 0x20)return(SPI_IN_work[1]); if(retry < 0){ qsort(work,5,sizeof(uint32_t),compare_int); return(work[1]); // 2番目を返す } else{ work[retry] = SPI_IN_work[1]; // 2番目をとっておく --retry; } } } // ############################################################################