 |
本程序使用的STM32芯片为:STM32F103C8 本程序使用的开发板为:http://meal.taobao.com/mealDetail.htm?spm=2013.1.0.0.IOMsWD&meal_id=161586695&item_num_id=40217070052&seller_id=636776613 运行效果: 第二个灯(PB9)不停地闪烁 
|
 |
|
 |
【程序】 // core_cm3.h头文件路径: C:\Keil_v5\ARM\Pack\ARM\CMSIS\4.5.0\CMSIS\Include // 汇编文件路径: C:\Keil_v5\ARM\Pack\Keil\STM32F1xx_DFP\2.1.0\Boards\Keil\MCBSTM32C\Middleware\NetworkDS\BSD_Client\RTE\Device\STM32F107VC
#include <stm32f10x.h>
#define _BV(n) (1 << (n))
// 延时函数, 时间约为半秒钟 // 其中数字我是随便写的,只要肉眼能看出来就行了 void delay() { int a, b; for (a = 0; a < 1000; a++) for (b = 0; b < 1000; b++); }
// 初始化I/O口 void init() { // 打开GPIOB的时钟 RCC->APB2ENR |= _BV(3); // 将PB9设置为: 输出模式,最大速度为10MHz GPIOB->CRH &= ~_BV(5); GPIOB->CRH |= _BV(4); }
int main(void) { init(); // 要点亮的LED灯为PB9 while (1) { GPIOB->BSRR = _BV(9); // 使PB9输出1,点亮LED灯 delay(); GPIOB->BRR = _BV(9); // 使PB9输出0,熄灭LED灯 delay(); // 记忆方法: 长的那个是输出1,短的那个是输出0 } }
// 下面这个函数必须写出来,否则编译会出错 void SystemInit() { }
|
 |
【知识点】 [1] 对于一个数a,执行a |= _BV(3)后即可将该数从右往左数第4位设置为1,执行a &= ~_BV(4)后即可将从右往左数第5位设为0。 例如,若a的值用二进制表示为00000000时,执行a |= _BV(0)后,a的值将变为00000001; 再执行a |= _BV(4)后将变为00010001 若此时再执行a &= ~_BV(4),a的值将变回00000001
[2] _BV(0) = 00000001 _BV(1) = 00000010 _BV(2) = 00000100 _BV(3) = 00001000 _BV(7) = 10000000 以此类推。
|
 |
[3] 在使用一个I/O口之前,需要开启时钟,然后设置输入/输出模式。 例如,本例在使用PB9之前,需要开启GPIOB的时钟,然后将PB9设置为输出。 开启GPIOB时钟的方法是把RCC->APB2ENR寄存器的第[3]位设为1,也就是执行: RCC->APB2ENR |= _BV(3); 该寄存器的结构如下图所示: 
|
 |
从图中可以看出,要打开GPIOA的时钟,只需把该寄存器的第[2]位设置为1就行了。
|
 |
[4] PB0~PB7的输入输出模式在寄存器GPIOB->CRL中设置,PB8~PB15是在GPIOB->CRH中设置。 GPIOB->CRL的第[1][0]位控制PB0端口,[5][4]控制PB1,[9][8]控制PB2,[13][12]控制PB3,一直到[29][28]控制PB7。 CRH寄存器中也是一样,只不过是从PB8到PB15。
|
 |
CRL:  CRH: 
|
 |
10樓
巨大八爪鱼
2016-4-23 14:10
|
 |
11樓
巨大八爪鱼
2016-4-23 14:12
因此,要想把PB9设为输出模式,只需要把CRH的第[5][4]位设为01、10或11就行了。 在本例中是设置的01,即速度为10MHz: GPIOB->CRH &= ~_BV(5); GPIOB->CRH |= _BV(4);
|