esp32c3,esp-idf 4.4.4,用spi2_host与ch623刷卡芯片用spi通信不用dma,给个例程
时间: 2024-03-10 19:50:00 浏览: 137
好的,以下是ESP32C3使用SPI2与CH623刷卡芯片进行通信的示例代码,不使用DMA:
```c
#include "driver/spi_master.h"
#define PIN_NUM_MISO 25
#define PIN_NUM_MOSI 23
#define PIN_NUM_CLK 19
#define PIN_NUM_CS 22
spi_device_handle_t spi_handle;
void spi_master_init()
{
esp_err_t ret;
spi_bus_config_t buscfg = {
.mosi_io_num = PIN_NUM_MOSI,
.miso_io_num = PIN_NUM_MISO,
.sclk_io_num = PIN_NUM_CLK,
.quadhd_io_num = -1,
.quadwp_io_num = -1,
.max_transfer_sz = 0, //默认为4094
};
spi_device_interface_config_t devcfg = {
.clock_speed_hz = 10 * 1000 * 1000, // SPI时钟频率为10MHz
.mode = 0, // SPI工作在模式0
.spics_io_num = PIN_NUM_CS, // 片选信号用GPIO22
.queue_size = 1, // 仅支持单个事务,因此队列大小为1
.command_bits = 8, // 发送命令时使用8位
.address_bits = 0, // 不使用地址
.dummy_bits = 0, // 不需要虚拟位
.cs_ena_pretrans = 0, // 在每次数据传输之前不使能片选信号
.cs_ena_posttrans = 0, // 在每次数据传输之后不禁用片选信号
.flags = SPI_DEVICE_NO_DUMMY, // 不需要虚拟位
.pre_cb = NULL, // 不需要传输前回调
.post_cb = NULL, // 不需要传输后回调
};
// 配置SPI总线
ret = spi_bus_initialize(SPI2_HOST, &buscfg, 1); // 使用SPI主机2,DMA通道1
assert(ret == ESP_OK);
// 添加SPI设备
ret = spi_bus_add_device(SPI2_HOST, &devcfg, &spi_handle);
assert(ret == ESP_OK);
}
void ch623_spi_write(uint8_t reg_addr, uint8_t reg_data)
{
esp_err_t ret;
spi_transaction_t trans = {
.flags = 0,
.cmd = reg_addr | 0x80, // 写寄存器时,命令位为1
.addr = 0,
.length = 8, // 寄存器地址占用8位
.rxlength = 0,
.user = NULL,
.tx_buffer = ®_data,
.rx_buffer = NULL,
};
// 发送SPI事务
ret = spi_device_polling_transmit(spi_handle, &trans);
assert(ret == ESP_OK);
}
uint8_t ch623_spi_read(uint8_t reg_addr)
{
esp_err_t ret;
uint8_t reg_data;
spi_transaction_t trans[2] = {
{
.flags = 0,
.cmd = reg_addr, // 读寄存器时,命令位为0
.addr = 0,
.length = 8, // 寄存器地址占用8位
.rxlength = 0,
.user = NULL,
.tx_buffer = NULL,
.rx_buffer = NULL,
},
{
.flags = 0,
.cmd = 0,
.addr = 0,
.length = 0,
.rxlength = 8, // 读取一个字节
.user = NULL,
.tx_buffer = NULL,
.rx_buffer = ®_data,
}
};
// 发送SPI事务
ret = spi_device_polling_transmit(spi_handle, &trans[0]);
assert(ret == ESP_OK);
ret = spi_device_polling_transmit(spi_handle, &trans[1]);
assert(ret == ESP_OK);
return reg_data;
}
void app_main()
{
spi_master_init();
// 向CH623写入寄存器
ch623_spi_write(0x00, 0x01);
// 从CH623读取寄存器
uint8_t reg_data = ch623_spi_read(0x00);
printf("Reg 0x00: %02x\n", reg_data);
}
```
在该示例代码中,我们首先通过`spi_bus_initialize()`函数初始化SPI总线,然后通过`spi_bus_add_device()`函数添加SPI设备。在`spi_device_interface_config_t`结构体中,我们可以设置SPI时钟频率、工作模式、片选信号GPIO等参数。在`spi_transaction_t`结构体中,我们可以设置SPI事务需要发送的命令、地址、数据等信息。
在`ch623_spi_write()`函数中,我们发送一个写寄存器的SPI事务。首先设置`trans.cmd`字段为`reg_addr | 0x80`,表示写寄存器时,命令位为1;然后将`reg_data`的值写入`trans.tx_buffer`中,发送SPI事务即可。
在`ch623_spi_read()`函数中,我们发送一个读寄存器的SPI事务。首先发送一个写寄存器的SPI事务,设置`trans.cmd`字段为`reg_addr`,表示读寄存器时,命令位为0。注意,在该事务中仅发送了命令位,不需要发送数据,因此`trans.tx_buffer`字段为`NULL`。然后发送一个读寄存器的SPI事务,设置`trans.rxlength`字段为8,表示读取一个字节的数据,将读取的数据保存在`reg_data`变量中,返回该变量即可。
最后,在`app_main()`函数中,我们调用`ch623_spi_write()`函数向CH623写入寄存器,然后调用`ch623_spi_read()`函数从CH623读取寄存器。
阅读全文