|
目标——能够学会LED流水灯的运作(包括使用固件库,自定义宏,直接操作寄存器) 能查阅GPIO库函数并加以运用 了解八个GPIO的输入输出模式 GPIO(General Purpose Input/Output)之从库函数到寄存器 第一步 需要板级支持包 bsp.led.h与bsp.led.c 将这两个文件 放入/USER/led内 打开工程文件 在USER中导入两个板级支持包 在 traget option的C/C++ 中的 IncludePaths添加 /User/led file:///C:/Users/YLenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg 否则会发生找不到文件的错误导致程序无法运行 准备工作完成 第二步 由于函数最开始是从startup开始执行的,原本3.0固件库需要设置的72M的时钟现在在file:///C:/Users/YLenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image003.png里面。这里面用汇编语言实现了时钟的设置file:///C:/Users/YLenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image004.png 进入systemInit定义后可以看见 file:///C:/Users/YLenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image006.jpg 在下面可以直接找到 file:///C:/Users/YLenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image008.jpg 进入时钟设置 SetSysClock定义 file:///C:/Users/YLenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image009.png 在这里可以看见这里是用一些条件编译来实现72M的时钟,进入file:///C:/Users/YLenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image010.png定义 file:///C:/Users/YLenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image011.png 直接定义了72M的时钟 进入file:///C:/Users/YLenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image012.png定义 file:///C:/Users/YLenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image014.jpg 里面涉及到系统时钟,AHB总线时钟,APB2,APB1外设总线时钟 HCLK和PCLK2都是72M时钟 PCLK1为36M时钟 file:///C:/Users/YLenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image016.jpg 具体看时间树 file:///C:/Users/YLenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image017.png file:///C:/Users/YLenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image018.png 至于其他的还看不懂 第三步 首先看清三个LED灯的接口以便后面编程 file:///C:/Users/YLenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image019.png 确认LED_GPIO_Config配置 1) 定义GPIO结构体(进入定义发现有三种子结构:引脚,速度,模式) 2) 使能AHB2上的GPIOB与GPIOF的外设时钟(3.5固件库手册P194,P208) 3) 选择引脚(3.5固件库手册P125 “GPIO_InitStructure.GPIO_Pin= GPIO_Pin_All;”) 4) 设置引脚速率(三种 10MHz 2MHz 50MHz 3.5固件库手册P125 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; ) 5) 为引脚模式选择输出模式(四种输出模式3.5固件库手册P125 GPIO_InitStructure.GPIO_Mode= GPIO_Mode_XXXXXXXXX) file:///C:/Users/YLenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image020.png 6) 初始化GPIOB PS: 后面的GPIOF可以直接选择引脚并初始化可以省略45步骤 GPIO_Init(GPIOA,&GPIO_InitStructure) 这里的初始化可以追到GPIO_InitTypeDef GPIO_InitStructure;进入定义 file:///C:/Users/YLenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image022.jpg 其实可以在3.5固件库P124内找到 7) 关闭LED灯 PS: GPIOB与GPIOF都要关闭 GPIO_SetBits设置指定的数据端口位 至于为什么GPIOB PIN0 ,GPIOF PIN7 8引脚置1会关闭LED灯就要看原理图了 file:///C:/Users/YLenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image024.jpg 第四步 回到main.c函数 LED1_TOGGLE; Delay(0x0FFFFF); LED1_TOGGLE; 这里用的是自定义宏的方式来完成LED灯的亮灭 进入LED1_TOGGLE;的定义可以发现其实是个定义控制IO的宏 #define LED1_TOGGLE digitalToggle(GPIOB,GPIO_Pin_0) 在这里还要提到一点点寄存器的操作,就是BSRR和BRR 这两个寄存器都是可以对ODR进行修改 BSRR是一个32位寄存器,由于我们使用的是GPIO端口是16位的,只用到BSRR的低16位,所以#define digitalHi(p,i) {p->BSRR=i;} 一旦低十六位设置为高电平,则ODR也会相应变为高电平 BRR是16位寄存器,#definedigitalLo(p,i) {p->BRR=i;} 此时设置为高电平的话那ODR相应的位就会被清除为零。所以输出的是低电平 第五步调用固件库控制IO来实现LED流水灯 LED1( ON ); Delay(0x0FFFFF); LED1( OFF ); 在bsp.led.h文件中可以看到开始对于ON OFF的定义以及带参宏 file:///C:/Users/YLenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image026.jpg GPIO_SetBits(GPIOB,GPIO_Pin_0);可以在3.5固件库P128找到 第六步 直接操作寄存器实现流水灯操作 GPIOB->ODR = 0XFFFE; /低电平,LED亮 Delay(0x0FFFFF); GPIOB->ODR= 0XFFFF; /高电平,LED灭 这个是直接操作ODR寄存器 那么我就想试试用BRR寄存器来控制一下 GPIOB->BRR = 0XFFFF Delay(0x0FFFFF); GPIOB->BRR = 0XFFFE; 结果运行后发现LED灯只会亮不会灭,这是什么情况。。。。跟我想象中完全不一样
|