(基于ARM的)微机原理与接口技术笔记合集(7-14)
我是北航仪光低档垃圾暴毙货剑人,曾经是航C猪脚.咕了两个月,马上要烤期了,各位的破防水准备好了吗?现在是12月11号,再过3周就要考试了,之前一直想更新但是一直拖,但是再拖下去就暴毙了.现在我决定不继续拖了,于是有了这个合集,2个月来的R710F的上路历程.
首先是汇编语言杂记
(真的是笔记)如果配合ARM手册食用效果更佳.考试如果考一车汇编我必然挂科,不是开玩笑.



注意R710F是不带FPU的 所有的float和double都是软件处理.
R710F好像也没有硬件除法器......



汇编和C相互调用
ATPCS规定了:小于4个参数:寄存器r0到r3传参数
import CFunc
C调用汇编:使用export把程序段导出给C语言调用
比如说下面的汇编程序段要实现复制字符串的功能:

在C里面写个函数:
就可以调用上面的汇编程序了
嵌入式高级语言编程简介
像str71x.s这样的汇编文件是启动代码()
不光r710f有启动代码 其他的板子,比如说树莓派pico(2个cortex-m0+核)或者stm32f103c8t6(1个cortex-m3核)都需要对应的启动文件,这个汇编文件和编译器相关.也有的编译器支持用C语言写启动文件.
启动代码需要做的:
建立栈区,堆区,向量表,硬件地址等,初始化C运行时
运行
main函数捕获异常
r710f芯片大概结构(这个开发板的生产厂家现在好像已经寄了)
native总线:
FLASH,SRAM,调试口JTAG,PRCCU,
apb2总线(慢速):
模数转换ADC,增强型中断控制器EIC,定时器TIM,实时时钟RTC,外部中断XTI,看门狗WDG,3组GPIO
apb1总线:(快速)
2组IIC,2组带缓冲区的SPI,4组UART,1个USB,1个CAN,1个HDLC

存储空间(对于别的板子,例如stm32,存储空间地址配置有差异.可以查手册获得这些信息)
r710f的地址范围:0x00000000到0xffffffff
0x00000000BOOT区
0x20000000SRAM
r710fz264KB SRAM
0x40000000FLASH
256KB Bank0
16KB Bank1
EMI 最大可以扩展4个16MB的FLASH(16位的)需要配置寄存器
0xa0000000PRCCU(复位和时钟控制器)
0xc0000000APB1外设
0xe0000000APB2外设
0xfffffb00
R710F的启动模式

R710F供电模式和时钟
PRCCU
power,reset,clock control unit(供电,复位,时钟控制器)
对于CPU两个重要的事情:第一个是复位的状态一定要确定 第二个是时钟
RESET是复位到最初始的状态,是后面所有事情的基础.
上电复位,软件指令复位,看门狗复位
上电复位:RAM的东西不确定的
软件复位/看门狗复位:RAM的东西不丢失
CPU必会死机(躲不掉的).看门狗:一种硬件定时器,当核心死机了或者跑飞了复位.
上电和掉电的顺序很重要!
需要电源管理模块.可以做功耗管理,低功耗模式.
R710F集成2个稳压模块.只用3.3V供电就OK了

如果是电池供电,全速工作会非常费电.

R710F的时钟树(重点)

CK是时钟源(有源晶振)
选择时钟源用配置寄存器
32768无源晶振是低功耗时用的
USB有专用时钟

上手一个板子,理解时钟树很重要.R710F主频最大48MHz,引8MHz时钟源,过PLL(锁相环)倍频12分频2得48MHz,然后1分频给MCLK就是48MHz.如果是16MHz的时钟源就需要修改PLL配置寄存器,时序乱了CPU就不能正常工作.外设如果需要24M的时钟在PCLK处开2分频.
下面这个图是从CSDN搬的.STM32有4个时钟源,时钟树也更加复杂,但是顺着找顺着配置就能做出来开单片机必然先配置时钟,有的时候是人家SDK替你做了,自己做的时候需要看时钟树.

I/O接口技术简介
IO口的作用:解决速度匹配问题,信号转换,输入输出控制
CPU与IO之间信息:数据,状态信息,控制信息
IO口的编地址方式:统一编址(存储器映像),独立编址(有专门的指令访问外设)
GPIO的硬件结构
外设通过寄存器和处理器连接
寄存器组包括:配置寄存器(CFGR) 状态寄存器(SR) 数据寄存器(DR)
CPU与IO之间信息:数据,状态信息,控制信息
ARM对IO口进行了统一编址,不用I/O指令(通过ARM库的结构指针访问)
并行传输:一次传输多位(可以是一个数)需要多根线 用并口
并口速度快了可能有速度的微小差异(导致传输出错),干扰大
串行传输:一次传输一位(按顺序走) 用串口
80x86的外设有专门的指令去访问(不占存储空间)
GPIO功能:读引脚的高低电平/输出高低电平 切忌直接用GPIO接在电机等大电流器件上
配置IO口:一个GPIO有3个配置寄存器

8个模式:
输入:高阻(模拟)输入,TTL输入 CMOS输入 带上拉和下拉的输入(注意不是单独配置上拉和下拉)TTL和CMOS是检测1的电平不一样.AIN是模拟输入
输出:推拉输出/开漏输出(OUT模式或者复用模式)
下面是STM32的IO口结构(网上找的图,不放我手绘的了),和R710F的类似.但是
更复杂,有更舒适的库函数可以用,而且可以单独配置上拉或下拉.

串行接口
UART: Universal Asynchronous Receiver Transmitter 通用异步收发器
串口 一次发一个bit 必须从bit0开始(LSBFIRST)
和并行对应 并行可以一次可以发一个字节
USB:Universal Serial Bus也是一种串行接口协议
高电平空闲,一般1个起始位,8个数据位(最常见的),[1个可选的校验位],1个(或2个)停止位
起始位低电平,然后是原始数据,校验位,停止位.
速度问题 baudrate
baudrate高的时候传输快,但是时钟偏差容易导致通信失败.
工业控制不能轻易的用蓝牙或WIFI因为不可靠,有可能丢帧
3.3V或5V的串口可以通过RS232模块转成大的电压 -12V(低) +12V(高)可以传输100米
为保证抗干扰 baudrate需要调低
常用于远程有线传输的还有RS485/RS422模块

R710F的UART配置方式
配置 baudrate寄存器 baudrate=PCLK1/(16*BaudReg)
配置控制寄存器
缓冲寄存器(RX和TX)
CPU和外设之前的传送数据方式
1.无条件传送(点灯就是这样的)
外设简单,要求速度快/两次传送
需要buffer/latch
2.查询(轮询)方式
先查询再传送
至少2个端口(数据/状态)
3.中断方式
外设向CPU发中断(IRQ)->CPU中断当前工作进入IRQ函数->办完了返回
协调快速CPU和慢速外设
4.DMA方式
Direct Memory Access 直接从外设到存储器 省得CPU去搬砖 也可以外设搬到外设比如说把AD的结果搬到SPI
最先进的方式(硬件DMA) 用于大块数据传输/快速数据
需要CPU让开一些总线给DMA用 代价是CPU访问变慢
可以配合中断使用
使用流程:配置,传送,传送完了怎么办

中断技术
定义:CPU暂时中止当前的程序切换到中断处理程序(IRQHANDLER)
意义:CPU和IO并行工作,处理故障,提高实时性
中断系统:
早期的板子没有自带NVIC(nested vectored interrupt controller)
中断源:
分类:
按产生方式:强迫中断/非强迫中断
按中断位置:内部/外部
按进入handler方式:向量中断/非向量中断
中断优先级/中断嵌套:在中断处理函数里面可以再来中断,硬件处理(stm32或者树莓派pico的硬件NVIC/ r710f的EIC)
寄存器配置:查找datasheet
EIC把ARM7TDMI的2个中断(IRQ/FIQ)扩成32个中断
工作流程:EIC接受中断(ICR打开相应中断),更新IVR拼一个向量表
编程:初始化,配置,打开中断
设置IRQ中断优先级,打开中断,EIC负责配置
直接打开FIQ.在硬件上FIQ可以保证比IRQ优先处理

如何进入异常:
入口放跳转指令
b exception_handler注意跳转范围限制文字池 32位的地址
ldr pc,=handler_addr
如何初始化 IVR和32个SIR
用地址初始化:缺点:32个子程的地址高16位必须相同
在EIC_IVR生成跳转指令
中断服务子程(ISR)是一种特殊的子程序
中断的步骤:
第一步:别的硬件发送中断请求

第三步:处理中断
保护现场(硬件可以做),保护断点(可能需要软件做,否则寄存器的关键数据变了,程序跑飞了)
开中断,处理,关中断,恢复现场.
哪些事情是硬件做或者SDK软件实现好了的,哪些是需要手写的 看不同的CPU和SDK手册
R710F的中断向量表:


向量表决定了FIQ可以打断IRQ
ARM7TDMI的异常(和中断有关,但是它们是两个概念)
直接异常:软中断/undefined instruction/预取指异常
间接异常:数据终止
外部产生的: RESET/IRQ/FIQ
RESET是最高级的 强制重开.

出现异常的时候R710F核心自动做的:

为什么是PC-4因为涉及流水线,设置PC为跳转到IRQ地址

R710F只有2个中断(IRQ和FIQ)通过EIC和XTI(外部中断控制器)实现中断的扩展
新一些的ARM Cortex-M板子普遍用核心自带的NVIC(nested vectored interrupt controller)处理中断

定时器(TIMER)


计数器:对谁计数 怎么变 复位?
R710F的定时器16位
counter初始化为0xfffc
这点极不友好,重置就是0xfffc,不是任意的数

注:STM32是可以指定定时器重置后装载的数的,也能控制向上/向下计数,使用更加灵活,而且还有SYSTICK定时器可以用.
5个中断(溢出中断,2个比较中断,2个捕获中断)
输入->边沿检测电路ICAP变化,把计数器的值copy到ICAR/ICBR
可以测量引脚的脉冲宽度(PWM)太快的和太慢的都不能测.
输出引脚可以用于定时/中断,产生硬件PWM输出
OCAR用于控制脉宽:计数器与OCAR一致 OCMPA置OLVLA
OCBR用于控制周期:计数器与OCBR一致 OCMPA置OLVLB同时复位
OCAR<OCBR:PWM
OCAR=OCBR:方波
OCAR>OCBR:无输出

寄存器手册(纯寄存器开发要用,库函数开发可以不那么care)



r710F:板载12位ADC
输入0-2.5V 4个通道->4个寄存器(STM32f103c8t6和树莓派pico都是0-3.3V的AD模块)
可以出中断
配置时钟(PRESCALER=APB2FREQ/(SAMPLEFREQ*512*4))

配置过程:
模式:round robin(连续出多个)/single channel operation
初始化:
配置AD模块
ADC12_Init()配置GPIO模拟输入
GPIO_Config(GPIO1,1,GPIO_HI_AIN_TRI)配置prescaler(低7位有效)
ADC12_PrescalerConfig配置转换模式
配置通道
轮询等待转换结果
取结果
关闭转换

