-
将
stm32f103z8t6
模板改成
stm32f103c8t6
只需要将
c++
MD
改为
S
TM32F10X_MD,USE_STDPERIPH_DRIVER
STM32
嵌入式笔记
常见知识点解析
第
1
页
共
1
页
前言
:基础知识
VDD:
电源电压(单极器件);电
源电压(
4000
系列数字电
路);漏极电压(场效应
管)
VCC
:
电源电压
(
双极器件)
;
电源电压
(
74
系列数字电路)
;
声控
载波
(
Voice Controlled
Carrier)
VSS:
地或电源负极
VEE
:负电压供电;场效应管的源极(
S
)
VPP
:编程
p>
/
擦除电压。
详解:
在电子电路中,
VCC
是电路的供电电压
,
VDD
是芯片的工作电压:
VCC
:
C=circuit
表示电路的意思
,
即接入电路的电压,
D=device
表示器件的意思
,
即
器件内部的工作电压,在普通的电子电路中,一般
Vcc>Vdd !
VSS
:
S=series
表示公共连接的意思,也就是负极。
有些
IC
同时有
VCC
和
VDD
,
这种器件带有电压转换功能。
在
“
场效应
”
即
COMS
元件中,
VDD
乃
CMOS
的漏极引脚,
VSS
乃
CMOS
的源极引脚,<
/p>
这是元件引脚符号,它没有
“VCC”
的名称,你的问题包含
3
个符号,
p>
VCC / VDD /VSS
,
这显然是电路符号。
第
2
页
共
2
页
开放板硬件资源连接:
LED0=PB5
p>
LED1=PE5(
通过
TIM3
控制的
LED1
的闪烁情况)
< br>
KEY0 =PE4
KEY1=PE3
KEY2=PE2
KEY_UP=PA0
While
();
当括号里面为
1
时为真时,
p>
这是一个死循环,
代码不再向下执行。
当括
号里面为
0
为
假,代码继续向下执行。
While(1);
这是一个死循环,代码不再向下执行。
任何美好情感的得到,任何美好事物的创造
从来都是不轻松的
你不可能轻轻松松的实现
梦想
获得成功
人类一切美好的东西都是要有称重的
都是会累的
其实所谓的爱就是分享
同步的感受这个世界,成熟起来独立和分享
你们在同步的观察和感受这个世界
努力让自己独立起来
在一起时努力甜蜜,不在一起时各自精彩
第
3
页
共
3
页
浮空输入:
浮空就是逻辑电平器件的输入引脚不接高电平也不接低电平,
由于逻辑电平的内
部的结构,
当输入引脚悬空时,
相当于该引脚
接入了高电平。
一般实际运用时,该引脚不建
议悬空,易受干扰
。通俗的讲就是让管教什么也不接,浮空着。
模拟输入:模拟输入是指传统方式的输入。数字输入时输入
PCM
数字信号。即
0
、
1
p>
的二进
制数字信号,通过数模转换,转换成模拟信号,经前级放大进
入功率放大器,功率放大器还
是模拟的。
推挽输出:
可以输出高电平,低电平
,连接数字器件,推挽结构一般是指两个三极管分别受
两个互补信号的控制,总是在一个
三极管导通的时候另一个截止。高低电平由
IC
的电源决
定。
开漏输出:
输出端相当于三极管的集电极,
要得到高电平状态需要上拉电阻
才行,
适合于做
电流型驱动,其吸收电流能力相对较强。
复用开漏输出、复用推挽输出:可以理解
为
GPIO
口被用作第二功能时的配置情况(即并非
作为通用
IO
口使用)
第
4
页
共
4
页
GPIO_Mode_AIN
模拟输入
GPIO_Mode_Out_O
D
开漏输出
PIO_Mode_IN_FLOATING
浮空输入
GPI
O_Mode_Out_PP
推挽输出
GPIO_Mode_IPD
下拉
GPIO_Mode_AF_OD
复用开漏输出
GPIO_Mode_IPU
上拉
p>
GPIO_Mode_AF_PP
复用推挽输出
关
于
引
脚
复
用
与<
/p>
映
射
的
问
题
:
default(
默
认
复
用
功
能
)
<
/p>
remap(
重定义功能
)
1
、
例如串口
1
的发送接收引脚是
PA9,PA10
,
当我们把
PA9,PA10
< br>不用
作
GPIO
,而用做复用功
能串口
1
的发送接收引脚的时候,叫
端
口复
用
1
、
GPIO
端口时钟使能。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
2
、复用外设时钟使能。
比如你要将端口
PA9,PA10
复用为串口,所
以要使能串口时钟。
RCC_AP
B2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); <
/p>
2
、即一个外设的引脚除了具有默认的端口外,还可以通过设置重
映
射寄存器的方式,把这个外设的引脚映射到其它的端口。
重映
射
AFIO
重映射的步骤:
1
、使能被映射到的
IO
端口时钟
2
、使能被映射到的外设时钟
3
、使能
AFIO
功
能的时钟
4
、
进行重映射
GPIO_InitTypeDef
GPIO_InitStructure;
//
PW
M
中重映射的例子
第
5
页
共
5
页
TIM_TimeBaseInitTypeDef
TIM_TimeBaseStructure;
TIM_OCInitTypeDef
TIM_OCInitStructure;
RCC_APB
1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
//
使
能
定
时器
3
时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB
|
RCC_APB2Periph_AFIO,
ENABLE);
//
使能
GPIO
外设和
AF
IO
复用功能
模块时钟
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,
ENABLE);
//Timer3
部
分重映射
TIM3_CH2->PB5
remap(
重定义功能
)//
此方格中的需要进行重映射
MODE
的设置问题:
1
、
LED
灯设置为推挽
输出。
2
、
KEY0
、
KEY1
、
KEY2
都是低电平有效,
KEY_UP
是高电平有效
第
6
页
共
6
页
KEY0
、
KEY1
、
KEY2
设置为上拉输入、
KEY_UP
设置为下拉输入。
p>
3
、
u8
KEY_Scan(u8 mode)
{
}
static u8
key_up=1;//
按键按松开标志
if(mode)key_up=1;
//
支持连按
{
p>
delay_ms(10);//
去抖动
key_up=0;
if(KEY0==0)return KEY0_PRES;
else if(KEY1==0)return KEY1_PRES;
else if(KEY2==0)return KEY2_PRES;
else if(WK_UP==1)return WKUP_PRES;
if(
key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
}else
if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)key_up=1;
return 0;//
无按键按下
按键扫描(不支持连续按
)的一般思路
(
按一下加一
)
u8 KEY_Scan(void)
{
static u8 key_up=1;//
仅第一次执行,
第二次不会被按下。代表上次按键没有被按下,是松开的。
但
是保留上一次的值
if
(
key_up &&
KEY
按下)
{
del
ay_ms(10);//
延时,防抖
p>
key_up=0;//
标记这次
key<
/p>
已经按下
/
/key_up=1,
代表按键没有被按下,
key_up=0
代表按键被按下
if(KEY
确实按下
)
{
return
KEY_VALUE;
}
}else if(KEY
没有按下
)
key_up=1;//
此时的值
会被保留在
static
里面
return
没有按下
}
按键扫描(两种模式合二为一)的一般思路
u8 KEY_Scan(u8 mode)
{
static u8 key_up=1;
//
此句没有意义
if(mode==1)
key_up=1;//
支持连续按
key_up=1;
代表一直没有按下
p>
key_up
一
直会等于
< br>1
第
7
页
共
7
页
if
(
key_up &&
KEY
按下)
{
del
ay_ms(10);//
延时,防抖
p>
key_up=0;//
标记这次
key<
/p>
已经按下
此句没有意义
if(KEY
确实按下
)
{
return
KEY_VALUE;
}
}else if(KEY
没有按下
)
key_up=1;
此句没有意义
return
没有按下
}
比较重要的函数的用法:
例题
1
、带参数的形式
u8 Is_Leap_Year(u16 year)
{
if(year%4==0) /
/
必须能被
4
整除
{
if(year%100==0)
{
if(year%400==0)
return 1;//
如果以
p>
00
结尾
,
还要能
被
400
整除
能被<
/p>
4
、
100
、<
/p>
400
整除
else return 0;
/
/
能被
4
和
1
00
整除
但是不能被
400
整除
}else return 1;
//<
/p>
仅能被
4
整除
} else return 0;
/
/
都整除不了
}
for(t=1970;t
//
把所有年份的秒钟相加
{
if(Is_Leap_Year(t))
seccount+=31622400;//
闰年的秒钟数
else seccount+=31536000;
//
平年的秒钟数
第
8
页
共
8
页
}
第一章
中断优先级分组
NVIC__IRQChannel = USART1_IRQn; //
在
misc.c
中有
NV
IC_Init
定位到
stm32
f10x.h
的
结构体中
NVIC__IRQChannelPreemptionPriority=3
;//
抢占优先级
3
NVIC__IRQChannelSubPriority = 3;
NVIC__IRQChannelCmd = ENABLE;
//
子优先级
3
//IRQ
通道使能
NVIC_Init(&NVIC_InitStructure);
//
根据指定的参数初始化
VIC
寄存器
第二章
串行通信
串行通信的通信方式
同步通信:带时钟同步信号传输。
-SPI
,
IIC
通信接口
异步通信:不带时钟同步信号。
第
9
页
共
9
页
<
/p>
-UART(
通用异步收发器
),
单总线
USART_InitTypeDef
USART_InitStructure;//
结构体
USART__BaudRate =
bound;//
串口波特率
USART__WordLength = USART_WordLength_8b
;//
字长为
8
位数据
格式
USART__StopBits =
USART_StopBits_1;//
一个停止位
USART__Parity =
USART_Parity_No;//
无奇偶校验位
USART__HardwareFlowControl =
USART_HardwareFlowControl_None;//
无硬件数据
流控制
USART__Mode =
USART_Mode_Rx | USART_Mode_Tx;
//
收发
模式
USART_Init(USART1,
&USART_InitStructure);
//
初始化串口
1
USART_ITConfig(USART1,
USART_IT_RXNE,
ENABLE);//
开启串口接受中断
USART_Cmd(USART1, ENABLE);
1
、
void
USART1_IRQHandler(void)
//
串口
1
中断服务程定位到
startup_stm32f10x.h
2
、
USA
RT_GetITStatus
3
、
USART_ClearITPendingBit //
定位到
.c
中
串口通信的原理
第
10
页
共
10
页
ABCDEFGHI
……
.(0x0D),(0x0A)
第
11
页
共
11
页
第三章
外部中断的概述
以线
0<
/p>
位例:它对应了
GPIOA.0
,GPIOB.0
,GPIOC.0
......GPIOI.0
.
而
中断线每次只能连接到
1
个
IO
口上,这样就需要通过配置来决定对应的中断线配置到哪个
GPIO<
/p>
上了
即每个
E
XTI
线对应
GPIOA.0 ,GPIOB.0
,GPIOC.0 ......GPIOI.0G
个
IO
p>
引脚
GPIOx.0
映射到
EXTI0
GPIOx.1
映射到
EXTI1
…
GPIOx.15
映射到
EXTI15
第
12
页
共
12
页
从
表中可以看出,外部中断线
5~9
分配一个中断向量,共用一个
服务函数
外部中断线
10~15
分配一个中断向量,共用一个中断服务函数。
IO
口外部中断在中断向量表中只分配了
7
个中断向量,
也就是说只能用
7
个中断服务函数。
EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandler
EXTI4_IRQHandler
EXTI9_5_IRQHandler
EXTI15_10_IRQHandler
外部中断一般的设置步骤
初始化
IO
口为输入。
//
外部中断初始化、中断优先级分组、
GPIO_Init();
②
p>
开启
IO
口复用时钟。
RCC
_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); <
/p>
设置
IO
口与中断线的映射关系。
void GPIO_EXTILineConfig();
初始化线上中断,设置触发条件等。
EXTI_Init();
p>
配置中断分组(
NVIC
),并使能中断。
NVIC_Init();
⑥
编写中断服务函数。
EXTIx_IRQHandler();
清除中断标志位
EXTI_ClearITPendingBit();
外部中断常用库函数
第
13
页
共
13
页
①
void
GPIO_EXTILineConfig(uint8_t GPIO_PortSource,
uint8_t GPIO_PinSource);
//
设置
I
O
口与中断线的映射关系
exp:
GPIO_EXTILi
neConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);//
解释:中断线
EXTI2
与
GPIOE
连接了<
/p>
②
void
EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
//
初始化中断线:触发方式等
③
ITStatus
EXTI_GetITStatus(uint32_t EXTI_Line);
//
判断中断线中断状态,是否发生
④
void
EXTI_ClearITPendingBit(uint32_t EXTI_Line);
//
清除中断线上的中断标志位
KEY0
KEY1
KEY2
设置为下降沿触发
KEY_UP
设置为上升沿触发
p>
设置
IO
口与中断线的映射关系
:
按键对应
GPIOE.0
GPIOE.2
GPIOE.3
GPIOE.4
所以设置
IO
口与中断映射的时候,<
/p>
只能设置成
EXTI_Line0
p>
、
EXTI_Line2
、
EXTI_Line3
、
EXTI_Line4
p>
即映射号与所使用的
IO
号要一一对应。<
/p>
第四章
定时器
高级定时器:
TIM1 ~TIM8
p>
带死区控制盒紧急刹车,
可应用于
PWM<
/p>
电
机控制
通用定时器:
TIM2~TIM5
通用。定时计数,
PWM
输出,输入
捕获,输出比较
基本定时器:
TIM6
、
TIM7
主要应用于驱动
DAC
通用定时器的特点:
4
个独立的通道(
1
、
输入捕
获
2<
/p>
、输出比较
3
、
PWM
生成
(
边缘或中间对齐模式
p>
)
4
、
单脉冲模式输出)
APB1
时钟
第
14
页
共
14
页
可
使用外部信号(
TIMx_ETR
)控制定时器和定时器互连(
可以用
1
个
定时器控制另外一个定
时器)的同步电路。
时钟的计算方法:
除非
APB1
的分频系数是
1
,
否则通用定时器的时钟等于
APB1
时钟的
2
倍。
默认调用
SystemInit
函数情
况下:
SYSCLK=72
p>
初始化的时候
APB1
的时钟为
2
分频,
所以
APB1<
/p>
为
36MHZ
AHB
时钟
=72M
APB1
时钟
=36M
所以
APB1
的分频系数
=
AHB/APB1
时钟
=2
所以,通用定时器时钟
CK_INT=2*36M=72M
定时时间:
t=(arr+1)(pcs+1)/Tclk
第
15
页
共
15
页