打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033

LiSun

打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

一、首先是界面介绍。

在这里插入图片描述
在这里插入图片描述

二、工具的目的

  1. 可视化选择IO口功能。
  2. 自由配置IO支持的功能。
  3. 适用各类MCU,方便移植和开发。
  4. 功能配置和裁剪(选项-syscfg-待完成–需要适配keil语法有些麻烦)

三、ls_gpio.h模板

/********************************************************************************
* @file    ls_gpio.h
* @author  jianqiang.xue
* @version V1.1.0
* @date    2022-12-11
* @brief   业务类--GPIO定义
********************************************************************************/
#ifndef __LS_GPIO_H
#define __LS_GPIO_H
#define LS_IO_VERSION "CX32L003_通用模板"

#include "cx32l003_hal.h"
#include "cx32l003_hal_def.h"
#include "ls_syscfg.h"
#include "bsp_gpio.h"
#include "bsp_exti.h"

/* GPIO_EXTI_INT_EDGE;             // 中断类型 边沿触发
    GPIO_EXTI_INT_LOWFALL;  // 下降沿触发中断
    GPIO_EXTI_INT_HIGHRISE; // 上升沿触发中断
    GPIO_EXTI_INT_FALLRISE; // 下降沿上升沿都触发中断
GPIO_EXTI_INT_LEVEL;            // 中断类型 电平触发
    GPIO_EXTI_INT_LOWFALL;  // 低电平触发中断
    GPIO_EXTI_INT_HIGHRISE; // 高电平触发中断 */

#define GPIO_CLK(GPIO)                              (RCC_HCLKEN_##GPIO##CKEN)
#define GPIO_APBx                                   (0)
/************************************GPIO***********************************/
#define LS_IO_NUM                                   (16)
/* Public Struct -------------------------------------------------------------*/

union io_support_t {
    uint64_t val; // 对外值
    struct {
        uint64_t swo                : 1;

        uint64_t adc0_ch0           : 1;
        uint64_t adc0_ch1           : 1;
        uint64_t adc0_ch2           : 1;
        uint64_t adc0_ch3           : 1;
        uint64_t adc0_ch4           : 1;
        uint64_t adc0_ch5           : 1;
        uint64_t adc0_ch6           : 1;
        uint64_t adc1_ch0           : 1;
        uint64_t adc1_ch1           : 1;
        uint64_t adc1_ch2           : 1;
        uint64_t adc1_ch3           : 1;
        uint64_t adc1_ch4           : 1;
        uint64_t adc1_ch5           : 1;
        uint64_t adc1_ch6           : 1;

        uint64_t tim1_ch1           : 1; // PWM0
        uint64_t tim1_ch2           : 1; // PWM1
        uint64_t tim1_ch3           : 1; // PWM2
        uint64_t tim1_ch4           : 1; // PWM3
        uint64_t tim2_ch1           : 1; // PWM4
        uint64_t tim2_ch2           : 1; // PWM5
        uint64_t tim2_ch3           : 1; // PWM6
        uint64_t tim2_ch4           : 1; // PWM7

        uint64_t uart0_tx           : 1;
        uint64_t uart0_rx           : 1;
        uint64_t uart1_tx           : 1;
        uint64_t uart1_rx           : 1;
        uint64_t uart2_tx           : 1;
        uint64_t uart2_rx           : 1;

        uint64_t i2c0_scl           : 1; // 硬件IIC
        uint64_t i2c0_sda           : 1;
        uint64_t i2c1_scl           : 1;
        uint64_t i2c1_sda           : 1;
        uint64_t i2c_scl_soft       : 1; // 软件IIC
        uint64_t i2c_sda_soft       : 1;

        uint64_t spi0_clk           : 1;
        uint64_t spi0_mosi          : 1;
        uint64_t spi0_miso          : 1;
        uint64_t spi0_nss           : 1;

        uint64_t spi1_clk           : 1;
        uint64_t spi1_mosi          : 1;
        uint64_t spi1_miso          : 1;
        uint64_t spi1_nss           : 1;

#if !LS_IO_EXTEND_SUPPORT
        uint64_t reserve            : 7;
#endif
    } bit;
};

typedef enum {
    IO_TYPE_IN_NULL = 0, // 默认输入 无上下拉
    IO_TYPE_IN_PULLUP,   // 输入,上拉
    IO_TYPE_IN_PULLDOWN, // 输入,下拉

    IO_TYPE_OUT_PP,      // 默认输出 推免输出
    IO_TYPE_OUT_OD,      // 开漏输出
    // 中断输入
    IO_TYPE_INIRQ_LEVEL_LOW,     // 电平触发-低电平
    IO_TYPE_INIRQ_LEVEL_HIGH,    // 电平触发-高电平
    IO_TYPE_INIRQ_EDGE_LOWFALL,  // 边沿触发-下降沿
    IO_TYPE_INIRQ_EDGE_HIGHRISE, // 边沿触发-上降沿
    IO_TYPE_INIRQ_EDGE_FALLRISE, // 边沿触发-任意电平变化

    IO_TYPE_SWO,        // 默认烧录脚
    IO_TYPE_KEY,        // 按键,会注册到软定时器中扫描
    IO_TYPE_MATRIX_KEY_X, // 矩阵键盘X轴,会注册到软定时器中扫描
    IO_TYPE_MATRIX_KEY_Y, // 矩阵键盘Y轴,会注册到软定时器中扫描
    IO_TYPE_W2812X,

    IO_TYPE_ADC0_CH0,
    IO_TYPE_ADC0_CH1,
    IO_TYPE_ADC0_CH2,
    IO_TYPE_ADC0_CH3,
    IO_TYPE_ADC0_CH4,
    IO_TYPE_ADC0_CH5,
    IO_TYPE_ADC0_CH6,
    IO_TYPE_ADC1_CH0,
    IO_TYPE_ADC1_CH1,
    IO_TYPE_ADC1_CH2,
    IO_TYPE_ADC1_CH3,
    IO_TYPE_ADC1_CH4,
    IO_TYPE_ADC1_CH5,
    IO_TYPE_ADC1_CH6,

    IO_TYPE_TIM1_CH1, // PWM0
    IO_TYPE_TIM1_CH2, // PWM1
    IO_TYPE_TIM1_CH3, // PWM2
    IO_TYPE_TIM1_CH4, // PWM3
    IO_TYPE_TIM2_CH1, // PWM4
    IO_TYPE_TIM2_CH2, // PWM5
    IO_TYPE_TIM2_CH3, // PWM6
    IO_TYPE_TIM2_CH4, // PWM7

    IO_TYPE_UART0_TX,   // 串口,通过命令配置电气特性
    IO_TYPE_UART0_RX,
    IO_TYPE_UART1_TX,   // 串口,通过命令配置电气特性
    IO_TYPE_UART1_RX,
    IO_TYPE_UART2_TX,
    IO_TYPE_UART2_RX,

    IO_TYPE_I2C0_SCL,   // 硬件IIC
    IO_TYPE_I2C0_SDA,   // 硬件IIC
    IO_TYPE_I2C1_SCL,
    IO_TYPE_I2C1_SDA,
    IO_TYPE_I2C_SCL_SOFT,   // 软件IIC
    IO_TYPE_I2C_SDA_SOFT,   // 软件IIC

    IO_TYPE_SPI0_CLK,
    IO_TYPE_SPI0_MOSI,
    IO_TYPE_SPI0_MISO,
    IO_TYPE_SPI0_NSS,
    IO_TYPE_SPI1_CLK,
    IO_TYPE_SPI1_MOSI,
    IO_TYPE_SPI1_MISO,
    IO_TYPE_SPI1_NSS,

    IO_TYPE_MAX,
} io_type_t;

extern const union io_support_t g_io_support[LS_IO_NUM];
extern const io_type_t g_io_default_type[LS_IO_NUM];
extern const bsp_gpio_t g_io_cfg[LS_IO_NUM];
#ifdef LS_IO
const bsp_gpio_t g_io_cfg[LS_IO_NUM] = {
    {(GPIOD), (GPIO_PIN_2), GPIO_CLK(GPIOD), (0), (GPIOD_IRQn)},
    {(GPIOD), (GPIO_PIN_3), GPIO_CLK(GPIOD), (0), (GPIOD_IRQn)},
    {(GPIOD), (GPIO_PIN_4), GPIO_CLK(GPIOD), (0), (GPIOD_IRQn)},
    {(GPIOD), (GPIO_PIN_5), GPIO_CLK(GPIOD), (0), (GPIOD_IRQn)},
    {(GPIOD), (GPIO_PIN_6), GPIO_CLK(GPIOD), (0), (GPIOD_IRQn)},
    {(GPIOC), (GPIO_PIN_3), GPIO_CLK(GPIOC), (0), (GPIOC_IRQn)},
    {(GPIOC), (GPIO_PIN_4), GPIO_CLK(GPIOC), (0), (GPIOC_IRQn)},
    {(GPIOC), (GPIO_PIN_5), GPIO_CLK(GPIOC), (0), (GPIOC_IRQn)},
    {(GPIOC), (GPIO_PIN_6), GPIO_CLK(GPIOC), (0), (GPIOC_IRQn)},
    {(GPIOB), (GPIO_PIN_4), GPIO_CLK(GPIOB), (0), (GPIOB_IRQn)},
    {(GPIOB), (GPIO_PIN_5), GPIO_CLK(GPIOB), (0), (GPIOB_IRQn)},
    {(GPIOA), (GPIO_PIN_3), GPIO_CLK(GPIOA), (0), (GPIOA_IRQn)},
    {(GPIOD), (GPIO_PIN_1), GPIO_CLK(GPIOD), (0), (GPIOD_IRQn)},
    {(GPIOC), (GPIO_PIN_7), GPIO_CLK(GPIOC), (0), (GPIOC_IRQn)},
    {(GPIOA), (GPIO_PIN_1), GPIO_CLK(GPIOA), (0), (GPIOA_IRQn)},
    {(GPIOA), (GPIO_PIN_2), GPIO_CLK(GPIOA), (0), (GPIOA_IRQn)},
};

const union io_support_t g_io_support[LS_IO_NUM] = {
    {0x808010010}, {0x1100020}, {0x888000}, {0x2022C00040}, {0x1045110080},
    {0x42220004}, {0x24440008}, {0x808000000}, {0x1010408002}, {0x4020800000},
    {0x841080000}, {0x4010200000}, {0x2000001}, {0x4100001}, {0x45000000},
    {0x4022920000}, 
};

const io_type_t g_io_default_type[LS_IO_NUM] = {
    IO_TYPE_TIM1_CH2, IO_TYPE_TIM2_CH2, IO_TYPE_TIM1_CH1, IO_TYPE_TIM2_CH4, IO_TYPE_ADC0_CH6,
    IO_TYPE_TIM1_CH3, IO_TYPE_TIM1_CH4, IO_TYPE_TIM2_CH1, IO_TYPE_ADC0_CH0, IO_TYPE_IN_NULL,
    IO_TYPE_IN_NULL, IO_TYPE_TIM2_CH3, IO_TYPE_SWO, IO_TYPE_SWO, IO_TYPE_UART0_RX,
    IO_TYPE_UART0_TX,
};
#else
#endif

#endif

  1. 定义IO支持类型
  2. 定义默认类型,上电自动初始化完毕

四、ls_syscfg.h 模板

/********************************************************************************
* @file    ls_syscfg.h
* @author  jianqiang.xue
* @version V1.1.0
* @date    2023-03-04
* @brief   业务类--功能宏定义
********************************************************************************/

#ifndef __LS_SYSCFG_H
#define __LS_SYSCFG_H


//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------

/**************************************LOG**************************************/
// <e> Log Switch
// =======================
#define LS_LOG_SWITCH                                              (0x1)

//  <o> Log Grade
//  <i> Default: 0
//      <0=> ALL
//      <1=> TRACE
//      <2=> DEBUG
//      <3=> INFO
//      <4=> WARN
//      <5=> ERROR
//      <6=> FATAL
//      <7=> OFF
#define LS_LOG_GRADE                                               (0x2)

//  <o> Log Out
//  <i> Default: 0
//      <0=> RTT
//      <1=> UART
#define LS_LOG_OUT                                                 (0x1)
//  <q> MAX LEN
//  <i> Default: 128   Min Data Len 128
#define LS_LOG_MAX_LEN                                             (128)
// </e>

/************************************FLASH**************************************/
// <h> FLASH
// =======================
//
//  <o> Page Size
//  <i> Default: 0x200 (512 byte)
#define LS_FLASH_PAGE_SIZE                                         (0x200U)

//  <o> Flash Max Size
//  <i> Default: 0x10000 (64K byte)
#define LS_FLASH_MAX_SIZE                                          (0x10000U)

//  <o> Boot Loader Starting Address
//  <i> Default: 0
#define LS_FLASH_START_ADDR                                        (0x0000000)

//  <o> Boot Loader Size
//  <i> Default: 0x1400 (5K byte), use dfu 0x2000
#define LS_FLASH_BOOT_SIZE                                         (0x2000)

//  <o> Kv Flash Page
//  <i> Default: 3
#define LS_FLASH_KV_PAGE                                           (3)

//  <o> Flash Write Byte Ability
//  <i> The ability to write is also byte to it.
//  <i> Default: 4
#define LS_FLASH_WRITE_BYTE_ABILITY                                (1)

//  <o> FLASH_INFO_TYPE(MCU user Kv_Sys / NRF user FDS)
//      <0=> KV_SYS
//      <1=> FDS
#define LS_FLASH_INFO_TYPE                                         (0)

// </h>

/*************************************APP_IO************************************/
// <h> APP_IO
// =======================
//  <q> Save Flash Support
#define LS_APP_IO_SAVE_SUPPORT                                     (0)

//  <q> Active Report Support (ATCMD enevt)
#define LS_APP_IO_ACTIVE_REPORT_SUPPORT                            (0)

//  <q> Key Scan Support
#define LS_APP_IO_KEY_SCAN_SUPPORT                                 (1)

//  <q> Matrix Key Support
#define LS_APP_IO_MATRIX_KEY_SUPPORT                               (0)

//  <e> Tiemr Support (IO Operation)
#define LS_APP_IO_TIMER_SUPPORT                                    (1)
//   <o> Task Number
#define LS_APP_IO_TIMER_NUM                                        (2)
//   <o> Timer Time (ms)
#define LS_APP_IO_TIMER_TIME_MS                                    (1000)
//  </e>

//  <q> Sys Vcc Support
#define LS_APP_IO_SYS_VCC_SUPPORT                                  (0)

//  <q> Swo Off
#define LS_APP_IO_SWO_OFF                                          (0)
//  <q> Extend Support
#define LS_IO_EXTEND_SUPPORT                                       (0)
// </h>
/**************************************KEY**************************************/
// <h> KEY
// =======================
//  <o> Button scan cycle (ms) <10-65535>
//  <i> Default: 10
#define LS_BUTTON_SCAN_CYCLE_MS                                    (10)

//  <o> Single click time(ms) <0-65535>
//  <i> 1 timec of one click
//  <i> Default: 100
#define LS_BUTTON_SINGLE_CLICK_TIME                                (50)

//  <o> Release time(ms) <0-65535>
//  <i> press -> release
//  <i> Default: 100
#define LS_BUTTON_RELEASE_TIME                                     (140)

//  <o> Double click time(ms) <0-65535>
//  <i> 1 timec of double click interval time
//  <i> Default: 150
#define LS_BUTTON_DOUBLE_CLICK_TIME                                (200)

//  <o> Long press time(ms) <100-65535>
//  <i> Long press
//  <i> Default: 1000
#define LS_BUTTON_LONG_PRESS_TIME                                  (800)

//  <o> Long long press time(ms) <1000-65535>
//  <i> Long long press
//  <i> Default: 1000
#define LS_BUTTON_LONG_LONG_PRESS_TIME                             (10000)

//   <q> Automatic Scanning(Idle Sop, Interrupt Activation)
//   <i> Whether to automatically disable scanning
//       <0=> DISABLE
//       <1=> ENABLE
#define LS_BUTTON_AUTOMATIC_SCANNING                               (0)

// </h>

/**************************************ADC**************************************/
// <h> ADC
// =======================
//
//  <e> ADC0
#define LS_ADC0_EN                                                 (1)

//   <o> Clk Divider
//    <i> 0-PCLK/1, 1-PCLK/2, 2-PCLK/4, 3-PCLK/8, 4-PCLK/16, ..., 7-PCLK/128
#define LS_ADC0_CLK_DIV                                            (5)


//   <o> Sampling Number
//    <i> Default: 10
#define LS_ADC0_SAMPLING_NUM                                       (10)

//   <q> ADC0 IRQ
#define LS_ADC0_IRQ_SEL                                            (1)

//   <e1.7> ADC0_CH
//    <o0.0> ADC0_CH0
//    <o0.1> ADC0_CH1
//    <o0.2> ADC0_CH2
//    <o0.3> ADC0_CH3
//    <o0.4> ADC0_CH4
//    <o0.5> ADC0_CH5
//    <o0.6> ADC0_CH6
//    <o0.7> ADC0_CH7 (sys_vcc)
#define LS_ADC0_CH                                                 (255)
//   </e>
//   <o> Timer Cycle
//    <i> Default: 100ms
#define LS_ADC0_TIMER_CYCLE_MS                                     (228)
//  </e>

//  <h> Resistance Information
//   <h> Thermistor

//    <o> Pull Up Resistance Value
//    <i> Default: 100
//    <i> Unit: KOhm
#define LS_THERMISTOR_PULL_UP_VAL                                  (100)

//    <o> Coefficient corresponding to NTC resistance
//    <i> Default: 0 (x*1000)
#define LS_THERMISTOR_NTC_K                                        (4250)

//    <o> Reference voltage
//    <i> Default: 3300 (x*1000)
#define LS_THERMISTOR_REFERENCE_VOLTAGE                            (2700)
//    </h>

//   <h> LDR
//   <i> Photosensitive resistance
//    <o> Pull Up Resistance Value
//    <i> Default: 680
//    <i> Unit: KOhm
#define LS_LDR_PULL_UP_VAL                                         (680)

//    <o> Reference voltage
//    <i> Default: 3300 (x*1000)
#define LS_LDR_REFERENCE_VOLTAGE                                   (2700)
//    </h>

//   <h> Power resistance
//   <i> Power supply resistance
//    <o> Pull Up Resistance Value
//    <i> Default: 300000
//    <i> Unit: KOhm
#define LS_POWER_PULL_UP_VAL                                       (300)

//    <o> Pull Down Resistance Value
//    <i> Default: 100
//    <i> Unit: KOhm
#define LS_POWER_PULL_DOWN_VAL                                     (300)

//    <o> Reference voltage
//    <i> Default: 3300 (x*1000)
#define LS_POWER_REFERENCE_VOLTAGE                                 (2700)
//   </h>
//  </h>
// </h>

/**************************************I2C**************************************/
// <h> I2C
// =======================
//  <e> I2C0
#define LS_I2C0_EN                                                 (0)

//   <o> I2C0 SPEED uint khz
//   <i> Default: 100 khz
#define LS_I2C0_SPEED_RATE                                         (400)
//  </e>

//  <e> I2C1
#define LS_I2C1_EN                                                 (0)

//   <o> I2C1 SPEED uint khz
//   <i> Default: 100 khz
#define LS_I2C1_SPEED_RATE                                         (100)
//  </e>

//  <e> I2C2
#define LS_I2C2_EN                                                 (0)

//   <o> I2C2 SPEED uint khz
//   <i> Default: 100 khz
#define LS_I2C2_SPEED_RATE                                         (100)
//  </e>
// </h>

/**************************************UART*************************************/
// <h> UART
// =======================
//  <e> UART0
#define LS_UART0_EN                                                (1)

//   <o> UART0 Baud Rate
//   <i> Default: 115200
//       <9600    => 9600
//       <19200   => 19200
//       <57600   => 57600
//       <115200  => 115200
#define LS_UART0_BAUD_RATE                                         (115200)

//   <o> UART0 Working mode
//   <i> Default: full duplex
//       <0  => Full Duplex
//       <1  => Half Duplex
#define LS_UART0_WORK_MODE                                         (0)

//   <o> UART0 RX cache size
//   <i> Default: 256
#define LS_UART0_CACHE_SIZE                                        (64)
//  </e>

//  <e> UART1
#define LS_UART1_EN                                                (0)

//   <o> UART1 Baud rate
//   <i> Default: 115200
//       <9600    => 9600
//       <19200   => 19200
//       <57600   => 57600
//       <115200  => 115200
#define LS_UART1_BAUD_RATE                                         (115200)

//   <o> UART1 Working mode
//   <i> Default: full duplex
//       <0  => Full Duplex
//       <1  => Half Duplex
#define LS_UART1_WORK_MODE                                         (0)

//   <o> UART1 RX cache size
//   <i> Default: 256
#define LS_UART1_CACHE_SIZE                                        (256)
//  </e>

//  <e> UART2
#define LS_UART2_EN                                                (0)

//   <o> UART2 Baud Rate
//   <i> Default: 115200
//       <9600    => 9600
//       <19200   => 19200
//       <57600   => 57600
//       <115200  => 115200
#define LS_UART2_BAUD_RATE                                         (115200)

//   <o> UART2 Working Mode
//   <i> Default: full duplex
//       <0  => Full Duplex
//       <1  => Half Duplex
#define LS_UART2_WORK_MODE                                         (0)

//   <o> UART2 RX Cache Size
//   <i> Default: 256
#define LS_UART2_CACHE_SIZE                                        (256)
//  </e>

//  <o> Printf
//  <i> Default: UART0
//      <0=> UART0
//      <1=> UART1
//      <2=> UART2
#define LS_FUART_PRINT                                             (0)

// </h>

/**************************************PWM**************************************/
// <h> PWM
// =======================
//  <e> TIM1
//  <i> pwm hz = sys_clock / (Prescaler+1) / (Period+1)
//  <i> 3125 hz = 24000000 / (63+1) / (119+1)
#define LS_TIM1_EN                                                 (1)

//   <o> Prescaler
//   <i> Default: 63
#define LS_TIM1_PRESCALER                                          (63)

//   <o> Period
//   <i> Default: 119
#define LS_TIM1_PERIOD                                             (119)

//   <o> Level logic
//   <i> Reverse --> low level light up
//   <i> Forward --> high level light up
//       <0=> Reverse
//       <1=> Forward
#define LS_TIM1_LEVEL_LOGIC                                        (1)

//   <q> TIM1_CH1 (PWM0)
//   <i> Default: DISABLE
//       <0=> DISABLE
//       <1=> ENABLE
#define LS_PWM0_EN                                                 (1)

//   <q> TIM1_CH2 (PWM1)
//   <i> Default: DISABLE
//       <0=> DISABLE
//       <1=> ENABLE
#define LS_PWM1_EN                                                 (1)

//   <q> TIM1_CH3 (PWM2)
//   <i> Default: DISABLE
//       <0=> DISABLE
//       <1=> ENABLE
#define LS_PWM2_EN                                                 (1)

//   <q> TIM1_CH4 (PWM3)
//   <i> Default: DISABLE
//       <0=> DISABLE
//       <1=> ENABLE
#define LS_PWM3_EN                                                 (1)
//  </e>

//  <e> TIM2
//  <i> pwm hz = sys_clock / (Prescaler+1) / (Period+1)
//  <i> 3125 hz = 24000000 / (63+1) / (119+1)
#define LS_TIM2_EN                                                 (1)

//   <o> Prescaler
//   <i> Default: 63
#define LS_TIM2_PRESCALER                                          (63)

//   <o> Period
//   <i> Default: 119
#define LS_TIM2_PERIOD                                             (119)

//   <o> Level logic
//   <i> Reverse --> low level light up
//   <i> Forward --> high level light up
//       <0=> Reverse
//       <1=> Forward
#define LS_TIM2_LEVEL_LOGIC                                        (1)

//   <q> TIM2_CH1 (PWM4)
//   <i> Default: DISABLE
//       <0=> DISABLE
//       <1=> ENABLE
#define LS_PWM4_EN                                                 (1)

//   <q> TIM2_CH2 (PWM5)
//   <i> Default: DISABLE
//       <0=> DISABLE
//       <1=> ENABLE
#define LS_PWM5_EN                                                 (1)

//   <q> TIM2_CH3 (PWM6)
//   <i> Default: DISABLE
//       <0=> DISABLE
//       <1=> ENABLE
#define LS_PWM6_EN                                                 (1)

//   <q> TIM2_CH4 (PWM7)
//   <i> Default: DISABLE
//       <0=> DISABLE
//       <1=> ENABLE
#define LS_PWM7_EN                                                 (1)
//  </e>
// </h>

/*************************************Memory************************************/
// <h> Memory
// =======================
//   <o> Memory SIZE
#define LS_MEMORY_SIZE                                              (512+128)
// </h>
/*************************************BOOT************************************/
// <h> BootLoader
// =======================
//   <q> BOOT_SUPPORT
#define BOOT_SUPPORT                                               (1)
//   <s> chip ic
#define CHIP_IC                                                    "CX32L003"
//   <s> version info
#define VERSION_INFO                                               "0.9"
// </h>

//------------- <<< end of configuration section >>> -----------------------

/*********************************[业务引脚命令]*******************************/
#define LS_IO_LED_IND_ID                                           (11)

/********************************[FLASH INFO]*********************************/
#define LS_FLASH_APP_ADDR                                          (LS_FLASH_START_ADDR + LS_FLASH_BOOT_SIZE)
#define LS_FLASH_APP_SIZE                                          (LS_FLASH_MAX_SIZE - LS_FLASH_BOOT_SIZE - (LS_FLASH_KV_PAGE * LS_FLASH_PAGE_SIZE))
#define LS_FLASH_OTA_ADDR                                          (LS_FLASH_APP_ADDR + LS_FLASH_APP_SIZE / 2)
#define LS_FLASH_END_ADDR                                          (LS_FLASH_START_ADDR + LS_FLASH_MAX_SIZE)

#define LS_KV_BASE_ADDR                                            (LS_FLASH_END_ADDR - (LS_FLASH_KV_PAGE * LS_FLASH_PAGE_SIZE))
#define LS_KV_BACK_ADDR                                            (LS_KV_BASE_ADDR + (LS_FLASH_KV_PAGE - 1) * LS_FLASH_PAGE_SIZE)
#define LS_OPTION_BYTES_ADDR                                       (0x08000000)

#define LS_KV_KEY_BOOT_INFO                                         0x01
#define LS_KV_KEY_POWER_INFO                                        0x02
#define LS_KV_KEY_USER_INFO                                         0x03
#define LS_KV_KEY_UID                                               0x04

#define LS_KV_KEY_IO_INFO                                           0x05
#endif

  1. 功能裁剪

五、简单讲解功能

(1) 引用ATCMD

  1. 查询IO信息: AT+IOINFO?
    返回:IO版本,是否支持保存,IO总数量
static int atcmd_get_io_info(atcmd_pack_t *pack) {
    uint8_t buff[60] = {0};
    snprintf((char*)buff, 60, "io_ver:%s,save_support:%d,io_num:%d",
            IO_VERSION, g_io.flag.save_support, LS_IO_NUM);
    strcat((char*)buff, AT_OK);
    pack->reply(buff, strlen((char*)buff));
    return 0;
}
ATCMD_INIT("AT+IOINFO?", atcmd_get_io_info);
  1. 当前内存使用情况: AT+MEMINFO?
    使用值,总数量 (单位:byte)
static int atcmd_get_mem_info(atcmd_pack_t *pack) {
    uint8_t buff[60] = {0};
    mem_info_t* temp = os_get_memory_info();
    if (temp != NULL) {
        snprintf((char*)buff, 60, "%d,%d", temp->used, temp->size);
    }
    strcat((char*)buff, AT_OK);
    pack->reply(buff, strlen((char*)buff));
    return 0;
}
ATCMD_INIT("AT+MEMINFO?", atcmd_get_mem_info);
  1. IO事件:AT+IOEVENT?
    返回全部IO事件状态
typedef enum {
    IO_EVENT_NULL    = 0,
    IO_EVENT_IO_LOW, // 中断事件
    IO_EVENT_IO_HIGH,
    IO_EVENT_IO_KEY_SINGLE_CLICK, // 按键事件
    IO_EVENT_IO_KEY_TWO_CLICK,    // 双击
    IO_EVENT_IO_KEY_LONG_PRESS,   // 长按3秒
    IO_EVENT_IO_KEY_LONG_LONG_PRESS,   // 长按10秒
} io_event_t;
static int atcmd_get_event(atcmd_pack_t *pack) {
    uint8_t buff[LS_IO_NUM * 2 + 10] = {0};
    for (uint8_t i = 0; i < LS_IO_NUM; i++) {
        char temp = g_io.func[i].io_event + '0';
        strncat((char*)buff, &temp, 1);
        if (i != LS_IO_NUM - 1)
            strncat((char*)buff, ",", 1);
    }
    strcat((char*)buff, AT_OK);
    pack->reply(buff, strlen((char*)buff));
    clean_signal_irq();
    return 0;
}
ATCMD_INIT("AT+IOEVENT?", atcmd_get_event);
  1. IO当前配置类型:AT+IOCFGALL?
static int atcmd_io_cfg_get_all(atcmd_pack_t *pack) {
    char buff[LS_IO_NUM*2 + 10] = {0};
    char temp[5] = {0};
    uint8_t len = 0;
    for (uint8_t i = 0; i < LS_IO_NUM; i++) {
        len = snprintf(temp, 5, "%d", g_io.type[i]);
        strncat(buff, temp, len);
        if (i != LS_IO_NUM - 1)
            strncat(buff, ",", 1);
    }
    strcat(buff, AT_OK);
    pack->reply((uint8_t*)buff, strlen(buff));
    return 0;
}
ATCMD_INIT("AT+IOCFGALL?", atcmd_io_cfg_get_all);
  1. 配置IO类型:AT+IOCFGALL=18,19,1,1,1,1,1,1,1,1,1,1,1,1,38,37
    这里填写的是IO索引表的序号(参考:一、界面介绍)
  2. 设置IO高低电平:AT+IOALL=1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
    只对输出类型引脚有效
static int atcmd_set_io_all(atcmd_pack_t *pack) {
    uint8_t argc[LS_IO_NUM] = {0};
    char *arg; // 临时存放值
    uint8_t cnt = 0;
    uint8_t buff[20] = {0};
    arg = strtok((char*)(pack->data), ",");
    while (arg != NULL) {
        argc[cnt++] = (uint8_t)atoi(arg);
        arg = strtok(NULL, ",");
    }
    pack->argc = cnt;
    if (pack->argc != LS_IO_NUM) {
        strcat((char*)buff, AT_ARGCERR);
        pack->reply(buff, strlen((char*)buff));
        return -1;
    }
    for (uint8_t i = 0; i < LS_IO_NUM; i++) {
        if (g_io.type[i] == IO_TYPE_OUT_PP)
            bsp_gpio_set_pin(g_io.cfg[i].port, g_io.cfg[i].pin, argc[i]);
    }
    strcat((char*)buff, AT_OK);
    pack->reply(buff, strlen((char*)buff));
    return 0;
}
ATCMD_INIT("AT+IOALL=", atcmd_set_io_all);
  1. 当前IO高低电平:AT+IO?
static int atcmd_get_io(atcmd_pack_t *pack) {
    uint8_t buff[LS_IO_NUM * 2 + 20] = {0};
    for (uint8_t i = 0; i < LS_IO_NUM; i++) {
        char temp = (uint8_t)bsp_gpio_get_state(g_io.cfg[i].port, g_io.cfg[i].pin) + '0';
        strncat((char*)buff, &temp, 1);
        if (i != LS_IO_NUM - 1)
            strncat((char*)buff, ",", 1);
    }
    strcat((char*)buff, AT_OK);
    pack->reply(buff, strlen((char*)buff));
    return 0;
}
ATCMD_INIT("AT+IO?", atcmd_get_io);
  1. IO任务:
    查询任务:AT+IO_TASK?
    设置IO任务基准时间:AT+IO_TIMER_MS=1,10
    设置IO任务:AT+IO_TASK=0,1,0,20,0,40,1,11
    设置周期任务 =<task_id>,<is_valid>,<is_repeat>,<start_time>,<start_task_event>,<stop_time>,<stop_task_event>,<IO_ID>
extern os_timer_id OS_TIMER_ID(app_io);

// 设置周期任务的基准时间 =<off/on>,<ms>
static int atcmd_set_io_timer_ms(atcmd_pack_t *pack) {
    uint32_t argc[1] = {0};
    uint8_t buff[40] = {0};
    pack->argc = sscanf((char*)(pack->data), "%d", &argc[1]);
    if (pack->argc != 1) return -1;
    // 先停止周期任务,并将任务全部取消。
    OS_TIMER_STOP(app_io);
    for (uint8_t i = 0; i < LS_APP_IO_TIMER_NUM; i++) {
        g_io.task[i].is_valid = 0;
    }
    if (argc[0]) {
        if (os_timer_restart(OS_TIMER_ID(app_io), argc[0]) != OS_OK)
            strcat((char*)buff, "io timer restart fail");
        g_io.timer_io_time_ms = argc[0];
    } else {
        if (os_timer_stop(OS_TIMER_ID(app_io)) != OS_OK)
            strcat((char*)buff, "io timer stop fail");
    }
    strcat((char*)buff, AT_OK);
    pack->reply(buff, strlen((char*)buff));
    return 0;
}

// 设置周期任务 =<task_id>,<is_valid>,<is_repeat>,<start_time>,<start_task_event>,<stop_time>,<stop_task_event>,<IO_ID>
static int atcmd_set_task_func(atcmd_pack_t *pack) {
    uint8_t buff[30] = {0};
    if (!g_io.flag.timer_support) {
        strcat((char*)buff, AT_NONSUPPORT);
        pack->reply(buff, strlen((char*)buff));
        return -1;
    }
    uint32_t argc[16] = {0};
    pack->argc = sscanf((char*)(pack->data), "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
                        &argc[0],  &argc[1],  &argc[2],  &argc[3],
                        &argc[4],  &argc[5],  &argc[6],  &argc[7],
                        &argc[8],  &argc[9],  &argc[10], &argc[11],
                        &argc[12], &argc[13], &argc[14], &argc[15]);
    if (pack->argc / 8 > 2 || pack->argc / 8 < 1) {
        strcat((char*)buff, AT_ARGCERR);
        pack->reply(buff, strlen((char*)buff));
        return -1;
    }
    OS_TIMER_STOP(app_io);
    for (uint8_t i = 0; i < pack->argc / 8; i++) {
        g_io.task[argc[0 + i * 8]].is_valid         = argc[1 + i * 8];
        g_io.task[argc[0 + i * 8]].is_repeat        = argc[2 + i * 8];
        g_io.task[argc[0 + i * 8]].start_time       = argc[3 + i * 8];
        g_io.task[argc[0 + i * 8]].start_task_event = argc[4 + i * 8];
        g_io.task[argc[0 + i * 8]].stop_time        = argc[5 + i * 8];
        g_io.task[argc[0 + i * 8]].stop_task_event  = argc[6 + i * 8];
        g_io.task[argc[0 + i * 8]].id               = argc[7 + i * 8];
        if (g_io.type[argc[7 + i * 8]] != IO_TYPE_OUT_PP) { // 周期任务目标,会被强制设置为输出
            uint8_t temp = IO_TYPE_OUT_PP;
            io_cfg(argc[7 + i * 8], (io_type_t *)&temp, NULL);
            g_io.type[argc[7 + i * 8]] = temp;
            g_io.flag.write_in = 1;
        }
        g_io.task[argc[0 + i*8]].countdown = 0;
    }
    if (os_timer_restart(OS_TIMER_ID(app_io), g_io.timer_io_time_ms) != OS_OK) {
        strcat((char*)buff, "io timer restart fail");
    } else
        strcat((char*)buff, AT_OK);
    pack->reply(buff, strlen((char*)buff));
    return 0;
}
// 得到周期任务 =<task_id>,<is_valid>,<is_repeat>,<start_time>,<start_task_event>,<stop_time>,<stop_task_event>,<IO_ID>
static int atcmd_get_task_func(atcmd_pack_t *pack) {
    uint8_t buff[30] = {0};
    for (uint8_t i = 0; i < LS_APP_IO_TIMER_NUM; i++) {
        snprintf((char *)buff, 30, "%d,%d,%d,%d,%d,%d,%d,%d\r\n",
        i, g_io.task[i].is_valid, g_io.task[i].is_repeat,
        g_io.task[i].start_time, g_io.task[i].start_task_event,
        g_io.task[i].stop_time, g_io.task[i].stop_task_event, g_io.task[i].id);
        pack->reply(buff, strlen((char*)buff));
    }
    pack->reply((uint8_t *)AT_OK, strlen(AT_OK));
    return 0;
}

ATCMD_INIT("AT+IO_TIMER_MS=", atcmd_set_io_timer_ms);
ATCMD_INIT("AT+IO_TASK=", atcmd_set_task_func);
ATCMD_INIT("AT+IO_TASK?", atcmd_get_task_func);
  1. ADC
    AT+ADC0_CFG?
    AT+ADC0_TIMER_MS=300
    AT+ADC0_START
    AT+ADC0_STOP
    AT+GET_ADC0_VAL?
    AT+ADC0_CFG=?
    AT+ADC0_CFG=1,10
#include "bsp_adc.h"
extern bsp_adc_cfg_t g_adc0_cfg;
extern os_timer_id OS_TIMER_ID(adc0_collection);
extern uint32_t g_adc0_timer_ms;

static int atcmd_adc0_cfg_help(atcmd_pack_t *pack) {
    char buff[60] = {0};
    snprintf(buff, 60, "AT+ADC0_CFG=<clk_sel(0-7)>,<sample_num(0-255)>\r\n");
    strcat(buff, AT_OK);
    pack->reply((uint8_t*)buff, strlen(buff));
    return 0;
}

static int atcmd_get_adc0_cfg(atcmd_pack_t *pack) {
    char buff[30] = {0};
    snprintf(buff, 30, "%d,%d\r\n", g_adc0_cfg.clk_sel, g_adc0_cfg.sample_num);
    strcat(buff, AT_OK);
    pack->reply((uint8_t*)buff, strlen(buff));
    return 0;
}

static int atcmd_set_adc0_cfg(atcmd_pack_t *pack) {
    uint32_t argc[2] = {0};
    char buff[20] = {0};
    pack->argc = sscanf((char*)(pack->data), "%d,%d", &argc[0], &argc[1]);
    if (pack->argc != 2) {
        strcat(buff, AT_ARGCERR);
        pack->reply((uint8_t*)buff, strlen(buff));
        return -2;
    }
    bsp_adc0_deinit();
    g_adc0_cfg.clk_sel = (uint8_t)argc[0];
    g_adc0_cfg.sample_num = argc[1];
    if (bsp_adc0_init(&g_adc0_cfg)) {
        strcat(buff, AT_ERROR);
    } else {
        strcat(buff, AT_OK);
    }
    pack->reply((uint8_t*)buff, strlen(buff));
    return 0;
}


static int atcmd_set_adc0_timer_ms(atcmd_pack_t *pack) {
    uint32_t argc[1] = {0};
    uint8_t buff[40] = {0};
    pack->argc = sscanf((char*)(pack->data), "%d", &argc[0]);
    if (pack->argc != 1) return -1;
    // 先停止周期任务,并将任务全部取消。
    OS_TIMER_STOP(adc0_collection);
    if (argc[0]) {
        if (os_timer_restart(OS_TIMER_ID(adc0_collection), argc[0]) != OS_OK)
            strcat((char*)buff, "adc0 timer restart fail");
        g_adc0_timer_ms = argc[0];
    } else {
        if (os_timer_stop(OS_TIMER_ID(adc0_collection)) != OS_OK)
            strcat((char*)buff, "adc0 timer stop fail");
    }
    strcat((char*)buff, AT_OK);
    pack->reply(buff, strlen((char*)buff));
    return 0;
}

static int atcmd_adc0_start(atcmd_pack_t *pack) {
    uint8_t buff[40] = {0};
    if (os_timer_restart(OS_TIMER_ID(adc0_collection), g_adc0_timer_ms) != OS_OK)
        strcat((char*)buff, "adc0 timer restart fail");
    strcat((char*)buff, AT_OK);
    pack->reply(buff, strlen((char*)buff));
    return 0;
}

static int atcmd_adc0_stop(atcmd_pack_t *pack) {
    uint8_t buff[40] = {0};
    if (os_timer_stop(OS_TIMER_ID(adc0_collection)) != OS_OK)
        strcat((char*)buff, "adc0 timer stop fail");
    strcat((char*)buff, AT_OK);
    pack->reply(buff, strlen((char*)buff));
    return 0;
}

static int atcmd_get_adc0_val(atcmd_pack_t *pack) {
    uint8_t buff[60] = {0};
    snprintf((char *)buff, 60, "%d,%d,%d,%d,%d,%d,%d,%d\r\n",
    bsp_adc0_get_ch_val(0), bsp_adc0_get_ch_val(1), bsp_adc0_get_ch_val(2), bsp_adc0_get_ch_val(3),
    bsp_adc0_get_ch_val(4), bsp_adc0_get_ch_val(5), bsp_adc0_get_ch_val(6), bsp_adc0_get_ch_val(7));
    strcat((char*)buff, AT_OK);
    pack->reply(buff, strlen((char*)buff));
    return 0;
}

static int atcmd_get_adc0_designated_val(atcmd_pack_t *pack) {
    uint32_t argc[1];
    uint8_t buff[30] = {0};

    pack->argc = sscanf((char*)(pack->data), "%d", &argc[0]);
    if (pack->argc != 1) return -1;
    snprintf((char *)buff, 30, "%d", bsp_adc0_get_ch_val(argc[0]));
    strcat((char*)buff, AT_OK);
    pack->reply(buff, strlen((char*)buff));
    return 0;
}

ATCMD_INIT("AT+ADC0_TIMER_MS=", atcmd_set_adc0_timer_ms);
ATCMD_INIT("AT+ADC0_START", atcmd_adc0_start);
ATCMD_INIT("AT+ADC0_STOP", atcmd_adc0_stop);
ATCMD_INIT("AT+GET_ADC0_VAL=", atcmd_get_adc0_designated_val);
ATCMD_INIT("AT+GET_ADC0_VAL?", atcmd_get_adc0_val);

ATCMD_INIT("AT+ADC0_CFG=?", atcmd_adc0_cfg_help);
ATCMD_INIT("AT+ADC0_CFG=", atcmd_set_adc0_cfg);
ATCMD_INIT("AT+ADC0_CFG?", atcmd_get_adc0_cfg);
  1. PWM
    AT+PWM=0,10
    AT+TIM1_CFG=7,99,0
    AT+TIM1_CFG=?
    AT+PWM_TASK=
#include "bsp_pwm.h"
#include "bsp_tim.h"
#if LS_TIM1_EN
extern bsp_tim_cfg_t g_tim1_cfg;
static int atcmd_set_tim1_cfg_help(atcmd_pack_t *pack) {
    char buff[85] = {0};
    snprintf(buff, 60, "AT+TIM1_CFG=<prescaler(0-65534)>,<period(0-65534)>,<level_logic(0-1)>\r\n");
    strcat(buff, AT_OK);
    pack->reply((uint8_t*)buff, strlen(buff));
    return 0;
}
static int atcmd_set_tim1_cfg(atcmd_pack_t *pack) {
    uint32_t argc[3] = {0};
    char buff[10] = {0};
    pack->argc = sscanf((char*)(pack->data), "%d,%d,%d", &argc[0], &argc[1], &argc[2]);
    if (pack->argc != 3) {
        strcat(buff, AT_ARGCERR);
        pack->reply((uint8_t*)buff, strlen(buff));
        return -2;
    }
    bsp_tim1_pwm_deinit();
    g_tim1_cfg.prescaler   = (uint16_t)argc[0];
    g_tim1_cfg.period      = (uint16_t)argc[1];
    g_tim1_cfg.level_logic = (uint8_t)argc[2];
    if (bsp_tim1_pwm_init(&g_tim1_cfg)) {
        strcat(buff, AT_ERROR);
    } else {
        strcat(buff, AT_OK);
    }
    pack->reply((uint8_t*)buff, strlen(buff));
    return 0;
}
ATCMD_INIT("AT+TIM1_CFG=?", atcmd_set_tim1_cfg_help);
ATCMD_INIT("AT+TIM1_CFG=", atcmd_set_tim1_cfg);
#endif
#if LS_TIM2_EN
extern bsp_tim_cfg_t g_tim2_cfg;
static int atcmd_set_tim2_cfg_help(atcmd_pack_t *pack) {
    char buff[85] = {0};
    snprintf(buff, 60, "AT+TIM2_CFG=<prescaler(0-65534)>,<period(0-65534)>,<level_logic(0-1)>\r\n");
    strcat(buff, AT_OK);
    pack->reply((uint8_t*)buff, strlen(buff));
    return 0;
}
static int atcmd_set_tim2_cfg(atcmd_pack_t *pack) {
    uint32_t argc[3] = {0};
    char buff[10] = {0};
    pack->argc = sscanf((char*)(pack->data), "%d,%d,%d", &argc[0], &argc[1], &argc[2]);
    if (pack->argc != 3) {
        strcat(buff, AT_ARGCERR);
        pack->reply((uint8_t*)buff, strlen(buff));
        return -2;
    }
    bsp_tim2_pwm_deinit();
    g_tim2_cfg.prescaler   = (uint16_t)argc[0];
    g_tim2_cfg.period      = (uint16_t)argc[1];
    g_tim2_cfg.level_logic = (uint8_t)argc[2];
    if (bsp_tim2_pwm_init(&g_tim2_cfg)) {
        strcat(buff, AT_ERROR);
    } else {
        strcat(buff, AT_OK);
    }
    pack->reply((uint8_t*)buff, strlen(buff));
    return 0;
}
ATCMD_INIT("AT+TIM2_CFG=?", atcmd_set_tim2_cfg_help);
ATCMD_INIT("AT+TIM2_CFG=", atcmd_set_tim2_cfg);
#endif

static int atcmd_set_pwm_val_help(atcmd_pack_t *pack) {
    char buff[60] = {0};
    snprintf(buff, 60, "AT+PWM=<ch(0-7)>,<val(0-65535)>\r\n");
    strcat(buff, AT_OK);
    pack->reply((uint8_t*)buff, strlen(buff));
    return 0;
}

static int atcmd_set_pwm_val(atcmd_pack_t *pack) {
    uint32_t argc[2] = {0};
    uint8_t buff[10] = {0};
    pack->argc = sscanf((char*)(pack->data), "%d,%d", &argc[0], &argc[1]);
    if (pack->argc != 2) {
        strcat((char*)buff, AT_ARGCERR);
        pack->reply(buff, strlen((char*)buff));
        return -2;
    }
    if (bsp_pwm_set_pulse(argc[0], argc[1])) {
        strcat((char*)buff, AT_ERROR);
    } else {
        strcat((char*)buff, AT_OK);
    }
    pack->reply(buff, strlen((char*)buff));
    return 0;
}

ATCMD_INIT("AT+PWM=?", atcmd_set_pwm_val_help);
ATCMD_INIT("AT+PWM=", atcmd_set_pwm_val);

gitee地址:LiSunSDK开源地址

posted on 2023-03-18 12:52  xuejianqiang  阅读(11)  评论(0编辑  收藏  举报  来源
打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033