ps:
开发模式
1.基于库函数(标准库) 推荐
2.基于HAL库 图形化
3.基于寄存器 最直接
一、创建工程
1、打开keil5
new Project->路径->命名->保存
2、选择型号:stm32f103c8
初始创建工程我们不使用快捷项目建设
3、准备
在项目目录处创建User和Start
对start目录
配置路径
结果展示
直到这一步我们只是解决基于寄存器开发。
(一)GPIO(General Purpose Input Output)通用输入输出口 共有八种工作模式
1、作用
输出控制:设高低电平,控外设(如 LED、继电器、电机等)开关。
输入采集:当输入引脚,采外设状态(如按钮、传感器信号)。
通信扩展:模拟 I2C、SPI 等协议,与设备数据交互。
逻辑构建:组合引脚
2、连接:挂载在APB2外设总线上
分为GPIOA-GPIOAE
每个GPIO均有16个引脚,分别为PX0-PX15
同时连接方式:
PX0-PX15(共16位) -> 驱动程序(驱动增强) -> 寄存器(共32位,所以只用到低16位) -> APB2
GPIO组成:驱动程序和寄存器
3、输入模式
上拉输入模式:保持高电平
下拉输入模式:保持低电平
浮空模式:高低电平浮动,无法确定
模拟输入模式(ADC):连续。模拟信号
TTL施密特触发器:将模拟信号转换为数字信号
复用功能输入:数字信号
输入数据寄存器:存储
4、输出模式
位设置/清除寄存器:操作某一位的引脚高低电平。写入
输出数据寄存器:读/写
输出控制:上为P-MOS连接VDD(高电平),下接N-MOS连接VSS(低电平)。存在三种模式:
(1)推挽输出模式:
若寄存器为1时,连接P-MOS,输出VDD高电平;
若寄存器为0时,连接N-MOS,输出VSS低电平;
此时写入数据对引脚具有绝对控制!
(2)开漏模式模式:P-MOS管无效,只有N-MOS作用。作为通信协议的驱动模式(I2C)
只有低电平具有驱动作用。
若寄存器为1时,N-MOS断开,成高阻态;
若寄存器为0时,连接N-MOS,输出VSS低电平;
(3)关闭模式:上下均关闭,由外部信号控制
片上外设:控制下述两类模式,只为其提供电平输入,其余作用同上。
复用开漏模式
复用推挽模式
5、分类
端口配置寄存器(共两个64位):每一个引脚端口需要4位控制,所以需要4*16=64
端口配置高寄存器:GPIOx_CRH,x为A-E
端口配置低寄存器:GPIOx_CRL,x为A-E
端口输入寄存器(GPIOx_IDR,x为A-E):高十六位不使用,低十六位对应16个引脚
端口输出寄存器(GPIOx_ODR,x为A-E):高十六位不使用,低十六位对应16个引脚
端口位设置/清除寄存器(GPIOx_BSRR,x为A-E):
高十六位对应清除功能,低十六位对应位设置功能;
写1标识清除或者设置,0标识不影响
端口位清除寄存器(GPIOx_BRR,x为A-E):低十六位作用同上对应清除功能
端口配置锁定寄存器(GPIOx_LCKR,x为A-E):对操作端口信号进行锁定
(二)其他外设
LED:长脚为正,短脚为负
有源蜂鸣器:自带震荡源,接上正负极即可正常工作
三级管:基集、发射集、集电极;前者电位相异则集电极通电导通
(PNP三级管,如右上图;NPN三极管为右下图)
面包板:横向导通和竖向导通
基本流程:电源->跳线->电阻->LED->跳线->电源
三、LED点亮
1、new Project
2、命名保存
3、型号:stm32f103C8
4、直接叉掉
5、在工程文件夹创建三个文件夹:User、Start、Library
5.1 对Start文件夹:
5.2 对Library:
由两部分组成
5.3 对User:
6、在keil中,添加文件
6.1 添加Group
6.2 添加文件
对Start:
效果图
对Libarary:
效果图
对User:
效果图
最后一定点击OK
将导入的main.c清空
7、配置路径
效果图
7、配置宏:USE_STDPERIPH_DRIVER
8、初始main.c
#include "stm32f10x.h" // Device header
int main(){
while(1){
}
}
9、配置仿真 ST-Link
10、编译结果
11、小工具:删除编译产生的中间文件,缩小空间便于传递压缩包
keilkill.bat文件(缺图一张)
3.31
12、代码编写
(1)RCC外设库函数
常用函数
RCC/AHB外设时钟控制
RCC/APB1外设时钟控制
RCC/APB1外设时钟控制
void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
(2)GPIO库函数
此步骤包含选择GPIO工作模式、执行速度、控制端口(推挽输出模式、50MHz、pin0)
(3)GPIO库函数操作控制位
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//1
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//0
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
完整函数
#include "stm32f10x.h" // Device header
//目的:点亮PA0的LED
//步骤:
/*
1、RCC启用GPIOA时钟
2、初始化GPIOA
3、使用函数控制GPIOx位
*/
int main(){
//创建初始化对象
GPIO_InitTypeDef myGPIOA;
myGPIOA.GPIO_Pin = GPIO_Pin_0;
myGPIOA.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
myGPIOA.GPIO_Speed = GPIO_Speed_50MHz;
//1、RCC开启始终
//RCC_APB2PeriphClockCmd接受两个参数
//第一个参数表明操作谁的时钟
//第二个参数表明使能或者禁止
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
//2、初始化GPIO
//两个参数 第一个标识操作哪个外设GPIOx
GPIO_Init(GPIOA,&myGPIOA);
//3、外设函数操作
//GPIO_ResetBits(GPIOA,GPIO_Pin_0);//0 亮
//GPIO_SetBits(GPIOA,GPIO_Pin_0);//1
//GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_RESET);//0
//GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_SET);//1
GPIO_Write(GPIOA,Bit_RESET);
while(1){
}
}
推挽输出:高低电平均可以
开漏输出:仅低电平
四、LED流水线
代码
#include "stm32f10x.h" // Device header
#include "Delay.h"
//步骤:
/*
1、RCC启用GPIOA时钟
2、初始化GPIOA
3、使用函数控制GPIOx位
*/
int main(){
//创建初始化对象
GPIO_InitTypeDef myGPIOA;
myGPIOA.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
myGPIOA.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
myGPIOA.GPIO_Speed = GPIO_Speed_50MHz;
//1、RCC开启始终
//RCC_APB2PeriphClockCmd接受两个参数
//第一个参数表明操作谁的时钟
//第二个参数表明使能或者禁止
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
//2、初始化GPIO
//两个参数 第一个标识操作哪个外设GPIOx
GPIO_Init(GPIOA,&myGPIOA);
//3、外设函数操作
while(1){
GPIO_Write(GPIOA,~0x0001);//0000 0000 0000 0001 低电平有效此时
Delay_s(1);
GPIO_Write(GPIOA,~0x0002);//0000 0000 0000 0010 低电平有效此时
Delay_s(1);
}
}
五、蜂鸣器
代码
#include "stm32f10x.h" // Device header
#include "Delay.h"
//目的:蜂鸣器B10
//步骤:
/*
1、RCC启用GPIOX时钟
2、初始化GPIOX
3、使用函数控制GPIOx位
*/
int main(){
//创建初始化对象
GPIO_InitTypeDef myGPIOB;
myGPIOB.GPIO_Pin = GPIO_Pin_10;
myGPIOB.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
myGPIOB.GPIO_Speed = GPIO_Speed_50MHz;
//1、RCC开启始终
//RCC_APB2PeriphClockCmd接受两个参数
//第一个参数表明操作谁的时钟
//第二个参数表明使能或者禁止
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
//2、初始化GPIO
//两个参数 第一个标识操作哪个外设GPIOx
GPIO_Init(GPIOB,&myGPIOB);
//3、外设函数操作
while(1){
GPIO_ResetBits(GPIOB,GPIO_Pin_10);
Delay_ms(1000);
GPIO_SetBits(GPIOB,GPIO_Pin_10);
Delay_ms(3000);
GPIO_ResetBits(GPIOB,GPIO_Pin_10);
Delay_ms(100);
}
}
至此基本结束!