南京沁恒的,我们公司的F103全部换成他家的了,价格便宜直接替换ST,供电电压比ST宽,C6T6就带DAC,但是这些国产厂家有个普遍的问题,就是模拟功能的性能太差,如DAC和ADC
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)
{
}
}
图片待补充
南京沁恒的,我们公司的F103全部换成他家的了,价格便宜直接替换ST,供电电压比ST宽,C6T6就带DAC,但是这些国产厂家有个普遍的问题,就是模拟功能的性能太差,如DAC和ADC
刚从沁恒官网入手一块CH32V307开发板。
200字以内,仅用于支线交流,主线讨论请采用回复功能。