CH32V103有7个定时器,
1个16位高级定时器,包含通用定时器功能,并自带死区控制和紧急刹车,提供用于电机控制的PWM,
3个16位通用定时器,提供多达4个用于输入捕获/输出比较/PWM/脉冲计数的通道和增量编码器输入,
2个看门狗定时器(独立和窗口型),
系统时间定时器:64位自增型计数器.
我手中的DHT11温湿度传感器要一秒以上才能读取一次,所以就要用一个定时器来定时1.3秒读取一次,详细配置如下:
/*
* TIM2用作DHT11更新时基
* 1.3秒更新一次
*/
void TIM2_Base_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE );
TIM_TimeBaseInitStructure.TIM_Period = 13000-1;//计数值
TIM_TimeBaseInitStructure.TIM_Prescaler = 7200-1;//分频值
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit( TIM2, &TIM_TimeBaseInitStructure);
TIM_ITConfig(TIM2,TIM_IT_Update, ENABLE);//配置更新中断
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
配置起来不难和ST差不多,不同点在中断控制器上.对比如下:
CH32V103C8T6,沁恒微电子的RSIC-V架构32位通用型MCU,支持IMAC指令集,内置快速可编程中断控制器(PFIC– Programmable Fast Interrupt Controller)。PFIC是该公司自研设计的结构,所以用法上有独自的特色。
PFIC 控制器
44+3个可单独屏蔽中断,每个中断请求都有独立的触发和屏蔽位、状态位
提供一个不可屏蔽中断NMI
2级嵌套中断进入和退出硬件自动压栈和恢复,无需指令开销
4路可编程快速中断通道,自定义中断向量地址
CH32V103C8T6在中断写法上,书写一个中断服务函数时,需要为其声明中断属性,即在函数名前添加__attribute__((interrupt()))
,这样IDE在进行编译时,会将此函数体识别为中断服务函数,主动添加“压栈出栈”处理及中断返回指令。例如:在ch32v10x_it.c的顶部有如下写法.
void NMI_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void HardFault_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void EXTI0_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void TIM2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
中断服务函数中只要置位即可,处理交给while.
/*******************************************************************************
* Function Name : TIM2_IRQHandler
* Description : This function handles TIM2 Handler.
* Input : None
* Return : None
*******************************************************************************/
void TIM2_IRQHandler(void)
{
if(TIM_GetFlagStatus(TIM2, TIM_IT_Update)!= RESET){
DHT11_Updata = 1;
}
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
然后主程序去处理就好了
/*******************************************************************************
* Function Name : main
* Description : Main program.
* Input : None
* Return : None
*******************************************************************************/
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
Delay_Init();
USART_Printf_Init(115200);
printf("SystemClk:%d\r\n",SystemCoreClock);
//初始化
GPIO_Toggle_INIT();
EXTI0_INT_INIT();
SPI1_Init();
DHT11_Init();
ADC_Function_Init();
DMA_Tx_Init();
OLED_Init();
TIM2_Base_Init();
Opening_page();//启动页
OLED_Clear();
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //启动ADC转换
TIM_Cmd(TIM2,ENABLE); //使能定时器,1.3秒中断一次
while(1)
{
// GPIO_WriteBit(GPIOA, GPIO_Pin_0, (i==0) ? (i=Bit_SET):(i=Bit_RESET));
if(exti0_status == 0) //光敏电阻感到光
{
OLED_DisPlay_On(); //开启OLED
TIM_Cmd(TIM2,ENABLE);
if(DHT11_Updata == 1)
{ /*调用DHT11_Read_TempAndHumidity读取温湿度,若成功则输出该信息*/
if( DHT11_Read_TempAndHumidity ( & DHT11_Data ) == SUCCESS)
{
Main_page(); //成功显示温湿度,ADC电压值
}else
{
OLED_Clear();
DHT_ERR(); //失败显示错误
}
DHT11_Updata = 0;
}
MQ_7_Vol();
}else
{
OLED_DisPlay_Off(); //关闭oled
TIM_Cmd(TIM2,DISABLE); //关闭定时器
}
Delay_Ms(150);
}
}
这里TIM2只是用作了DHT11更新时基,其他神马和ST差不多,唯一不同点便是这中断的写法了.
感谢分享!
如果代码结构基本相同是不是可以使用ST的cubemx生产配置代码 然后再加入到CH32V103的工程里来
引用: littleshrimp 发表于 2021-3-4 15:58 如果代码结构基本相同是不是可以使用ST的cubemx生产配置代码 然后再加入到CH32V103的工程里来
要更换驱动文件,还要对比st的寄存器是否相同,另外中断管理器用的不一样需要更改.但可以和自家的ch32f103共用一套程序.
引用: 火辣西米秀 发表于 2021-3-1 23:09 PFIC 这种结构的优势是什么
沁恒加入了硬件压栈出栈,其他和nvic差不多,大概GPS和GNSS的区别吧!