CH32V307VCT6单片机程序写入教程

本文介绍了如何使用MounRiver集成开发环境创建CH32V307单片机工程,包括新建工程、理解工程目录结构、编写代码以及烧录过程。文章适合对STM32有一定了解的新手,帮助他们快速上手CH32V307单片机。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

之前在沁恒微电子官网上申请了块互连型的单片机,芯片的型号是CH32V307,之前在论坛上看到他们说这一块单片机和stm32系列的单片机差不多,正好今天板子到了我试了一下,发现真的和stm32差不多。

很多没有接触过stm32单片机但是白嫖到板子的朋友可能不会用这块板子,所以我就写了一篇文章来给大家介绍一下这块板子如何使用并且能点亮其中的一个LED灯。

一、芯片的介绍

这个板子使用的是CH32V307VCT6芯片,这个是基于青稞32位RISC-V(基于精简指令集计算压力建立的开放指令机构)指令集及架构设计的工业级通用增强型MCU。

其实这个可以去它官网看一下的,这里就不介绍这些内容了,反正你就把它当作一块stm32的单片机就可以了。

二、MounRiver集成开发IDE

这个软件是这个板子配套的,使用这个软件写代码难度低,而且这个文件配套了关于这个板子的WCH-Link一键下载,这样就不用再去下载烧录软件了。

下载的链接:MounRiver Studio

下载完成之后解压文件夹,然后双击里面的安装文件,选择安装目标文件夹,剩下的就随便了,然后会自动打开这个软件的,打开后会进入一个welcome,可以直接关闭,关闭后的样子如下:

img

当然你们没有左边和下面的内容,这个是我刚才测试的。

1.新建工程

打开这个集成开发环境后我们就可以来创建一下工程了,首先在任务栏中选择File选项,然后再选择New,在这里面选择MounRiver Project,选择之后会出现下面的页面:

img

首先是为你的工程取一个名字,在Project Name中现在你这个工程的名字:

img

然后就是项目的保存路径了,这里如果你直接点是没有办法的,因为它启用的是默认的,所以需要将这个默认选项改变为自定义的:

img

首先先取消一下Use solution location这个选项,这样才可以选择自定义的目录,选择的自定义目录一定要记住必要有中文。

然后就开始选择你芯片的型号了,这里要看准你芯片的型号,因为它会将启动文件和所包含的库文件都创建出来:

img

选择完后就可以点击Finish了,然后就开始自动创建,创建完成后在左边就会出现刚才你创建的项目了:

img

这就是创建工程的办法。

2.工程目录

上面创建好工程后大家可能都不知道这些文件是什么东西,这里就给大家一个个的介绍一下。

2.1 Include

首先是Includes文件夹

img

这个是列出你这个工程中导入了哪一些文件或者文件夹。

2.2 Core

这个文件夹中是存放这个单片机的外设文件的

img

2.3 Debug

这个文件夹中是来存放测试使用的一些函数和延迟的,我大概看了一下,在这里面存放了滴答定时器的初始化、毫秒延迟、微秒延迟和串口通讯的函数。

img

2.4 Ld

这个文件存放了一个文件,这个文件应该是有关于启动文件的说明等内容的,我也不清楚,反正必要动

img

2.5 Peripheral

这个文件就是库函数所放置的文件夹了

img

2.6 Startup

这个文件夹是用来存放启动文件的文件夹的。

img

这里面都是汇编语言。

2.7 User

这个是我们写代码的地方,大家在这里面写代码即可

img

在这里面有一个main.c文件,这个就是主函数和我们写代码的地方了,我们的代码都在这里面进行书写

3.书写代码

知道了上面的工程目录后,我们就可以来书写代码了,首先打开main.c文件

img

在这里面会发现,为什么会有这么多东西,其实我们都可以不用管,就嘎嘎写就完事了。

那我们该如何写呢?如果你学过STM32,那这里基本上难不住你,我们要点一个LED等,首先我们先确定一下要点的LED灯在哪个引脚接着的,然后就打开这个端口的时钟,配置GPIO,然后点亮即可。

是不是蛮简单的,那我们就开始来吧。

首先看一下原理图

img

然后再看看它连接的引脚,我找了半天,发现这个板子的LED1和LED2连接到公头上的,我靠,这个是真的恶心

img

也就是说这里需要结一个条线,还好我这有很多,大家没有的话可以在pdd或者淘宝上买一扎跳线,公头,母头都来点,这里我用条线将LED1和PC1相连

img

这里我们就知道了,我们用PC1来控制LED灯的亮灭。

知道了后就可以开始写一下代码了,首先定义一个函数,在函数中首先先定义一个变量,这个变量是:GPIO_InitTypeDef类型的,这个变量是用来初始化引脚的

GPIO_InitTypeDef GPIO_InitStruct = {0};

然后打开GPIOC的时钟,这里GPIOC的时钟和STM32一样,都是在APB2的,我们直接就可以用打开APB2的方式来打开GPIOC的时钟:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

然后就开始配置GPIOC_1,配置方法和STM32的配置方法一模一样,端口的输出模式也一样,这里不过多解释:

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;  // 这里设置为推挽输出方式
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;   // 设置GPIOC1
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;   // 设置输出速度为50MHz

然后就可以调用端口初始化函数进行初始化了:

GPIO_Init(GPIOC, &GPIO_InitStruct);

完整代码如下:

void MX_LED_Init(void){
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStruct);
}

然后在main函数中就可以调用这个函数来进行点灯了。

在main函数中首先需要先调用一下刚才创建的函数,然后在while循环中就可以开始点灯了:

int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	SystemCoreClockUpdate();
	Delay_Init();
	MX_LED_Init();    // 刚才创建的函数
    // 下面的串口通讯,不用管
	USART_Printf_Init(115200);	
	printf("SystemClk:%d\r\n",SystemCoreClock);
	printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
	printf("This is printf example\r\n");
	// *****************************************
	while(1)
    {
	    GPIO_WriteBit(GPIOC, GPIO_Pin_1, Bit_RESET);  // 点亮LED灯
	}
}

效果如下:

img

然后再灭了它:

int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	SystemCoreClockUpdate();
	Delay_Init();
	MX_LED_Init();    // 刚才创建的函数
    // 下面的串口通讯,不用管
	USART_Printf_Init(115200);	
	printf("SystemClk:%d\r\n",SystemCoreClock);
	printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
	printf("This is printf example\r\n");
	// *****************************************
	while(1)
    {
	    GPIO_WriteBit(GPIOC, GPIO_Pin_1, Bit_SET);  // 点亮LED灯
	}
}

img

感觉太单调了,给它来个闪烁吧:

int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	SystemCoreClockUpdate();
	Delay_Init();
	MX_LED_Init();
	USART_Printf_Init(115200);	
	printf("SystemClk:%d\r\n",SystemCoreClock);
	printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
	printf("This is printf example\r\n");

	while(1)
    {
	    GPIO_WriteBit(GPIOC, GPIO_Pin_1, Bit_RESET);
	    Delay_Ms(500);
	    GPIO_WriteBit(GPIOC, GPIO_Pin_1, Bit_SET);
	    Delay_Ms(500);
	}
}

这个拍照拍不出效果,大家自己去搞一下就知道了。

4.烧录代码

写好代码后就需要将代码进行一下烧录进板子了,这里就需要知道一下如何将写好的代码烧录进板子中,首先需要将代码进行编译,编译按钮:

img

这三个按钮都是编译,但是编译的模式不一样,首先第一个按钮是编译修改过的文件,速度比较快。

第二个按钮是编译当前文件,就是当前你打开的文件,可以当调试当前文件中有没有问题。

第三个是将整个工程编译,我个人感觉太慢了,没必要。

编译完后我们就开始用单片机连接电脑,这里需要准备一条Type-C的通讯线,然后将这条线一端连接电脑,一端连接单片机

img

img

然后打开单片机,回到IDE,在IDE中找到这个按钮:

img

但是不能直接点,首先点击那个下箭头,点击Configuration,然后就到达这个页面了

img

在这个页面中有很多按钮,这里给大家一一介绍一下:

第一个大按钮

img

这个是查看你板子的读写是否被锁,如果没有被锁那会出现这样子的提示:

img

如果说你的板子是锁着的,那会出现下面的提示:

img

当你的板子被锁了,那就没有办法进行烧录程序,只能给它解锁。

第二个按钮

img

这个按钮就是将板子的读写给锁住。

第三个就是解锁板子:

img

然后到下面

img

这里是配置下载器的,一开始没有,你要确定你的板子进行开启,然后点击Query,这个就会搜索一下你的板子

img

然后其它的可以不用管了,点击Apply and Close就可以了,然后再点击那个东西即可,这样代码就会烧录就去。

img

出现这个就代表了烧录成功,如果你烧录出现这个情况:

img

这个情况就因为你的单片机锁着的没办法进行烧录。

总结

这块板子和STM32差不多,学会了STM32的标准库开发,基本上这个板子不会很难,只不过就是这个板子需要的外设比较多。

<think>好的,我现在需要帮用户解决如何解除CH32V307VCT6芯片的写保护问题。首先,我得回忆一下之前用户提供的引用内容,看看有没有相关的信息。 用户提到了四个引用,其中引用3详细介绍了CH32V307芯片的特性,包括存储器的容量和供电电压等,但可能没有直接提到写保护。引用4是关于USART中断处理的代码,可能和烧录有关,但不太直接。引用1和2是关于开发板和开发环境搭建的信息,可能涉及到烧录工具的使用,但具体解除写保护的方法可能需要更深入的技术文档。 首先,解除写保护通常涉及到芯片的选项字节(Option Bytes)或Flash保护位的配置。对于许多MCU来说,解除写保护需要通过特定的工具或软件,在烧录时进行配置。例如,ST的芯片使用ST-LINK Utility来修改选项字节,而沁恒的芯片可能有自己的工具。 接下来,我需要确认CH32V307VCT6是否使用类似的机制。根据引用3,该芯片有256KB的Flash,支持串行调试接口,可能使用的是WCH-Link调试器。用户提到的引用2中提到了开发环境搭建,可能使用MounRiver Studio,这个IDE可能内置了烧录和配置工具。 步骤可能包括: 1. 使用正确的烧录工具,如WCH-Link,连接芯片。 2. 在MounRiver Studio中,找到选项字节配置或Flash设置的选项。 3. 禁用写保护位,可能需要输入特定的密码或使用解除指令。 4. 重新上电或复位芯片,使配置生效。 另外,用户可能需要检查是否在代码中意外启用了写保护。例如,在初始化代码中设置了Flash的写保护寄存器,导致后续无法烧录。这时候需要进入RAM启动模式,或者通过硬件复位的方式解除。 还有可能是在烧录过程中,工具没有正确识别芯片状态,需要先擦除整个Flash,包括受保护的扇区。或者使用厂商提供的特定解除命令,比如通过串口发送特定指令。 需要提醒用户注意,错误的操作可能导致芯片锁死,所以要按照官方指南操作。参考引用2中的开发环境搭建,确保工具链正确,并且参考官方文档中的Flash编程部分。 可能的问题:用户是否已经尝试过常规的擦除方法?是否在烧录时收到写保护错误信息?如果是,通常的解决步骤是连接调试器,通过工具解除保护,然后进行擦除和烧录。 总结步骤: 1. 使用WCH-Link和MounRiver Studio连接开发板。 2. 进入Flash配置界面,找到选项字节设置。 3. 禁用相关的写保护选项,保存并重新烧录。 4. 如果仍然不行,尝试全片擦除或使用厂商提供的解除命令。 需要确保用户按照官方文档操作,避免操作失误。如果有更详细的错误信息,可以进一步排查。</think>### CH32V307VCT6芯片解除写保护方法 #### 一、写保护机制与解除原理 CH32V307VCT6芯片的写保护功能通过Flash控制寄存器($FLASH\_CTLR$)实现,涉及$OB\_RDP\_LEVEL$选项字节配置[^3]。默认情况下,芯片可能因以下情况触发写保护: 1. 选项字节中读保护等级被设置为非0值 2. 用户代码中意外修改了Flash保护位 3. 烧录工具未正确配置保护选项 #### 二、硬件准备 1. **开发板/调试器**:推荐使用官方赤菟开发板(CH32V307-EVT-R1)配合WCH-Link调试器[^1][^2] 2. **软件环境**:安装MounRiver Studio(支持CH32V307的官方IDE) 3. **接线确认**:SWD接口正确连接(SWCLK、SWDIO、GND) #### 三、操作步骤 1. **连接调试器** ```python # 在MounRiver Studio中配置调试器参数示例 debug_tool = "WCH-Link" interface = "SWD" speed = 4000 # kHz ``` 2. **解除写保护流程** - **方法1:通过选项字节修改** 1. 打开工程属性 → Flash配置页 2. 勾选"Erase Option Bytes Before Programming" 3. 设置读保护等级为Level 0: ```c // 对应选项字节配置 OB->RDP = 0xAA55; // 解除读保护 ``` 4. 执行全片擦除操作 - **方法2:命令行工具操作** 使用WCH提供的`wch_flash_tool`: ```bash wch_flash_tool -c WCH-Link -m erase_all wch_flash_tool -c WCH-Link -m program -f firmware.bin ``` 3. **验证操作** 查看Flash状态寄存器: $$ FLASH\_STATR = 0x00000000 $$ 若$bit1=0$(PGAERR位)表示无保护错误 #### 四、注意事项 1. **供电稳定性**:确保3.3V供电电压偏差不超过±5%[^3] 2. **复位时序**:修改选项字节后需执行硬件复位 3. **代码审查**:检查用户代码中是否包含以下高危操作: ```c FLASH->CTLR |= FLASH_CTLR_PG; // 意外使能编程模式 FLASH->OBKEYR = 0x45670123; // 未授权的选项字节修改 ```
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恰柠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值