# gd32f303cct6 **Repository Path**: Jerry-yl/gd32f303cct6 ## Basic Information - **Project Name**: gd32f303cct6 - **Description**: gd32f303cct6 cupping2 - **Primary Language**: C - **License**: AFL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2025-12-06 - **Last Updated**: 2025-12-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README `` # gd32f303cct6 #### 介绍 gd32f303cct6 cupping2 #### 软件架构 应用固件程序源于:gd32f303/GD32F30x_Firmware_Library_V3.0.1/GD32F30x_Firmware_Library_V3.0.1/Examples #### 固件架构 ```mermaid block-beta columns 1 block:Layer1 style Layer1 fill:#ff9999,stroke:#ff0000,stroke-width:2px a["main.c"] style a fill:#ffcccc b["task.c"] style b fill:#ffb3b3 end block:Layer2 style Layer2 fill:#99ccff,stroke:#0066cc,stroke-width:2px c["button driver"] style c fill:#ff6666 e["buzzer driver"] style e fill:#cce0ff f["motor driver"] style f fill:#99ccff g["... driver"] style g fill:#66b3ff end block:Layer3 style Layer3 fill:#d9d9d9,stroke:#b3b3b3,stroke-width:2px j["GD32F30x_Firmware_Library_V3.0.1"] style j fill:#b3b3b3 end block:Layer4 style Layer4 fill:#c2f0c2,stroke:#33cc33,stroke-width:2px k["startup_gd32f30x_hd.s"] style k fill:#999999 l["gd32f30x_flash.ld"] style l fill:#b3f0b3 end block:Layer5 style Layer5 fill:#fff2cc,stroke:#ffcc00,stroke-width:2px m["ARMv7-m"] style m fill:#ffd11a n["Cortex®-M4"] style n fill:#ffd11a end ``` #### 文档说明 ├── build #烧录hex文件 ├── build.py #自动编译程序 ├── datasheet #产品及芯片规格书 ├── gd32f303 #gd公司SDK Lib ├── GD32F303CCT6.jflash #Flash烧写 ├── LICENSE #源码license ├── Makefile #工程编译配置文件 ├── program.py #自动烧录芯片程序 ├── README.en.md #工程说明英文版(未释放) ├── README.md #工程说明中文版 ├── segger #jlinkrtt lib └── usr #用户驱动文件 #### 安装教程 1. linux ubuntu 2. vscode + arm gcc 3. 参照gd32f303/GD32F30x_yonghushouce_Rev3.2.pdf第7章-7.3节编写gd32f303/GCC/startup_gd32f30x_hd.s 4. 参照gd32f303/GD32F30x_yonghushouce_Rev3.2.pdf第1章-1.3.3节编写gd32f303/GCC/gd32f30x_flash.ld #### 使用说明 1. 导入gd32f303/GCC/startup_gd32f30x_hd.s 2. 导入gd32f303/GCC/gd32f30x_flash.ld 3. build.py 运行 4. programe.py 运行 #### 迭代注意 * 在迭代源码之前,请务必打开datasheet/GD32F303xxDatasheetRev3.1.pdf 中第2章-2.6节GD32F303Cx LQFP48/QFN48 pin definitions 了解所有gpio的映射功能,对齐工程中的功能 #### 虚拟定时器 文件位置:usr/src/user_timer.c 虚拟定时器为task提供时钟源,其时钟源来源于TIMER4定时器,它处理一些定时要求不高的场合,最大处理频率30Khz ##### API step 1: User_Timer_Init(); step 2: User_Timer_Config(TIMERID0, 160, button_callback, NULL); step 3: User_Timer_Start(TIMERID0); #### 按键 文件位置:usr/board_driver/button_input.c 按键使用GPIO中断模式与定时器中断结合处理 step 1: 当GPIO触发按键首先进入中断获取gpio电平 step 2: 在定时器button_callback回调中扫描按键状态 step 3: 在获取的按键值处理对应的功能驱动 ##### KEY_FILTER_TIME * KEY_FILTER_TIME 为设置按键消抖时间 ##### KEY_LONG_PRESSED_TIME * KEY_LONG_PRESSED_TIME 为设置按键长按时间 ##### KEY_CLICK_TIME * KEY_CLICK_TIME 为连击间隔时间,意思为当按键释放-->下一次按键,这个间隔时间 ##### 示例 > ```c 00> Build Date Apr 9 2025 15:45:14 00> =============================== 00> main_loop 00> main_loop 00> main_loop 00> main_loop 00> main_loop 00> power_key = 1 00> main_loop 00> main_loop 00> button_click.power_click = 1 00> main_loop 00> power_key = 1 00> main_loop 00> main_loop 00> main_loop 00> power_key_long_pressed = 1 00> main_loop 00> main_loop 00> main_loop 00> main_loop 00> button_click.power_click = 1 00> main_loop 00> power_key = 1 00> main_loop 00> power_key = 1 00> main_loop 00> button_click.power_click = 2 00> main_loop 00> main_loop 00> power_key = 1 00> power_key = 1 00> power_key = 1 00> main_loop 00> main_loop 00> button_click.power_click = 3 00> main_loop ``` #### 蜂鸣器 文件位置:usr/board_driver/buzzer.c buzzer用定时器摸拟4Khz PWM ##### 示例 > ```c static void buzzer_callback(void *arg) { /* 启动蜂鸣器 */ buzzer_set->run_buzzer(); return; } ``` #### RLED灯 文件位置:usr/board_driver/rled.c rled用定时器摸拟13Khz PWM ##### 档位 * 从0-100 %占空比分5个档 ```c /* pwm_duty 0 - 25 - 50 - 75 - 100 */ enum PWM_DUTY { DUTY0 = 100, DUTY25 = 25, DUTY50 = 50, DUTY75 = 75, DUTY100 = 0 }; ``` ##### 示例 > ```c static void rled_callback(void *arg) { static enum PWM_DUTY PWM_DUTY = DUTY75; /* 启动rled 13Khz */ rled_set->run_rled(PWM_DUTY); return; } ``` #### 气泵 文件位置:usr/board_driver/pump.c\ pump用定时器0+dma 输出20Khz PWM ##### 示例 > ```c uint16_t duty = 0; for (;;) { // pump_set->stop_pump(); pump_set->run_pump(duty++); printf("main_loop\n"); delay_1ms(1000); } ``` #### 输入检测 文件位置:usr/board_driver/detect_voltage.c 3个输入检测口分别为:EMS_ADC,VBAT_ADC,PUMP_ADC ```c enum DETECT_INPUT { EMS_ADC, VBAT_ADC, PUMP_ADC, DETECT_MAX }; ``` ##### 应用 ```c /* adc输入检测 */ detect_set = detect_driver_init(); detect_set->detect_adc_init(); detect_set->adc_value[EMS_ADC] = detect_set->detect_result(EMS_ADC); printf("EMS_ADC=%d\n",detect_set->adc_value[EMS_ADC]); detect_set->adc_value[VBAT_ADC] = detect_set->detect_result(VBAT_ADC); printf("VBAT_ADC=%d\n",detect_set->adc_value[VBAT_ADC]); detect_set->adc_value[PUMP_ADC] = detect_set->detect_result(PUMP_ADC); printf("PUMP_ADC=%d\n",detect_set->adc_value[PUMP_ADC]); ``` ##### 示例 ```c 00> main_loop 00> EMS_ADC=691 00> VBAT_ADC=704 00> PUMP_ADC=669 00> main_loop 00> EMS_ADC=691 00> VBAT_ADC=707 00> PUMP_ADC=682 00> main_loop 00> EMS_ADC=696 00> VBAT_ADC=714 00> PUMP_ADC=689 00> main_loop 00> EMS_ADC=704 00> VBAT_ADC=718 00> PUMP_ADC=696 ``` #### 输出控制 文件位置:usr/board_driver/control.c 8个输出口分别为: ```c enum CTRL_OUTPUT { PWR_CTRL, VALVE_CTRL, FSTCH_CTRL, EMS_CTRL, OLED_RES, OLED_DC, OLED_CS, IR_CTRL, CTRL_MAX }; ``` ##### 应用 ```c /* 输出控制 */ ctrl_set = ctrl_driver_init(); ctrl_set->device_init(); uint8_t control_flag = 0; control_flag = !control_flag; ctrl_set->ctrl_run(PWR_CTRL,control_flag); ``` #### OLED 文件位置: usr/board_driver/oled.c * gd32这里采用硬件spi驱动oled * 有4个特别需要注意的地方 > 采用软件cs--pa6 > spi失能miso功能,spi初始化不要配置pa6,在gpio初始化中配置 > spi标志位用SPI_FLAG_TRANS ```c while (SET == spi_i2s_flag_get(SPI0, SPI_FLAG_TRANS)) ``` > 根据驱动datasheet/0.66寸OLED单屏和模块/模块-7P/0.66-7pin_SPI(ssd1315).C demo可以发现ssd1315的timing顺序为: DC--->CS--->CLK--->DIN 同时CLK空闲时保持低电平,则SPI需配置为 :SPI_CK_PL_LOW_PH_1EDGE ##### 如何驱动 1. 参照根据驱动datasheet/0.66寸OLED单屏和模块/模块-7P/0.66-7pin_SPI(ssd1315).C demo可以发现ssd1315的timing顺序为: DC--->CS--->CLK--->DIN 2. spi驱动写完后,用逻辑分析仪抓出spi data 3. 其它的基本都是自定义显示,自已写显示,注意就是ssd1315 的martix是根据:行[8]个 和 列[8*128],因为64x48点阵,注意:您应该了解OLED显示屏 0.66英寸(SSD1315)是基于128×64分辨率的屏幕。当您想要使用驱动进行显示时,您需要从(32,0)而不是(0,0)开始绘制。其范围是从(32,0)到(96,48):如果您尝试无法正确计算出坐标位置,您可以使用:https://wiki.seeedstudio.com/cn/Grove-OLED-Display-0.66-SSD1306_v1.0/模块进行绘制 ##### 取模工具 采用arduino 关联的oled取模工具 https://javl.github.io/image2cpp/ 注意画布大小设为:自定义 画布大小: 64 x 48 背景颜色: 黑色 反转图像颜色:打勾 抖动: 二元的 亮度 / Alpha 阈值: 128 缩放: 缩放以适合,保持比例 中间图像: 垂直 仅当使用大于原始图像的画布时,图像居中才有效。 旋转图像: 0度 翻转图片: 垂直 代码输出格式: 纯字节 绘制模式: 垂直 - 每像素 1 位 如果您的图像在显示器上看起来一团糟,如下图所示,请尝试使用其他模式。 以字节为单位交换位: 不用勾 其他格式选项: 不用勾 ##### 应用 ```c /* oled功能 */ uint8_t trun_on = 0xAF; oled_set = oled_driver_init(); oled_set->init_oled(); oled_set->clear_oled(); delay_1ms(5); oled_set->send_com(&trun_on,1); oled_set->fill_oled(); oled_set->dis_set(); /* task定时器 */ User_Timer_Init(); /* oled处理进程 150hz*/ User_Timer_Config(TIMERID3, 320, oled_callback, NULL); User_Timer_Start(TIMERID3); ``` #### EMS坐垫 文件位置: usr/board_driver/ems_ctrl.c * 采用TIMER3定时器PWM比较输出 * ems坐垫由频率设为25Khz的3组pwm控制:分别为 ```c enum EMS_PWM { EMS_PWM1, EMS_PWM2, EMS_PWM_BOOT }; ``` ##### 应用 ```c /* ems功能 */ static struct ems_func *ems_set; static void ems_callback(void *arg); /* ems功能 */ ems_set = ems_driver_init(); ems_set->init_ems(); /* task定时器 */ User_Timer_Init(); /* ems处理进程 15hz*/ User_Timer_Config(TIMERID4, 3200, ems_callback, NULL); /** * @func: * @description: EMS坐垫进程 * @param {void} *arg * @return {*} * @example: */ static void ems_callback(void *arg) { static int index, flag; if (index < 1599) ems_set->run_ems(EMS_PWM_BOOT, index); if (index == 1600) { ems_set->stop_pump(EMS_PWM_BOOT, 0); } else index += 2; return; } ``` #### 已知bug 虚拟定时器 rled 和buzzer pwm都存在定时器处理延迟,存在定时器处理130 hz的周期延迟,所以用于一些定时要求不高的场合产生pwm #### 参与贡献 1. [gd32官方资料](https://www.gigadevice.com.cn/product/mcu/mcus-product-selector/gd32f303cct6) 2. #002_SCH_GD32F303CCA S-CUP Mar 22 2025 3. oled/E066XJ-W-C16-06 FPC 16 Pin OLED FOR 002 .pdf 4. datasheet/0.66寸OLED单屏和模块/模块-7P/0.66-7pin_SPI(ssd1315).C #### 常见问题 * ubuntu 无法启动:开机时按“esc"键进入grub,用nomodeset进入 * ubuntu 无法启动双显示器:重装显卡驱动