文号
929066
阅读
6230
回复
3
收藏
0
CH32V307单片机学习记录
2024/02/05
IP:北京

CH32V307 是国产32bit单片机

手中有块CH32V307的开发板,开发板自带烧录器和USB转串口调试,以此作为学习和的平台;

软件开发环境IDE 使用的是MounRiver Studio

实验包括了,GPIO输出高低电平、DMA模式的内存复制、DMA中断实验

查看芯片手册 使用寄存器和库函数混合进行编程、使用寄存器是为了对单片机有更深的了解;

DMA模式,从一个数组复制到另一个数组的实验,产生中断;

主要代码如下

配置两个IO作为输出口 PC0 和PC1 通过示波器采集电平波形,用来观察时间间隔

void regMode_IO_Init()
{
    RCC->APB2PCENR |= RCC_APB2Periph_GPIOC; //配置 APB2 外设时钟使能寄存器   使能GPIOC 模块时钟
    GPIOC->CFGLR |= GPIO_CFGLR_MODE0;       //11 输出模式  50MHz
    GPIOC->CFGLR &= ~GPIO_CFGLR_CNF0;       //00 推挽输出模式

    GPIOC->CFGLR |= GPIO_CFGLR_MODE1;       //11 输出模式  50MHz
    GPIOC->CFGLR &= ~GPIO_CFGLR_CNF1;       //00 推挽输出模式


}

DMA使用了 DMA1的3通道 、开启DMA通道3中断、开启半传输中断和传输结束中断

void regMode_DMA1_CH3_Init()
{
    RCC->AHBPCENR |= RCC_AHBPeriph_DMA1;    //配置 AHB 外设时钟使能寄存器   使能DMA1 模块时钟

    NVIC_EnableIRQ(DMA1_Channel3_IRQn);

    //配置 DMA1 通道3 配置寄存器
    DMA1_Channel3->CFGR |= DMA_CFGR3_TCIE;   //传输完成中断使能控制
    DMA1_Channel3->CFGR |= DMA_CFGR3_HTIE;   //半传输   中断使能控制

    DMA1_Channel3->CFGR &= ~DMA_CFGR3_DIR;   //从外设读  0
    DMA1_Channel3->CFGR |= DMA_CFGR3_PINC;   //使能外设地址增量递增操作
    DMA1_Channel3->CFGR |= DMA_CFGR3_MINC;   //使能内存地址增量递增操作
    DMA1_Channel3->CFGR |= DMA_CFGR3_PSIZE_1;//外设地址数据宽度设置 32bit
    DMA1_Channel3->CFGR |= DMA_CFGR3_MSIZE_1;//存储器宽度32bit
    DMA1_Channel3->CFGR |= DMA_CFGR3_MEM2MEM;
    //配置 DMA1 通道3 配置寄存器   结束

    DMA1_Channel3->PADDR = (u32)SRC_BUF;    //配置 DMA1 通道 3 外设地址寄存器
    DMA1_Channel3->MADDR = (u32)DST_BUF;    //配置 DMA1 通道 3 存储器地址寄存器
    DMA1_Channel3->CNTR = Buf_Size;         //配置 DMA1 通道 3 传输数据数目寄存器

    DMA1->INTFCR |= DMA1_FLAG_TC3;          //配置DMA1 中断标志清除寄存器
    DMA1_Channel3->CFGR |= DMA_CFGR1_EN;    //配置DMA1 通道3 配置寄存器      使能通道3
}

DMA1 中断处理函数

void DMA1_Channel3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));

void DMA1_Channel3_IRQHandler(void)
{
    if((DMA1->INTFR &= DMA_TCIF3) != RESET)      //判断中断标志
    {
        DMA1->INTFCR |= DMA_CTCIF3;              //清除中断标志
        GPIOC->OUTDR &= ~GPIO_OUTDR_ODR0;
    }
    if((DMA1->INTFR &= DMA_HTIF3) != RESET)      //判断中断标志
    {
        DMA1->INTFCR |= DMA_CHTIF3;              //清除中断标志
        GPIOC->OUTDR &= ~GPIO_OUTDR_ODR1;
    }

}
void DMA_MEM2MEM()
{
    u8 i = 0;

    printf("0 SRC_BUF:\r\n");
    for(i = 0; i < Buf_Size; i++)
    {
        printf("0x%08x\r\n", SRC_BUF[i]);
    }

    printf("0 DST_BUF:\r\n");
    for(i = 0; i < Buf_Size; i++)
    {
        printf("0x%08x\r\n", DST_BUF[i]);
    }

    regMode_DMA1_CH3_Init();

    while(DMA1->INTFR & DMA_TCIF3 == RESET) //通道3 的传输完成标志
    {
    }

    Flag = BufCmp(SRC_BUF, DST_BUF, Buf_Size);
    if(Flag == 0)
    {
        printf("DMA Transfer Fail\r\n");
    }
    else
    {
        printf("DMA Transfer Success\r\n");
    }

    printf("SRC_BUF:\r\n");
    for(i = 0; i < Buf_Size; i++)
    {
        printf("0x%08x\r\n", SRC_BUF[i]);
    }

    printf("DST_BUF:\r\n");
    for(i = 0; i < Buf_Size; i++)
    {
        printf("0x%08x\r\n", DST_BUF[i]);
    }
    while(1)
    {
    }
}

main 函数

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() );
    printf("This is printf example\r\n");

    regMode_IO_Init();
    GPIOC->OUTDR |= GPIO_OUTDR_ODR0;
    GPIOC->OUTDR &= ~GPIO_OUTDR_ODR0;

    GPIOC->OUTDR |= GPIO_OUTDR_ODR0;
    GPIOC->OUTDR |= GPIO_OUTDR_ODR1;

    GPIOC->OUTDR &= ~GPIO_OUTDR_ODR0;
    GPIOC->OUTDR &= ~GPIO_OUTDR_ODR1;

    GPIOC->OUTDR |= GPIO_OUTDR_ODR0;
    GPIOC->OUTDR |= GPIO_OUTDR_ODR1;

    regMode_DMA1_CH3_Init();
    DMA_MEM2MEM();

    while(1)
    {

    }
}

图片待补充

笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的