STM32F0-DAY1

时钟周期:时钟周期就是外接晶振的倒数  周期(S) = 1/频率(HZ)

机器周期:完成一个基本操作所需要的时间叫机器周期,根据不同的板子它的机器周期不同

指令周期:是指完成一条指令所需要的时间, 取址-解析-执行所需要的时间。通常含一个机器周期的指令称为单周期指令,包含两个机器周期的指令称为双周期指令

rigester修饰的变量不能取地址

volatile 防止编译器优化:有时候编译器会将一个地址当成寄存器的值。为了防止出错需要用volatile来修饰该变量。

STM32F0-DAY1_第1张图片

中断和异常:异常是系统内部的,是发生错误时产生的,而中断大部分是人为的,属于外部发送的是有需求的

STM32F0-DAY1_第2张图片

查找:

STM32F0-DAY1_第3张图片

参数带###define是不会展开的

STM32_day1

【1】课程介绍

1. 51 -- 8位单片机

   32 -- 32位: 处理数据的宽度是32位 效率高速度快

2. 物联网IOT

工业自动化 -- 工业物联网(4.0) 可编程逻辑控制器(PLC) 机械臂(ABB) 无人机(UAV drone) 京东仓库

医疗 心电图 音视转化 脑电波控制

农业 智慧农业 智能大棚 果蔬溯源 机械采摘

家用 智能家居(小米) 安防 智能供配电

消防 云消防

为什么32? STM32-GD32

3. 嵌入式硬件

C语言基础 计算机组成原理 数字模拟电路 --> 单片机 51 32融合软硬件(裸机 实时操作系统freeRTOS RThread) --> ARM高端处理器平台 移植linux

4. 什么叫学会32 -- 实现功能 学外设

电量显示 LED GPIO

报警功能 蜂鸣器 PWM

电池电压 ADC(模拟 - 数字)

显示信息(打印) UART

时间显示 RTC

按键功能 按键中断

自动重启 WDT

计步功能 加速度传感器(陀螺仪) I2C

5. 7天

入门 基础ARM 开发环境搭建

     GPIO UART

提升 中断 时钟系统 ADC+DMA SPI+液晶

6. 开发板观察

芯片:chip

片上系统:soc - system on chip 单个芯片上集成一个完整的计算机系统

最小系统板:CPU 晶振(需要起振 为系统提供基本的时钟信号【*】) 电源 复位 RAM(随机存储器) ROM(只读存储read only)

核心板:CPU

底板:承载

开发板:学习用 外设功能全

PCB板: 电子硬件 AltiumDesigner(DXP) protell

【*】

1. 机器周期 执行一个基本操作

   指令周期 取指-解析-执行需要的全部时间

   时钟周期  振荡周期 时钟频率的倒数 周期(S)=1/频率(HZ) 时间的量

   指令周期 > 机器周期

2. 单片机工作原理

1)PC程序计数器 CPU读取指令的时候知道在什么位置

2)指令解码电路 从内存中读指令的含义

3)运算电路(ALU) ANR OR 门电路实现的

4)CPU内部寄存器 临时存储信息的场所

7. 传感器

检测部分:

可燃气体传感器MQ-5

红外感应 火焰传感器 温湿度传感器DHT11(数字)

光电开关 触摸按键 光敏电阻(随光强增大阻值减小 压敏 热敏 气敏) 超声波 电位器(滑动变阻器)

控制部分:

继电器 蜂鸣器(无源) 风扇 舵机(SG90) 水泵 电机

通信:

NBIOT WiFi

【2】 理论讲解

1. stm32f051k8 - contexM0

   ST意法半导体

   M micro-eletonics

   32 - 32位 (STM32 STM8家族)

   f foundition基础的 w-wireless l-low低功耗

   051入门级别 103主流接入型 407高性能

   k pin count: k/6 32pin c/8 48pin

   8 code size: 64kbyets

2.  STM32最主要的CPU部分使用的是ARM的核

[面试题] 谈谈你对arm的理解?

1. arm是一个公司 只做技术服务 不生产也不出售芯片 16年被软银收购 (*NXP恩智浦-飞思卡尔 新唐科技nutovon TI德州仪器)

2. arm代表一门技术 精简指令集【*】

精简指令集RISC和复杂指令集CISC有什么区别?

STM32F0-DAY1_第4张图片

3. arm处理器

3. ARM体系架构发展

V1-V3最早的版本 现在已经废弃

V4-V6经典处理器运用的比较多

V7-Contex系列使用的架构 支持Thumb-32位指令集【*】

ARM指令 Thumb thumb2有什么区别?

V8-支持Thumb-64位指令

ARM指令集:ARM指令是32位的指令,编代码全部是 32bits 的,每条指令能承载更多的信息,因此使用最少的指令完成功能, 所以在相同频率下运行速度也是最快的, 但也因为每条指令是32bits 的而占用了最多的程序空间。

Thumb指令集:Thumb指令是16位的指令长度,编代码全部是 16bits 的,每条指令所能承载的信息少,因此它需要使用更多的指令才能完成功能, 因此运行速度慢, 但它也占用了最少的程序空间,但是Thumb指令集中的数据处理指令的操作数仍然是32,指令地址也为32位,并且有些处理器可以根据指令译码器将Thumb指令转换为32位的ARM指令

cortexM0只支持thumb指令集

Thumb-2指令集:Thumb-2指令集是16+32混合,在前面两者之间取了一个平衡, 兼有二者的优势, 当一个 操作可以使用一条 32bits指令完成时就使用 32bits 的指令, 加快运行速度, 而当一次操作只需要一条16bits 指令完成时就使用16bits 的指令,节约存储空间。

*

三星: SP6818 A53 arm-v8

高通: 骁龙865 855 arm-v8

华为: 麒麟980 arm-v8

飞思卡尔: IMX6 arm-v7

4. 早期经典处理器 ARM7 ARM9 ARM11之后都叫cortex系列

取指 - 译码 - 执行

arm7: 三级流水线 冯诺依曼结构 程序指令和数据存储混合

arm9: 五级流水线 哈弗结构 程序指令和数据存储分开

cortex-M 低成本优化方案 智能家居周边产品

cortex-A 跑操作系统 高性能 电视手机

cortex-R realtime实时系统 汽车制动 动力系统

实时和分时操作系统?

分时: windows linux 流行的PC和服务器 CPU划分时间片处理

实时: 用在单片机 PLC

5. CortexM0体系

1) 结构框图

2)两种工作模式

   线程模式 Thread 芯片复位之后执行用户程序

   处理模式 Handler 处理器发生异常或者中断

   两种工作状态

   thumb状态 处理器正常运行

   调试状态 调试程序时候的状态

3)内部寄存器

   R0-R12 13个通用寄存器

   R13 栈指针寄存器 SP

   R14 链接寄存器 LR

   R15 程序计数器 PC

   xPSR : APSR 应用PSR

           IPSR 中断PSR

           EPSR 执行PSR

4)cortexM0中断和异常

最多支持32个外部中断(IRQ)和一个不可屏蔽的中断(NMI)同时支持多种系统异常(Reset hardFault Systick)

【3】 安装环境

1. keil MDK-ARM 注册机

2. STM32CubeMX 加载固件库

3. STLink驱动

【4】存储器映射

1. GPIOA地址0x2800 0000  -- 不正确(手册印刷错误)

真正的地址是?

在application/user/core - main.c下的stm32f51x8.h里面找到真正的地址是:0x48000000

#define GPIOA_BASE (AHB2PERIPH_BASE + 0x00000000UL)

#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000UL)

#define PERIPH_BASE  0x40000000UL



#define FLASH_BASE  0x08000000UL

#define FLASH_BANK1_END  0x0800FFFFUL -- FLASH大小:64K

#define PERIPH_BASE  0x40000000UL //外设基地址

2.地址封装

MODER 0x00 0x2800 0000

OTYPER  0x04 0x2800 0004

OSPEEDR

PUPDR

IDR

ODR

BSRR

LCKR

对地址进行宏定义

#define GPIOA_BASE ((unsigned int)0x28000000)

#define GPIOA_ODR (GPIOA_BASE + 0x14)

读操作

val = *(unsigned int*)GPIOA_ODR

写操作

*(unsigned int*)GPIOA_ODR = val

改进

#define GPIOA_ODR (*(unsigned int*) (GPIOA_BASE + 0x14))

val = GPIOA_ODR

GPIOA_ODR = val

利用结构体把地址封装

typedef struct{

   uint32_t MODER;

   uint32_t OTYPER;

   uint32_t OSPEEDR;

   uint32_t PUPDR;

   uint32_t IDR;

   uint32_t ODR;

   uint32_t BSRR;

   uint32_t LCKR

}GPIO_TypeDef;

#define GPIOA_BASE ((unsigned int)0x28000000)

#define GPIOA ((GPIO_TypeDef*)GPIOA_BASE)

GPIOA->ODR = 0x20;

3. startup_stm32f051x8.s - 汇编文件 启动代码

Stack_Size  EQU  0x400 //定义栈的大小是1K

AREA    STACK, NOINIT, READWRITE, ALIGN=3

//AREA定义一个地区,没有初始化的栈,可读可写,起始地址是8的倍数

__initial_sp //是一个标号 指向栈顶

Heap_Size EQU  0x200 //定义堆的的大小是512B

__heap_base //堆的其实地址

Heap_Mem  SPACE  Heap_Size //堆的空间

__heap_limit //堆的结束地址

AREA RESET, DATA, READONLY //定义一只读数据的区间

EXPORT  __Vectors //声明全局标号 __Vectors在其他文件可以引用

DCD     __initial_sp //栈顶的地址

AREA    |.text|, CODE, READONLY //一般代表代码段

IMPORT  __main //表示函数是调用其他文件的

LDR     R0, =SystemInit //系统上电复位之后第一个执行的程序 初始化时钟

LDR     R0, =__main

//__main是一个标准的C库函数 作用是初始化用户堆栈 在这个函数的结尾会调用main函数

1 byte(B) = 8 bits(b) 八个二进制

1K = 1024byte 1M 1G 1T

【5】拓展补充

1. targer

ROM : 0x10000 = 64K

RAM : 0x200   = 8K

c/c++

USE_HAL_DRIVER,STM32F051x8

#if defined (USE_HAL_DRIVER)

 #include "stm32f0xx_hal.h"

#endif /* USE_HAL_DRIVER */

STM32F051x8: 是指flash大小不同

STM32F10X_LD 16-32K

STM32F10X_MD 64-128K

STM32F10X_HD 256-512K

2. 手册架构图2.1

总线矩阵: 协调内核系统总线和DMA总线的访问

AHB: 高速高性能总线

APB:外设总线

AHB2APB bridge AHB在AHB和APB之间提供同步连接,因为AHB和APB的频率不同

* ICode DCode

3. 位操作

清零 与0清0

num & (~(1<

置1 或1清1

num | (1<

位域: [7:4] 0101 先清0再置1

num & (~(0xf<<4)) | (0x5<<4)

取出某一位的状态

num & (1<<4)

4. # ##用法

#把宏参数变为一个字符串

##把两个宏参数链接在一起

#define STR(s) #s

#define CON(a,b) (int)(a##e##b)

main()

{

   printf(STR(bck)); //输出字符串"bck"

   printf("%d\n",CON(2,3); //2e3 = 2000

}



5. union联合体/共用体

union 名字{

   成员1;

   ...

};

1)判断大小端

uinon aa{

unsigned char a;

unsigned int b;

};

union aa tt;

tt.b = 0x12345678;

if(tt.a == 0x78) //小端

  (tt.a == 0x12) //大端

2)结构体里做差异

struct aa{

   int a;

   union{

      char b;

      char c;

   }

   int d;

}

6.

typedef unsigned           int uint32_t;

#define   __I     volatile const

#define   __O     volatile      

#define   __IO    volatile

存储类型

1)auto 自动

auto int a; //声明一个自动类型的变量

局部变量在不加auto的时候默认就是自动类型

非自动类型: 1. 全局变量 2.static修饰

2)register 寄存器类型

变量执行的效率高 修饰的变量不能取地址(内存上的变量才取地址)

3)static

延长声明周期

限定作用域 只能在本文中使用

4)extern

声明函数或者变量是在其他文件中定义的

5)const

   修饰的是只读变量

   const修饰的全局变量.ro

   const修饰的局部变量在栈上

   const int a = 10; //a是一个只读 不允许修改(不要拿指针去修改)

   const int *p // const修饰的是*p 指针指向的内容不能改 指针可以改

   int const *p // 和上面一样 const在谁前面 谁就不能改

   int * const p //指针不能改

   const int * const p //*p p都不能改

6) volatile

1. 防止编译器优化

   int a;

   a=100; // a=1;

   ...

   a=200; // a=0;

2. 每次从内存里面拿最新的值,不从寄存器或者缓存里面拿

适用情况:

1. 多线程访问同一个变量

2. 中断状态寄存器(通过指针访问硬件地址)

3. 中断中访问非自动类型的变量(全局或者static修饰的)

[笔试]请向0xaaaabbbb地址中写入数据0x12345678i

int *a = (int *)0xaaaabbbb;

*a = 0x12345678;



#define CON (*((volatile int *)0xaaaabbbb))

CON = 0x12345678;

你可能感兴趣的:(STM32,stm32,单片机,嵌入式硬件)