一.前言
对于ALIENTEK MiniSTM32来说,要完成跑马灯的操作,以板子自带的LED为例,要了解哪个IO口对应的该LED的操作(硬件),怎么对IO口进行操作(软件)。
二.硬件
对于ALIENTEK MiniSTM32,板子自带的LED(DS0,DS1)已经在开发板上与对应的IO口相连接,DS0接PA8,DS1接PD2。
(上图为STM32与LED 的连接图)
三.软件
1.IO口的初始化,初始化 PA8 和 PD2 为输出口(并且默认输出为1).并使能这两个口的时钟
(新建文件led.c)
#include"led.h"
void LED_Init(void)
{
RCC->APB2ENR|=1<<2; //使能PORTA时钟
//(问题:APB2ENR是什么,为什么要选用APB2)
RCC->APB2ENR|=1<<5; //使能PORTD时钟
GPIOA->CRH&=0XFFFFFFF0; //清除相应的位
GPIOA->CRH|=0X00000003; //PA8推挽输出
//(问题:什么是推挽输出,ODR是什么,位运算)
GPIOA->ODR|=1<<8; //PA8输出高
GPIOD->CRL&=0XFFFFF0FF;
GPIOD->CRL|=0X00000300; //PD2推挽输出
//(问题:CRL,CRH是什么)
GPIOD->ODR|=1<<2; //PD2输出高
}
APB2ENR是什么?
APB2ENR是APB2总线上的外设时钟使能寄存器
为什么要选用APB2?
时钟是由RCC控制,RCC挂载在AHB系统总线,如果需要打开GPIOB的时钟,就需要打开APB2的外设时钟。
什么是推挽输出?
可以输出高低电平,连接数字器件。在stm32中推挽电路由两个MOS管组成:输出高电平时P-MOS管导通,引脚联通VDD(3.3v)。输出低电平时N-MOS导通,引脚联通GND。
ODR是什么?
ODR 是一个端口输出数据寄存器,。该寄存器为可读写,从该寄存器读 出来的数据可以用于判断当前 IO 口的输出状态。
位运算
& 与1不变,与0为0
| 或0不变,或1为1
CRL,CRH是什么?2
CRL 和 CRH 是配置模式的 2 个 32 位的端口配置寄存器,控制着每个 IO 口的模式及输出速率。
对于这部分的操作,首先要明白对哪个IO口进行操作,再选择初始化时钟,配置IO口的工作方式,最后控制IO口输出高低电平。
2新建led.h
#ifndef__LED_H
#define__LED_H
#include"sys.h" //sys.h里面定义了STM32的I/O口输入读取宏定义和输出宏定义
//LED端口定义
#define LED0 PAout(8) //PA8
#define LED1 PDout(2) //PD2
void LED_Init(void); //初始化
#endif
(sys.h里面有关的宏定义)
3.新建main函数
#include "sys.h"
#include "delay.h"
#include "led.h"
int main(void)
{
Stm32_Clock_Init(9); //系统时钟设置
delay_init(72); //延时初始化
LED_Init(); //初始化与LED连接的硬件接口
while(1)
{
LED0=0;
LED1=1;
delay_ms(300);
LED0=1;
LED1=0;
delay_ms(300);
}
}
时钟的初始化
Stm32_Clock_Init 函数中,我们设置了 APB1 为 2 分频,APB2 为 1 分频,AHB 为 1 分频, 同时选择 PLLCLK 作为系统时钟。该函数只有一个参数 PLL,就是用来配置时钟的倍频数的, 比如当前所用的晶振为 8Mhz,PLL 的值设为 9,那么 STM32 将运行在 72M 的速度下。
(u8表示8位长度的数据类型,一个字节是8位,所以,u8是一个字节。)