• stm32寄存器版学习笔记01 GPIO口的配置(LED、按键)


      STM32的I/O口可以由软件配置成如下8种模式:输入浮空、输入上拉、输入下拉、模拟输入、开漏输出、推挽输出、推挽式复用功能及开漏复用功能。每个I/O口由7个寄存器来控制:配置模式的端口配置寄存器CRL和CRH(模式、速度);数据寄存器IDR和ODR;置位/复位寄存器BSRR;复位寄存器BRR;锁存寄存器LCKR。

    I/O口模式:

    GPIO的8种模式
    通用输出 推挽输出(Push-Pull) 可以输出高、低电平,连接数字器件  
    开漏输出(Open-Drain) 开漏引脚不连接外部的上拉电阻时,只能输出低电平;如果需要同时具备输出高电平的功能,则需要接上拉电阻  
    复用功能输出 复用功能推挽输出 片内外设功能(I2C的SCL,SDA) GPIO口被用作第二功能时的配置情况(即并非作为通用IO口使用)
    复用功能开漏输出 片内外设功能(TX1,MOSI,MISO,SCK,SS)
    输入 模拟输入 应用ADC模拟输入,或者低功耗下省电  
    浮空输入 可以做KEY识别,外部按键输入 IO的电平状态是不确定,完全由外部输入决定
    下拉输入 IO内部下拉电阻输入 不确定信号->低电平
    上拉输入 IO内部上拉电阻输入 不确定信号->高电平

      

     



    1.GPIO口配置步骤

    ①使能PORTx(x=A~G)

      APB2外设时钟使能寄存器(RCC_APB2ENR)

    置1开启。清0关闭。

    8-2位使能GPIO G-A

      Eg:RCC->APB2ENR| = 1 << 2;  //使能PORTA时钟

    ②配置IO口模式 低8位(CRL) 高8位(CRH)

      端口配置低寄存器(GPIOx_CRL) (x=A..E)

      Eg:GPIOA->CRL |= 0x00000003;  //PA0推挽输出

    ③配置端口输入和输出电平

      端口输入数据寄存器(GPIOx_IDR) (x=A..E)

      端口输出数据寄存器(GPIOx_ODR) (x=A..E)

    Eg: GPIOA->ODR |= 1 <<8;  //PA8输出高

    2.GPIO配置相关寄存器

      端口位设置/清除寄存器(GPIOx_BSRR) (x=A..E)

    ODR寄存器只进行置1操作,不支持写0操作。用BSRR寄存器进行清除。

      端口位清除寄存器(GPIOx_BRR) (x=A..E)

      端口位清除寄存器(GPIOx_BRR) (x=A..E)  具体参看数据手册

      当执行正确的写序列设置了位16(LCKK)时,该寄存器用来锁定端口位的配置。位[15:0]用于锁定GPIO端口的配置。在规定的写入操作期间,不能改变LCKP[15:0]。当对相应的端口位执行了LOCK序列后,在下次系统复位之前将不能再更改端口位的配置。 每个锁定位锁定控制寄存器(CRL, CRH)中相应的4个位。

    3.LED

    //led.c                    
    //LED IO口初始化
    void LED_Init(void)
    {
        RCC->APB2ENR|=1<<2;      //使能PORTA时钟        
        RCC->APB2ENR|=1<<5;      //使能PORTD时钟         
        GPIOA->CRH&=0XFFFFFFF0; 
        GPIOA->CRH|=0X00000003;//PA8推挽输出     
      GPIOA->ODR|=1<<8;                //PA8输出高
                                                  
        GPIOD->CRL&=0XFFFFF0FF;
        GPIOD->CRL|=0X00000300;//PD2推挽输出
        GPIOD->ODR|=1<<2;         //PD2输出高
    }
    
    //led.h
    #ifndef __LED_H
    #define __LED_H     
    #include "sys.h"
    
    //LED端口定义
    #define LED0 PAout(8)    // PA8
    #define LED1 PDout(2)    // PD2    
    
    void LED_Init(void);    //初始化                         
    #endif 
    
    //main.c
    #include "sys.h"
    #include "usart.h"        
    #include "delay.h"    
    #include "led.h" 
    int main(void)
    {         
        Stm32_Clock_Init(9); //系统时钟设置
        delay_init(72);             //延时初始化
        LED_Init();        //初始化与LED连接的硬件接口
        while(1)
        {
            LED0=0;
            LED1=1;
            delay_ms(300);
            LED0=1;
            LED1=0;
            delay_ms(300);
        }     
    }

    4.按键KEY输入

    //key.c
    #include "key.h"
    #include "delay.h"
    //按键初始化函数
    //PA0 PA15 PC5设置成输入
    void KEY_Init(void)
    {
        RCC->APB2ENR|=1<<2;     //使能PORTA时钟
        RCC->APB2ENR|=1<<4;     //使能PORTC时钟
        JTAG_Set(SWD_ENABLE);    //关闭JTAG 开启SWD PA15占用了JTAG一个口
        GPIOA->CRL&=0XFFFFFFF0;    //PA0设置成输入  
        GPIOA->CRL|=0X00000008;   
        GPIOA->CRH&=0X0FFFFFFF;    //PA15设置成输入
        GPIOA->CRH|=0X80000000;              
        GPIOA->ODR|=1<<15;           //PA15上拉 PA0默认下拉
        GPIOC->CRL&=0XFF0FFFFF;    //PC5设置成输入  
        GPIOC->CRL|=0X00800000;   
        GPIOC->ODR|=1<<5;           //PC5上拉
    } 
    //按键处理函数
    //mode:0不支持连续按;1,支持连续按
    //响应优先级KEY0>KEY1>WK_UP
    u8 KEY_Scan(u8 mode)
    {     
        static u8 key_up=1;//按键按松开标志
        if(mode)key_up=1;  //支持连按      
        if(key_up&&(KEY0==0||KEY1==0||WK_UP==1))
        {
            delay_ms(10);//去抖动
            key_up=0;
            if(KEY0==0)
                        return KEY0_PRES;
            else if(KEY1==0)
                        return KEY1_PRES;
            else if(WK_UP==1)
                        return WKUP_PRES; 
        }else if(KEY0==1&&KEY1==1&&WK_UP==0)
                key_up=1;          
        return 0;// 无按键按下
    }
    
    //key.h
    #ifndef __KEY_H
    #define __KEY_H     
    #include "sys.h"
    
    #define KEY0_PRES    1        //KEY0按下
    #define KEY1_PRES    2        //KEY1按下
    #define WKUP_PRES    3        //WK_UP按下
    
    #define KEY0  PCin(5)          //PC5
    #define KEY1  PAin(15)         //PA15 
    #define WK_UP PAin(0)          //PA0  WK_UP
         
    void KEY_Init(void);        
    u8 KEY_Scan(u8 mode);        
    #endif
    
    //main.c
    #include "sys.h"
    #include "usart.h"        
    #include "delay.h"    
    #include "led.h" 
    #include "key.h" 
    
    int main(void)
    {         
        u8 t;      
        Stm32_Clock_Init(9);     
        delay_init(72);            
        LED_Init();                   
        KEY_Init();          
        LED0 = 0;                    
        while(1)
        {
            t=KEY_Scan(0);        
            switch(t)
            {                 
                case KEY0_PRES:
                    LED0=!LED0;
                    break;
                case KEY1_PRES:
                    LED1=!LED1;
                    break;
                case WKUP_PRES:                
                    LED0=!LED0;
                    LED1=!LED1;
                    break;
                default:
                    delay_ms(10);    
            } 
        }         
    }
    
                        
  • 相关阅读:
    产品化软件开发与项目化软件开发的对比
    4.ThinkPHP 3.1.2 输出和模型使用
    ThinkPHP 3.1.2 输出和模型使用1
    事务管理配置与@Transactional注解使用
    logstash 区分多个文件index端配置
    logstash 读取多个系统相同文件shipper端
    centos 6.5安装git
    如何查看PHP的配置信息
    MVC模式和URL访问
    1.环境搭建
  • 原文地址:https://www.cnblogs.com/kuotian/p/5506564.html
Copyright © 2020-2023  润新知