Купил на распродажу на Алиэкспресс 20 шт. микроконтроллеров CH32V003J4M6 за 270 рублей. Разберемся, что это за зверь такой и что с ним можно сделать
Обзор
Серия CH32V003 основана на ядре QingKe RISC-V2A промышленного микроконтроллера общего назначения, с частотой 48 МГц, широким диапазоном напряжений, однопроводным последовательным отладочным интерфейсом, низким энергопотреблением, сверхкомпактным. Серия CH32V003 имеет встроенную группу контроллеров DMA, группу 10-разрядных АЦП, группу компараторов на операционных усилителях, несколько таймеров и стандартные интерфейсы связи USART, I2C, SPI
Выпускаются в разных форм факторах
CH32V003J4M6 в корпусе SOP8. В каждом форм факторе свои назначения на разных пинах. У этой платы распиновка следующая
Для прошивки нужно докупить WCH-Link программатор
Лучше купить как на картинке версию WCH-LinkE. На Али цена 350 рублей. Документация к нему тут
Схема соединения программатора с микроконтроллером
Можно заметить, что два порта находятся на одном пине. И это правильно
Микроконтроллер я припаял на переходник и собрал эту схему на макетной плате
Добавил лампочку на пин 1 и резистор на 100 ом для примера использования
Программирование
Для программирования можно использовать как Arduino IDE, так специальную под этот микроконтроллер MounRiver Studio (MRS). Скачать можно с сайта http://mounriver.com/download. Будем использовать её. С системой устанавливается много примеров. Устанавливаем
Так же нужно установить для программатора утилиты: WCHISPTool и WCH-LinkUtility. Все ссылки программы будут в конце статьи
Запускаем MRS. Напишем первый самый простой пример
Hello World
Чтобы создать проект нажимаем File -> New -> MounRiver Project
Даём название своему проекту. Выбираем плату. Нажимаем Finish
Практически первая программа готова
#include "debug.h"
vu8 val;
void USARTx_CFG(void) {
GPIO_InitTypeDef GPIO_InitStructure = {0};
USART_InitTypeDefUSART_InitStructure = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_USART1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_30MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOD, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
}
int main(void) {
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
SystemCoreClockUpdate();
Delay_Init();
#if (SDI_PRINT == SDI_PR_OPEN)
SDI_Printf_Enable();
#else
USART_Printf_Init(115200);
#endif
printf("SystemClk:%d\r\n",SystemCoreClock);
printf("ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
// сюда добавляем
USARTx_CFG();
while(1) {
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET) {
/* waiting for receiving finish */
}
USART_SendData(USART1, ~val);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){
/* waiting for sending finish */
}
}
}
По умолчанию создаётся интерфейс для взаимодействия с программой по UART. Инициализация пинов происходит в функции USARTx_CFG. В основной функции main сначала происходит инициализация, потом запускается основной поток в бесконечном цикле while. В нем считываются значения в переменную val и сразу же отправляется обратно
Добавим строчку
printf("Hello world!!!\r\n");
После
printf("ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
При загрузке микроконтроллера должно выйти сообщение Hello world!!!
Чтобы увидеть сообщение надо открыть Terminal
Нажимаем Window -> Show View -> Other -> Terminal
Появится дополнительное окно
Чтобы подключиться нажимаем кнопку в красном кружке Launch Terminal
Теперь можно компилировать приложение
Нажимаем в меню Build
И загружаем в микроконтроллер
Нажимаем Download
Если появляется ошибка
значит пин загрузки 8 занят. Нужно сбросить микроконтроллер. Нажимаем Flash -> Configuration
Выбираем Erase Code Flash -> By Power off
Нажимаем кнопку Apply
Снова загружаем прошивку Download
Правильным результатом в Terminal должно появится сообщение Hello World!!!
Ну и конечно, как же без примера морганием лампочкой
Blink
#include "debug.h"
void GPIO_Toggle_INIT(void){
GPIO_InitTypeDefGPIO_InitStructure = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_30MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
}
int main(void){
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
SystemCoreClockUpdate();
Delay_Init();
GPIO_Toggle_INIT();
while(1){
Delay_Ms(1000);
GPIO_WriteBit(GPIOD, GPIO_Pin_6, Bit_SET);
Delay_Ms(1000);
GPIO_WriteBit(GPIOD, GPIO_Pin_6, Bit_RESET);
}
}
Инициализируем пин D6. В основном потоке зажигаем, тушим каждую секунду
Результат
Некоторые заметки
1. Утилита WCH-LinkUtility поможет установить режим, в котором будет работать программатор, стереть микроконтроллер и другие дополнительные настройки
2. Инициализация пинов на микроконтроллере: GPIO_Pin_6 – 6 пин, GPIO_Pin_1 – 1 пин, GPIOD – пины PD, GPIOC – пины PC, GPIOA – пины PA
3. Пины можно менять местами по определенным правилам. Искать по ключевому слову GPIO_PinRemapConfig
Вывод
Очень интересная недорогая плата. В следующей статье расскажу, как подключить библиотеку с кучей примеров ch32v003fun к MRS. Подписывайся!