打印
[STM32F1]

stm32(F103c8t6)自学笔记

[复制链接]
楼主: t60yz
手机看帖
扫描二维码
随时随地手机跟帖
81
t60yz|  楼主 | 2023-11-22 11:35 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
和C51中的中断是一样的,只不过32的资源更加丰富;  

使用特权

评论回复
82
t60yz|  楼主 | 2023-11-22 11:35 | 只看该作者
1.2 中断系统内部机制(中断和异常向表)
         由于Stm32中断资源众多,所以这里的中断都是由NVIC统一管理。

左边需要执行的众多中断会根据分组和优先级排队,其中抢占优先级具有最高优先级(可直接由NVIC传入CPU,中断CPU正在执行的主程序或者中断),而响应优先级则具有插队排第一位的权限(优先级次于抢占优先级),当左边排队完成,NVIC会根据左边的排队决定当前该执行哪一个中断然后传给CPU(CPU不知道优先级逻辑,由NVIC处理,节约算力和IO口)

使用特权

评论回复
83
t60yz|  楼主 | 2023-11-22 11:35 | 只看该作者

使用特权

评论回复
84
t60yz|  楼主 | 2023-11-22 11:35 | 只看该作者
中断和异常向表,建议翻看手册;

使用特权

评论回复
85
t60yz|  楼主 | 2023-11-22 11:36 | 只看该作者

使用特权

评论回复
86
t60yz|  楼主 | 2023-11-22 11:36 | 只看该作者
1.3 EXTI简介
触发中断,中断响应是正常的流程,但是Stm32还提供了一种额外的中断处理:事件响应。

当选择触发事件响应,那么该中断信号将不会通过NVIC传入CPU,而是直接传给某一个外设并触发它。例如触发ADC模块‘触发DMA等。

总结:中断响应是正常的流程,引脚电平变化触发中断。事件响应不会触发中断,而是触发别的外设操作,属于外设之间的联合操作。

注意:相同的pin口的中断不能同时被触发,如PA0、PB0、PC0三个中断同时需要传入NVIC,但是最终只会有一个被传入。

在EXTI内部有对数据筛选处理的模块,最终只有指定的IO数据会传入NVIC,其它的会作为事件触发传给指定的外设。

使用特权

评论回复
87
t60yz|  楼主 | 2023-11-22 11:36 | 只看该作者

使用特权

评论回复
88
t60yz|  楼主 | 2023-11-22 11:36 | 只看该作者
1.4 EXTI机制

使用特权

评论回复
89
t60yz|  楼主 | 2023-11-22 11:36 | 只看该作者



使用特权

评论回复
90
t60yz|  楼主 | 2023-11-22 11:37 | 只看该作者
1.5 AFIO复用IO口

使用特权

评论回复
91
t60yz|  楼主 | 2023-11-22 11:37 | 只看该作者
2.点触式旋转编码器
2.1 结构原理

使用特权

评论回复
92
t60yz|  楼主 | 2023-11-22 11:37 | 只看该作者

使用特权

评论回复
93
t60yz|  楼主 | 2023-11-22 11:37 | 只看该作者

使用特权

评论回复
94
t60yz|  楼主 | 2023-11-22 11:37 | 只看该作者
2.2 代码实现(详细步骤说明)
该模块需要用到中断,如何实现呢?其实原理就是将模块IO口使能使其数据能够到达NVIC再到CPU就好了。

五个步骤:

1.打开对应IO口的RCC外设时钟(不打开IO口不能工作);

2.配置IGPO口的模式;

3.配置AFIO,使其选择我们要用的GPIO口,连接到EXTI;

4.配置EXTI模式,选择触发方式及响应方式(中断or事件);

5.配置NVIC,选择一个合适的中断优先级。

使用特权

评论回复
95
t60yz|  楼主 | 2023-11-22 11:38 | 只看该作者
#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "mokuaicount.h"
extern int num;

/***************************************************/初始化旋钮模块
#include "xuanniu.h"                  // Device header
#include "stm32f10x.h"

void Xuanniu_init(uint16_t GPIO_Pin)//需要指定端口Pin进行模式设置
{
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE);//使能GPIOA的时钟
       
        GPIO_InitTypeDef Xuanniu_InitStruct;  

        Xuanniu_InitStruct.GPIO_Mode=GPIO_Mode_IPU;//设置为 上拉输入 模式
        Xuanniu_InitStruct.GPIO_Pin=GPIO_Pin;  //外界参数设置Pin口
        Xuanniu_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;  //输出速度为50MHz,在输入模式下该设置没用
        GPIO_Init( GPIOA,&Xuanniu_InitStruct); //以上三个都要传入该函数初始化
}

/***************************************************/配置中断
//**该模块由中断函数实现,可接入任意输入模式的模块实现计数
//**这里引入Key实现数据的减法,LightR实现加法
#include "stm32f10x.h"                  // Device header
#include "mokuaicount.h"
#include "Delay.h"
#include "xuanniu.h"


int num;

void Count_interrupt_init(void)
{
        //1、2、**步骤一二在模块内已经实现
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//AFIO时钟需要使能
       
        Xuanniu_init(GPIO_Pin_0|GPIO_Pin_1);
        //3**配置AFIO,选择输入引脚
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);//Xuanniu旋钮
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource1);
        //4**配置EXTI寄存器,选择触发方式,这里配置EXTI和GPIO一样需要定义一个结构体
        EXTI_InitTypeDef EXTI_InitStruct;
        EXTI_InitStruct.EXTI_Line=EXTI_Line0|EXTI_Line1;
        EXTI_InitStruct.EXTI_LineCmd=ENABLE;
        EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
        EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;
        EXTI_Init(&EXTI_InitStruct);
        //5**配置NVIC,选择合适的中断优先级 --------每一个外设要单独配置
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//要先分组,整个系统NVIC只分配一种模式
        //**配置Xuanniu A端
        NVIC_InitTypeDef NVIC_InitStruct_Xuanniu;
        NVIC_InitStruct_Xuanniu.NVIC_IRQChannel=EXTI0_IRQn;
        NVIC_InitStruct_Xuanniu.NVIC_IRQChannelCmd=ENABLE;
        NVIC_InitStruct_Xuanniu.NVIC_IRQChannelPreemptionPriority=1;
        NVIC_InitStruct_Xuanniu.NVIC_IRQChannelSubPriority=1;
        NVIC_Init(&NVIC_InitStruct_Xuanniu);
        //**配置Xuanniu C端
        NVIC_InitStruct_Xuanniu.NVIC_IRQChannel=EXTI1_IRQn;
        NVIC_InitStruct_Xuanniu.NVIC_IRQChannelCmd=ENABLE;
        NVIC_InitStruct_Xuanniu.NVIC_IRQChannelPreemptionPriority=1;
        NVIC_InitStruct_Xuanniu.NVIC_IRQChannelSubPriority=1;
        NVIC_Init(&NVIC_InitStruct_Xuanniu);
       
       
        //****所有配置完成
}

//中断位置随便放,也不需要声明
void EXTI0_IRQHandler()//正转触发
{
        if(EXTI_GetITStatus(EXTI_Line0)==SET)
        {
                if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==0)
                {
                        if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)==1)
                        {
                                num++;
                        }
                }
        }
        EXTI_ClearITPendingBit(EXTI_Line0);
}
void EXTI1_IRQHandler()
{
        if(EXTI_GetITStatus(EXTI_Line1)==SET)
        {
                if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)==0)
                {
                        if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==1)
                        {
                                num--;
                        }
                }
        }
        EXTI_ClearITPendingBit(EXTI_Line1);
}


/***************************************************/主函数
int main(void)
{
        OLED_Init();
        Count_interrupt_init();
        OLED_ShowString(1,1,"Hello,my honey");
        OLED_ShowString(2,1,"Hello WangFang");
        OLED_ShowString(3,1,"Hello Tomorrow");
        while(1)
        {
                OLED_ShowSignedNum(4,1,num,5);
        }
}
/*********************阿布君***********************/
/****************编码不易,谢谢关注*****************/
/****************QQ:2062808868********************/

使用特权

评论回复
96
t60yz|  楼主 | 2023-11-22 11:38 | 只看该作者
六、TIM定时中断
1.结构原理
1.1 介绍

使用特权

评论回复
97
t60yz|  楼主 | 2023-11-22 11:38 | 只看该作者
1.2 定时器种类
不同型号的开发板拥有的定时器资源不一样

基本定时器只支持向上计数(由0加到重装载值触发中断后清零)

通用定时器和高级定时器都支持向上计数、向下计数、中央对齐三种模式计数

使用特权

评论回复
98
t60yz|  楼主 | 2023-11-22 11:38 | 只看该作者

使用特权

评论回复
99
t60yz|  楼主 | 2023-11-22 11:38 | 只看该作者
1.3 基本定时器框图

使用特权

评论回复
100
t60yz|  楼主 | 2023-11-22 11:39 | 只看该作者
1.4 通用定时器框图

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则