、写在前面:最近在看江协科技的STM32入门课程,以此记录,当个笔记。
一、硬件准备
1、STM32F103C8T6最小系统板,面包板,杜邦线,STlink下载器,一个LED灯。
二、STM32C8T6简介
系列:主流系列STM32F1 内核:ARM Cortex-M3 主频:72MHz RAM:20K(SRAM) ROM:64K(Flash) 供电:2.0~3.6V(标准3.3V) 封装:LQFP48
片上资源外设:
三、GPIO
GPIO是通用输入/输出端口的简称,是STM32可控制的引脚。GPIO的引脚与外部硬件设备连接,可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。
GPIO基本结构
1、浮空输入模式(GPIO_Mode_IN_FLOATING)
浮空输入模式下,I/O口的高低电平信号直接进入数据寄存器,I/O口的电平状态完全由外部端口决定,如果I/O引脚悬空,读取该引脚的电平是不确定的。
2、上拉输入(GPIO_Mode_IPU)
上拉输入模式下,I/O端口电平直接进入数据寄存器。但当I/O引脚悬空时,因内部接入了上拉电阻,保持高电平。接入低电平时,读取I/O引脚时仍为低电平。
3、下拉输入(GPIO_Mode_IPD)
下拉输入模式下,I/O端口电平直接进入数据寄存器。但当I/O引脚悬空时,因内部接入了下拉电阻,保持低电平。接入高电平时,读取I/O引脚时仍为高电平。
4、模拟输入(GPIO_Mode_AIN)
模拟输入模式下,I/O端口的模拟信号(电压信号,而非电平信号)直接模拟输入到片上外设模块,比如ADC模块等等。
5、开漏输出模式(GPIO_Mode_Out_OD)
开漏输出模式下,通过设置位设置/清除寄存器或者输出数据寄存器的值,途经N-MOS管,最终输出到I/O端口。注意N-MOS管,当设置输出的值为高电平的时候,N-MOS管处于关闭状态,此时I/O端口的电平就不会由输出的高低电平决定,而是由I/O端口外部的上拉或者下拉决定;当设置输出的值为低电平的时候,N-MOS管处于开启状态,此时I/O端口的电平就是低电平。同时,I/O端口的电平也可以通过输入电路进行读取;注意,I/O端口的电平不一定是输出的电平。
6、复用开漏输出模式(GPIO_Mode_AF_OD)
复用开漏输出模式下,与开漏输出模式相似,只是高低电平的来源为片上外设。
7、推挽输出(GPIO_Mode_OUT_PP)
推挽输出模式下,通过设置位设置/清除寄存器或者输出数据寄存器的值,途经P-MOS管和N-MOS管,最终输出到I/O端口。注意P-MOS管和N-MOS管,当设置输出的值为高电平的时候,P-MOS管处于开启状态,N-MOS管处于关闭状态,此时I/O端口的电平就由P-MOS管决定:高电平;当设置输出的值为低电平的时候,P-MOS管处于关闭状态,N-MOS管处于开启状态,此时I/O端口的电平就由N-MOS管决定:低电平。同时,I/O端口的电平也可以通过输入电路进行读取;注意,此时I/O端口的电平一定是输出的电平。
8、复用推挽输出(GPIO_Mode_AF_PP)
推挽复用输出模式,与推挽输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的。
四、LED简介
LED:发光二极管,正向通电点亮,反向通电不亮。
五、硬件电路连接
、
电阻作用:保护电路。
六、程序实现
工程模板为江科大STM32课程工程模板
LED.h
#ifndef _LED_H
#define _LED_H
#define GPIO GPIOA
#define GPIOPIN GPIO_Pin_1
void LED_init(void);
void LED_ON(void);
void LED_OFF(void);
#endif
LED.c
#include "stm32f10x.h" // Device header
#include "led.h"
/*
*函数功能: LED初始化
*函数参数: 无
*返回值: 无
*/
void LED_init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //开始GPIOA的时钟
GPIO_InitTypeDef GPIO_InitStructer; //定义一个结构体
GPIO_InitStructer.GPIO_Mode = GPIO_Mode_Out_PP; //设置模式为推挽输出
GPIO_InitStructer.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructer.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructer);
GPIO_SetBits(GPIOA,GPIO_Pin_1); //设置初始默认电平
}
/*-------------------------------------------------------------------------------------*/
/*
*函数功能: LED开启
*函数参数: 无
*返回值: 无
*/
void LED_ON(void)
{
GPIO_ResetBits(GPIO,GPIOPIN); //设置PA1引脚为低电平
}
/*-------------------------------------------------------------------------------------*/
/*
*函数功能: LED关闭
*函数参数: 无
*返回值: 无
*/
void LED_OFF(void)
{
GPIO_SetBits(GPIO,GPIOPIN); //设置PA1引脚为低电平
}
main.c
#include "stm32f10x.h" // Device header
#include "led.h"
#include "delay.h"
int main(void)
{
LED_init();
while (1)
{
LED_ON();
delay_ms(500);
LED_OFF();
delay_ms(500);
}
}
delay.c
#include "stm32f10x.h" // Device header
/*微秒级延时,范围:0~233015 */
void delay_us(uint32_t us)
{
SysTick->LOAD = 72 * us; //设置定时器重装值
SysTick->VAL = 0x00; //清空当前计数值
SysTick->CTRL = 0x00000005; //设置时钟源为HCLK,启动定时器
while(!(SysTick->CTRL & 0x00010000)); //等待计数到0
SysTick->CTRL = 0x00000004; //关闭定时器
}
/*毫秒级延时,范围:0~4294967295*/
/*将微秒级的延时函数延时1000微秒,得到延时一毫米,进行循环*/
void delay_ms(uint32_t ms)
{
while(ms--)
{
delay_us(1000);
}
}
/*秒级延时,范围:0~4294967295 */
/*与毫秒级延时同理,将毫秒级延时延时1000毫秒,得到1秒延时*/
void delay_s(uint32_t s)
{
while(s--)
{
delay_ms(1000);
}
}
delay.h
#ifndef _DELAY_H
#define _DELAY_H
void delay_us(uint32_t us);
void delay_ms(uint32_t ms);
void delay_s(uint32_t s);
#endif
STM32启动流程:
- 根据BOOT引脚的设置,选择启动模式,将主闪存、系统存储器或内置SRAM映射到0x00地址。
- 硬件初始化SP(栈指针),跳转到Reset_Handler(复位中断服务函数)。
- 软件初始化系统时钟(SystemInit),配置系统频率和时钟源。
- 软件初始化SP(栈指针),设置堆栈大小和位置。
- 跳转到main函数,开始执行用户程序。