ESP32S3 SPI发送间隔频率
- 驱动ADS8326
- esp32s3 spi例程 代码
- 测试
- 用寄存器方式实现spi发送
- 寄存器描述
驱动ADS8326
ads8326驱动时序
首先CS信号拉低,然后clk发送6个时钟,ads8326开始启动转换。
最后clk发送16个时钟,就会读取到两个字节的数据(高位在前)
esp32s3 spi例程 代码
//SPI总线配置结构
static spi_bus_config_t buscfg={
.miso_io_num = PIN_NUM_MISO, //设置主机输入
.mosi_io_num = -1, //设置主机输出
.sclk_io_num = PIN_NUM_CLK, //设置时钟引脚
.quadwp_io_num = -1, //不使用wp信号线
.quadhd_io_num = -1, //不使用hd信号线
.max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE,
// .intr_flags,//中断指示位
};
// 设备配置结构 配置SPI数据传输参数(可以新建多个结构体变量,相当于挂载spi设备,一个spi最多挂载3个设备,需要设置不同的片选引脚)
static spi_device_interface_config_t devcfg={
.command_bits=1, //默认控制位长度,设置为0-16
.address_bits=5, //默认地址位长度,设置为0-64
// .dummy_bits,//在地址和数据位段之间插入的dummy位长度,用于匹配时序,一般可以保持默认
.clock_speed_hz=5*1000*1000, //20Mhz 时钟频率,设置的是80MHz的分频系数,单位为Hz
.mode=0, //SPI 模式(0,1,2,3)
// .flags = SPI_DEVICE_RXBIT_LSBFIRST, //半双工通信
// .flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_POSITIVE_CS, //半双工通信
// .cs_ena_pretrans,//传输前CS信号的建立时间,只在半双工模式下有用
// .cs_ena_posttrans,//传输时CS信号的保持时间
.spics_io_num=PIN_NUM_CS, //设置cs引脚
.queue_size=7, //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 SPI_Init(void)
{
esp_err_t ret;
// uint8_t test_str[10];
ESP_LOGI(TAG, "SPI初始化");
//初始化配置SPI总线(配置HSPI)最后设置为0不启用DMA
ret = spi_bus_initialize(SPI2_ADS8326, &buscfg, SPI_DMA_DISABLED); //SPI_DMA_CH_AUTO
ESP_ERROR_CHECK(ret);
ret = spi_bus_add_device(SPI2_ADS8326, &devcfg, &spi2_handle);
ESP_ERROR_CHECK(ret);
AD_SPI_CS_H;
}
esp_err_t spi_read(spi_device_handle_t spi, uint8_t *data)
{
spi_transaction_t t;
memset(&t, 0, sizeof(t));
t.length=8*2; //数据总长度,单位:比特
t.tx_buffer=NULL;
t.rx_buffer=data;
// t.flags = SPI_TRANS_USE_RXDATA;
// t.user = (void*)0;
esp_err_t ret = spi_device_polling_transmit(spi, &t);
assert( ret == ESP_OK );
return ret;
}
//在一个线程上读取数据
spi_read(spi2_handle, &ads8326_val.Data[0]);
ESP_LOGI(TAG, "Data1:0x%x%x",ads8326_val.Data[0],ads8326_val.Data[1]);
ads8326_val.ADCdata=((uint16_t)ads8326_val.Data[0]<<8)|ads8326_val.Data[1];
ESP_LOGI(TAG, "ads8326AD值:%d",ads8326_val.ADCdata);
AD8326val=ads8326_val.ADCdata*3.3123/65535;
ESP_LOGI(TAG, "电压值:%fV",AD8326val);
当然你的主频要调到240Mhz
测试
两个发送间隔是9us 但是这个是不满足我们的要求的
用寄存器方式实现spi发送
1.初始配置还是采样之前的
2.在线程初始化前我们调用读取,目的是让api去设置寄存器,如果我们自己去设置工作量就会很大。
3.然后在我们线程中 触发寄存器去读。
4.然后去GPSPI2.data_buf[0]里面去读,里面是个GPSPI2.data_buf[16];
5.测试最快可以达到980ns一次。
//2.步代码
spi_read(spi2_handle, &ads8326_val.Data[0]);
///3.步代码
GPSPI2.user.usr_mosi=0; //清除 SPI_USR_MOSI。 置位此位,使能一次操作的读数据 (DIN) 阶段
GPSPI2.dma_conf.dma_afifo_rst=1; //置位 SPI_DMA_AFIFO_RST、SPI_BUF_AFIFO_RST 和 SPI_RX_AFIFO_RST 复位 buffer。
GPSPI2.dma_conf.buf_afifo_rst=1;
GPSPI2.dma_conf.rx_afifo_rst=1;
GPSPI2.cmd.update = 1;
while (GPSPI2.cmd.update);
GPSPI2.cmd.usr = 1;
寄存器描述
则具体的寄存器配置如下:
1. 配置 CMD 状态相关寄存器。
• 配置 SPI_USR_COMMAND_VALUE 为需要的命令值;
• 配置 SPI_USR_COMMAND_BITLEN。SPI_USR_COMMAND_BITLEN 为所需要的命令位长 - 1;
• 置位 SPI_USR_COMMAND;
• 清除 SPI_FCMD_DUAL 和 SPI_FCMD_QUAD。
2. 配置 ADDR 状态相关寄存器。
• 配置 SPI_USR_ADDR_VALUE 为需要的地址值;
• 配置 SPI_USR_ADDR_BITLEN。SPI_USR_ADDR_BITLEN 为所需要的地址位长 - 1;
• 置位 SPI_USR_ADDR 和 SPI_FADDR_DUAL;
• 清除 SPI_FADDR_QUAD。
3. 配置 DUMMY 状态相关寄存器。
• 在 SPI_USR_DUMMY_CYCLELEN 中配置 DUMMY 周期,其中 SPI_USR_DUMMY_CYCLELEN 的值
等于 DUMMY 阶段所需要的时钟周期数 - 1;
• 置位 SPI_USR_DUMMY。
4. 配置 DIN 状态相关寄存器。
• 在 SPI_MS_DATA_BITLEN 中配置读数据的位长。SPI_MS_DATA_BITLEN 的值等于所需要的位长 - 1;
• 置位 SPI_FREAD_QUAD 和 SPI_USR_MISO;
• 清除 SPI_FREAD_DUAL;
• 如果选择了 DAM 控制的传输模式,则需要配置 GDMA。如果选择了 CPU 控制的传输模式,则无需
任何操作。
5. 清除 SPI_USR_MOSI。
6. 置位 SPI_DMA_AFIFO_RST、SPI_BUF_AFIFO_RST 和 SPI_RX_AFIFO_RST 复位 buffer。
7. 置位 SPI_USR 开始 GP-SPI 传输。
最后上完整工程连接吧
esp32s3寄存器工程
这个我搞了好久被逼出来了的。有不对的请谅解。欢迎多多指教。
最后给你们推荐个:
一键 自动下载器
店主很好有啥问题可以互相交流,就是他帮助了我,感谢!