中级
30 分钟

使用 AT21CS01 和 PIC18F57Q43 快速恢复意外错误

单线串行 EEPROM

SWI EEPROM Click with Curiosity Nano with PIC18F57Q43

已发布 6月 24, 2024

点击板

SWI EEPROM Click

开发板

Curiosity Nano with PIC18F57Q43

编译器

NECTO Studio

微控制器单元

PIC18F57Q43

我们的解决方案利用单线EEPROM存储校准值、使用历史和设备特定信息,简化维护并提高整体效率。

A

A

硬件概览

它是如何工作的?

SWI EEPROM Click基于AT21CS01,这是一款由Microchip Technology提供的2针串行电可擦写可编程只读存储器(EEPROM),通过SI/O引脚收集能量为集成电路供电。它提供1,024位内存,组织为128个8位字,具有64位工厂编程序列号的安全寄存器,以及额外16字节的用户可编程和永久锁定存储。它提供了一个保证唯一的序列号用于库存跟踪和资产标记,并且在需要时可以始终保护数据。AT21CS01具有100年的数据保持能力,结合了前所未有的

数据存储和出色的能效。它以高可靠性和超高写入耐久性为特点,使每个内存位置能够进行超过一百万次循环,以满足当今高写入耐久性应用的要求。SWI EEPROM Click使用单线接口与MCU通信,根据定义,仅需要一条数据线(和地线)与MCU通信。路由到mikroBUS™插座PWM引脚的SI/O引脚是一个双向输入/输出引脚,用于串行传输数据到设备和从设备传输数据,在标准速度模式下的最大比特率为15.4Kbps,高速模式下为125Kbps。AT21CS01使用修改后的

I2C接口从读取和写入序列中提取电力。发送到设备的软件序列模拟了发送到I2C串行EEPROM的内容,除了一个4位操作码取代了设备地址中的典型4位设备类型标识符1010b。该设备被设计用于快速部署和显著重用现有I2C固件。此Click板™只能在3.3V逻辑电压水平下运行。使用具有不同逻辑电平的MCU之前,必须进行适当的逻辑电压电平转换。此外,它配有包含函数和示例代码的库,可用作进一步开发的参考。

SWI EEPROM Click top side image
SWI EEPROM Click bottom side image

功能概述

开发板

PIC18F57Q43 Curiosity Nano 评估套件是一款尖端的硬件平台,旨在评估 PIC18-Q43 系列内的微控制器。其设计的核心是包含了功能强大的 PIC18F57Q43 微控制器(MCU),提供先进的功能和稳健的性能。这个评估套件的关键特点包括一个黄 色用户 LED 和一个响应灵敏的机械用户开关,提供无

缝的交互和测试。为一个 32.768kHz 水晶振荡器足迹提供支持,确保精准的定时能力。套件内置的调试器拥有一个绿色电源和状态 LED,使编程和调试变得直观高效。此外,增强其实用性的还有虚拟串行端口 (CDC)和一个调试 GPIO 通道(DGI GPIO),提供广泛的连接选项。该套件通过 USB 供电,拥有由

 MIC5353 LDO 调节器提供支持的可调目标电压功能,确保在 1.8V 至 5.1V 的输出电压范围内稳定运行,最大输出电流为 500mA,受环境温度和电压限制。

PIC18F57Q43 Curiosity Nano double side image

微控制器概述 

MCU卡片 / MCU

default

建筑

PIC

MCU 内存 (KB)

128

硅供应商

Microchip

引脚数

48

RAM (字节)

8196

你完善了我!

配件

Curiosity Nano Base for Click boards 是一款多功能硬件扩展平台,专为简化 Curiosity Nano 套件与扩展板之间的集成而设计,特别针对符合 mikroBUS™ 标准的 Click 板和 Xplained Pro 扩展板。这款创新的基板(屏蔽板)提供了无缝的连接和扩展可能性,简化了实验和开发过程。主要特点包括从 Curiosity Nano 套件提供 USB 电源兼容性,以及为增强灵活性而提供的另一种外部电源输入选项。板载锂离子/锂聚合物充电器和管理电路确保电池供电应用的平稳运行,简化了使用和管理。此外,基板内置了一个固定的 3.3V 电源供应单元,专用于目标和 mikroBUS™ 电源轨,以及一个固定的 5.0V 升压转换器,专供 mikroBUS™ 插座的 5V 电源轨,为各种连接设备提供稳定的电力供应。

Curiosity Nano Base for Click boards accessories 1 image

使用的MCU引脚

mikroBUS™映射器

NC
NC
AN
NC
NC
RST
NC
NC
CS
NC
NC
SCK
NC
NC
MISO
NC
NC
MOSI
Power Supply
3.3V
3.3V
Ground
GND
GND
Single-Wire Data IN/OUT
PB0
PWM
NC
NC
INT
NC
NC
TX
NC
NC
RX
NC
NC
SCL
NC
NC
SDA
NC
NC
5V
Ground
GND
GND
1

“仔细看看!”

Click board™ 原理图

SWI EEPROM Click Schematic schematic

一步一步来

项目组装

Curiosity Nano Base for Click boards front image hardware assembly

从选择您的开发板和Click板™开始。以Curiosity Nano with PIC18F57Q43作为您的开发板开始。

Curiosity Nano Base for Click boards front image hardware assembly
Charger 27 Click front image hardware assembly
PIC18F47Q10 Curiosity Nano front image hardware assembly
Prog-cut hardware assembly
Board mapper by product8 hardware assembly
Necto image step 2 hardware assembly
Necto image step 3 hardware assembly
Necto image step 4 hardware assembly
Necto image step 5 hardware assembly
Necto image step 6 hardware assembly
PIC18F57Q43 Curiosity MCU Step hardware assembly
Necto No Display image step 8 hardware assembly
Necto image step 9 hardware assembly
Necto image step 10 hardware assembly
Debug Image Necto Step hardware assembly

软件支持

库描述

该库包含 SWI EEPROM Click 驱动程序的 API。

关键功能:

  • swieeprom_mem_write_page - 此函数将数据写入指定的内存地址页。

  • swieeprom_mem_read - 此函数从指定的内存地址读取数据。

  • swieeprom_mem_clear - 此函数将整个内存清零。

开源

代码示例

完整的应用程序代码和一个现成的项目可以通过NECTO Studio包管理器直接安装到NECTO Studio 应用程序代码也可以在MIKROE的GitHub账户中找到。

/*!
 * @file main.c
 * @brief SWI EEPROM Click Example.
 *
 * # Description
 * This example demonstrates the use of SWI EEPROM Click board by writing specified data to
 * the memory and reading it back.
 *
 * The demo application is composed of two sections :
 *
 * ## Application Init
 * Initializes the driver and logger and checks the communication.
 *
 * ## Application Task
 * Writes the specified text message to the memory and reads it back. After that, erases
 * the whole memory and tries to read the same message verifying that the memory is erased.
 * All data is being displayed on the USB UART where you can track the program flow.
 *
 * @note
 * This application is written for the following MCUs and specifically for MIKROBUS 1:
 * STM32F407ZG, MK64FN1M0VDC12, TM4C129XNCZAD, GD32VF103VBT6, PIC32MX795F512L
 * In order to use it on another MCUs the pin_x functions must be defined in a way
 * it matches the required timing specifications for the Single Wire interface.
 *
 * @author Stefan Filipovic
 *
 */

#include "board.h"
#include "log.h"
#include "swieeprom.h"

#define DEMO_TEXT_MESSAGE       "MIKROE"
#define STARTING_ADDRESS        0x00

static swieeprom_t swieeprom;   /**< SWI EEPROM Click driver object. */
static log_t logger;    /**< Logger object. */

/**
 * @brief Pin init function.
 * @details This function initializes the SIO pin.
 * @return None.
 * @note By default it initializes the SIO pin to the PWM pin from MIKROBUS 1.
 * The implementation differs from MCU to MCU.
 */
static void pin_init( void );

/**
 * @brief Pin low function.
 * @details This function sets the SIO pin to LOW logic level.
 * @return None.
 * @note The pin it uses should match the one that is initialized using the pin_init function.
 * The implementation differs from MCU to MCU.
 */
static void pin_low( void );

/**
 * @brief Pin release function.
 * @details This function releases the SIO pin by setting it to digital input.
 * @return None.
 * @note The pin it uses should match the one that is initialized using the pin_init function.
 * The implementation differs from MCU to MCU.
 */
static void pin_release( void );

/**
 * @brief Pin get function.
 * @details This function returns the SIO pin logic state.
 * @return Pin logic state.
 * @note The pin it uses should match the one that is initialized using the pin_init function.
 * The implementation differs from MCU to MCU.
 */
static uint8_t pin_get( void );

/**
 * @brief SWI EEPROM reset function.
 * @details This function initializes the SIO pin and performs the SWI reset.
 * @return @li @c  0 - Success,
 *         @li @c -1 - Error.
 * See #err_t definition for detailed explanation.
 * @note None.
 */
static err_t swieeprom_reset ( void );

/**
 * @brief SWI EEPROM start stop function.
 * @details This function sends the SWI start/stop signal.
 * @return None.
 * @note None.
 */
static void swieeprom_start_stop ( void );

/**
 * @brief SWI EEPROM logic write 0 function.
 * @details This function sends the SWI logic zero signal.
 * @return None.
 * @note None.
 */
static void swieeprom_logic_write_0 ( void );

/**
 * @brief SWI EEPROM logic write 1 function.
 * @details This function sends the SWI logic one signal.
 * @return None.
 * @note None.
 */
static void swieeprom_logic_write_1 ( void );

/**
 * @brief SWI EEPROM logic read function.
 * @details This function reads the SWI logic state.
 * @return Logic state.
 * @note None.
 */
static uint8_t swieeprom_logic_read ( void );

void application_init ( void ) 
{
    log_cfg_t log_cfg;  /**< Logger config object. */

    /** 
     * Logger initialization.
     * Default baud rate: 115200
     * Default log level: LOG_LEVEL_DEBUG
     * @note If USB_UART_RX and USB_UART_TX 
     * are defined as HAL_PIN_NC, you will 
     * need to define them manually for log to work. 
     * See @b LOG_MAP_USB_UART macro definition for detailed explanation.
     */
    LOG_MAP_USB_UART( log_cfg );
    log_init( &logger, &log_cfg );
    log_info( &logger, " Application Init " );

    // Click initialization.
    swieeprom.swi_reset = &swieeprom_reset;
    swieeprom.swi_start_stop = &swieeprom_start_stop;
    swieeprom.swi_logic_0 = &swieeprom_logic_write_0;
    swieeprom.swi_logic_1 = &swieeprom_logic_write_1;
    swieeprom.swi_logic_read = &swieeprom_logic_read;
    if ( SWIEEPROM_ERROR == swieeprom_init ( &swieeprom ) ) 
    {
        log_error( &logger, " Communication init." );
        for ( ; ; );
    }
    
    if ( SWIEEPROM_ERROR == swieeprom_check_communication ( &swieeprom ) )
    {
        log_error( &logger, " Check communication." );
        for ( ; ; );
    }
    
    log_info( &logger, " Application Task " );
}

void application_task ( void ) 
{
    uint8_t data_buf[ 8 ] = { 0 };
    // Write data to the specified address
    log_printf ( &logger, " Memory address: 0x%.2X\r\n", ( uint16_t ) STARTING_ADDRESS );
    memcpy ( data_buf, DEMO_TEXT_MESSAGE, strlen ( DEMO_TEXT_MESSAGE ) );
    if ( SWIEEPROM_OK == swieeprom_mem_write_page ( &swieeprom, STARTING_ADDRESS, 
                                                    data_buf, strlen ( DEMO_TEXT_MESSAGE ) ) )
    {
        log_printf ( &logger, " Write data: %s\r\n", data_buf );
        Delay_ms ( 100 );
    }
    // Read data from the specified address to verify the previous memory write
    memset ( data_buf, 0, sizeof ( data_buf ) );
    if ( SWIEEPROM_OK == swieeprom_mem_read ( &swieeprom, STARTING_ADDRESS, 
                                              data_buf, sizeof ( data_buf ) ) )
    {
        log_printf ( &logger, " Read data: %s\r\n", data_buf );
        Delay_ms ( 1000 );
        Delay_ms ( 1000 );
    }
    // Clear whole memory
    if ( SWIEEPROM_OK == swieeprom_mem_clear ( &swieeprom ) )
    {
        log_printf ( &logger, " Memory clear\r\n" );
        Delay_ms ( 100 );
    }
    // Read data from the specified address to verify the previous memory clear
    memset ( data_buf, 0, sizeof ( data_buf ) );
    if ( SWIEEPROM_OK == swieeprom_mem_read ( &swieeprom, STARTING_ADDRESS, 
                                              data_buf, sizeof ( data_buf ) ) )
    {
        log_printf ( &logger, " Read data: %s\r\n\n", data_buf );
        Delay_ms ( 1000 );
        Delay_ms ( 1000 );
    }
}

int main ( void ) 
{
    /* Do not remove this line or clock might not be set correctly. */
    #ifdef PREINIT_SUPPORTED
    preinit();
    #endif
    
    application_init( );
    
    for ( ; ; ) 
    {
        application_task( );
    }

    return 0;
}

#ifdef __MIKROC_AI__
    #ifdef STM32F407ZG
        void pin_init( void ) 
        { 
            digital_in_t sio_in;
            digital_in_init ( &sio_in, PD12 );
        }

        void pin_low( void ) 
        { 
            if ( !GPIOD_MODER.B24 ) 
            { 
                GPIOD_MODER.B24 = 1; 
            }
            GPIOD_ODR.B12 = 0;
        }

        void pin_release( void )
        { 
            if ( GPIOD_MODER.B24 ) 
            { 
                GPIOD_MODER.B24 = 0; 
            }
        }

        uint8_t pin_get( void )
        {
            if ( GPIOD_MODER.B24 ) 
            { 
                GPIOD_MODER.B24 = 0; 
            }
            return GPIOD_IDR.B12;
        }
    #elif MK64FN1M0VDC12
        void pin_init( void ) 
        { 
            digital_in_t sio_in;
            digital_in_init ( &sio_in, PE6 );
        }

        void pin_low( void ) 
        { 
            if ( !GPIOE_PDDR.B6 ) 
            { 
                GPIOE_PDDR.B6 = 1; 
            }
            GPIOE_PDOR.B6 = 0;
        }

        void pin_release( void )
        { 
            if ( GPIOE_PDDR.B6 ) 
            { 
                GPIOE_PDDR.B6 = 0; 
            }
        }

        uint8_t pin_get( void )
        {
            if ( GPIOE_PDDR.B6 ) 
            { 
                GPIOE_PDDR.B6 = 0; 
            }
            return GPIOE_PDIR.B6;
        }
    #elif TM4C129XNCZAD
        void pin_init( void ) 
        { 
            digital_in_t sio_in;
            digital_in_init ( &sio_in, PD0 );
        }

        void pin_low( void ) 
        { 
            if ( !GPIO_PORTD_AHB_DIR.B0 ) 
            { 
                GPIO_PORTD_AHB_DIR.B0 = 1; 
            }
            GPIO_PORTD_AHB_DATA.B0 = 0;
        }

        void pin_release( void )
        { 
            if ( GPIO_PORTD_AHB_DIR.B0 ) 
            { 
                GPIO_PORTD_AHB_DIR.B0 = 0; 
            }
        }

        uint8_t pin_get( void )
        {
            if ( GPIO_PORTD_AHB_DIR.B0 ) 
            { 
                GPIO_PORTD_AHB_DIR.B0 = 0; 
            }
            return GPIO_PORTD_AHB_DATA.B0;
        }
    #elif PIC32MX795F512L
        void pin_init( void ) 
        { 
            digital_in_t sio_in;
            digital_in_init ( &sio_in, PD1 );
        }

        void pin_low( void ) 
        { 
            if ( TRISD1_bit ) 
            { 
                TRISD1_bit = 0; 
            }
            LATD1_bit = 0;
        }

        void pin_release( void )
        { 
            if ( !TRISD1_bit ) 
            { 
                TRISD1_bit = 1; 
            }
        }

        uint8_t pin_get( void )
        {
            if ( !TRISD1_bit ) 
            { 
                TRISD1_bit = 1; 
            }
            return RD1_bit;
        }
    #else
        #error "Pin functions are not defined for the selected MCU"
    #endif
#elif __clang__
    #ifdef STM32F407ZG
        #define GPIOD_MODER             ( *( uint32_t * ) 0x40020C00 )
        #define GPIOD_IDR               ( *( uint32_t * ) 0x40020C10 )
        #define GPIOD_ODR               ( *( uint32_t * ) 0x40020C14 )
        #define GPIO_MODER_PIN12_MASK   ( ( uint32_t ) 3 << 24 )
        #define GPIO_MODER_PIN12_INPUT  ( ( uint32_t ) 0 << 24 )
        #define GPIO_MODER_PIN12_OUTPUT ( ( uint32_t ) 1 << 24 )
        #define GPIO_PIN12_MASK         ( ( uint32_t ) 1 << 12 )
        void pin_init( void ) 
        { 
            digital_in_t sio_in;
            digital_in_init ( &sio_in, PD12 );
        }

        void pin_low( void ) 
        { 
            if ( GPIO_MODER_PIN12_OUTPUT != ( GPIOD_MODER & GPIO_MODER_PIN12_MASK ) ) 
            { 
                GPIOD_MODER &= ~GPIO_MODER_PIN12_MASK;
                GPIOD_MODER |= GPIO_MODER_PIN12_OUTPUT;
            }
            GPIOD_ODR &= ~GPIO_PIN12_MASK;
        }

        void pin_release( void )
        { 
            if ( GPIO_MODER_PIN12_INPUT != ( GPIOD_MODER & GPIO_MODER_PIN12_MASK ) ) 
            { 
                GPIOD_MODER &= ~GPIO_MODER_PIN12_MASK;
            }
        }
    
        uint8_t pin_get( void )
        {
            if ( GPIO_MODER_PIN12_INPUT != ( GPIOD_MODER & GPIO_MODER_PIN12_MASK ) ) 
            { 
                GPIOD_MODER &= ~GPIO_MODER_PIN12_MASK;
            }
            return ( GPIO_PIN12_MASK == ( GPIOD_IDR & GPIO_PIN12_MASK ) );
        }
    #elif MK64
        #define GPIOE_PDOR              ( *( uint32_t * ) 0x400FF100 )
        #define GPIOE_PDIR              ( *( uint32_t * ) 0x400FF110 )
        #define GPIOE_PDDR              ( *( uint32_t * ) 0x400FF114 )
        #define GPIO_PDDR_PIN6_INPUT    ( ( uint32_t ) 0 << 6 )
        #define GPIO_PDDR_PIN6_OUTPUT   ( ( uint32_t ) 1 << 6 )
        #define GPIO_PIN6_MASK          ( ( uint32_t ) 1 << 6 )
        void pin_init( void ) 
        { 
            digital_in_t sio_in;
            digital_in_init ( &sio_in, PE6 );
        }

        void pin_low( void ) 
        { 
            if ( GPIO_PDDR_PIN6_OUTPUT != ( GPIOE_PDDR & GPIO_PIN6_MASK ) ) 
            { 
                GPIOE_PDDR |= GPIO_PDDR_PIN6_OUTPUT;
            }
            GPIOE_PDOR &= ~GPIO_PIN6_MASK;
        }

        void pin_release( void )
        { 
            if ( GPIO_PDDR_PIN6_INPUT != ( GPIOE_PDDR & GPIO_PIN6_MASK ) ) 
            { 
                GPIOE_PDDR &= ~GPIO_PDDR_PIN6_OUTPUT;
            }
        }
    
        uint8_t pin_get( void )
        {
            if ( GPIO_PDDR_PIN6_INPUT != ( GPIOE_PDDR & GPIO_PIN6_MASK ) ) 
            { 
                GPIOE_PDDR &= ~GPIO_PDDR_PIN6_OUTPUT;
            }
            return ( GPIO_PIN6_MASK == ( GPIOE_PDIR & GPIO_PIN6_MASK ) );
        }
    #elif TM4C129
        #define GPIOD_PORTD_DIR         ( *( uint32_t * ) 0x4005B400 )
        #define GPIOD_PORTD_DATA        ( *( uint32_t * ) 0x4005B3FC )
        #define GPIO_PORTD_PIN0_INPUT   ( ( uint32_t ) 0 )
        #define GPIO_PORTD_PIN0_OUTPUT  ( ( uint32_t ) 1 )
        #define GPIO_PIN0_MASK          ( ( uint32_t ) 1 )
        void pin_init( void ) 
        { 
            digital_in_t sio_in;
            digital_in_init ( &sio_in, PD0 );
        }

        void pin_low( void ) 
        { 
            if ( GPIO_PORTD_PIN0_OUTPUT != ( GPIOD_PORTD_DIR & GPIO_PIN0_MASK ) ) 
            { 
                GPIOD_PORTD_DIR |= GPIO_PORTD_PIN0_OUTPUT;
            }
            GPIOD_PORTD_DATA &= ~GPIO_PIN0_MASK;
        }

        void pin_release( void )
        { 
            if ( GPIO_PORTD_PIN0_INPUT != ( GPIOD_PORTD_DIR & GPIO_PIN0_MASK ) ) 
            { 
                GPIOD_PORTD_DIR &= ~GPIO_PORTD_PIN0_OUTPUT;
            }
        }
    
        uint8_t pin_get( void )
        {
            if ( GPIO_PORTD_PIN0_INPUT != ( GPIOD_PORTD_DIR & GPIO_PIN0_MASK ) ) 
            { 
                GPIOD_PORTD_DIR &= ~GPIO_PORTD_PIN0_OUTPUT;
            }
            return ( GPIO_PIN0_MASK == ( GPIOD_PORTD_DATA & GPIO_PIN0_MASK ) );
        }
    #else
        #error "Pin functions are not defined for the selected MCU"
    #endif
#elif __GNUC__
    #ifdef STM32F407ZG
        #define GPIOD_MODER             ( *( uint32_t * ) 0x40020C00 )
        #define GPIOD_IDR               ( *( uint32_t * ) 0x40020C10 )
        #define GPIOD_ODR               ( *( uint32_t * ) 0x40020C14 )
        #define GPIO_MODER_PIN12_MASK   ( ( uint32_t ) 3 << 24 )
        #define GPIO_MODER_PIN12_INPUT  ( ( uint32_t ) 0 << 24 )
        #define GPIO_MODER_PIN12_OUTPUT ( ( uint32_t ) 1 << 24 )
        #define GPIO_PIN12_MASK         ( ( uint32_t ) 1 << 12 )
        void pin_init( void ) 
        { 
            digital_in_t sio_in;
            digital_in_init ( &sio_in, PD12 );
        }

        void pin_low( void ) 
        { 
            if ( GPIO_MODER_PIN12_OUTPUT != ( GPIOD_MODER & GPIO_MODER_PIN12_MASK ) ) 
            { 
                GPIOD_MODER &= ~GPIO_MODER_PIN12_MASK;
                GPIOD_MODER |= GPIO_MODER_PIN12_OUTPUT;
            }
            GPIOD_ODR &= ~GPIO_PIN12_MASK;
        }

        void pin_release( void )
        { 
            if ( GPIO_MODER_PIN12_INPUT != ( GPIOD_MODER & GPIO_MODER_PIN12_MASK ) ) 
            { 
                GPIOD_MODER &= ~GPIO_MODER_PIN12_MASK;
            }
        }
    
        uint8_t pin_get( void )
        {
            if ( GPIO_MODER_PIN12_INPUT != ( GPIOD_MODER & GPIO_MODER_PIN12_MASK ) ) 
            { 
                GPIOD_MODER &= ~GPIO_MODER_PIN12_MASK;
            }
            return ( GPIO_PIN12_MASK == ( GPIOD_IDR & GPIO_PIN12_MASK ) );
        }
    #elif MK64
        #define GPIOE_PDOR              ( *( uint32_t * ) 0x400FF100 )
        #define GPIOE_PDIR              ( *( uint32_t * ) 0x400FF110 )
        #define GPIOE_PDDR              ( *( uint32_t * ) 0x400FF114 )
        #define GPIO_PDDR_PIN6_INPUT    ( ( uint32_t ) 0 << 6 )
        #define GPIO_PDDR_PIN6_OUTPUT   ( ( uint32_t ) 1 << 6 )
        #define GPIO_PIN6_MASK          ( ( uint32_t ) 1 << 6 )
        void pin_init( void ) 
        { 
            digital_in_t sio_in;
            digital_in_init ( &sio_in, PE6 );
        }

        void pin_low( void ) 
        { 
            if ( GPIO_PDDR_PIN6_OUTPUT != ( GPIOE_PDDR & GPIO_PIN6_MASK ) ) 
            { 
                GPIOE_PDDR |= GPIO_PDDR_PIN6_OUTPUT;
            }
            GPIOE_PDOR &= ~GPIO_PIN6_MASK;
        }

        void pin_release( void )
        { 
            if ( GPIO_PDDR_PIN6_INPUT != ( GPIOE_PDDR & GPIO_PIN6_MASK ) ) 
            { 
                GPIOE_PDDR &= ~GPIO_PDDR_PIN6_OUTPUT;
            }
        }
    
        uint8_t pin_get( void )
        {
            if ( GPIO_PDDR_PIN6_INPUT != ( GPIOE_PDDR & GPIO_PIN6_MASK ) ) 
            { 
                GPIOE_PDDR &= ~GPIO_PDDR_PIN6_OUTPUT;
            }
            return ( GPIO_PIN6_MASK == ( GPIOE_PDIR & GPIO_PIN6_MASK ) );
        }
    #elif GD32VF103VBT6
        #define GPIOC9_CTL1_MASK    ( ( uint32_t ) 0x000000F0 )
        #define GPIOC9_IO_MASK      ( ( uint32_t ) 0x00000200 )
        #define GPIOC_CTL1          ( *( uint32_t * ) 0x40011004 )
        #define GPIOC_ISTAT         ( *( uint32_t * ) 0x40011008 )
        #define GPIOC_OCTL          ( *( uint32_t * ) 0x4001100C )

        void pin_init( void ) 
        {
            static digital_in_t sio_in;
            digital_in_init ( &sio_in, PC9 );
        }

        void pin_low( void ) 
        { 
            if ( ( GPIO_CFG_DIGITAL_INPUT << 4 ) == ( GPIOC_CTL1 & GPIOC9_CTL1_MASK ) ) 
            { 
                GPIOC_CTL1 = ( GPIOC_CTL1 & ~( GPIOC9_CTL1_MASK ) ) | ( GPIO_CFG_DIGITAL_OUTPUT << 4 );
            }
            GPIOC_OCTL &= ~GPIOC9_IO_MASK;
        }

        void pin_release( void )
        { 
            if ( ( GPIO_CFG_DIGITAL_OUTPUT << 4 ) == ( GPIOC_CTL1 & GPIOC9_CTL1_MASK ) ) 
            { 
                GPIOC_CTL1 = ( GPIOC_CTL1 & ~( GPIOC9_CTL1_MASK ) ) | ( GPIO_CFG_DIGITAL_INPUT << 4 );
            }
        }

        uint8_t pin_get( void )
        {
            if ( ( GPIO_CFG_DIGITAL_OUTPUT << 4 ) == ( GPIOC_CTL1 & GPIOC9_CTL1_MASK ) ) 
            { 
                GPIOC_CTL1 = ( GPIOC_CTL1 & ~( GPIOC9_CTL1_MASK ) ) | ( GPIO_CFG_DIGITAL_INPUT << 4 );
            }
            return ( GPIOC9_IO_MASK == ( GPIOC_ISTAT & GPIOC9_IO_MASK ) );
        }
    #else
        #error "Pin functions are not defined for the selected MCU"
    #endif
#else
    #error "Pin functions are not defined for the selected toolchain"
#endif

static err_t swieeprom_reset ( void )
{
    // Pin initialization
    pin_init ( );
    
    // Reset
    pin_low ( );
    // tDSCHG delay: 150+us
    Delay_80us( );
    Delay_80us( );
    pin_release ( );
    // tRRT delay: 8+us
    Delay_10us( );
    
    // Discovery
    pin_low ( );
    // tDRR delay: 1-2us
    Delay_1us( );
    pin_release ( );
    // tDACK delay: 8-24us
    Delay_9us( );
    
    if ( pin_get ( ) )
    {
        return SWIEEPROM_ERROR;
    }
    return SWIEEPROM_OK;
}

static void swieeprom_start_stop ( void )
{
    pin_release ( );
    // tHTSS delay: 150+us
    Delay_80us( );
    Delay_80us( );
}

static void swieeprom_logic_write_0 ( void )
{
    pin_low ( );
    // tLOW0 delay: 6-16us
    Delay_10us( );
    pin_release ( );
    // tBIT - tLOW0 delay: 8-24us - 6-16us
    Delay_6us( );
}

static void swieeprom_logic_write_1 ( void )
{
    pin_low ( );
    // tLOW1 delay: 1-2us
    Delay_1us( );
    pin_release ( );
    // tBIT - tLOW1 delay: 8-24us - 1-2us
    Delay_10us( );
    Delay_5us( );
}

static uint8_t swieeprom_logic_read ( void )
{
    pin_low ( );
    // tRD delay: 1-2us
    Delay_1us( );
    pin_release ( );
    // tMRS delay: 1-2us
    Delay_1us( );
    uint8_t pin_state = pin_get ( );
    // tBIT - tRD - tMRS delay: 8-24us - 1-2us - 1-2us
    Delay_9us( );
    Delay_5us( );
    return pin_state;
}

// ------------------------------------------------------------------------ END

额外支持

资源

喜欢这个项目吗?

'购买此套件' 按钮会直接带您进入购物车,您可以在购物车中轻松添加或移除产品。