前题:
感觉一个警报灯<流水灯>,用库函数居然要很大的篇幅,虽然库函数很简单和方便,但是总是容易囫囵吞枣。而且嵌入式单片机编程中的位操作非常多,于是在这里用寄存器来好好锻炼下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系列的芯片。其他参考数据手册。