赞
踩
型号:STM32F103
学习平台:bilibili江协科技的stm32教程
学习内容:EXIT外部中断、TIM定时中断、I2C协议、MCU6050
目录
1)基础理解:需要先理解中断系统,组成:①中断②中断优先级③中断嵌套
2)简述:
①EXIT外部中断,中断的一种,监测GPIO的电平信号,但该电平变化时,立即向NVIC发出中断申请,需要通过NVIC的裁决来中断CPU主程序,转向执行EXIT制定的中断程序
②触发方式:上升沿/下降沿/双边沿/软件触发
③支持所有GPIO口,但不同同时触发相同Pin的中断。
④触发响应方式:中断响应/事件响应
3)NVIC:
①简述:嵌套中断向量控制器,是内核外设,统一分配中断优先级和管理中断,EXIT需要通过NVIC来中断CPU。
②通俗理解:一个排队管理员,让大家(中断请求)排好队(按优先级排队),每次只能挑最前面(优先级最高)进去房间(CPU)
③结构:如图1,NVIC可以输入多种中断,如EXIT、TIM、ADC等等,最后通过优先级的机制,输出一个中断请求给CPU。
图1
④优先级分组:
抢占:中断嵌套
响应:优先排队
两者相同则按中断号排队
图2
1)代码:
①中断配置部分:
- void Encoder_Init(void)
- {
- //使能GPIOB与AFIO的时钟
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
-
- //用结构体配置GPIO口,此处我们用PB0与PB1,因为器件有两个相,以此来判断正反,所以利用两个中断
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
-
- //配置AFIO外部中断引脚选择,我们用的是0号与1号
- GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);
- GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);
-
- //用EXTI结构体来配置
- EXTI_InitTypeDef EXTI_InitStructure;
- EXTI_InitStructure.EXTI_Line = EXTI_Line0 | EXTI_Line1;//选择0与1号中断线
- EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能
- EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//外部中断模式
- EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;//上升沿
- EXTI_Init( &EXTI_InitStructure );
-
- //配置NVIC,中断优先级
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//分组2
- NVIC_InitTypeDef NVIC_InitStructure;
- NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//选择0号外部中断
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能,通道开启
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级设置1
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//响应优先级设置1
- NVIC_Init( &NVIC_InitStructure );
-
- NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;;//选择1号外部中断
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能,通道开启
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级设置1
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;//响应优先级设置1
- NVIC_Init( &NVIC_InitStructure );
-
- }
②中断函数部分:
- void EXTI0_IRQHandler(void)
- {
- if (EXTI_GetITStatus(EXTI_Line0) == SET)//判断正向的相位差中第二个相的中断标志位是否SET,既触发
- {
- if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)//判断正向的相位差中第一个相是否处于低电平,既利用相位差来计次,(详细的请看原视频,b站江协科技的stm32教程)
- {
- Encoder_Count ++;//计次加
- }
- EXTI_ClearITPendingBit(EXTI_Line0);//中断标志位清0
- }
- }
- void EXTI1_IRQHandler(void)
- {
- if (EXTI_GetITStatus(EXTI_Line1) == SET)//判断反向的相位差中第二个相的中断标志位是否SET,既触发
- {
- if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0)//判断反向的相位差中第一个相是否处于低电平,既利用相位差来计次
- {
- Encoder_Count --;//计次减
- }
- EXTI_ClearITPendingBit(EXTI_Line1);//中断标志位清0
- }
- }
2)实现结果:
①正向
②反向
1)简述:
①定时器是一个强大且复杂的外设,能对输入的时钟进行计数,但计数值累计至设定值时触发中断。(还有其他功能,如输出比较等等)
②具有16位计数器(即最大计数值为65536,实际代码写入为65535)、预分频器、自动重装寄存器的时基单元。
③分类
图1 定时器分类表
图2 基本定时器结构图
图3 定时中断基本结构
1)代码:
①定时器以及中断配置部分
- void Timer_Init(void)
- {
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//由于我们使用通用定时器,所以选择TIM2,而TIM2在总线APB1上,所以开启APB1的时钟
- TIM_InternalClockConfig(TIM2);//TIM2的时基单元由内部时钟驱动
-
-
- //配置时基单元,内部时钟频率为72MHZ,即每秒72M次计数,72M/7200 = 10000,分频后,每秒计数10000次,则计数10000次,时间为1秒。我们目的就是每秒触发一次中断。
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//用结构体初始化时基单元
- TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//配置分频值为1.即不分频
- TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//选择向上计数模式
- TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;//ARR配置自动重装值
- TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;//配置psc预分频器
- TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//不需要,先配置0
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
-
-
- TIM_ClearFlag(TIM2, TIM_FLAG_Update); //(先清除以下中断标志位,否则系统会自动在使能中断后,马上进行一次中断)
- TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//(配置时钟的中断为更新中断并且使能)
-
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置NVIC,选择分组2
- NVIC_InitTypeDef NVIC_InitStructure;
- NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
- NVIC_Init(&NVIC_InitStructure);
-
- TIM_Cmd(TIM2, ENABLE);
- }
-
②主函数部分
- int main(void)
- {
- OLED_Init();
- Timer_Init();
- OLED_ShowString(1, 1, "Num:");
-
-
- //OLED_Clear();
-
- while(1)
- {
- OLED_ShowNum(1, 5, Num, 5);
- OLED_ShowNum(2, 5, TIM_GetCounter(TIM2), 5);
- }
- }
-
- void TIM2_IRQHandler(void)
- {
- if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
- {
- Num ++;
- TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//每次中断后都让其清除标志位
- }
-
-
- }
2)结果显示
流程不难理解,但是要细究每一处的话,太难,二周目再进行彻底的剖析,现在主要偏向于应用。(没有模电基础,能上岸的话就进行二周目深入学习)
一种通信协议,其有两根通信线:SCL与SDA,为同步的半双工通信方式。带有数据应答,支持总线挂载多设备
暂无
6轴姿态传感器,可以用于需要检测/矫正姿态的场景。
测量X、Y、Z轴的加速度以及角速度,所以称为6轴(可以扩展到9轴,通过磁力计实现,9轴可以修正偏航问题)
暂无
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。