PC-G850VS / ミニI/OにADコンバーターMCP3008を接続する

# 概要  
PC-G850VSの11ピンコネクターをミニI/Oとして使って、そこに8チャンネル10ビットのADコンバーターMCP3008を外づけしてみる。 
 
MCP3008は、既製のSPIライブラリで制御することがほとんどだと思うが、ここでは制御プログラムを独自に実装する。といってもたいそうなものでは全然なく、データシートのタイミングチャートどおりに3ビットパラレルのディジタル信号を36個順番にADコンバーターに送り込むだけである。あとはADコンバーターからビット[9]～[0]の順番で返ってくる10ビットAD変換値を読み取ればよい。  

# タイミング表  
[MCP3004/3008データシート](http://ww1.microchip.com/downloads/en/DeviceDoc/21295d.pdf), FIGURE 5-1, p.20をExcelで整理し直した。  
入力チャンネルに応じて黄色列の値を上から順番にminiput()函数の引数としてPC-G850VSのミニI/OからADコンバーターへ送り込む。これで1サンプルが取得できる。Excelファイルは[ここ](https://drive.google.com/open?id=1izgOLRrqY28s_H43VxbcH89sd1DP2Llh)。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/193936/6f2e85a2-92e2-d404-a5a9-c88f6e3c0b6d.png)  

# 実験回路  
下の回路で試してみる。チャンネル[0]～[3]に印加された電圧をそれぞれAD変換する。  
<img src="https://qiita-image-store.s3.amazonaws.com/0/193936/c7c7e5c0-c25b-57cc-1a01-f0c00e3349d3.png" height=200> <img src="https://qiita-image-store.s3.amazonaws.com/0/193936/265af900-49c9-9072-c7e3-d52260a3447e.png" height=200>  


# ソースコード  

```MCP3008.c
unsigned int read(unsigned char CH){
    unsigned char mosi[36] = {3,4,6,4,6,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,1};
    unsigned char ch[8][6] =          {{0,2,0,2,0,2},  /*CH0*/
                                       {0,2,0,2,4,6},  /*CH1*/
                                       {0,2,4,6,0,2},  /*CH2*/
                                       {0,2,4,6,4,6},  /*CH3*/
                                       {4,6,0,2,0,2},  /*CH4*/
                                       {4,6,0,2,4,6},  /*CH5*/
                                       {4,6,4,6,0,2},  /*CH6*/
                                       {4,6,4,6,4,6}}; /*CH7*/

    unsigned char miso[10];
    unsigned char i, k;
    unsigned int sum;

    /* Some bits of the digital data which are to be transferred to ADC are replaced according to the input channel you specify.*/
    for(i=0; i<6; i++){
        mosi[i+5] = ch[CH][i];
    }

    /*The thirty-six of 3-bit digital data are transferred to ADC, and then the ADC will output each bit of a 10-bit digital code one at a time.*/
    k = 9;
    for(i=0; i<36; i++){
        miniput(mosi[i]);
        if((i>=16) && (i%2==0)){
            miso[k] = miniget();
            k--;
        }
    }

    /*Some shifting operations can generate a 10-bit digital code.*/
    sum = 0;
    for(i=0; i<10; i++){
        sum |= miso[i]<<i;
    }

    return sum;
}

main(){
    unsigned int i; /*For PC-G850VS, a busy wait does not need a "volatile" qualifier.*/
    while(1){
        printf("%4d, %4d, %4d, %4d\n", read(0), read(1), read(2), read(3));
        for(i=0; i<500; i++){} /*busy wait*/
    }
}
```

# 実行結果  
 
4チャンネルの変換結果をロジアナで連続して観測したところ: 
![screenshot.png](https://qiita-image-store.s3.amazonaws.com/0/193936/977f1e4f-bdf0-6eba-b556-9bf21c100bd4.png)  
<img src="https://qiita-image-store.s3.amazonaws.com/0/193936/cad7466c-607d-41c2-7787-14cbfb4a2506.png" width=300>



# 参考
- [ポケコン PC-G850Vで電子回路工作(5/31)](https://k1segawa.exblog.jp/21294135/) 
- [POCKET COMPUTER MODEL PC-G850V(S) User Manual/ Interface](http://wrabetz.de/resources/Sharp_PC-G850VS_Interface.pdf)   

# 関連  
- [はてなブログ / ADコンバーターMCP3008 / SPI](http://ti-nspire.hatenablog.com/archive/category/AD%E3%82%B3%E3%83%B3%E3%83%90%E3%83%BC%E3%82%BF%E3%83%BCMCP3008%20%2F%20SPI)  


#追記: ループを全部開いて少しだけ速くした
(2019/09/06) https://ti-nspire.hatenablog.com/entry/2019/09/06/120035