• 沁恒CH32V103C8T6开发环境笔记


    CH32V103C8T6

    CH32V103C8T6是沁恒的RISC-V内核MCU, 基于RISC-V3A处理器, 内核采用2级流水线处理,设置了静态分支预测、指令预取机制,支持DMA. 主要参数如下

    • CPU: 32位RISC-V3A, RV32IMAC指令集, 最高80MHz, 典型72MHz
    • RAM: 20KB
    • Flash: 64KB
    • BootLoader: 3.75KB 系统引导程序存储区
    • 供电: 2.7V - 5.5V (兼容3.3V和5V)
    • Timer: 通用3, 高级1, 看门狗2, 系统时钟1
    • ADC: 12bit, 10CH
    • SPI: 2
    • I2C: 2
    • UART: 3
    • USBHD: 1
    • 封装: LQFP48

    硬件部分

    需要准备一片 WCH-Link 用于烧录沁恒的芯片. 市面上有兼容 DAP-Link 和 WCH-Link 的烧录器. 注意看烧录器的说明, 其模式在加电前通过按键可以切换. 烧录 CH32V103 时, 必须处于 WCH-Link的状态

    开发板 Blue Pill

    因为 CH32V103C8T6 引脚布局与 STM32F103C8T6, CH32F103C8T6 完全一致, 硬件设计通用,PIN对PIN兼容, 所以可以直接使用 STM32F103C8T6 核心板(Blue Pill)作为开发板.
    手里正好有一片 STM32F103C6T6 的开发板, 电路和 STM32F103C8T6 是一样的, 只是芯片型号不同, 于是用热风焊将C6T6吹下来, 把 CH32V103C8T6 换上去.

    热风枪温度设置成290度, MCU加上助焊油, STM32F103C6T6 吹掉之后的焊盘

    焊上了 CH32V103C8T6, 第一次放得有点歪

    又吹了一遍, 这次小心放正了

    测了一遍各PIN脚间电阻, 感觉有些PIN虚焊了, 所以又用电烙铁拖了一遍


    连线

    WCH-Link -> Blue Pill
    3V3      -> 3V3
    GND      -> GND
    SWD      -> SWIO
    SCK      -> SWCLK
    RX       -> PA9 
    TX       -> PA10
    

    如果不观察串口输出的话, RX/TX可以不连


    软件部分

    软件部分其实就是 MounRiver Studio, 下载完解压后安装. MounRiver Studio 是基于 Eclipse 的扩展开发环境, 对于熟悉 Eclipse 的人用起来还比较方便. 安装 MounRiver Studio 的同时, WCH-Link 的驱动就装上了, 不需要再另外安装.

    如果需要观察串口输出, 还需要使用串口工具, 例如 putty.

    测试项目

    创建项目

    下面建一个测试项目, 通过GPIO驱动板子上的PC13 LED

    File -> New -> MounRiver Project, 在对话框中

    • 选择芯片型号 WCH -> CH32V103 [RIsC-V] -> CH32V103C8T6
    • 输入Project Name, 例如 Test001
    • 勾选 Use default location, 如果需要放到其他目录, 这里可以不勾选, 自行选择
    • Template Type 选择 NoneOS, 因为这只是个简单测试, 只需要while循环即可
    • 点击 Finish

    在项目 Project Explorer 中会出现目录结构,

    编辑代码

    用户代码在 User 目录下, 展开 User, 打开 main.c 将内容修改为

    #include "debug.h"
    
    
    void GPIO_Toggle_INIT(void)
    {
        GPIO_InitTypeDef GPIO_InitStructure = {0};
    
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOC, &GPIO_InitStructure);
    }
    
    
    int main(void)
    {
        u8 i = 0;
    
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        Delay_Init();
        USART_Printf_Init(115200);
        printf("SystemClk:%d\r\n", SystemCoreClock);
        printf("GPIO Toggle TEST\r\n");
        GPIO_Toggle_INIT();
    
        while(1)
        {
            Delay_Ms(500);
            GPIO_WriteBit(GPIOC, GPIO_Pin_13, (i == 0) ? (i = Bit_SET) : (i = Bit_RESET));
            printf("TEST\r\n");
        }
    }
    

    编译项目

    编译和烧录的过程, MounRiver 都已经包装得很好, 所以这部分比较简单.

    使用图标栏中的编译按钮, 或者按F7编译项目(完整编译使用Shift+F7)

    烧录

    首先在设备管理器中查看 Ports (COM & LPT), 如果烧录器处于WCH-Link状态并且已经连接电脑, 会出现 WCH-LinkRV SERIAL(COMx) 这样的设备

    使用图标栏中的下载按钮(Download), 或者按F8烧录.

    如果以上步骤都正常, 应该能看到开发板上的LED每隔半秒切换一次亮灭状态. 串口使用115200波特率连接, 能看到输出的文字"TEST"


    其他测试

    PWM输出

    #include "debug.h"
    
    /* PWM Output Mode Definition */
    #define PWM_MODE1    0
    #define PWM_MODE2    1
    
    /* PWM Output Mode Selection */
    #define PWM_MODE    PWM_MODE1
    //#define PWM_MODE     PWM_MODE2
    
    void TIM1_PWMOut_Init(uint16_t arr, uint16_t psc, uint16_t ccp)
    {
        GPIO_InitTypeDef        GPIO_InitStructure = {0};
        TIM_OCInitTypeDef       TIM_OCInitStructure = {0};
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure = {0};
    
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1, ENABLE);
    
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
    
        TIM_TimeBaseInitStructure.TIM_Period = arr;
        TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
        TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
        TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure);
    
    #if(PWM_MODE == PWM_MODE1)
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    
    #elif(PWM_MODE == PWM_MODE2)
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
    
    #endif
    
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_Pulse = ccp;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
        TIM_OC1Init(TIM1, &TIM_OCInitStructure);
    
        TIM_CtrlPWMOutputs(TIM1, ENABLE);
        TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Disable);
        TIM_ARRPreloadConfig(TIM1, ENABLE);
        TIM_Cmd(TIM1, ENABLE);
    }
    
    int main(void)
    {
        uint8_t i = 0, d = 0;
        Delay_Init();
        USART_Printf_Init(115200);
        printf("SystemClk:%d\r\n", SystemCoreClock);
    
        TIM1_PWMOut_Init(255, 72 - 1, i);
    
        while(1)
        {
            Delay_Ms(10);
            if (d == 0)
            {
                TIM_SetCompare1(TIM1, i++);
                if (i == 255) d = 1;
            }
            else
            {
                TIM_SetCompare1(TIM1, i--);
                if (i == 0) d = 0;
            }
        }
    }
    

    参考

  • 相关阅读:
    关于Java8 stream的相关使用及解析
    【Linux】命名管道
    王熙凤穿越到 2022 年,一定会采购的单点登录服务
    数据可视化之全球咖啡豆的产销:全球总产量平稳上升,预计今年总产量约1.75亿袋
    View Design 全系产品升级至 Vue 3,并发布 View UI Plus 正式版
    一文带你搞懂环绕通知@Around与最终通知@After的实现
    ZLMeidaKit在Windows上启动时:计算机中丢失MSVCR110.dll,以及rtmp推流后无法转换为flv视频流解决
    一步步撸脚本监控
    【AI实战】应用xgboost.XGBRegressor搭建空气质量预测模型(一)
    JavaSE - 包、本类中如何调用其他类中的方法
  • 原文地址:https://www.cnblogs.com/milton/p/16245084.html