其实驱动也不是针对ESP32,任何芯片去读都可以用下面方法。下面是以esp32为例。
准备条件:
1-确认自己的spi连线没有问题
2-确认自己的spi驱动没有问题
下面先看看MCP3208的手册:
1-通信速度,先确认自己芯片的最大spi速度。esp32 -spi初始化的时候不要超过这个速度。

2-然后看时序图

2-1 分析一下时序图,
发送:我们发送的第一个字节的1-5bit是我们要关注的,
第一位是开始,没细看,直接写1
第二位是singl/diff,其实就是单边采样和差分采样,我们只看单边的。写1

第3-5位,即D2-D0位就是通道的数据位,根据真值表可以写出第一个字节的值,分别对应8个通道。
uint8_t adc_ch[]={0xC0,0xC8,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8};
后面3位无意义不关注。后面发送的数据无意义。0xFF即可。
接收:从时序图可以看出,接收的第一个字节有一个B11数据,即adc数据的第12位。
后面的数据则是adc数据的剩下11位。
读取的整体思路
先发送第一个带通道的字节,得到adc的第12位,
然后发送一个0xff,得到11-4位
然后发送一个0xff,得到3-1位。
至此12位数据全部得到,重新组合即可。
编写读取函数:驱动是从之前lcd驱动移植的,会有冗余代码。
- #ifndef _MSPI_H_
- #define _MSPI_H_
-
- #include "driver/spi_master.h"
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
-
- #define PIN_NUM_MISO 12
- #define PIN_NUM_MOSI 13
- #define PIN_NUM_CLK 14
- #define PIN_NUM_CS 15
-
- #define PIN_NUM_DC 21
- #define PIN_NUM_RST 18
- #define PIN_NUM_BCKL 5
-
- #define PARALLEL_LINES 16
-
-
- #define SPI_ADC_CH0 0
- #define SPI_ADC_CH1 1
- #define SPI_ADC_CH2 2
- #define SPI_ADC_CH3 3
- #define SPI_ADC_CH4 4
- #define SPI_ADC_CH5 5
- #define SPI_ADC_CH6 6
- #define SPI_ADC_CH7 7
-
-
- void lcd_spi_pre_transfer_callback(spi_transaction_t *t);
- //spi主机初始化
- void spi_master_init();
- //spi从机初始化
- void spi_slave_init();
-
- esp_err_t spi_write( uint8_t *data, int len);
- esp_err_t spi_read(uint8_t *data);
-
- esp_err_t spi_read_adc(uint8_t *sdata,uint8_t *rdata);
- short spi_read_adc_ch(uint8_t ch);
-
- #endif
- #include "driver/gpio.h"
- #include "mspi.h"
-
- static spi_device_handle_t spi;
- static spi_bus_config_t buscfg={
- .miso_io_num=PIN_NUM_MISO,
- .mosi_io_num=PIN_NUM_MOSI,
- .sclk_io_num=PIN_NUM_CLK,
- .quadwp_io_num=-1,
- .quadhd_io_num=-1,
- .max_transfer_sz=1,
- };
- static spi_device_interface_config_t devcfg={
- .clock_speed_hz=100*1000, //Clock out at 10 MHz
- // .clock_speed_hz=80*1000*1000,
- .mode=0, //SPI mode 0
- //.cs_ena_pretrans=1,
- //.cs_ena_posttrans=1,
- .spics_io_num=PIN_NUM_CS, //CS pin
- .queue_size=5, //We want to be able to queue 7 transactions at a time
- //.pre_cb=lcd_spi_pre_transfer_callback, //Specify pre-transfer callback to handle D/C line
- };
-
- void lcd_spi_pre_transfer_callback(spi_transaction_t *t)
- {
- int dc=(int)t->user;
- //gpio_set_level(PIN_NUM_DC, dc);
- }
-
- //spi主机初始化
- void spi_master_init()
- {
-
- esp_err_t ret;
- //Initialize the SPI bus
- ret=spi_bus_initialize(HSPI_HOST, &buscfg, 1);
- ESP_ERROR_CHECK(ret);
- //Attach the LCD to the SPI bus
- ret=spi_bus_add_device(HSPI_HOST, &devcfg, &spi);
- ESP_ERROR_CHECK(ret);
- }
- //spi从机初始化
- void spi_slave_init()
- {
-
- }
-
- esp_err_t spi_write(uint8_t *data, int len)
- {
- esp_err_t ret;
- spi_transaction_t t={0};
- if (len==0) return 0; //no need to send anything
- //memset(&t, 0, sizeof(t)); //Zero out the transaction
-
- //gpio_set_level(PIN_NUM_CS, 0);
-
- t.length=len*8; //Len is in bytes, transaction length is in bits.
- t.tx_buffer=data; //Data
- //t.user=(void*)1; //D/C needs to be set to 1
- ret=spi_device_polling_transmit(spi, &t); //Transmit!
-
- assert(ret==ESP_OK); //Should have had no issues.
-
- //gpio_set_level(PIN_NUM_CS, 1);
-
- return ret;
- }
-
- esp_err_t spi_read(uint8_t *data)
- {
- spi_transaction_t t={0};
-
- //gpio_set_level(PIN_NUM_CS, 0);
-
- //memset(&t, 0, sizeof(t));
- t.length=8;
- t.flags = SPI_TRANS_USE_RXDATA;
- //t.user = (void*)1;
- esp_err_t ret = spi_device_polling_transmit(spi, &t);
-
- assert( ret == ESP_OK );
- *data = t.rx_data[0];
-
- //gpio_set_level(PIN_NUM_CS, 1);
-
- return ret;
- }
-
- esp_err_t spi_read_adc(uint8_t *sdata,uint8_t *rdata)
- {
- spi_transaction_t t={0};
-
- //gpio_set_level(PIN_NUM_CS, 0);
-
- //memset(&t, 0, sizeof(t));
- t.length=8*3
- ;
- t.tx_buffer=sdata;
- t.flags = SPI_TRANS_USE_RXDATA;
- //t.user = (void*)1;
- esp_err_t ret = spi_device_polling_transmit(spi, &t);
-
- assert( ret == ESP_OK );
- rdata[0] = t.rx_data[0];
- rdata[1] = t.rx_data[1];
- rdata[2] = t.rx_data[2];
-
- //gpio_set_level(PIN_NUM_CS, 1);
-
- return ret;
-
- }
-
-
-
- short spi_read_adc_ch(uint8_t ch)
- {
- short ADC_RE;
- uint8_t adc_ch[]={0xC0,0xC8,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8};
- uint8_t spi_sdata1[3]={0xE0,0xff,0xff};
- uint8_t spi_data1[3] ={0};
-
- spi_sdata1[0]=adc_ch[ch];
-
- spi_read_adc((uint8_t *)spi_sdata1,(uint8_t *)spi_data1);
-
-
- int v_adc =(spi_data1[0]&0x01)<<11|spi_data1[1]<<3|(spi_data1[2]&0xe0)>>4;
-
- ADC_RE = v_adc*3300/4095;
-
- return ADC_RE;
- }
使用:使用spi_read_adc_ch时先初始化spi。
- int i_adc =spi_read_adc_ch(SPI_ADC_CH3);
- int v_adc =spi_read_adc_ch(SPI_ADC_CH4);
-
-
- printf("esp32-v: %d I:%d, spi-v:%d I:%d\r\n",volt,i_v,v_adc,i_adc);
运行效果:
