stm 32 LED(寄存器版本)

前题:  

  感觉一个警报灯<流水灯>,用库函数居然要很大的篇幅,虽然库函数很简单和方便,但是总是容易囫囵吞枣。而且嵌入式单片机编程中的位操作非常多,于是在这里用寄存器来好好锻炼下C语言的位操作。

一、电路:

依然控制LED1闪灭就OK了,LED1接stm32芯片的PORTD.2口,高电平输出。

二、代码

1,main.h、main.c

#ifndef _MAIN_H_
#define _MAIN_H_

#include <stm32f10x.h>
#include "led.h"

#endif /*_MAIN_H_*/
#include "main.h"

int main(void)
{
    unsigned long delay;
    LedInit();
    while(1)
    {
        delay = 2000000;
        LedOnOff();
        while(delay--);
    }
}

2,led.h、led.c

#ifndef _LED_H_
#define _LED_H_

#include "gpio.h"

void LedInit(void);
void LedOnOff(void);

#endif /*_LED_H_*/
#include "led.h"
/******************************************
Name:    LedInit
Parameters:    Null
Retural Value:     NULL
Function:    Initialization of Led
******************************************/
void LedInit(void)
{
    GPIO_Configuration();
}


/******************************************
Name:    LedRecyc
Parameters:    Null
Retural Value:     NULL
Function:    On and Off the Led
******************************************/
void LedOnOff(void)
{
    volatile unsigned long delay = 2000000;;
    GPIOD->ODR |= 1 << 2;
    while(delay--);
    GPIOD->ODR &= ~(1 << 2);
    delay = 2000000;;
    while(delay--);
}

3,gpio.h、gpio.c

#ifndef _GPIO_H_
#define _GPIO_H_

#include <stm32f10x.h>

void GPIO_Configuration(void);

#endif /*_GPIO_H_*/
#include "gpio.h"


/******************************************
Name:    GPIO_Configuration
Parameters:    Null
Retural Value:     NULL
Function:    Initialization of GPIO;
Detailed description:    GPIOD.2: push-pull output,50MHz output rate, high level
******************************************/
void GPIO_Configuration(void)
{
    RCC->APB2ENR |= 1 << 5;
    GPIOD->CRL &= 0xFFFFF0FF;
    GPIOD->CRL |= 0x3 << 8;
    GPIOD->ODR |= 1 << 2;
}

代码说明:

1,在main()函数中有一处延时变量的赋值,一定注意赋值的位置;同样的在LedOnOff()函数中一样的注意该情况;然后就是延时的长短,变量值太小,将看不见闪灭的效果,给人的感觉是:一直灭或者一直亮,视初始值为低电平还是高电平而定;

2,GPIO_Configuration()函数中,首先使能APB2之GPIOD口时钟(寄存器 RCC_APB2ENR);然后配置GPORTD口(模式、速率)(寄存器GPIOx_CRL);其实还有个(GPIOx_CRH),功能和前面一样,都是I/O端口配置控制寄存器,区别在于,一个寄存器管I/O口的(0~7)号口,另外一个管着(8~15)位。我这里是GPIOD.2,理所当然的用GPIOx_CRL;注意有的情况下,寄存器某些位需要清零后才可以使用,昨晚没清零,然后死活不正确,清零的时候注意不能影响到其他与该功能无关的寄存器,就算另外寄存器没有使用都尽量别去动它里面的数据:所以,不清零的寄存器可以用2进制的 1来位操作与;要改变一个寄存器中的值,最简单的方法是操作该寄存器的数据寄存器(GPIOD_ODR)。

3,本人使用的是v3.5库中的部分文件,选取103系列的芯片。其他参考数据手册。

本文来自博客园,作者:鱼竿的传说,转载请注明原文链接:https://www.cnblogs.com/chineseboy/archive/2013/02/28/2936083.html

原文地址:https://www.cnblogs.com/chineseboy/p/2936083.html