当前位置: 首页 > news >正文

建设银行办信用卡网站首页杭州昨晚发生大事了

建设银行办信用卡网站首页,杭州昨晚发生大事了,yy直播下载,广告推广渠道5 EXIT外部中断 [toc] 注#xff1a;笔记主要参考B站 江科大自化协 教学视频“STM32入门教程-2023持续更新中”。 注#xff1a;工程及代码文件放在了本人的Github仓库。 5.1 STM32中断系统 图5-1 中断及中断嵌套示意图 中断 是指在主程序运行过程中#xff0c;出现了特定…5 EXIT外部中断 [toc] 注笔记主要参考B站 江科大自化协 教学视频“STM32入门教程-2023持续更新中”。 注工程及代码文件放在了本人的Github仓库。 5.1 STM32中断系统 图5-1 中断及中断嵌套示意图 中断 是指在主程序运行过程中出现了特定的中断触发条件中断源使得CPU暂停当前正在运行的程序转而去处理中断程序处理完成后又返回原来被暂停的位置继续运行。使用中断系统可以极大程度地提高程序的效率就像是给自己定闹钟可以不用担心错过时间而可以安心睡觉。在这个过程中有如下概念 中断优先级当有多个中断源同时申请中断时CPU会根据中断源的轻重缓急进行裁决优先响应更加紧急的中断源。中断嵌套当一个中断程序正在运行时又有新的更高优先级的中断源申请中断CPU再次暂停当前中断程序转而去处理新的中断程序处理完成后依次进行返回。 stm32的F1系列总共有68个可屏蔽中断通道中断源包含EXTI、TIM、ADC、USART、SPI、I2C、RTC等多个外设。所有的中断使用 嵌套向量中断控制器NVIC 统一管理中断每个中断通道都拥有16个可编程的优先等级可对优先级进行分组进一步设置抢占优先级和响应优先级。具体到某一个型号的芯片可能不会有这么多中断具体需要查看的芯片手册。下面是手册中的中断向量表节选 图5-2 中断向量表示意图 地址最后一列存储中断地址这个地址列表也称为 中断向量表。因为程序中的中断函数地址由编译器来分配所以中断函数地址不固定。但是由于硬件的限制中断跳转只能跳转到固定的地址执行程序。所以为了让硬件能跳转到一个地址不固定的中断函数里就需要在内存中定义一个固定的地址列表。当中断发生后首先跳转到这个固定的地址列表编译器会在这个固定的位置加上一条跳转到中断函数的代码于是中断跳转就可以跳转到任意位置了。C语言编程无需关注中断向量表汇编语言需要。 图5-3 NVIC的基本结构 上图给出了 嵌套向量中断控制器NVIC 的基本结构示意图。在stm32中NVIC用于统一管理中断和分配中断优先级属于内核外设是CPU的小助手可以让CPU专注于运算。从上图可以看出 NVIC有很多输入口每个都代表一个中断线路如EXIT、TIM、ADC等。每个中断线路上的斜杠n表示n条线因为一个外设可能会同时占用多个中断通道。NVIC只有一个输出口通过中断优先级确定中断执行的顺序。 NVIC的中断优先级 由优先级寄存器的4位二进制十进制0~15决定这4位可以进行切分分为 高n位 的抢占优先级和 低(4-n)位 的响应优先级。抢占优先级高的可以 中断嵌套响应优先级高的可以 优先排队抢占优先级和响应优先级均相同的按 中断号 排队。这个中断号就是指中断向量表的第二列“优先级”。 用医院的叫号系统来举例子。假设医生正在给某个病人看病外面还有很多病人排队 新来的病人 抢占优先级高 就相当于直接进屋打断医生给自己看病。新来的病人 响应优先级高 就相当于不打扰医生但直接插队排在队伍的第一个。 表5-1 NVIC优先级的分组方式 分组方式抢占优先级响应优先级分组0n00位取值为04位取值为0~15分组1n11位取值为0~13位取值为0~7分组2n22位取值为0~32位取值为0~3分组3n33位取值为0~71位取值为0~1分组4n44位取值为0~150位取值为0 注NVIC是内核外设更多关于NVIC的介绍参考“STM32F10xxx Cortex-M3编程手册”。 NVIC中断分组的配置寄存器在SCB_AIRCR中PRIGROUP这三位就是用于配置中断分组的。 5.2 STM32外部中断EXTI 图5-4 外部中断向量表 中断系统是管理和执行中断的逻辑结构外部中断是众多能产生中断的外设之一而EXTI就是其中之一上图给出了外部中断的中断向量表。EXTIExtern Interrupt外部中断 可以监测指定GPIO口的电平信号当其指定的GPIO口产生电平变化时EXTI将立即向NVIC发出中断申请经过NVIC裁决后即可中断CPU主程序使CPU执行EXTI对应的中断程序。 支持的触发方式上升沿/下降沿/双边沿/软件触发。支持的GPIO口所有GPIO口但相同的Pin不能同时触发中断。通道数16个GPIO_Pin外加PVD输出、RTC闹钟、USB唤醒、以太网唤醒。 注后面这四个功能是为了实现一些特殊的功能比如想实现某个时间让stm32退出停止模式由于外部中断可以在低功耗模式的停止模式下唤醒stm32就可以在GPIO口上连接一个RTC时钟作为外部中断。 触发响应方式中断响应/事件响应。 注中断响应就是正常的中断流程申请中断让CPU执行中断函数事件响应就是外部中断发生时不把外部中断信号给CPU而是选择触发一个事件将这个信号通向其他外设来触发其他外设的操作可以实现外设之间的联合工作。 图5-5 EXTI的基本结构 最左侧GPIO口的外设每个外设都有16个引脚。AFIO中断引脚选择本质上就是数据选择器从前面16*n个引脚中选择16根端口号不重复的引脚出来连接到后面的EXTI通道中。在STM32中AFIO主要完成两个任务复用功能引脚重映射、中断引脚选择。下面是中断引脚选择的AFIO示意图 PVD、RTC、USB、ETH四个特殊功能的外设。EXTI边沿检测及控制20个输入通道、两类输出。一类输出到NVIC中并且将这20路输出的95、1510路外部中断合并在一起以节省通道另一类输出到其他外设直接就是20路输出。 注上面这个EXTI的基本结构也是编写代码时的主要参考图 图5-6 EXTI框图方向为从右向左-stm32F10系列参考手册 上图给出了参考手册中的EXTI框图。基本逻辑与“EXTI的基本结构”中所述相同另外还有一些细节 边沿检测电路软件中断事件寄存器这个几个进行或门输出便可以实现“上升沿/下降沿/双边沿/软件触发”这四种触发方式。请求挂起寄存器相当于一个中断标志位通过读取该寄存器可以判断是哪个通道触发的中断。中断屏蔽寄存器/事件屏蔽寄存器相当于开关只有置1中断信号才能继续向左走。脉冲发生器产生一个电平脉冲用于触发其他外设的动作。 最后一个问题到底什么样的设备需要用到外部中断呢 答对于stm32来说若想获取一个由外部驱动的很快的突发信号就需要外部中断。 如旋转编码器平常不会有什么变化但是一旦拧动时会产生一段时间变化很快的突发信号就需要stm32能在短时间内快速读取并处理掉这个数据。再如红外遥控接收头平常也不会有什么变化但是一旦接收到信号时这个信号也是转瞬即逝的。但是不推荐按键使用外部中断。因为外部中断不能很好的处理按键抖动和松手检测的问题所以要求不高时还是建议在主函数内部循环读取。 5.2 旋转编码器介绍 对射式红外传感器就是一种通用传感器模块已经在第三节“GPIO通用输入输出口”中介绍过不再赘述。本实验只介绍旋转编码器。 旋转编码器 是一种用来测量位置、速度或旋转方向的装置当其旋转轴旋转时其输出端可以输出与旋转速度和方向对应的方波信号读取方波信号的频率和相位信息即可得知旋转轴的速度和方向。 图5-7 旋转编码器实物图 如上图旋转编码器主要有三种类型光栅式 / 机械触点式 / 霍尔传感器式。下面是这三种形式的介绍 光栅式老款鼠标配合对射式红外传感器使用在旋转过程中光栅编码盘会不断地 阻挡/透过 红外射线于是模块便会输出高低电平交替的方波方波的频率便代表了旋转速度。缺点是只有一路输出无法判断转动方向。机械触点式内部使用机械触点检测通断A口和B口输出的方波正交具体看下面的介绍。当然也有机械触点式编码器可以一个引脚输出速度信息、一个引脚输出旋转方向信息。霍尔传感器式直接附在电机后面的编码器中间是一个圆形磁铁旋转时两侧的霍尔传感器便可输出正交的方波信号。独立的编码器元件输入轴转动时输出便有波形。 注触点式不适合高速旋转的场景常用于音量调节。非接触形式的电机可以用于电机测速。 图5-8 机械触点式旋转编码器-实物拆解 图片右侧是旋转编码器的旋钮可以看到下面是一圈可以导电的金属片。中间有一个大的按键开关结构也可以检测通断但是该旋转编码器模块没有使用到该功能。左右两组金属触点。内部实际的连线如红线标注C口接地于是旋钮在旋转过程中就可以使A口、B口输出高低交替的方波。方波频率表示旋转速度。A口、B口配合旋钮可以产生相位相差90°的方波称为正交信号。顺时针旋转A口相位超前逆时针旋转B口相位超前。 图5-9 机械触点式旋转编码器-硬件电路 R1、R2上拉电阻。R3、R4输出限流电阻防止引脚电流过大。C1、C2滤波电容滤除高频不稳定纹波。 注C口已经默认接地只需关心A口、B口的高低变化及相位差即可。 5.3 实验对射式红外传感器计次 需求利用stm32的外部中断对 对射式红外传感器 产生的下降沿进行计次。 图5-10 对射式红外传感器计次-接线图 图5-11 对射式红外传感器计次-代码调用 代码展示OLED.h、OLED.c、OLED_Font.h代码见第四节“OLED调试工具”本节省略。 - main.c #include stm32f10x.h // Device header #include OLED.h #include CountSensor.hint main(void){//OLED初始化OLED_Init();OLED_ShowString(1,1,Neg-edge:);OLED_ShowNum(2,1,0,5); CountSensor_Init();while(1){OLED_ShowNum(2,1,CountSensor_Get(),5); }; } - CountSensor.h #ifndef __COUNTERSENSOR_H #define __COUNTERSENSOR_Hvoid CountSensor_Init(void); uint16_t CountSensor_Get(void);#endif - CountSensor.c #include stm32f10x.h // Device headeruint16_t CountSensor_Count 0;//中断触发次数/*** brief 对射式红外传感器起初始化-PB14*/ void CountSensor_Init(void){//EXIT初始化//1. 开启GPIO、AFIO的外设时钟EXTI和NVIC的时钟是一直打开的RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//2. 配置GPIO-PB14上拉输入GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPD;//上拉输入GPIO_InitStructure.GPIO_Pin GPIO_Pin_14;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOB, GPIO_InitStructure);//3. 配置AFIO库函数在GPIO中GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);//数据选择器//4. 配置NVICEXTI_InitTypeDef EXTI_InitStructure;EXTI_InitStructure.EXTI_Line EXTI_Line14;EXTI_InitStructure.EXTI_LineCmd ENABLE;EXTI_InitStructure.EXTI_Mode EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger EXTI_Trigger_Falling;//下降沿触发EXTI_Init(EXTI_InitStructure);//5. 配置NVIC库函数在misc.h文件中NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置中断的优先级分组每个工程只能出现一次NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel EXTI15_10_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority 1;NVIC_Init(NVIC_InitStructure); }/*** brief 输出中断触发的次数* retvl 无符号16位整型范围0~65535*/ uint16_t CountSensor_Get(void){return CountSensor_Count; }//中断函数的名字从启动文件“stratup_stm32f10x_md”中来 //中断函数都是无参无返回值的 void EXTI15_10_IRQHandler(void){//中断标志位判断if(EXTI_GetITStatus(EXTI_Line14)SET){CountSensor_Count;EXTI_ClearITPendingBit(EXTI_Line14);//清除中断标志位} } 编程感想 下降沿触发移除遮挡触发。传感器无遮挡时DO输出低电平传感器有遮挡时DO输出高电平。所以放入遮挡意味着上升沿移除遮挡相当于下降沿。采用上升沿触发计数可能不准确下降沿触发计数准确。中断函数的名字从启动文件“stratup_stm32f10x_md”中来并且中断函数都是无参无返回值的。 5.4 实验旋转编码器计次 需求利用stm32的外部中断对旋转编码器的转动进行计次顺时针加、逆时针减并显示在OLED显示屏上。 图5-12 旋转编码器计次-接线图 图5-13 旋转编码器计次-代码调用除库函数以外 代码展示OLED.h、OLED.c、OLED_Font.h代码见第四节“OLED调试工具”本节省略。 - main.c #include stm32f10x.h // Device header #include OLED.h #include RotaryEncoder.hint main(void){//配置中断的优先级分组每个工程只能出现一次NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//OLED显示屏初始化OLED_Init();OLED_ShowString(1,1,RE_Count:);OLED_ShowSignedNum(2,1,0,5);//传感器初始化RotaryEncoder_Init();while(1){OLED_ShowSignedNum(2,1,RotaryEncoder_GetCount(),5);if(RotaryEncoder_GetChange()1) {OLED_ShowString(3,1,Clockwise. );}else if(RotaryEncoder_GetChange()-1){OLED_ShowString(3,1,anti-Clockwise.);}}; } - RotaryEncoder.h #ifndef __ROTARYENCODER_H #define __ROTARYENCODER_Hvoid RotaryEncoder_Init(void); int16_t RotaryEncoder_GetCount(void); int16_t RotaryEncoder_GetChange(void);#endif - RotaryEncoder.c #include stm32f10x.h // Device header//旋转编码器计次 int16_t RotaryEncoder_Count_cur 0; int16_t RotaryEncoder_Count_pre 0;/*** brief 旋转编码器Rotary Encoder初始化-A口PB0、B口PB1*/ void RotaryEncoder_Init(void){//开启外设时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//配置GPIOB-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库函数在GPIO中GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);//配置EXTIEXTI_InitTypeDef EXTI_InitStructure;EXTI_InitStructure.EXTI_Line EXTI_Line0 | EXTI_Line1;EXTI_InitStructure.EXTI_LineCmd ENABLE;EXTI_InitStructure.EXTI_Mode EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger EXTI_Trigger_Falling;//下降沿触发EXTI_Init(EXTI_InitStructure);//配置NVIC库函数在misc.h文件中NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel EXTI0_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority 1;NVIC_Init(NVIC_InitStructure);NVIC_InitStructure.NVIC_IRQChannel EXTI1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority 2;NVIC_Init(NVIC_InitStructure); }/*** brief 获取从程序复位开始的计次* retvl int16_t变量范围-32768~32767*/ int16_t RotaryEncoder_GetCount(void){return RotaryEncoder_Count_cur; }/*** brief 获取状态变化值* retvl int16_t变量-1表示逆时针转、0初始化状态、1表示顺时针转*/ int16_t RotaryEncoder_GetChange(void){return (RotaryEncoder_Count_cur - RotaryEncoder_Count_pre); }/*** brief A口下降沿中断函数*/ void EXTI0_IRQHandler(void){if(EXTI_GetITStatus(EXTI_Line0)SET){if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1)0){RotaryEncoder_Count_pre RotaryEncoder_Count_cur;RotaryEncoder_Count_cur--;//B口超前减计数}EXTI_ClearITPendingBit(EXTI_Line0);} }/*** brief B口下降沿中断函数*/ void EXTI1_IRQHandler(void){if(EXTI_GetITStatus(EXTI_Line1)SET){if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0)0){RotaryEncoder_Count_pre RotaryEncoder_Count_cur;RotaryEncoder_Count_cur;//A口超前加计数}EXTI_ClearITPendingBit(EXTI_Line1);} } 编程感想 管理Hardware文件夹。本次实验继承的是“OLED显示屏”实验的代码而非“对射式红外传感器计次”。猜测是因为驱动文件的命名不规范本人的实验文件均按照模块的英文名来命名。注意每个模块在使用的时候都要进行初始化。注意进入中断函数的时候要检查中断标志位退出的时候清零中断标志位。注意主函数和中断函数不要操控同一个硬件避免不必要的硬件冲突。中断函数一般执行简短快速的代码如操作中断标志位等。
http://www.hkea.cn/news/14367299/

相关文章:

  • 站长工具seo综合医院网站建设技术方案
  • net域名大网站交互设计专业就业前景
  • 网站收录降低重庆建设注册执业中心网站
  • 网站开发年度总结工作东圃手机网站制作费用
  • 做7寸照片的网站手机如何开发软件
  • 银川网站建设哪家价格低七牛备份wordpress
  • 沈阳网站制作的公司精准扶贫电商网站建设计划书
  • 如何自建网站 优帮云wordpress定时发布功能
  • 龙岗网站建设 信科网络网站后台怎么控制
  • 如何给自己网站做网站优化迈若网站建设
  • 房产交易网站开发网页设计尺寸怎么设计
  • 站长工具seo综合查询隐私查询南京房产网
  • 新手怎么用DW建设一个网站网站备案名称更改
  • 旅游网站开发 结束语html怎么做成网站
  • 福州网站制作公司营销网站免费正能量安全
  • 网站建设升级创意产品设计方案
  • 静态网站建设的技术运用wordpress改商城
  • 档案网站建设与知识管理基层组织建设部 网站
  • 网站建设维护工作wordpress主机记录
  • 国外网站设计公司国外设计师作品网站
  • 做游戏的网站有哪些合肥门户网站有哪些
  • 百度收录提交网站后多久收录网站开发的软件
  • 胶州哪家公司做网站吉林智能网站建设价格
  • 答题网站开发网站设计企业
  • 免费建站自助建站网站总体设计
  • 网站策划的工作要求绍兴公司做网站
  • 我英文网站建设铁门关网站建设
  • 交网站建设域名计入什么科目网站推广seo软件
  • 营销型网站建设价格是多少极客wordpress主题
  • 做网站商机app开发技术路线