gentleman
发表于 2023-8-15 08:31:04
2023/08/11 第十四集
接上回寄存器
传统8051 一次只能看到8个寄存器
R0 R1 => WR0
WR0编号 对应 低存储器R0编号
R0 R1 R2 R3 =>DR0
编号被4整除
32-35H保留
intel 80251继承效果特别好
用寄存器反应存储器
寄存器组0~3反应存储器00H~1FH
存储器低32位字节不能动,给寄存器留着
RS1 RS0 选择哪一组寄存器
测试程序
//$NOMOD51
//$INCLUDE (STC32.H)
ORG 0000H
LJMP MAIN
ORG 0003H
MAIN:
ORL 08EH,#02H
MOV R7,#0A0H
MOV 0D0H,#18H ;这是psw 第3组
MOV R7,#00H
MOV R15,#0A5H
END
测试结果
看到rs 为第三组寄存器
R15寄存器内的值为0xa5
R15没有地址映射
专用寄存器
R10 B
R11 A
DR56 DPX
DR60 SPX
可以尝试MOV R10,#11H
可以看到B 中的值变为0x01
几个SFR
dpsl 段: dptr 地址
| |
DPXL DPH DPL
CY
MSBADD/ADDC 进位
SUB/SUBB/CMP
MUL DA
32位与8位不同
AC
仅8位有用
F0
用户使用
RS1 RS0
寄存器组选择位
OV
溢出 和/差太大
UD
用户定义标志
P
校验
PSW1 多了N
运算结果为负, 15=“1”
设置该位,否则清除该位
Z
运算结果为0 设置该位
对PSW 影响的指令
gentleman
发表于 2023-8-15 10:52:01
2023/08/11 第十五集
处理器内核和存储空间映射
内部结构
24位地址总线 16M存储器
无需外部flash总线
结构和地址空间
MOVC MOVS 人为增加了指令的复杂度
24位总线引入段的概念,直接知道访问的十哪一片区域
64k程序空间
code
64k程序空间 code区域 程序代码FF:0000H 到FF:FFFFH
ecode ecode 拓展
保留 留着以后研发芯片,给与新的用途
64k拓展RAM 外部扩展SRAM 用的地址,试验箱有没焊接,只支持8位数据
拓展SFR 不是传统SFR,传统SFR还保留
保留 很大 留着以后用
8K 扩展RAM 扩展ram 也是在cpu内部
xdata 也不是随便分,intel有个基本的规则
保留 64K edata SRAM越大性能越高也越贵
速度快
4kRAM
一段简单的测试代码
void main()
{
volatile unsigned char a=170,b=90;
volatile unsigned char c;
c=a+b;
} 取消run to main()调试
好奇为啥我这里的启动引导代码与何老师的不一样,我这里不是一个简单的跳转指令,
先是移动了一下dptr,然后向寄存器里面放了个立即数0x41f ,再进行自减运算
减到0后才进行跳转
没问题了,何老师的启动引导代码再后面0xFF0022那里,是一样的
下面是何老师的启动引导代码
00:0000~00:0FFF基本RAM
4K EDATA
7E:0000~7E:FFFFXSFR
拓展sfr,能访问更多的设备,原来的sfr不够用了。
复位PC 从FF:0000H开始
中断PC 从对应的中断入口开始
FF:0003HINT0中断
eeprom 扇区擦除
低端256字节RAM
这里兼容传统8051
stc32g RAM 12K
4K EDATA
8K XDATA(理论能到8MB)
可位寻址存储器
DATA 0x20~0x7F
96字节
SFR 0x80~0xFF (原来传统8051是被8整除)
128字节
中断
stc32展现工程能力创新,实践能力创新
中断机制与arm有一些不同
最快相应,最小代价。
中断原理
正在执行某个事件,外部紧急事件
cpu轮询<中断<DMA
RX ______________
------>| 移位接收缓存器 |
|高电平通知cpu |
| cpu |
|_______________|
cpu 检测高电平/脉冲 响应根源
如果不响应,缓冲区溢出,产生错误
中断优先级有程序设计人员决定
高低电平 还是脉冲由芯片设计人员决定(看数据手册)
中断标志
在寄存器中。在早期轮询系统中,轮询寄存器中标志位,判断是否发生中断。
发生中断,停止main函数的执行。执行中断子程序,执行结束,恢复main函数
堆栈机制用于中断前地址的存储
中断系统
实现中断过程的功能部件
中断源
打断当前执行程序的紧急时间
中断优先级
多个中断,优先处理 优先级高的(先和校长说话)。
gentleman
发表于 2023-8-18 09:11:19
2023/08/15 第16集
可以看到 80251指令集比8051要复杂很多,多了许多指令。
计划先将8051指令集 的汇编掌握的熟练高一些,后面再看情况再详细学习80251指令集
数据类型和端
数据类型 bit
byte
word 不要求边界对齐
doublewrold 不要求边界对齐 可以再keil中验证
大端保存高址低字节 地址高字节
MOVE WR0,#A3B6H
MOVE 只能将0拓展或1拓展的32位立即数 放到双字寄存器中
符号规则
符号表示
兼容以前的
A 累加器
DPTR 数据指针
PC 指令地址
C 进位
AB 乘除
SP 堆栈指针
DPS 数据指针选择器
R0~R7 八个8位寄存器
MCS-251
@Ri R0 R1间接寻址 00H~FFH
Rn n:0~7 8位寄存器
rrr 二进制码
Rm m:0~15
Rmd 目标寄存器
Rms 源寄存器
m,md,ms 编号0~15
ssss m/md二进制编码
SSSS ms 二进制编码
WRj DR 与Ri 类似
多了@WRj+dis16偏移量寻址
@WRk+dis24偏移量寻址
dir8 dir16 直接寻址地址
#data8#data16 立即数
#0data16 #1data16 补充32位
#short 常数 1 /2 /4
vv #short二进制编码 1/2 = 00 2/201 4/2 10
bit(二进制码yyy) bit51 可位寻址地址 SFR0/8 结尾
rel 相对寻址
addr11/addr16/addr24 11/16/24目标地址
寻址模式
cpu找操作数 叫寻址模式addrssing
寄存器寻址 包含操作数
立即寻址 包含操作数
直接寻址 包含操作数地址
间接寻址 包含操作数地址寄存器
位移寻址 寄存器和偏移量
相对寻址 吓一跳指令的符号偏移量(都是写标号,编译器自己会算)
位寻址 包含位地址
立即数寻址 #data8#data16 32:16位立即数放入DRk MOVH 数据放高位 保持低位不变
递增/递减 #short
gentleman
发表于 2023-8-18 09:33:55
本帖最后由 gentleman 于 2023-8-18 10:58 编辑
2023/08/15第十七集
直接寻址模式
8位 RAM 00:0000H~00:007FH
SFR S:080H~S:0FFH
可以8/16/32 形式访问
16位
RAM00:0000H~00:FFFFH
8/16/32 形式访问
每个存储器区域有个编号,直接写00不认
SFRS:000H~S:1FFH
MOV DR0, EDATA 0100H
立即数去掉#就变成地址
MOVWR2,0x60
间接寻址模式
8 @Rii=0/1 00:0000H~00:00FFH
16 @WRj j=0/2/4/。。。/30 00:0000H~00:FFFFH
32 @DRk k=0/4/8/。。。/60 DRk 低24位(高8位必须0) 放着整个16M
8051:
8(@Ri)
16(@DPTR/@A+DPTR)
16程序计数器(@A+PC)
MOV @DR0, WR8
寄存器寻址
8 R0~R15
16 WR0 WR2~WR30
32 DR0 DR4~DDR60
8051:
仅R0~R7
MOV Rmd Rms
INC WR4,#2 原来只能+1现在可以+1/+2/+4 至少提高四倍可以查表用不能加255!只能1/2 /4
位移寻址
@WRj+dis16
超过0xFFFF 会回卷00: 小于0也回卷
@WRj+dis24
相对寻址模式
return:
MOVR1,#0xA0
MOVA,#0x60
ADD A,R1
JCreturn
位寻址
80251更多0x20~0x7F SFR均可位寻址
8051 0x20~0x2F 0x0 或0x8 结束的SFR
SETB20H.0
指令模式 source bin可以选择
32g支持source
A5根据模式生成
8051: SUB A,RN
1 0 0 1 1 r r r
0x9C
80251:
1001 1100 ssss SSSS
0x9C44
因为指令长度可变,CPU无法译码,为了区分这两个指令,加A5 (~A=5抗干扰)
80251 268指令8051 111条2.5倍
何老师提供程序文件很全,包含全部的指令,相信对80251指令集的学习有很大帮助
指令
ADD
CY第7位(MSB?)有进位 CY 1
AC低3位进位 AC 1仅8位数据有效
无符号 CY 标志 溢出
第6位进位 第7位没进, 或7进位6没进位,则 OV1
有符号
正数相加得负数 或负数相加的正数,表示结果溢出 OV 1
零标志
结果=0 Z=1
符号标志
结果.7 = 1N=1
结果.7 = 0N=0
具体指令就不抄了,贴张手册上的图片
机器码也可以很容易推到出来(有的要加A5)
gentleman
发表于 2023-8-18 11:33:19
2023/08/15 第十八集
ADDC
基本和刚才一样 CY AC OV N Z 都一样
指令
SUB
第7位借位CY=1
减有符号OV + 减 - = -; - 减 + = + (这里+/- 表示正数/负数)
8位影响AC
指令
INC
DEC
乘法指令
8位x8位 积16位
>255 ov=1
16x16 32位
>65535 ov = 1
CY 总为0
MSB 置位 N=1
结果= 0Z=0
现在不用ALU ,有专门的硬件做乘法
注意 目的md=0,2,4...
Rmd <- Rmd X Rms 存放高字节
Rmd+1 放低字节
目的md=1,3,5...
Rmd-1 <- Rmd X Rms 存放高字节
Rmd 放低字节
类似的
WRjd +2 /-2参考上面看jd=0 4 8 /2 6 10
除法
设置商MSB N=1
商=0 Z=1
<src>包含0x00 不行
指令
目的偶数rmd+1放商rmd-1放余数
WRjd 类似
BCD
DA A
比较
CMP
还是减法,就是不存,只存标志位
影响CY OV AC(8BIT)N Z
这节课将所有的算数指令都讲完了
感觉到课程的知识密度很大,几个小时就讲完了数据类型,符号,寻址模式,还有算数部分的指令。
尽管已经有一定的8051指令集汇编的基础,听下来还是觉着很累。
看完回放后清晰了很多。不知道剩下的200来条指令安排几个课时。
80251指令集比8051的指令多了很多,对程序影响也很大,比如INC 能+4,一定会提升程序运行的速度。
gentleman
发表于 2023-8-22 11:24:57
本帖最后由 gentleman 于 2023-8-23 11:03 编辑
2023/08/19 usb实战(未完)
USB-CDC
速度快 12M
简单可靠
有缓冲区
模式选XSMALL
Misc control填入 REMOVEUNUSED
然后编译器就报错了,它好像不认识REMOVEUNUSED ,不加就能编译通过{:4_177:}
注意是添加到L251 misc 中 我添加到了C251所以不能编译。
添加到L251 misc后编译成功。
0错误,0警告。
编译成功,使用串口助手进行测试
看到接收到发送的 hello world
不停电下载
刚从已经写好了usb-cdc 虚拟串口
只需要在ISP中勾选 串口模式,下次使用hid 与每次下载前都发送自定义命令 就可以不停电下载
这个功能贼好用
有时候也可以软件配置IAP_CONTR = 0x60进入下载模式
STC8H 类似,按需使用xdata/data 的库
需要中断的, 使用中断的库
取消这个注释,可以使用printf
写一条测试一下
测试结果
额,算是成功了吗?
咋全是乱码啊。
加\xfd试试
还是乱码啊,先放着后面再来研究
重建工程,把代码粘过去,问题消失。
看论坛的大神说乱码的原因是,发送的是UTF-8字符,编码不同,不能正常显示。
static/image/hrline/4.gif
USB-CDC 转串口
USB-CDC 转双串口
USB-CDC 转4串口
可以看到功能很强大
转单个串口分析简单一点,便于分析
[*] usb硬件初始化
[*]编写读取函数和写入函数
[*]配置USB中断
[*]配置设备描述符/标识符//通过这一步,电脑知道你插入的是啥。是U盘 键鼠 还是其他的usb设备
USB初始化
端点0 波特率,停止位,校验位
断电1~5 正常通讯
缓存
INTRIN 寄存器 开启5个端点的寄存器
USB初始化代码本不变,什么设备都一样。
USB读写
USBADR 和读有关的寄存器,
先写地址,在写数据
USB中断
有很多中断
端点1发送数据
发送不重要
看接收
gentleman
发表于 2023-8-25 10:27:36
2023/08/18 第19集
CPU指令集架构
intel 手册有错的,信 编译器,不信手册
ANL
影响符号标志N 0标志Z
32位运行8051效率很低,因为要加A5
精简指令集不是吧操作精简,由于只能再寄存器操作,容易做流水线与编译器优化
risc 要先将存储器 搬到寄存器,昨晚运算在搬回来
ANL P1,#01110011B
清除P1 的第7位,第3位还有第2位
与 清0或 置1异或 取反
ORL影响N, Z
8051 简单,不用考虑大端
ORL P1,#00110010B
P1 的第5位,第4位还有第1位置1
32位数据不能直接操作
XRL
XRL A,#0011 0011B
好处是只影响这几位取反
CLR A
清0
CPL A
A 的内容全部取反
移位
影响N Z
内部
这个移位好像比 c 的更好用啊{:4_165:}
gentleman
发表于 2023-8-25 10:54:40
2023/08/18 第 20 集
SWAP A
半字节交换
3~0 <==>7~4
留个空,学了《硬件描述语言》以后画硬件电路。
数据传送指令
MOV --认识的第一条汇编,那时是通过返汇编,看到把数据搬来搬去
传统8051 搞小车只能搞低功耗
32位8051有很多硬件算数运算单元,提升很多。可以搞很多以前搞不来的。
MOV dir8, dir8 只用了1个时钟
存储器一个地址搬到另一个地址。只用1个时钟
说明一定不是单端口存储器,
单端口存储器1个时钟只能操作一个地址
至少是双端口的存储器。
时钟数与字节数没有关系,不是说字节数长,时钟数一定会长
MOV @Ri,A
c指针就翻译成间接寻址
STC三级流水线
取址 译码 执行指令
取址 译码 执行指令
取址 译码 执行指令
一旦执行,有源源不断的指令
gentleman
发表于 2023-8-25 11:20:15
2023/08/18 第 21 集
继续讲MOV
MOVX 外部RAM
访问外部要3个时钟
堆栈指令
PUSH
有的指令集没有,用软件模拟push pop;
入栈 SP+1放入堆栈空间
还是搬内存中的内容,只是搬的位置是确定的。
PUSH S:82H; 入栈操作, DPL 在SFR S:82H
PUSH S:82H; 入栈操作, DPH 在SFR S:83H
入栈前 (SP)=0x09 (DPTR)=0x123
入栈后 (SP)=0x0B 0x0A 保存DPL(0x23)0x0B 保存DPH(0x12)
POP
出栈
POP dir8
把sp指针指向的 数据恢复到dir8地址的数据存贮单元
XCH
交换指令
支持存储器直接交换
位指令
CLR CY
与之前讲的不同 这个是对位进行操作
CLR bit
CLR bit51
编译器很聪明,自己知道用哪个。先用原来的8051,原来寻址不了的用bit51
调用指令
指令到这节课差不多讲完了。
这些指令一定要配合何老师给的例程进行学习。
何老师的例程应该是包含所有200多条指令。
把例程进行单步运行一遍,对于指令的理解有极大的帮助。
gentleman
发表于 2023-8-30 08:11:18
2023/08/22 第二十二集
控制指令
RETI是中断中返回,RET 是 子程序返回
如果在终端中写RET中断只能执行一次
对比一下
跳转
CALL 需要回来
JMP 不需要回来
所以一个叫调用 一个叫跳转
AJMP JMPADR 跳到标号jmpadr 存的地址
EJMP 能跳刀整个16M 空间的任意位置
LJMP 只能64k间接寻址
SJMP rel rel 编译器编译完了是相对地址
根据下一条指令算偏移量
MOV DPTR,#JMP_TBL
JMP @A+DPTR
JMP_TBL: AJMP LABEL0
AJMP LABEL1
AJMP LABEL2
查表
JCCY=1 跳转
像ADD 后就可能有 进位
JNCCY =0 跳转
这俩不影响标志位 只判断
JNCLABEL1
CPL CY
JNC LABEL2
跳进来 CY清楚从LABEL2 开始
JB/JNB判断位的