https://www.denshi.club/parts/2021/04/raspberry-pi-pico-12-spi-apia-dmcp.html
を見て、下記のC言語プログラムをRaspberry Pi Picoに書き込んだら、MCP3008とSPI通信が出来たようなのですが、このプログラムは、GP5をLowにしてから、GP3から3バイト、ダミーデータをMCP3008に書きこんで、MCP3008からRaspberry Pi Picoに返ってきた値3バイトをbufferに格納して、2バイト目のbufferと8ビット符号なし00000011の論理積を8ビット左にシフトした値と3バイト目のbufferの論理和に3.2562をかけて1024で割るみたいなことをしているのですか?
例えば、2バイト目のbufferが00100010で3バイト目のbufferが00101100だったら、00100010と00000011の論理積で00000010となり、00000010を8ビット左にシフトすると、00000000となり、00000000と00101100の論理和が44となり、44*3.2562/1024で0.13991484375になるということですか?
また、SPIのボーレートが2MHzとなっているのは、サンプル期間が終了してから10データビットがすべてクロック出力されるまでの時間が1.2 msを超えてはならないとMCP3008の仕様書に書いてあるからでしょうか?SPIのボーレートは1kHz以上ならどんな値でも大丈夫でしょうか?
#include <stdio.h> #include "pico/stdlib.h" #include "hardware/spi.h" #include "hardware/gpio.h" #include "hardware/adc.h" #define PIN_SCK 2 #define PIN_MOSI 3 #define PIN_MISO 4 #define PIN_CS 5 #define SPI_PORT spi0 static float Vref = 3.2562; static inline void cs_select() { asm volatile("nop \n nop \n nop"); gpio_put(PIN_CS, 0); // Active low asm volatile("nop \n nop \n nop"); } static inline void cs_deselect() { asm volatile("nop \n nop \n nop"); gpio_put(PIN_CS, 1); asm volatile("nop \n nop \n nop"); } void setup_SPI(){ // This example will use SPI0 at 2MHz. spi_init(SPI_PORT, 2 * 1000 * 1000); gpio_set_function(PIN_MISO, GPIO_FUNC_SPI); gpio_set_function(PIN_SCK, GPIO_FUNC_SPI); gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI); // Chip select is active-low, so we'll initialise it to a driven-high state gpio_init(PIN_CS); gpio_set_dir(PIN_CS, GPIO_OUT); gpio_put(PIN_CS, 1); } int readADC(uint8_t ch){ uint8_t writeData[] = {0b00000001, 0x00, 0x00}; switch(ch){ case 0: writeData[1] = 0b10000000; break; case 1: writeData[1] = 0b10010000; break; case 2: writeData[1] = 0b10100000; break; case 3: writeData[1] = 0b10110000; break; case 4: writeData[1] = 0b11000000; break; case 5: writeData[1] = 0b11010000; break; case 6: writeData[1] = 0b11100000; break; case 7: writeData[1] = 0b11110000; } // printf("\n %0b %0b %0b\n",writeData[0],writeData[1],writeData[2]); uint8_t buffer[3]; cs_select(); sleep_ms(1); spi_write_read_blocking(SPI_PORT, writeData, buffer, 3); sleep_ms(1); cs_deselect(); return (buffer[1] & 0b00000011) << 8 | buffer[2]; } int main() { stdio_init_all(); adc_init(); adc_gpio_init(26); adc_select_input(0); const float conversion_factor = Vref / (1 << 12); printf("\nHello, MCP3008 Reading raw data from registers via SPI...\n"); setup_SPI(); while (1) { for (uint8_t i=0; i<8; i++){ printf("ch%d is %.4fV\n", i, Vref * readADC(i) / 1024); sleep_ms(10); } uint16_t result = adc_read(); printf("ADC voltage: %f V\n", result * conversion_factor); sleep_ms(5000); } return 0; }