因为本怪精力有限,[Cavendish 3.0]已经停止维护,除非出现重大BUG,现在推出了新硬件Caven 3.14 !Core-Caven32就是为其设计的全新代码框架。
Caven 3.14 板载硬件DAP-Link和TTL串口(可以Debug和串口3打印数据),此外还有一个LCD-1.3寸屏。
只需要一根Type-c数据线和一台电脑即可开发 Caven 3.14 !
其实Core-Caven32里面放的是一个32位系统的代码库,包括ARM-M0、ARM-M0+、ARM-M3、ARM-M4(F)、RISC-V(虽然它的初衷是为Cavend 3.14服务)。
本设计仅供于学习、参考,不可商用和水毕业论文(参与开发者随意)!
更新日志
2020.开始创建
2021.框架稳定
2022.驱动
2024.开始收尾,CavenRTOS
更新速度Top | Base底层完成度(独立) | Mode调度层完成度(共享) |
---|---|---|
AT32F415 | 90% | 95% |
AT32F403A | 40% | 95% |
STM32F103 | -- | 95% |
GD32F405 | -- | 95% |
CH32V203 | 90% | 95% |
HC32L110 | 99.8% | 不在Caven框架(内存太小) |
Other | -- | -- |
首先,要先确认Caven 3.14上面的CH549芯片是否有固件/驱动。
如果没用,请到Core-Caven32\DAP-Link
文件夹下面查看使用说明!如果电脑检测不到驱动,请去WCH官网寻求帮助,谢谢!嘉立创EDA dap-link硬件资料
驱动&资料
MCU的Keil依赖&工具&资料 (因为这个东西不经常变更就不放在这里了)
子模块链接 (里面有食用方法)
Cavendish硬件资料 嘉立创EDA 或者 SwiperWitty/PCB-MCU ,注意是Caven 3.14哦!
关于有些小白直接下载压缩包
如果你直接下载,它里面会缺少[Caven-MCU_Lib]文件的内容,因为[Caven-MCU_Lib]文件是子模块。解决办法是git 下载这个子模块手动copy到[Core-Caven32]文件夹,但是这样极其愚蠢,我是不推荐的,而且没法获取代码更新。
关于git 下载此项目
因为这个工程里面有子模块(就是上面那个子模块链接,以防呆瓜不看,再说一遍),所以使用之前要从\Core-Caven32
文件cd
到\Caven-MCU_Lib
git clone --recursive https://github.com/SwiperWitty/Core-Caven32.git
cd .\Caven-MCU_Lib\
git branch // 查看分支
git checkout main // 切换到主分支
cd ..
// ok了
如果你发现[Caven-MCU_Lib]文件夹是空的,那么你就需要执行下面的命令
//在Core-Caven32文件夹下的命令行
cd .\Caven-MCU_Lib\
git submodule update --init --recursive
// 如果没反应
git pull
// 如果还是没反应,那就应该去看git子模块使用方法
// 如果成功了,接下来执行切换到主分支
git branch
git checkout main
cd ..
其他疑问:
如果port 443 after : Timed out
,你可以试试
设置网络代理,系统代理的 IP 地址和端口号。
git config --global http.proxy http://127.0.0.1:7890
或者,取消网络代理(例如使用gitee)
git config --global --unset http.proxy
自动告诉你有哪些功能以及如何使用(Keil也会)!
所有会自动提升的功能都是已经写好的!
这个功能是最重要的东西,当然你可能主观上不想用,但是实际上你在启动的时候,他就运行了。
- 系统实时时钟管理
- 多任务(状态机&触发器)
由Base_Sys_time.c
提供最基础的调用,注意此文件提供三点:初始化系统时钟、获取/设置系统实时时钟、delay。
typedef struct
{
u32 SYS_Time_H; //每Frequency进1
u32 SYS_Time_L; // 24bit 的
}SYS_Time_Type;
typedef struct
{
U32 SYS_Sec;
U32 SYS_Us; // 这里最大 1000 000
}SYS_BaseTIME_Type;
void SYS_Time_Init(int Set);
void SYS_Time_Set(SYS_BaseTIME_Type * time);
void SYS_Time_Get(SYS_BaseTIME_Type * time);
void SYS_Base_Delay(int time, int speed);
由MODE_Time.c
提供用户使用的时钟函数,提供用户层能使用的数据,例如当日时间Caven_Watch_Type
,日期Caven_Date_Type
,其中Caven_Watch_Type
是内带系统总秒数的。
// 日期
typedef struct
{
U16 year;
U8 month;
U8 day;
U32 SYS_Day;
}Caven_Date_Type;
// 时间
typedef struct
{
U8 hour;
U8 minutes;
U8 second;
U32 time_us; // 这里最大 1000 000
U32 SYS_Sec;
}Caven_Watch_Type;
Mode_Init.TIME(ENABLE);
Mode_Use.TIME.Delay_Ms(10);
Mode_Use.TIME.Get_Watch_pFun();
- 时间触发函数
- 事件任务函数
由Time_Handle.c
提供时间触发函数,只由时间触发,但是并不执行任务,是否执行任务请访问Task_Overtime_Type
结构体。
typedef struct
{
volatile Caven_Watch_Type Set_time;
volatile Caven_Watch_Type Begin_time;
volatile char Trigger_Flag; //[000][1][000]
volatile char Flip_falg; //[000][111][000] only Read
int Switch;
}Task_Overtime_Type;
int API_Task_Timer (Task_Overtime_Type *task,Caven_Watch_Type now_time);
由Caven_event_frame.c
提供事件任务函数。
typedef struct
{
int events_num;
unsigned char events[CAVEN_EVENTS_MAX];
D_pFun events_pFun[CAVEN_EVENTS_MAX];
}Caven_event_Type;
int Caven_new_event_Fun(Caven_event_Type *events,D_pFun event_pFun,int *handle);
int Caven_delete_event_Fun(Caven_event_Type *events,int *handle);
int Caven_trigger_event_Fun(Caven_event_Type *events,int const handle,char data);
int Caven_handle_event_Fun(Caven_event_Type *events);
例如
Caven_Watch_Type now_time;
Caven_event_Type SYS_events;
int BZZ_event_Handle = 0;
void BZZ_event_task_Fun (void * data)
{
int temp_data = *(int *)data;
if (temp_data) {
Mode_Use.BZZ.SET_pFun(ENABLE);
Mode_Use.BZZ.SET_pFun(DISABLE);
}
else {
Mode_Use.BZZ.SET_pFun(DISABLE);
}
*(int *)data = 0; // 退出任务
}
void Main_Init(void)
{
int reverse = 0;
system_clock_config();
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
Mode_Index();
Mode_Init.TIME_Init_State = Mode_Init.TIME(ENABLE);
Mode_Init.LED(ENABLE);
Mode_Init.BZZ(ENABLE);
now_time = Mode_Use.TIME.Get_Watch_pFun();
Caven_new_event_Fun(&SYS_events,BZZ_event_task_Fun,&BZZ_event_Handle); // 创建BZZ事件任务
}
int main (void)
{
Main_Init();
Task_Overtime_Type LED_Task = {
.Switch = 1,
.Begin_time = now_time,
.Set_time.second = 1,
.Set_time.time_us = 5000,
.Flip_falg = 1,
};
API_Task_Timer (&LED_Task,now_time); // 创建LED时间任务
while(1)
{
Mode_Use.LED.SET_pFun(1,LED_Task.Flip_falg); // 访问任务状态
if(LED_Task.Trigger_Flag)
{
Caven_trigger_event_Fun(&SYS_events,BZZ_event_Handle,1); // 触发事件
}
Caven_handle_event_Fun(&SYS_events); // 事件运行函数
}
}
由例程看出,LED灯被LED_Task结构体控制,每1.5s交换一次状态,每次交换状态,BZZ都会响一次。
M0: STM32F030F4、STM32G030F6(M0+)
M3: STM32F103RC、GD32F103RC
M4: STM32F405RC、AT32F415RC、AT32F425RC、AT32F403ARC、
RISC-V: CH32V203C8T6、CH32V307RET6(这玩意Flash不行)
通信:
- UART(硬)
- SPI(软、硬)(硬件->【普\DMA】)
- IIC(软)
- USB(部分)(硬)
- CAN(部分)(硬)
模拟:
- ADC(普、DMA)
- DAC(部分)
系统时钟:
- SYS_TICK
- 看门狗(选)
Flash
- 掉电保存
- Bootloard(部分)
数字(时钟输入输出):
- PWM
- ENCODE(编码)
GPIO:
- 输入
- 输出
Keil会用吧?
WCH-Link驱动会装吧?
Github会clone吧?
满足这些你就可以正常使用了!
MDK设置
下载方式是CMSIS-DAP,也就是所谓的WCH-Link,按照上述步骤你就可以看到这个
如果上述有问题请参考一下内容(如果你认真看完这些,依旧没解决,我可以帮帮你;如果你没有认真看,那我只能请你熟读并背诵了)
WCH-Link相关:看这里 如果需要给WCH-Link下载程序,那么需要将CH549的D-接到VDD激活CH549的USB下载模式,然后如果是V1.0版本的WCH-Link固件,需要根据TX接GND去切换RSIC-V/ARM下载模式。当然你可以选择直接下载ARM专用固件(WCH-Link_APP_IAP_ARM.bin)或者RSIC-V专用固件(WCH-Link_APP_IAP_RV.bin)。
芯片检测不到:看这里 的【 三、设置keil 章节】的 【3、配置好相应的Flash Download选项】
如果问题还是没有解决:看这里
卡文迪许怪
qq讨论群:455839434