编写第一个程式
修改1:20210531
第一个步骤一定是写一个简单的程式 由 data BUS 输出 Hi/Low 控制 LED 亮灭,来確定这个开发板是可以用的,确认是可以被控制的。不过,ARM 的设定有一些复杂,需要一边看参考手册,一边做设定。下边列了STM32 的网站,除了下载参考手册以外,也建议注册一下,然后,在上面找找有没有其他好货可以下载的!!
STM32F072RB 规格资料
Mainstream ARM Cortex-M0 USB line MCU with 128 Kbytes Flash, 48 MHz CPU, USB, CAN and CEC functions
.
STM32F072RB Reference manual (参考手册)
RM0091: STM32F0x1/STM32F0x2/STM32F0x8 advanced ARM®-based 32-bit MCUs
设定 GPIO 的方法
设定GPIO的程序
1. 打开 特定 GPIO 的时钟 (AHBENR)
2. 设定 这个 GPIO 特定 脚位的 功能 inpu、output,(MODER)。
3. 设定响应的时钟的频率(OSPEEDR)
4. 设定硬体的匹配方式 PP、OD、(OTYPER)
“0” – Push-pull模式, “1” – OD 模式。
5. 设定硬件对外的物理匹配 pull-up、pull-down (PUPDR)
以下的资料都是从 “RM0091: 参考手册” 摘取出来。
void GPIOA6_7_8_init(void)
{
RCC -> AHBENR |=0x1ul <<17;
GPIOA->MODER &=~ ((0x03ul <<6*2)|(0x03ul <<7*2)|(0x03ul <<8*2));
GPIOA->MODER |=(0x01ul <<6*2)|(0x01ul <<7*2)|(0x01ul <<8*2);
GPIOA->OSPEEDR |=(0x01ul <<6*2)|(0x01ul <<7*2)|(0x01ul <<8*2);
}
上图是配置 Port-A 的 6/7/8 三只脚为输出模式;下图是配置 Port-C 的 )0~7 八只脚为输出。
void GPIOC0_7_init(void) //--define Port C, pin 0~7
{
RCC->AHBENR |= 0x1ul<<19;
GPIOC->MODER &= ~(0xfffful);
GPIOC->MODER |= 0x5555ul;
GPIOC->OSPEEDR &= ~0xfffful;
GPIOC->OSPEEDR |= 0x5555ul;
}
AHB peripheral clock enable register (RCC_AHBENR)(第127页)
GPIO port mode register (GPIOx_MODER) (x =A…F)(第165页)
GPIO port output speed register (GPIOx_OSPEEDR) (x = A…F)(第166页)
当观察程式内容会发现,MODER 和OSPEEDR 都是同时出现两次,其目的是第一次清除需求的位置里的内容,第二次是设定需要的值。
下图是
Table 24. Port bit configuration table
(第157页)
GP = general-purpose, PP = push-pull, PU = pull-up, PD = pull-down, OD = open-drain, AF = alternate function.
清除的设定是 一个 pin 位 0x01, 两个 pin 位 是0x03, 四个 pin 位 是0x0f; 让后用反向 变成 00,再做 AND 处理。后面的 << 6 * 2 就是 第 6 脚用的 2 位置, << 9 * 2 就是 第 9 脚用的 2 位置.
(当然,如果是 1 位置,这个 1 会被省略)。MODER 和 OSPEEDR 都是 2 位置。
#define AllLed_on 1
#define AllLed_off 2
#define OddLed_on 3
#define evenLed_on 4
#define BitLed_on 5
#define R_on 6
#define G_on 7
#define B_on 8
先把需要的功能定义起来,再用 function()做规划,然后在main.c 里面就很方便使用了。
void Ledchange(uint8_t mode)
{
switch(mode){
case AllLed_on:
GPIOC->ODR |= 0xfful;
break;
case AllLed_off:
GPIOC->ODR &=~0xfful;
// GPIOC->ODR &= 0xfffffful;
break;
case OddLed_on:
GPIOC->ODR &=~0xfful;
GPIOC->ODR |= 0x55ul;
break;
case evenLed_on:
GPIOC->ODR &=~0xfful;
GPIOC->ODR |= 0xaaul;
break;
case BitLed_on:
for(int i=0;i<8;i++){
GPIOC->ODR &=~0xfful;
GPIOC->ODR |= 0x1ul <
Delay(12*i);
}
break;
}
}
int main (void) {
,...
...
Ledchange(AllLed_on);
Delay(500);
Ledchange(AllLed_off);
Delay(500);
Ledchange(OddLed_on);
Delay(500);
...
}