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) { } }
图片待补充
时段 | 个数 |
---|---|
{{f.startingTime}}点 - {{f.endTime}}点 | {{f.fileCount}} |