はじめに
シリアル通信を試しました
注意点
SWIOだけではシリアル通信できません。
WCH-LinkEのRXとCH32V003F4P6のUTX(pin2,PD5)を接続する必要があります。
接続
3.3V GND SWIO(PD1) TX(PD5)の4本です。
プログラム
サンプルがほぼそのままで動作しました。楽〜C:\Users\USERNAME\Downloads\ch32v003fun\examples\uart_tx_dma\uart_tx_dma.c
ch32v003funをWindowsに構築しCH32V003F4P6でLチカ | atooshi-noteでch32v003funをダウンロードした場所と同じです。
接続してポートを認識しており(COM7でした)、teratermで通信を確認しました。
/*
* This example uses DMA for the UART to transfer the "Hello World!\r\n" string
* once per second. Connect a UART Rx pin to D5, flash the example, setup your
* uart for 115200n1 and the messages should appear
シリアル通信のチェック
*/
#include "ch32v003fun.h"
// Set UART baud rate here
#define UART_BR 115200
// LED on D6 (nanoCH32V003 board)
// #define LED_PIN 6
#define LED_PIN 4 // ch32v003f4p6のdevelopmetboard
// DMA transfer completion interrupt. It will fire when the DMA transfer is
// complete. We use it just to blink the LED
__attribute__((interrupt)) __attribute__((section(".srodata")))
void DMA1_Channel4_IRQHandler(void)
{
// Clear flag
DMA1->INTFCR |= DMA_CTCIF4;
// Blink LED
GPIOD->OUTDR ^= 1<<LED_PIN;
}
static void led_setup(void)
{
RCC->APB2PCENR = RCC_APB2Periph_GPIOD;
GPIOD->CFGLR =
((GPIO_CNF_IN_PUPD)<<(4*1)) | // Keep SWIO enabled.
(GPIO_Speed_2MHz | GPIO_CNF_OUT_PP)<<(4*LED_PIN);
// LED ON
GPIOD->BSHR = 1<<LED_PIN;
}
static void uart_setup(void)
{
// Enable UART and GPIOD
RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_USART1;
// Push-Pull, 10MHz Output on D5, with AutoFunction
GPIOD->CFGLR = (GPIOD->CFGLR & ~(0xF<<(4*5))) |
((GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF)<<(4*5));
// Setup UART for Tx 8n1
USART1->CTLR1 = USART_WordLength_8b | USART_Parity_No | USART_Mode_Tx;
USART1->CTLR2 = USART_StopBits_1;
// Enable Tx DMA event
USART1->CTLR3 = USART_DMAReq_Tx;
// Set baud rate and enable UART
USART1->BRR = ((FUNCONF_SYSTEM_CORE_CLOCK) + (UART_BR)/2) / (UART_BR);
USART1->CTLR1 |= CTLR1_UE_Set;
}
static void dma_uart_setup(void)
{
// Enable DMA peripheral
RCC->AHBPCENR = RCC_AHBPeriph_SRAM | RCC_AHBPeriph_DMA1;
// Disable channel just in case there is a transfer in progress
DMA1_Channel4->CFGR &= ~DMA_CFGR1_EN;
// USART1 TX uses DMA channel 4
DMA1_Channel4->PADDR = (uint32_t)&USART1->DATAR;
// MEM2MEM: 0 (memory to peripheral)
// PL: 0 (low priority since UART is a relatively slow peripheral)
// MSIZE/PSIZE: 0 (8-bit)
// MINC: 1 (increase memory address)
// CIRC: 0 (one shot)
// DIR: 1 (read from memory)
// TEIE: 0 (no tx error interrupt)
// HTIE: 0 (no half tx interrupt)
// TCIE: 1 (transmission complete interrupt enable)
// EN: 0 (do not enable DMA yet)
DMA1_Channel4->CFGR = DMA_CFGR1_MINC | DMA_CFGR1_DIR | DMA_CFGR1_TCIE;
// Enable channel 4 interrupts
NVIC_EnableIRQ(DMA1_Channel4_IRQn);
}
static void dma_uart_tx(const void *data, uint32_t len)
{
// Disable DMA channel (just in case a transfer is pending)
DMA1_Channel4->CFGR &= ~DMA_CFGR1_EN;
// Set transfer length and source address
DMA1_Channel4->CNTR = len;
DMA1_Channel4->MADDR = (uint32_t)data;
// Enable DMA channel to start the transfer
DMA1_Channel4->CFGR |= DMA_CFGR1_EN;
}
int main(void)
{
static const char message[] = "Hello World!!!\r\n";
SystemInit();
led_setup();
uart_setup();
dma_uart_setup();
while (1)
{
dma_uart_tx(message, sizeof(message) - 1);
Delay_Ms(1000);
}
}
参考
CH32V003をArduinoで使う: DJ HIGO オフィシャルブログ
以上:)