首页 > 解决方案 > DS3234 RTC 与 ESP32 spi 通信错误

问题描述

我正在尝试学习协议和 ESP32。我是 Arduino 用户,但我想使用 eclipse 迁移到 ESP32,根本不使用 arduino ide。

我正在尝试通过 SPI 通信使用 DS3234 rtc,但我无法使其工作。

首先,我用 Arduino 设置了 RTC,一切正常,1Hz 脉冲也很好(闪烁的 LED)。然后我首先尝试从 ESP32 中读取,但我无法使其工作。

我尝试了来自 API 参考站点的 SPI2 (HSPI_HOST) 的引脚以及来自 spi_master 模板的引脚,在模式 1 和 3 中,基于 Arduino .ide 中使用的模式(我也尝试了模式 0),我尝试了 1 的频率, Spi_freq 为 4,10,16,80MHz。Arduino SPI 频率为 4MHz。

来自 Espressif 网站的 API 参考:GPIO 编号 CS0* 15 SCLK 14 MISO 12 MOSI 13

我还尝试通过设置代码在传输开始和结束时手动将 CS 设置为低和高:[全选] [展开/折叠]

spi_device_interface_config_t.spics_io_num=-1

GeSHi © Codebox Plus 扩展。我给你 main.c 文件和我拥有的输出。

我正在使用 time.h 和 time() 函数来获取系统时间,但正如您将在输出中看到的那样,这也没有给出正确的时间,甚至试图将 1970 年 1 月 1 日星期二的 0:00:00 设置为 rtc不起作用,因为您会看到 Read 函数的返回是 0:00:00 1 作为第 2000-1-1 天,这是不正确的,并且秒数也没有变化。

可能主要担心的是我的 spi 设置中是否存在关于总线、开发、初始化等的问题。如果有人能提供帮助,那就太好了。谢谢。

#include "stdio.h"
#include "stdbool.h"
#include "freertos/FreeRTOS.h"
#include "esp_system.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/spi_master.h"
#include "string.h"
#include "time.h"

#define MISO 12
#define MOSI 13
#define CLK 14
#define CS 15

#define PIN_NUM_MISO 25
#define PIN_NUM_MOSI 23
#define PIN_NUM_CLK  19
#define PIN_NUM_CS   22

#define SQW_1Hz 0b00000000;
#define WRITE_CONTROL_REG 0x8E
#define READ_CONTROL_REG 0x0E
#define WRITE_TIME_REG 0x80
#define READ_TIME_REG 0x00


spi_device_handle_t spi;
spi_bus_config_t busCfg;
spi_device_interface_config_t devCfg;


uint8_t bcdToInt(uint8_t bcd){
    return bcd-6*(bcd>>4);
}

uint8_t intToBcd(uint8_t dec){
    return dec+6*(dec/10);
}

uint8_t bcdTo24Hour(uint8_t bcdHour){
    uint8_t hour;
    if(bcdHour&0x40){
        bool isPm = ((bcdHour& 0x20)!=0);
        hour=bcdToInt(bcdHour& 0x1f);
        if(isPm){
            hour+=12;
        }
    }else{
        hour= bcdToInt(bcdHour);
    }
    return hour;
}


void spiInit(){

    busCfg.miso_io_num=MISO;
    busCfg.mosi_io_num=MOSI;
    busCfg.sclk_io_num=CLK;

//  busCfg.miso_io_num=PIN_NUM_MISO;
//  busCfg.mosi_io_num=PIN_NUM_MOSI;
//  busCfg.sclk_io_num=PIN_NUM_CLK;
    busCfg.quadhd_io_num=-1;
    busCfg.quadwp_io_num=-1;

    spi_bus_initialize(HSPI_HOST,&busCfg,2);

    vTaskDelay(100/portTICK_PERIOD_MS);

    devCfg.mode=1;
    devCfg.clock_speed_hz=1*1000*1000;
    devCfg.spics_io_num=CS;
    devCfg.queue_size=7;

    spi_bus_add_device(HSPI_HOST,&devCfg,&spi);

    vTaskDelay(100/portTICK_PERIOD_MS);

//  gpio_pad_select_gpio(PIN_NUM_CS);
//  gpio_set_direction(PIN_NUM_CS,GPIO_MODE_OUTPUT);
//  gpio_set_level(PIN_NUM_CS,1);

//  gpio_pad_select_gpio(CS);
//  gpio_set_direction(CS,GPIO_MODE_OUTPUT);
//  gpio_set_level(CS,1);

}

void setCS(){

    gpio_set_level(CS,0);
}

void unsetCS(){
    gpio_set_level(CS,1);
}

void setControlReg(const uint8_t cmd){


    esp_err_t ret;
    spi_transaction_t t;
    memset(&t,0,sizeof(t));
    t.length=8;
    t.tx_buffer=&cmd;
    ret=spi_device_transmit(spi,&t);

    assert(ret==ESP_OK);
}
void setTime(const uint8_t *data,uint8_t cmd,int len){

    //setCS();
    setControlReg(cmd);

    esp_err_t ret;
    spi_transaction_t t;
    memset(&t,0,sizeof(t));
    t.length=len*8;
    t.tx_buffer=&data;
    ret=spi_device_transmit(spi,&t);
    assert(ret==ESP_OK);
    //unsetCS();
}

uint8_t* readData(const uint8_t cmd,int len,uint8_t *data){

    //setCS();
    setControlReg(cmd);

    esp_err_t ret;
    spi_transaction_t t;
    memset(&t,0,sizeof(t));
    t.length=len*8;
    t.flags=SPI_TRANS_USE_RXDATA;
    ret=spi_device_transmit(spi,&t);
    //printf("Get Data result");
    assert(ret==ESP_OK);

    //unsetCS();

    data=t.rx_data;

    return data;

}

void print_time(struct tm tm){

    printf("Time: %i:%i:%i %i Day %i-%i-%i\n",tm.tm_hour,tm.tm_min,tm.tm_sec,tm.tm_wday,tm.tm_year+2000,tm.tm_mon+1,tm.tm_mday);
}

uint8_t* timeToBuffer(uint8_t *data,struct tm tm){
    printf("Time to buffer");
    print_time(tm);
    data[0]=intToBcd(tm.tm_sec);
    data[1]=intToBcd(tm.tm_min);
    data[2]=intToBcd(tm.tm_hour);
    data[3]=intToBcd(tm.tm_wday);
    data[4]=intToBcd(tm.tm_mday);
    data[5]=intToBcd(tm.tm_mon);
    data[6]=intToBcd(tm.tm_year);

    return data;

}

void bufferToTime(struct tm *tm,uint8_t *buffer){


    tm->tm_sec=bcdToInt(buffer[0]);
    tm->tm_min=bcdToInt(buffer[1]);
    tm->tm_hour=bcdTo24Hour(buffer[2]);
    tm->tm_wday=bcdToInt(buffer[3]);
    tm->tm_mday=bcdToInt(buffer[4]);
    tm->tm_mon=bcdToInt(buffer[5]);
    tm->tm_year=bcdToInt(buffer[6]);

}


void app_main(void)
{
    printf("Initializing SPI\n");
    spiInit();

    printf("Set Time\n");

    uint8_t bufferData[7];
    memset(bufferData,0,sizeof(bufferData));

    time_t curTime;
    time(&curTime);
    printf("%s\n",ctime(&curTime));
    struct tm *myTime=localtime(&curTime);


    setTime(timeToBuffer(bufferData,*myTime),WRITE_TIME_REG,7);
    memset(bufferData,0,sizeof(bufferData));

    printf("Start Reading\n");
    while (true) {
        readData(READ_TIME_REG,7,bufferData);
        bufferToTime(myTime,bufferData);
        print_time(*myTime);
        vTaskDelay(1000/portTICK_PERIOD_MS);
    }
}

输出:

初始化 SPI

设置时间

1970 年 1 月 1 日星期四 00:00:00

缓冲时间时间:0:0:0 4 天 2070-1-1

开始阅读

时间:0:0:0 0 天 2000-1-0

时间:0:0:0 0 天 2000-1-0

时间:0:0:0 0 天 2000-1-0

标签: ctimeesp8266spiesp32

解决方案


我发现了问题。

一组时间工作正常。在读取时,我必须注释掉标志并将 t.rx_buffer 设置为数据变量。所以这个函数中的代码就像这样。

uint8_t* readData(const uint8_t cmd,int len,uint8_t *data){

    setCS();
    setControlReg(cmd);

    esp_err_t ret;
    spi_transaction_t t;
    memset(&t,0,sizeof(t));
    t.length=len*8;
    //t.flags=SPI_TRANS_USE_RXDATA;
    //t.tx_buffer=data;
    t.rx_buffer=data;
    ret=spi_device_transmit(spi,&t);
    //printf("Get Data result");
    assert(ret==ESP_OK);

    unsetCS();

    //data=t.rx_data;

    return data;

}

推荐阅读