- /********************************** (C) COPYRIGHT *******************************
- * File Name : main.c
- * Author : WCH
- * Version : V1.0.0
- * Date : 2021/06/06
- * Description : Main program body.
- *********************************************************************************
- * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
- * Attention: This software (modified or not) and binary are used for
- * microcontroller manufactured by Nanjing Qinheng Microelectronics.
- *******************************************************************************/
- /*
- *@Note
- USART Print debugging routine:
- USART1_Tx(PA9).
- This example demonstrates using USART1(PA9) as a print debug port output.
- */
- #include "debug.h"
- /* Global typedef */
- /* Global define */
- #define RX_BUF_SIZE 512
- #define TX_BUF_SIZE 512
- #define USART_MODE_DMA 0
- /* Global Variable */
- void USART2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
- void SysTick_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
- void USART2_Init(void);
- void DMA_INIT(void);
- void SYSTICK_Init_Config(u_int64_t ticks);
- uint8_t g_usart2RxBuf[RX_BUF_SIZE] = {0};
- uint8_t g_usart2TxBuf[TX_BUF_SIZE] = {0};
- uint16_t g_usart2RxCnt = 0;
- uint16_t g_usart2TxCnt = 0;
- uint8_t g_usart2SendOK = 1;
- volatile uint8_t g_usart2RecvOK = 0;
- uint8_t g_rxTimeOut = 10;
- /*********************************************************************
- * @fn main
- *
- * [url=home.php?mod=space&uid=247401]@brief[/url] Main program.
- *
- * [url=home.php?mod=space&uid=266161]@return[/url] none
- */
- int main(void)
- {
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- SystemCoreClockUpdate();
- Delay_Init();
- USART_Printf_Init(115200);
- printf("SystemClk:%d\r\n",SystemCoreClock);
- printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
- SYSTICK_Init_Config((SystemCoreClock / 1000)-1);
- #if USART_MODE_DMA
- DMA_INIT();
- #else
- #endif
- USART2_Init();
- #if USART_MODE_DMA
- USART_DMACmd(USART2, USART_DMAReq_Tx | USART_DMAReq_Rx, ENABLE);
- #else
- #endif
- while(1)
- {
- if (g_usart2RecvOK) {
- g_usart2RecvOK = 0;
- printf("recved data:\r\n");
- for(uint16_t i = 0;i< g_usart2RxCnt;i++) {
- printf("%c",g_usart2RxBuf[i]);
- }
- g_usart2RxCnt = 0;
- printf("\r\n");
- }
- }
- }
- /*********************************************************************
- * @fn USART2_Init
- *
- * @brief Initializes the USART2 peripheral.
- *
- * @return none
- */
- void USART2_Init(void) {
- GPIO_InitTypeDef GPIO_InitStructure = {0};
- USART_InitTypeDef USART_InitStructure = {0};
- NVIC_InitTypeDef NVIC_InitStructure = {0};
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
- /* USART2 TX-->A.2 RX-->A.3 */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOA, &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(USART2, &USART_InitStructure);
- #if USART_IDLE_RECV_MODE
- USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);
- #else
- USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
- #endif
- NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- USART_Cmd(USART2, ENABLE);
- }
- /*********************************************************************
- * @fn DMA_INIT
- *
- * @brief Configures the DMA for USART2 & USART3.
- *
- * @return none
- */
- void DMA_INIT(void)
- {
- DMA_InitTypeDef DMA_InitStructure = {0};
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
- DMA_DeInit(DMA1_Channel7);
- DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART2->DATAR); /* USART2->DATAR:0x40004404 */
- DMA_InitStructure.DMA_MemoryBaseAddr = (u32)g_usart2TxBuf;
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
- DMA_InitStructure.DMA_BufferSize = TX_BUF_SIZE;
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
- DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
- DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
- DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
- DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
- DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
- DMA_Init(DMA1_Channel7, &DMA_InitStructure);
- DMA_DeInit(DMA1_Channel6);
- DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART2->DATAR);
- DMA_InitStructure.DMA_MemoryBaseAddr = (u32)g_usart2RxBuf;
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
- DMA_InitStructure.DMA_BufferSize = RX_BUF_SIZE;
- DMA_Init(DMA1_Channel6, &DMA_InitStructure);
- }
- void USART2_Send_Data(uint8_t *data,uint16_t size) {
- while(!g_usart2SendOK);
- USART_SendData(USART2, *data++);
- g_usart2SendOK = 0;
- }
- /*********************************************************************
- * @fn USART2_IRQHandler
- *
- * @brief This function handles USART2 global interrupt request.
- *
- * @return none
- */
- void USART2_IRQHandler(void)
- {
- if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
- {
- USART_ClearFlag(USART2,USART_FLAG_RXNE);
- if(g_usart2RxCnt > RX_BUF_SIZE) {
- g_usart2RxCnt = 0;
- } else {
- g_rxTimeOut = 1;
- g_usart2RxBuf[g_usart2RxCnt++] = USART_ReceiveData(USART2);
- }
- }
- }
- /*********************************************************************
- * @fn SYSTICK_Init_Config
- *
- * @brief SYSTICK_Init_Config.
- *
- * @return none
- */
- void SYSTICK_Init_Config(u_int64_t ticks)
- {
- SysTick->SR &= ~(1 << 0);//clear State flag
- SysTick->CMP = ticks;
- SysTick->CNT = 0;
- SysTick->CTLR = 0xF;
- NVIC_SetPriority(SysTicK_IRQn, 15);
- NVIC_EnableIRQ(SysTicK_IRQn);
- }
- /*********************************************************************
- * @fn SysTick_Handler
- *
- * @brief SysTick_Handler.
- *
- * @return none
- */
- void SysTick_Handler(void)
- {
- if(SysTick->SR == 1)
- {
- SysTick->SR = 0;//clear State flag
- if (g_rxTimeOut) {
- g_rxTimeOut--;
- if (!g_rxTimeOut)
- {
- g_usart2RecvOK = 1; //一帧接收完成
- }
- }
- }
- }
2、下载验证
1)串口助手设置100ms定时发送
接收和发送都为59条数据
2)串口助手设置5ms定时发送
波特率为115200 bit/s 以一个起始位、一个停止位计算 传输一个字节;
传输1个bit位需要 1/115200 = 8.6805us;
传输10bit = 86.805us; 那么两个字节之间的间隔为一个停止位和起始位
36个字节传输需要:86.805*36 = 3.125ms
再加上每次1ms的延时,以及printf的执行,会导致有些打印出来,因此只能搜索is来统计数据
串口中断处理程序
综上:间隔100ms和间隔5ms发送和接收都是没有问题,可见CH32V307上手还是很快的,直接参考例程即可上手,快速开发。