小白跟做江科大32单片机之旋转编码器计次

原理部分按照下面这个链接理解即可y小白跟做江科大32单片机之对射式红外传感器计次-CSDN博客https://blog.csdn.net/weixin_58051657/article/details/139350487icon-default.png?t=N7T8https://blog.csdn.net/weixin_58051657/article/details/139350487


实验过程

1.按照江科大老师给的电路图进行连接

2.rev.h代码

#ifndef _REV__H
#define _REV__H

void xuanzhuan_Init(void);
int16_t turn(void);


#endif
 

3.rev.c代码

#include "stm32f10x.h" 

int16_t rev_Count;

void xuanzhuan_Init(void)
{
    //使用各个外设前必须开启时钟,否则对外设的操作无效
    //中断只需开始B口和AFIO即可,EXTI和NVIC无需开启时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);    //开启GPIOB的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);    //开启AFIO的时钟
    
    
    /*GPIO初始化*/
    GPIO_InitTypeDef GPIO_InitStructure;                    //定义结构体变量
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;              //GPIO模式,赋值为上拉输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;    //GPIO引脚,赋值为第1,2号引脚
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //GPIO速度,赋值为50MHz
    
    GPIO_Init(GPIOB, &GPIO_InitStructure);                    //将赋值后的构体变量传递给GPIO_Init函数
                                                            //函数内部会自动根据结构体的参数配置相应寄存器
                                                            //实现GPIOB的初始化
    /*AFIO选择中断引脚*/
    //将外部中断的0号线映射到GPIOB,即选择PB0为外部中断引脚
    //将外部中断的1号线映射到GPIOB,即选择PB1为外部中断引脚
    //AFIO这个函数在GPIO那个里面
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);
    
    
    
    /*EXTI初始化*/
    //这个在library中找一下
    EXTI_InitTypeDef EXTI_InitStruct;
    EXTI_InitStruct.EXTI_Line=EXTI_Line0|EXTI_Line1;              //选择哪个口
    EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;      //中断
    EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;   //这个需要搜索一下EXTI_Trigger,现在是上升沿触发
    EXTI_InitStruct.EXTI_LineCmd=ENABLE;                //中断打开
    EXTI_Init(&EXTI_InitStruct);
    
    //NVIC在初始化之前需要指定中断优先级分组
    /*NVIC中断分组*/
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    /*NVIC初始化*/
    NVIC_InitTypeDef NVIC_InitStruct;
    NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn;       //选择配置NVIC的EXTI0线,因为那个0线过来的
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;  //这个是自己给的,值越低优先级越高
    NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
    NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; 
    NVIC_Init(&NVIC_InitStruct);
    
    
    NVIC_InitStruct.NVIC_IRQChannel=EXTI1_IRQn;       //选择配置NVIC的EXTI1线,因为那个0线过来的
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;  //这个是自己给的,值越低优先级越高
    NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;        //次优先级低一点
    NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; 
    NVIC_Init(&NVIC_InitStruct);
}

int16_t turn(void)
{
    int16_t temp;
    temp=rev_Count;
    rev_Count=0;
    return temp;
}

//中断函数不需要声明
//这里还没有弄懂
void EXTI0_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line0)==SET)      //判断是否是外部中断14号线触发的中断
    {
        if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0)
        {
            if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)        //PB0的下降沿触发中断,此时检测另一相PB1的电平,目的是判断旋转方向
            {
                rev_Count--;                    //此方向定义为反转,计数变量自减
            }
        }
        EXTI_ClearITPendingBit(EXTI_Line0);        //清除外部中断14号线的中断标志位
                                                    //中断标志位必须清除
                                                    //否则中断将连续不断地触发,导致主程序卡死
    }
    
}


void EXTI1_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line1)==SET)      //判断是否是外部中断14号线触发的中断
    {
        if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
        {
            if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0)        //PB0的下降沿触发中断,此时检测另一相PB1的电平,目的是判断旋转方向
            {
                rev_Count++;                    //此方向定义为反转,计数变量自减
            }
        }
        EXTI_ClearITPendingBit(EXTI_Line1);        //清除外部中断14号线的中断标志位
                                                    //中断标志位必须清除
                                                    //否则中断将连续不断地触发,导致主程序卡死
    }
    
}

4.main.c代码

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "rev.h"

int16_t num;
int main()
{
  OLED_Init();
    xuanzhuan_Init();
    OLED_ShowString(1, 2, "zhuan:");
    while (1)
    {
        num+=turn();
        OLED_ShowNum(2, 2,num, 5);
    }
}
 

5.试验结果

STM32旋转编码器计次试验结果

相关推荐

  1. 科大51单片机DS18B02按键控制效果

    2024-06-06 15:56:01       21 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-06 15:56:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-06 15:56:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-06 15:56:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-06 15:56:01       20 阅读

热门阅读

  1. 【SAP HANA 34】HANA查找函数LOCATE的使用

    2024-06-06 15:56:01       10 阅读
  2. Mybatis学习之Spring boot整合Mybatis示例

    2024-06-06 15:56:01       9 阅读
  3. 什么是HTTPS协议,与HTTP协议有什么区别

    2024-06-06 15:56:01       10 阅读
  4. 【杂记-webshell恶意脚本木马】

    2024-06-06 15:56:01       8 阅读
  5. PTA R6-1 寻找链表元素的前驱结点

    2024-06-06 15:56:01       9 阅读
  6. 逆序数求解算法

    2024-06-06 15:56:01       8 阅读
  7. CSRF 令牌的生成过程和检查过程

    2024-06-06 15:56:01       8 阅读
  8. Xilinx FPGA 管脚的默认电平配置方法 XDC约束

    2024-06-06 15:56:01       10 阅读
  9. shell 支持多线程

    2024-06-06 15:56:01       9 阅读