本人是初学者,水平有限,写个简单的学习笔记方便大家参考,同时也方便自己查缺补漏。
STM32学习一
1.点亮板上的LED小灯
首先,我们在点灯之前还要看看LED的硬件连接
看到硬件电路后,发现小灯是低电平点亮的,也就说通过给的IO口送低电平就可以点亮LED了。那么我们该如何操作呢,是像51单片机那样直接给直接类似sbit LED = P1 ^ 0;那后在主函数里写个LED = 0;就好了呢?回答没有那么简单,在STM32里面可以通过寄存器的配置来操作IO口,也可以通过STM32的固件库来操作IO口。当然直接操作寄存器的话,感官上比较的直接,但是如果我们要配置很多的IO口以及模式的时候就没那么方便了,或许我输错了一个字符,我们相应的操作就没法实现,所以我个人推荐使用固件库来操作。因为所有的外设的驱动官方都给封装好了,方便直接,至于怎么实现的就要看你学习的深度了,刚开始熟悉固件库的使用就好了。
那么我们操作IO的相应的库函数有哪些呢,下面我来简单的说一下,直说我下面例程里用到的函数,没有用到的我就不讲了,因为库函数很多,要全部都讲的话你我都吃不消。好的,现在我要全部点亮5个LED小灯我需要用到下面的库函数:
1)GPIO_InitTypeDef GPIO;结构体
2)void RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);时钟配置函数
3)GPIO_Init(GPIOF, &GPIO);IO初始化函数
4)GPIO_Write(GPIOF, 0XF73F); IO操作函数
5)GPIO_Reset(GPIOF, GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10); IO操作函数
下面我就来详细说说每个库函数是干嘛的,我们该怎么用。先看第一个,在库函数里面他是如下先表示的:
typedef struct
{
Uint16_t GPIO_Pin;
GPIOSpeed_TypeDef GPIO_Speed;
GPIOMode_TypeDef GPIO_Mode;
}GPIO_InitTypeDef; 结构体里的第一个代表是每一个管脚我们填的参数是GPIO_Pin_0 ~ GPIO_Pin_15 或者GPIO_Pin_All;记得每次初始化的时候只能写一个,要初始化多个请参考GPIO_Pin_0 | GPIO_Pin_1;我们把这个结构体又重新定了一个名字叫GPIO;紧接着我们就要给结构体里填东西了
GPIO.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10; //初始化6,7,8,9,10管脚
GPIO.GPIO_Mode = GPIO_Mode_Out_PP; //设置IO口为推挽输出
GPIO.GPIO_Speed = GPIO_Speed_50MHz; //设置IO响应速度为 50MHZ;
紧接着初始化时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);//使能F组IO时钟 设置时钟为72MHZ
再接着初始化IO GPIO_Init(GPIOF, &GPIO); &GPIO就是我们定义的结构体;
下面我们看看程序如何编写的:
#include “stm32f10x.h”
void LED_GPIO_Init(void) {
GPIO_InitTypeDef GPIO;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);
GPIO.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
GPIO.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOF, &GPIO);
GPIO_Write(GPIOF, 0XFFFF);
}
int main (void) {
LED_GPIO_Init();
while (1) {
GPIO_ResetBits(GPIOF, GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 );
}
}
烧写到开发板上,是不是发现5个灯亮了起来。
其中还有俩个GPIO_Write();跟GPIO_ResetBits();函数,大家看看具体写的参数也应该知道啥意思了,我就不多说了。
2.跑马灯
如果小灯点亮起来,那么我们让小灯有点动作,也是初学者常做的跑马灯了,前面都能看懂的话,我就直接上程序有新的东西我会指出的
#include "stm32f10x.h"
void LED_GPIO_Init(void) {
GPIO_InitTypeDef GPIO;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);
GPIO.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
GPIO.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOF, &GPIO);
GPIO_Write(GPIOF, 0XFFFF);
}
void delay(uint32_t counter) {
while (counter --);
}
int main (void) {
int i;
LED_GPIO_Init();
while (1) {
for (i = 0; i < 5; i ++) {
switch (i) {
case 0: GPIO_ResetBits(GPIOF, GPIO_Pin_6); break;
case 1: GPIO_ResetBits(GPIOF, GPIO_Pin_7);
break;
case 2: GPIO_ResetBits(GPIOF, GPIO_Pin_8); break;
case 3: GPIO_ResetBits(GPIOF, GPIO_Pin_9); break;
case 4: GPIO_ResetBits(GPIOF, GPIO_Pin_10); break;
}
delay(0x000fffff);
GPIO_Write(GPIOF, 0XFFFF);
}
}
}
里面也没有啥新鲜的东西,玩过51或者AVR的人这里看看就是一些C语言的操作,其实学习ARM裸机开发跟学习51差不多,因为目前都不需要我们直接操作寄存器,这样显得方便很多
3.呼吸灯
写呼吸灯之前我们先要了解一个概念叫做PWM,什么是PWM呢?上百度去查叫做脉冲宽度调制,说的好高打上看不懂,啊是?下面我找了一张图片,相信大家就能明白了
了解一个概念:占空比=高电平所占时间/周期T。我们就是通过控制占空比来控制的灯亮灭情况,看起来就像人在呼吸的样子。程序里该如何实现呢?我们整定一个固定的周期,然后让高低电平延时的时间之和跟这个周期相等就好了,下面也直接上程序吧
#include "stm32f10x.h"
void LED_GPIO_Init(void) {
GPIO_InitTypeDef GPIO;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);
GPIO.GPIO_Pin = GPIO_Pin_6;
GPIO.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOF, &GPIO);
GPIO_Write(GPIOF, 0XFFFF);
}
void delay(uint32_t counter) {
while (counter --);
}
int main (void) {
int i, b;
LED_GPIO_Init();
b = 20000;
while (1) {
for (i = 0; i < b; i ++) {
GPIO_ResetBits(GPIOF, GPIO_Pin_6);
delay(b - i);
GPIO_SetBits(GPIOF, GPIO_Pin_6);
delay(i);
}
for (i = 0; i < b; i++) {
GPIO_ResetBits(GPIOF, GPIO_Pin_6);
delay(i);
GPIO_SetBits(GPIOF, GPIO_Pin_6);
delay(b - i);
}
delay(100);
}
}
烧写到板子上面看到灯的变化没有?如果看到了,那么LED的操作就到这里了,这也是GPIO的基本操作,掌握好了之后,就可以驱动
喇叭,继电器等一些常用的外设了。再者PWM是STM32自带的一个功能,我们现在是模拟PWM,等到时候直接操作STM32的PWM的时候就比这个更加的方便了。
最后我说下,我用的是MDK开发的,至于ARM的工程模版的建立,在以后的学习的过程中我会专门写一篇来介绍ARM工程模版的建立,方便我们后续的开发。
编者水平有限,属于初学者,有不到之处还请海涵,如果出现问题,直接加我QQ,上面有我的QQ号码。同时也欢迎大家一起来讨论学习。