JackieLaura 发表于 2015-12-1 14:06:11

【NUCLEO-L476RG开发】1、自制的简易LED库

   之前活动最后一天抢了一块L476的开发板,开发板早就收到了。   不过前段时间有点小忙,一直没有分享学习笔记。现在在这里献丑了,也要感谢ST给的这次体验的机会。


main.c
#include "stm32l476xx.h"
#include "led.h"

static int disable_jtag(void);

int main(void)
{
        disable_jtag();
        GreenLED.initialize(GreenLEDGPIO);
        while(1)
        {
                GreenLED.set(GreenLEDGPIO, LED_ON);
                GreenLED.set(GreenLEDGPIO, LED_OFF);
        }
}

static int
        disable_jtag(void)
{
        RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN | RCC_AHB2ENR_GPIOBEN;
        //PA15 AF5
        GPIOA->AFR &= ~(0xf0000000);       
        GPIOA->AFR |=   0x50000000 ;
        //PB3 PB4 PB5 AF5       
        GPIOB->AFR &= ~(0x00fff000);       
        GPIOB->AFR |=   0x00555000 ;
        return 0;
}
led.h
#ifndef _LED_H
#define _LED_H

#include "stm32l476xx.h"

#define RCC_AHB2Periph_GPIOA               RCC_AHB2ENR_GPIOAEN
#define RCC_AHB2Periph_GPIOB               RCC_AHB2ENR_GPIOBEN
#define RCC_AHB2Periph_GPIOC               RCC_AHB2ENR_GPIOCEN
#define RCC_AHB2Periph_GPIOD               RCC_AHB2ENR_GPIODEN
#define RCC_AHB2Periph_GPIOE               RCC_AHB2ENR_GPIOEEN
#define RCC_AHB2Periph_GPIOF               RCC_AHB2ENR_GPIOFEN
#define RCC_AHB2Periph_GPIOG               RCC_AHB2ENR_GPIOGEN
#define RCC_AHB2Periph_GPIOH               RCC_AHB2ENR_GPIOHEN

typedef enum {
        LED_ON = 0,
        LED_OFF
}LED_STATUS;

typedef enum {       
        GPIO_Pin_0 = 0,
        GPIO_Pin_1,
        GPIO_Pin_2,
        GPIO_Pin_3,
        GPIO_Pin_4,
        GPIO_Pin_5,
        GPIO_Pin_6,
        GPIO_Pin_7,
        GPIO_Pin_8,
        GPIO_Pin_9,
        GPIO_Pin_10,
        GPIO_Pin_11,
        GPIO_Pin_12,
        GPIO_Pin_13,
        GPIO_Pin_14,
        GPIO_Pin_15,
        GPIO_Pin_All,               
}GPIO_PIN_E;

typedef struct {       
        GPIO_TypeDef* GPIO_PORT;
        GPIO_PIN_E GPIO_PIN;
        uint32_t GPIO_CLK;
}LED_GPIO_T;

typedef struct {
        int (* initialize)(LED_GPIO_T);
        int (* set)(LED_GPIO_T, LED_STATUS);
        LED_STATUS (* get)(LED_GPIO_T);
        int (* toggle)(LED_GPIO_T);
}LED_T;

extern LED_T GreenLED;
extern LED_GPIO_T GreenLEDGPIO;

#endif
led.c
#include "led.h"

static int led_init(LED_GPIO_T);
static int led_set(LED_GPIO_T, LED_STATUS);
static LED_STATUS led_get(LED_GPIO_T);
static int led_toggle(LED_GPIO_T);

LED_GPIO_T GreenLEDGPIO = {       
        .GPIO_PORT = GPIOA,
        .GPIO_PIN = GPIO_Pin_5,
        .GPIO_CLK = RCC_AHB2Periph_GPIOA,
};

LED_T GreenLED = {
        .initialize = led_init,
        .set = led_set,
        .get = led_get,
        .toggle = led_toggle,
};

static int
        led_init(LED_GPIO_T gpio)
{
        int pincount = gpio.GPIO_PIN;
       
        RCC->AHB2ENR |= gpio.GPIO_CLK;
       
        gpio.GPIO_PORT->MODER &= \
                                                                                                ~(gpio.GPIO_PORT == GPIOA ? \
                                                                                                0x03ffffff : \
                                                                                                0xffffffff);                                                                                //reset values:0xabff ffff A                0xffff ffff B-G         0x0000 0000 H
        gpio.GPIO_PORT->MODER |= \
                                                                                                (pincount == 16) ? \
                                                                                                (gpio.GPIO_PORT == GPIOA ? 0x01555555 : 0x55555555) : \
                                                                                                (1 << (pincount * 2));
        gpio.GPIO_PORT->OTYPER &= \
                                                                                                (pincount == 16) ? \
                                                                                                0x0 : \
                                                                                                ~(1 << pincount);                                                                //reset values:0x0000 0000
        gpio.GPIO_PORT->PUPDR &= \
                                                                                                (pincount == 16) ? \
                                                                                                ((gpio.GPIO_PORT == GPIOA || gpio.GPIO_PORT == GPIOB) ? 0xfc000000 : 0x0) : \
                                                                                                ~(1 << (pincount * 2));                                        //reset values:0x6400 0000 A/B        0x0000 0000 others
        gpio.GPIO_PORT->OSPEEDR |= \
                                                                                                (pincount == 16) ? \
                                                                                                (gpio.GPIO_PORT == GPIOA ? 0xadaaaaaa : 0xaaaaaaaa) : \
                                                                                                (0x02 << (pincount * 2));                                //reset values:0x0c00 0000 A                0x0000 0000 others
        return 0;
}

static int
        led_set(LED_GPIO_T gpio, LED_STATUS ledStatus)
{
        switch(ledStatus)
        {
                case LED_ON:
                        gpio.GPIO_PORT->BSRR = gpio.GPIO_PIN == 16 ? 0xffff : 1 << gpio.GPIO_PIN;
                        break;
                case LED_OFF:
                        gpio.GPIO_PORT->BRR= gpio.GPIO_PIN == 16 ? 0xffff : 1 << gpio.GPIO_PIN;
                        break;
        }
        return 0;
}

static LED_STATUS
        led_get(LED_GPIO_T gpio)
{
        int input = gpio.GPIO_PORT->ODR;
        input >>= gpio.GPIO_PIN;
        returninput == 1 ? LED_ON : LED_OFF;
}

static int
        led_toggle(LED_GPIO_T gpio)
{
        switch(led_get(gpio))
        {
                case LED_ON:
                        led_set(gpio, LED_OFF);
                        break;
                case LED_OFF:
                        led_set(gpio, LED_ON);
                        break;
        }
        return 0;
}


工程源码:



demo效果需要仿真来完成,单步调试LD2一亮一灭,效果图片就不发了,自己下载试试。

wambob 发表于 2015-12-1 14:12:46

谢谢分享,真复杂

沐紫 发表于 2015-12-1 14:19:18

谢谢你哦

JackieLaura 发表于 2015-12-1 14:19:47

wambob 发表于 2015-12-1 14:12
谢谢分享,真复杂
是模仿别人方式写的。。。

JackieLaura 发表于 2015-12-1 14:20:23

沐紫 发表于 2015-12-1 14:19
谢谢你哦

谢谢沐紫的金币

QianFan 发表于 2015-12-1 14:47:43

不得不说,虽然很高大上,但是没啥用。每一个引脚占用一个LED_GPIO_T,占用了太多的资源。

yanhaijian 发表于 2015-12-1 14:56:44

呵呵,来劲的。

JackieLaura 发表于 2015-12-1 15:41:23

QianFan 发表于 2015-12-1 14:47
不得不说,虽然很高大上,但是没啥用。每一个引脚占用一个LED_GPIO_T,占用了太多的资源。 ...

标准库中的GPIOInitStructure不是每个IO占用一个?

QianFan 发表于 2015-12-1 16:30:51

JackieLaura 发表于 2015-12-1 15:41
标准库中的GPIOInitStructure不是每个IO占用一个?

那个是可以反复利用的。像GPIO_InitTypeDef ioIt;
ioIt.GPIO_Pin=GPIO_Pin_5;
GPIO_Init(GPIOA,&ioIt);
...

ioIt.GPIO_Pin=GPIO_Pin_6;
GPIO_Init(GPIOB,&ioIt);

而这个LED_GPIO_T是需要提前将所有的引脚定义,放到flash中的。不可能重复利用。一个引脚需要占用一个LED_GPIO_T的。如果你有100个引脚,需要占用100×sizeof(LED_GPIO_T),而使用GPIO_InitTypeDef只需要1×sizeof(GPIO_InitTypeDef)。

stary666 发表于 2015-12-1 16:52:26

看看,,,,,,,,,,,,,,,,,
页: [1] 2
查看完整版本: 【NUCLEO-L476RG开发】1、自制的简易LED库