单片机学习小组
直播中

石玉兰

7年用户 1434经验值
私信 关注

设定GPIO的方法是什么?

设定GPIO的方法是什么?

回帖(1)

黄远飞

2022-2-10 11:26:11
编写第一个程式

修改1:20210531
第一个步骤一定是写一个简单的程式 由 data BUS 输出 Hi/Low 控制 LED 亮灭,来確定这个开发板是可以用的,确认是可以被控制的。不过,ARM 的设定有一些复杂,需要一边看参考手册,一边做设定。下边列了STM32 的网站,除了下载参考手册以外,也建议注册一下,然后,在上面找找有没有其他好货可以下载的!!
STM32F072RB 规格资料
Mainstream ARM Cortex-M0 USB line MCU with 128 Kbytes Flash, 48 MHz CPU, USB, CAN and CEC functions.

STM32F072RB Reference manual (参考手册)
RM0091: STM32F0x1/STM32F0x2/STM32F0x8 advanced ARM®-based 32-bit MCUs


设定 GPIO 的方法
设定GPIO的程序
1. 打开 特定 GPIO 的时钟 (AHBENR)
2. 设定 这个 GPIO 特定 脚位的 功能 inpu、output,(MODER)。


3. 设定响应的时钟的频率(OSPEEDR)
4. 设定硬体的匹配方式 PP、OD、(OTYPER)
“0” – Push-pull模式, “1” – OD 模式。
5. 设定硬件对外的物理匹配 pull-up、pull-down (PUPDR)


以下的资料都是从 “RM0091: 参考手册” 摘取出来。


void GPIOA6_7_8_init(void)
{       
        RCC -> AHBENR |=0x1ul <<17;
        GPIOA->MODER &=~ ((0x03ul <<6*2)|(0x03ul <<7*2)|(0x03ul <<8*2));       
        GPIOA->MODER |=(0x01ul <<6*2)|(0x01ul <<7*2)|(0x01ul <<8*2);


        GPIOA->OSPEEDR |=(0x01ul <<6*2)|(0x01ul <<7*2)|(0x01ul <<8*2);
}


上图是配置 Port-A 的 6/7/8 三只脚为输出模式;下图是配置 Port-C 的 )0~7 八只脚为输出。


void GPIOC0_7_init(void)   //--define  Port C, pin 0~7
{
        RCC->AHBENR |= 0x1ul<<19;
        GPIOC->MODER &= ~(0xfffful);
        GPIOC->MODER |= 0x5555ul;
        GPIOC->OSPEEDR &= ~0xfffful;
        GPIOC->OSPEEDR |= 0x5555ul;       
}       


AHB peripheral clock enable register (RCC_AHBENR)(第127页)



GPIO port mode register (GPIOx_MODER) (x =A…F)(第165页)

GPIO port output speed register (GPIOx_OSPEEDR) (x = A…F)(第166页)

当观察程式内容会发现,MODER 和OSPEEDR 都是同时出现两次,其目的是第一次清除需求的位置里的内容,第二次是设定需要的值。
下图是Table 24. Port bit configuration table(第157页)


GP = general-purpose, PP = push-pull, PU = pull-up, PD = pull-down, OD = open-drain, AF = alternate function.
清除的设定是 一个 pin 位 0x01, 两个 pin 位 是0x03, 四个 pin 位 是0x0f; 让后用反向 变成 00,再做 AND 处理。后面的 << 6 * 2 就是 第 6 脚用的 2 位置, << 9 * 2 就是 第 9 脚用的 2 位置.
(当然,如果是 1 位置,这个 1 会被省略)。MODER 和 OSPEEDR 都是 2 位置。


#define AllLed_on   1
#define AllLed_off  2
#define OddLed_on        3
#define evenLed_on        4
#define BitLed_on   5
#define R_on                6
#define G_on                7
#define B_on                8


先把需要的功能定义起来,再用 function()做规划,然后在main.c 里面就很方便使用了。


void Ledchange(uint8_t mode)
{
        switch(mode){
                case  AllLed_on:
                        GPIOC->ODR |= 0xfful;
                        break;
                case  AllLed_off:
                        GPIOC->ODR &=~0xfful;
//                   GPIOC->ODR &= 0xfffffful;
                        break;
                case  OddLed_on:
                        GPIOC->ODR &=~0xfful;
                        GPIOC->ODR |= 0x55ul;
                        break;
                case  evenLed_on:
                        GPIOC->ODR &=~0xfful;
                        GPIOC->ODR |= 0xaaul;
                        break;
                case  BitLed_on:
                        for(int i=0;i<8;i++){
                                GPIOC->ODR &=~0xfful;
                                GPIOC->ODR |= 0x1ul <                                 Delay(12*i);
                        }
                        break;
                }
        }


int main (void) {
,...
...
        Ledchange(AllLed_on);
        Delay(500);
        Ledchange(AllLed_off);
        Delay(500);
        Ledchange(OddLed_on);
        Delay(500);
        ...
        }
举报

更多回帖

发帖
×
20
完善资料,
赚取积分