【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
谢谢分享,真复杂
是模仿别人方式写的。。。
沐紫 发表于 2015-12-1 14:19
谢谢你哦
谢谢沐紫的金币
不得不说,虽然很高大上,但是没啥用。每一个引脚占用一个LED_GPIO_T,占用了太多的资源。 呵呵,来劲的。 QianFan 发表于 2015-12-1 14:47
不得不说,虽然很高大上,但是没啥用。每一个引脚占用一个LED_GPIO_T,占用了太多的资源。 ...
标准库中的GPIOInitStructure不是每个IO占用一个? 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)。 看看,,,,,,,,,,,,,,,,,
页:
[1]
2