沁恆CH32V103C8T6開發環境筆記

来源:https://www.cnblogs.com/milton/archive/2022/05/08/16245084.html
-Advertisement-
Play Games

CH32V103C8T6是沁恆的RISC-V內核MCU, 基於RISC-V3A處理器, 內核採用2級流水線處理,設置了靜態分支預測、指令預取機制,支持DMA. 需要準備一片 WCH-Link 用於燒錄沁恆的晶元. 市面上有相容 DAP-Link 和 WCH-Link 的燒錄器. 註意看燒錄器的說明,... ...


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;
        }
    }
}

參考


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 回顧總結 到目前為止,Spring源碼中AbstractApplicationContext#refresh方法的已經解讀到第11個方法finishBeanFactoryInitialization,前10個方法介紹了: BeanFactory的準備,創建,刷新,個性化BeanFactory的擴展點 ...
  • package com.oop.demo06;public class Person { public void run(){ System.out.println("run"); }} package com.oop.demo06;public class Student extends Pers ...
  • 1、前言 好久沒有更新博客了,最近沒什麼假期,但是卻比以前還忙!工作、工作、工作,就像趕集似的,聚在一起。這個上海啥時候才能解封困在這裡暗無天日的。早點解封出去看看想見的人的人,做做該做的事。工作中有那麼一個需求客戶想要通過自己選擇列表的checkbox然後下載所選列表裡面的圖片,圖片我們是存在圖片 ...
  • 一 什麼是轉換 轉換是接受一個類型的值並使用它作為另一個類型的等價值的過程。 下列代碼演示了將1個short類型的值強制轉換成byte類型的值。 short var1 = 5; byte var2 = 10; var2 = (byte) var1; //強制轉換,將var1的值轉換成byte類型 二 ...
  • VS2019如何把項目部署和發佈 這裡演示:通過IIS文件publish的方式部署到Windows本地伺服器上 第一步(安裝IIS) 1.在自己電腦上搜索Windows功能里的【啟用或關閉Windows功能】 2.配置Internet Information Services 3.然後點擊確認就OK ...
  • 1、回調函數 關於回調函數,在之前的文章《回調函數》已經詳解講解過了,這個文章不再講解,不太懂的同學請看之前的文章《回調函數》。在之前講解回調函數中就使用串口作為示例,使用回調函數可以方便封裝通訊庫,晶元/模塊廠家的SDK和部分開源庫經常這樣做,這樣可以實現模塊間的解耦,模塊化編程。 這篇文章主要講 ...
  • 大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家介紹的是i.MXRT1xxx系列MCU時鐘相關功能引腳作用。 如果我們從一顆 MCU 晶元的引腳分類來看晶元功能,大概可以分為三大類:電源、時鐘、外設功能。作為嵌入式開發者,大部分時候關註得都是外設功能引腳,而對於時鐘相關引腳往往不太在意,其實 ...
  • Linux小白,可能描述的不規範,請見諒 事情經過 有一次我樹莓派由於某種原因導致桌面某個組件卡死,於是我就在跳出的“未響應”(類似windows的No Response視窗)點擊'End Process'後,桌面的菜單欄還在,但是圖標不見了。 這時我右鍵點擊桌面,發現右鍵菜單與之前截然不同(應該是 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 在我們開發過程中基本上不可或缺的用到一些敏感機密數據,比如SQL伺服器的連接串或者是OAuth2的Secret等,這些敏感數據在代碼中是不太安全的,我們不應該在源代碼中存儲密碼和其他的敏感數據,一種推薦的方式是通過Asp.Net Core的機密管理器。 機密管理器 在 ASP.NET Core ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 順序棧的介面程式 目錄順序棧的介面程式頭文件創建順序棧入棧出棧利用棧將10進位轉16進位數驗證 頭文件 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> 創建順序棧 // 指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改 ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • C總結與剖析:關鍵字篇 -- <<C語言深度解剖>> 目錄C總結與剖析:關鍵字篇 -- <<C語言深度解剖>>程式的本質:二進位文件變數1.變數:記憶體上的某個位置開闢的空間2.變數的初始化3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地 ...
  • 如果讓你來做一個有狀態流式應用的故障恢復,你會如何來做呢? 單機和多機會遇到什麼不同的問題? Flink Checkpoint 是做什麼用的?原理是什麼? ...
  • C++ 多級繼承 多級繼承是一種面向對象編程(OOP)特性,允許一個類從多個基類繼承屬性和方法。它使代碼更易於組織和維護,並促進代碼重用。 多級繼承的語法 在 C++ 中,使用 : 符號來指定繼承關係。多級繼承的語法如下: class DerivedClass : public BaseClass1 ...
  • 前言 什麼是SpringCloud? Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、網關、路由、鏈路追蹤等。Spring Cloud 並不是重覆造輪子,而是將市面上開發得比較好的模塊集成進去,進行封裝,從 ...
  • class_template 類模板和函數模板的定義和使用類似,我們已經進行了介紹。有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同。類模板用於實現類所需數據的類型參數化 template<class NameType, class AgeType> class Person { publi ...
  • 目錄system v IPC簡介共用記憶體需要用到的函數介面shmget函數--獲取對象IDshmat函數--獲得映射空間shmctl函數--釋放資源共用記憶體實現思路註意 system v IPC簡介 消息隊列、共用記憶體和信號量統稱為system v IPC(進程間通信機制),V是羅馬數字5,是UNI ...