[STM32F1] 基于STM32F103C8T6的EXTI外部中断感应灯

[复制链接]
1207|35
 楼主| 雨果喝水 发表于 2022-12-27 16:03 | 显示全部楼层
5)AFIO复用IO口

AFIO主要用于引脚复用功能的选择和定义
在STM32中,AFIO主要完成两个任务:复用功能引脚重映射、中断引脚选择
 楼主| 雨果喝水 发表于 2022-12-27 16:04 | 显示全部楼层
如图为中断引脚选择功能
8330063aaa6f6f090b.png
 楼主| 雨果喝水 发表于 2022-12-27 16:06 | 显示全部楼层
 楼主| 雨果喝水 发表于 2022-12-27 16:07 | 显示全部楼层
EXTI功能框图
2075163aaa7b80f76c.png
 楼主| 雨果喝水 发表于 2022-12-27 16:08 | 显示全部楼层
EXTI中断函数配置

外部中断软件设计
a) 软件设计思想
i. 初始化中断
ii. EXTI(外部中断)
 楼主| 雨果喝水 发表于 2022-12-27 16:10 | 显示全部楼层
所有使用到的外设时钟使能
初始化GPIO口
外部中断线配置
a) AFIO外部中断寄存器选择哪个端口
EXTI相关寄存器
NVIC配置
 楼主| 雨果喝水 发表于 2022-12-27 16:11 | 显示全部楼层
中断服务函数

中断服务函数的编写
a) 判断是哪一个中断(共用中断服务函数)
b) 清对应中断挂起标志位
c) 中断服务函数
 楼主| 雨果喝水 发表于 2022-12-27 16:12 | 显示全部楼层
程序代码

1、Exti.c
  1. #include "stm32f10x.h"
  2. #include "exti.h"


  3. void Exti_Init(void)
  4. {
  5.    
  6.           //1.配置GPIO
  7.           GPIO_InitTypeDef shake_init;       
  8.           EXTI_InitTypeDef exti_init;
  9.           NVIC_InitTypeDef nvic_init;
  10.        
  11.           NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//优先级分组配置

  12.                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE);//配置GPIO时钟
  13.           RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//配置EXTI中断时钟,又输出又中断
  14.           GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource2);
  15.           
  16.           
  17.          
  18.           
  19.        
  20.           shake_init.GPIO_Mode   =  GPIO_Mode_IPD;
  21.                 shake_init.GPIO_Pin    =  GPIO_Pin_2;
  22.     shake_init.GPIO_Speed  =  GPIO_Speed_10MHz;
  23.        
  24.                 GPIO_Init(GPIOA,&shake_init);

  25.        
  26.           //2.配置Exti外部中断
  27.           exti_init.EXTI_Line    = EXTI_Line2;//外部中断通道
  28.           exti_init.EXTI_LineCmd = ENABLE;//使能外部中断通道
  29.           exti_init.EXTI_Mode    = EXTI_Mode_Interrupt;//选择外部中断模式
  30.           exti_init.EXTI_Trigger = EXTI_Trigger_Falling;//中断触发方式
  31.          
  32.           EXTI_Init(&exti_init);//中断初始化
  33.           
  34.        
  35.           //3.配置NVIC中断控制器
  36.                
  37.           nvic_init.NVIC_IRQChannel    =  EXTI2_IRQn;//中断通道2
  38.                 nvic_init.NVIC_IRQChannelCmd =  ENABLE;    //使能通道
  39.                 nvic_init.NVIC_IRQChannelPreemptionPriority =  1; //抢占优先级
  40.                 nvic_init.NVIC_IRQChannelSubPriority   =  1;//子优先级
  41.                
  42.                 NVIC_Init(&nvic_init);  

  43. }



 楼主| 雨果喝水 发表于 2022-12-27 16:14 | 显示全部楼层
Exti.h
  1. #include "stm32f10x.h"

  2. void Exti_Init(void);


 楼主| 雨果喝水 发表于 2022-12-27 16:15 | 显示全部楼层
shake.c
  1. #include "stm32f10x.h"
  2. #include "shake.h"

  3. void Shake_Init(void)
  4. {
  5.             GPIO_InitTypeDef shake_init;       
  6.        
  7.           //1.使能GPIOA时钟
  8.                         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
  9.        
  10.        
  11.                 //2.结构体配置
  12.             shake_init.GPIO_Mode   =  GPIO_Mode_IPD;
  13.                         shake_init.GPIO_Pin    =  GPIO_Pin_2;
  14.             shake_init.GPIO_Speed  =  GPIO_Speed_10MHz;
  15.        
  16.                         GPIO_Init(GPIOA,&shake_init);

  17.        
  18.                        
  19.        
  20.           
  21.        
  22.        

  23. }


 楼主| 雨果喝水 发表于 2022-12-27 16:28 | 显示全部楼层
skake.h
  1. #include "stm32f10x.h"

  2. void Shake_Init(void);







 楼主| 雨果喝水 发表于 2022-12-27 16:29 | 显示全部楼层
relay.c
  1. #include "stm32f10x.h"
  2. #include "relay.h"


  3. void Relay_Init(void)
  4. {
  5.        
  6.             GPIO_InitTypeDef relay_init;
  7.                 //1.使能GPIOA时钟
  8.             RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

  9.        
  10.           //2.GPIOA3结构体配置
  11.                         relay_init.GPIO_Mode  = GPIO_Mode_Out_PP;
  12.             relay_init.GPIO_Pin   = GPIO_Pin_3 ;
  13.             relay_init.GPIO_Speed = GPIO_Speed_10MHz;
  14.        
  15.             GPIO_Init(GPIOA, &relay_init);
  16.        
  17. }


 楼主| 雨果喝水 发表于 2022-12-27 16:31 | 显示全部楼层
relay.h
#include "stm32f10x.h"

void Relay_Init(void);


 楼主| 雨果喝水 发表于 2022-12-27 16:32 | 显示全部楼层
main.c
  1. #include "stm32f10x.h"
  2. #include "main.h"
  3. #include "LED.h"
  4. #include "usart.h"
  5. #include "relay.h"
  6. #include "shake.h"
  7. #include "exti.h"

  8. void delay(uint16_t time)//延迟函数
  9. {
  10.                 uint16_t i=0;
  11.           while(time--)
  12.                 {
  13.                                 i=12000;
  14.                           while(i--);
  15.                 }
  16. }



  17. int  main()
  18. {
  19.          LED_Init();
  20.          usart_init();
  21.          Relay_Init();
  22.          Shake_Init();
  23.          Exti_Init();
  24.        
  25.          GPIO_SetBits(GPIOA,GPIO_Pin_3);
  26.        
  27. }


  28. void  EXTI2_IRQHandler(void)
  29. {
  30.     if(EXTI_GetITStatus(EXTI_Line2)!=RESET)//如果函数发生中断
  31.                 {
  32.                                 GPIO_ResetBits(GPIOA,GPIO_Pin_3);//接通继电器,开灯
  33.                           delay(1000);
  34.                           GPIO_SetBits(GPIOA,GPIO_Pin_3);//关闭继电器,关灯
  35.                 }
  36.                 else
  37.                 {
  38.                                 GPIO_SetBits(GPIOA,GPIO_Pin_3);//关闭继电器,关灯
  39.                 }
  40.                
  41.                 EXTI_ClearITPendingBit(EXTI_Line2);//中断标志清除

  42. }





 楼主| 雨果喝水 发表于 2022-12-27 16:35 | 显示全部楼层
USART.C
  1. #include "stm32f10x.h"
  2. #include "usart.h"

  3. void usart_init(void)   //串口初始化
  4. {
  5.             GPIO_InitTypeDef GPIO_initstructure;
  6.             USART_InitTypeDef USART_initstructure;
  7.             NVIC_InitTypeDef Nvic_Init;
  8.             NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);   //配置中断组为中断组2   misc.h
  9.        
  10.       RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  11.             RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);   //配置中断复用时钟
  12.       RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
  13.        

  14.                 
  15.         //配置PA9 TX       
  16.       GPIO_initstructure.GPIO_Mode   =GPIO_Mode_AF_PP; //推挽输出
  17.                         GPIO_initstructure.GPIO_Pin    =GPIO_Pin_9;
  18.                         GPIO_initstructure.GPIO_Speed  =GPIO_Speed_50MHz;
  19.                         GPIO_Init(GPIOA,&GPIO_initstructure);

  20.               //配置PA10 RX
  21.             GPIO_initstructure.GPIO_Mode   =GPIO_Mode_IN_FLOATING; //浮空输入
  22.                         GPIO_initstructure.GPIO_Pin    =GPIO_Pin_10;
  23.                        
  24.             GPIO_Init(GPIOA,&GPIO_initstructure);
  25.              
  26.              //串口1打开
  27.             USART_initstructure.USART_BaudRate=115200;    //波特率
  28.             USART_initstructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
  29.             USART_initstructure.USART_Mode=USART_Mode_Rx | USART_Mode_Tx;
  30.                         USART_initstructure.USART_Parity=USART_Parity_No;     //校验位
  31.                         USART_initstructure.USART_StopBits= USART_StopBits_1;         //停止位
  32.                         USART_initstructure.USART_WordLength= USART_WordLength_8b;  //有效字节长度  8位
  33.             USART_Init(USART1,&USART_initstructure);
  34.       //使能串口1
  35.                         USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);   //串口中断配置
  36.                         USART_Cmd(USART1,ENABLE);

  37.       
  38.    //配置中断
  39.       
  40.                                                
  41.                   Nvic_Init.NVIC_IRQChannel       =USART1_IRQn;       //设置中断通道  stm32f10x.h
  42.                   Nvic_Init.NVIC_IRQChannelCmd    =ENABLE;                   //控制是否使能
  43.                   Nvic_Init.NVIC_IRQChannelPreemptionPriority  =1;          //设置抢占优先级
  44.                   Nvic_Init.NVIC_IRQChannelSubPriority   =1;             //设置子优先级
  45.                
  46.                   NVIC_Init(&Nvic_Init);

  47. }


  48. //发送单个字符   调用方法   USARTSendByte(USART1,'o');
  49. void USARTSendByte(USART_TypeDef* USARTx, uint16_t Data){

  50.   USART_SendData(USART1,Data);
  51. while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)==RESET);  //判断是否发送完成

  52. }



  53. //发送字符串   //原理字符发送最后一位是\0判断是否最后一位\0就能发送字符串   调用方法   USARTSendStr(USART1,"ruanzebin");
  54. void USARTSendStr(USART_TypeDef* USARTx, char *str){

  55.    uint16_t i=0; //无符号整形十六位
  56.   
  57.     do{
  58.                        
  59.                 USARTSendByte(USARTx, *(str+i));
  60.                         i++;
  61.                
  62.                
  63.                 }while(*(str+i)!='\0');

  64.    while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);  //判断是否发送完成

  65. }
  66.   //printf 函数  putchar函数(输出单个字符)  通过重定向  输出数值
  67. int fputc(int ch ,FILE *f){


  68.   USART_SendData(USART1,(uint8_t)ch);
  69.   while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)==RESET);  //判断是否发送完成

  70.   return (ch);
  71. }
  72.   //scanf()  getchar函数   
  73. int fgetc(FILE *f)
  74. {
  75.        
  76.      while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE)==RESET); //判断是否接收成功

  77.        return (int)USART_ReceiveData(USART1);


  78. }






您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部