有几个程序的标号我不能理解,望指点一下
LP1: MOV MO,A
LP2: JNC LP1
TAB: AJMP ROUT1
HADD: MOV R1,A
LP: MOV A, @RO
CHA: MOV DPTR #TAB
CHB: ADD A,#02H
MAIN: MOV RO,#50H
SUBR: CLR C
MEM0:MOV A, @R0
BUSB: MOV R3 #N
LOOP: MOV A,#99
谢谢各位大哥
汇编语言的大师请进,我是一个刚学的新生请指点一二
全部回复(71)
正序查看
倒序查看
现在还没有回复呢,说说你的想法
@njyd
好象是电源电压(5V),具体要查手册. D/A片子电源与89c51不一定是一样的.
谢谢您的热心回复,我还有一个问题,就是TABLE指针的问题,表是存在堆栈里呢?还是在ROM中的我一直很迷糊.有这样的一个程序您帮我解释下:(这是一个99秒倒计数程序,8051+7447的硬件电路全文我没有全部上传只是倒计时部份)
A1:MOV 20H,#10
MOV 21H,#10
MOV A,20H
MOV DPTR,#TABLE
MOVC A.@A+DPTR
ADD A,#10H 数据码加上扫描值
MOV P2,A 显示
CALL DELAY 调用延时扫描
ANL P2,#00H 屏幕清零
MOV A,21H
MOV DPTR,#TABLE
MOVC A.@A+DPTR
ADD,#20H
MOV P2,A
CALL DELAY 调用延时
ANL P2,#00H
MOV A,#01 从这一步我就有点模糊了
CJNE A,21H,A1 #10与#01比较不相等转到A1我是这里
MOV A,01 不懂,是不是表被压在堆栈里了,我
CJNE A,20H,A1 想只有压在堆栈里时才有取一个数码
JMP START 跳到启始 堆栈指针才会减一呀.如果在ROM里
指针只会加一呀(我有点晕)
TABLE: DB 00H,00H,01H,02H,03H,04H
DB 05H,06H,07H,08H,09H
A1:MOV 20H,#10
MOV 21H,#10
MOV A,20H
MOV DPTR,#TABLE
MOVC A.@A+DPTR
ADD A,#10H 数据码加上扫描值
MOV P2,A 显示
CALL DELAY 调用延时扫描
ANL P2,#00H 屏幕清零
MOV A,21H
MOV DPTR,#TABLE
MOVC A.@A+DPTR
ADD,#20H
MOV P2,A
CALL DELAY 调用延时
ANL P2,#00H
MOV A,#01 从这一步我就有点模糊了
CJNE A,21H,A1 #10与#01比较不相等转到A1我是这里
MOV A,01 不懂,是不是表被压在堆栈里了,我
CJNE A,20H,A1 想只有压在堆栈里时才有取一个数码
JMP START 跳到启始 堆栈指针才会减一呀.如果在ROM里
指针只会加一呀(我有点晕)
TABLE: DB 00H,00H,01H,02H,03H,04H
DB 05H,06H,07H,08H,09H
0
回复
提示
@hyjs111
谢谢您的热心回复,我还有一个问题,就是TABLE指针的问题,表是存在堆栈里呢?还是在ROM中的我一直很迷糊.有这样的一个程序您帮我解释下:(这是一个99秒倒计数程序,8051+7447的硬件电路全文我没有全部上传只是倒计时部份)A1:MOV 20H,#10 MOV 21H,#10 MOV A,20H MOV DPTR,#TABLE MOVCA.@A+DPTR ADD A,#10H 数据码加上扫描值 MOV P2,A 显示 CALLDELAY 调用延时扫描 ANL P2,#00H 屏幕清零 MOV A,21H MOV DPTR,#TABLE MOVCA.@A+DPTR ADD,#20H MOV P2,A CALLDELAY 调用延时 ANL P2,#00H MOV A,#01 从这一步我就有点模糊了 CJNEA,21H,A1 #10与#01比较不相等转到A1我是这里 MOV A,01 不懂,是不是表被压在堆栈里了,我 CJNEA,20H,A1 想只有压在堆栈里时才有取一个数码 JMP START 跳到启始 堆栈指针才会减一呀.如果在ROM里 指针只会加一呀(我有点晕)TABLE:DB 00H,00H,01H,02H,03H,04H DB 05H,06H,07H,08H,09H
不要把我当高手,不经常干这个,要骗程的时候还要拿一本手册随时查看.
这段程序中好象没有与堆栈有关的操作.
这段程序试运行过没有?
一般来说,用#01与21H比较转移程序中应该有对21H的操作,否则是多余的,但我没找到.会不会在子程序DELAY中有?
下面用01和20H比较也没见对01和21H地址的操作.
有点晕.
这段程序中好象没有与堆栈有关的操作.
这段程序试运行过没有?
一般来说,用#01与21H比较转移程序中应该有对21H的操作,否则是多余的,但我没找到.会不会在子程序DELAY中有?
下面用01和20H比较也没见对01和21H地址的操作.
有点晕.
0
回复
提示
@hyjs111
谢谢您的热心回复,我还有一个问题,就是TABLE指针的问题,表是存在堆栈里呢?还是在ROM中的我一直很迷糊.有这样的一个程序您帮我解释下:(这是一个99秒倒计数程序,8051+7447的硬件电路全文我没有全部上传只是倒计时部份)A1:MOV 20H,#10 MOV 21H,#10 MOV A,20H MOV DPTR,#TABLE MOVCA.@A+DPTR ADD A,#10H 数据码加上扫描值 MOV P2,A 显示 CALLDELAY 调用延时扫描 ANL P2,#00H 屏幕清零 MOV A,21H MOV DPTR,#TABLE MOVCA.@A+DPTR ADD,#20H MOV P2,A CALLDELAY 调用延时 ANL P2,#00H MOV A,#01 从这一步我就有点模糊了 CJNEA,21H,A1 #10与#01比较不相等转到A1我是这里 MOV A,01 不懂,是不是表被压在堆栈里了,我 CJNEA,20H,A1 想只有压在堆栈里时才有取一个数码 JMP START 跳到启始 堆栈指针才会减一呀.如果在ROM里 指针只会加一呀(我有点晕)TABLE:DB 00H,00H,01H,02H,03H,04H DB 05H,06H,07H,08H,09H
当然存在ROM中,用散转指令查表.
0
回复
提示
@njyd
96没玩过,对你的问题不大清楚. 我的理解: 嵌入式单片机应该是专为某个系统设计,集成于这个系统中.相对于通用式. 输入输出通道的速度是相对的,说高速应该是相对于现在常用的速度(同类型).应该是个类别,具体的实现要看具体说明.
关于串口通讯(如附档所示)如8051输出一个11111110,那么第一个二极管能点亮吗?书上有我的点晕1139013857.xls
0
回复
提示
@hyjs111
大哥我还有两个问题,不好意思打扰了1.假如我编一个程序如何知道在烧写后占用了程序储存器的多少空间2.MOVX,访问外部存储器如何知道外部存储器的地址的,又如何编写外部存储器的程序,书上有可我看的有点不明白,希望您指点一下 祝:大哥新年快乐,在新的一年里事业有成 小弟:韩愈 敬呈
“关于串口通讯(如附档所示)如8051输出一个11111110,那么第一个二极管能点亮吗?”
你这是并行输出,不是串行.
如果用P0口做输出,程序就是这样写.单片机的输出口只能带8个LSTTL的输入,电流只有几mA,直接带LED不够,需要加缓冲.是0还是1点亮就要看你的缓冲电路.
“1.假如我编一个程序如何知道在烧写后占用了程序储存器的多少空间 ”
编译完成后就可看到目标文件的长度,就是占用的空间.
“2.MOVX,访问外部存储器如何知道外部存储器的地址的,又如何编写外部存储器的程序,”
MOVX是访问外部*数据*存储器,这和硬件设计有关.如果是数据存储器你只要知道大小就行了,如果作为IO口就要看硬件是怎么做的.
外部数据存储器只要用MOVX去读写就行了.
如果是程序存储器,就由EA脚电平(硬件接高电平还是低电平)决定.
如果EA脚高电平而且程序计数器不高于内部ROM的大小,则是访问内部ROM.
如果EA脚低电平则全部是访问外部ROM.
如果程序计数器高于内部ROM的大小,不论EA脚电平高低都访问外部ROM.
使用内外程序存储器的程序编写没有不同之处.
你这是并行输出,不是串行.
如果用P0口做输出,程序就是这样写.单片机的输出口只能带8个LSTTL的输入,电流只有几mA,直接带LED不够,需要加缓冲.是0还是1点亮就要看你的缓冲电路.
“1.假如我编一个程序如何知道在烧写后占用了程序储存器的多少空间 ”
编译完成后就可看到目标文件的长度,就是占用的空间.
“2.MOVX,访问外部存储器如何知道外部存储器的地址的,又如何编写外部存储器的程序,”
MOVX是访问外部*数据*存储器,这和硬件设计有关.如果是数据存储器你只要知道大小就行了,如果作为IO口就要看硬件是怎么做的.
外部数据存储器只要用MOVX去读写就行了.
如果是程序存储器,就由EA脚电平(硬件接高电平还是低电平)决定.
如果EA脚高电平而且程序计数器不高于内部ROM的大小,则是访问内部ROM.
如果EA脚低电平则全部是访问外部ROM.
如果程序计数器高于内部ROM的大小,不论EA脚电平高低都访问外部ROM.
使用内外程序存储器的程序编写没有不同之处.
0
回复
提示
@njyd
“关于串口通讯(如附档所示)如8051输出一个11111110,那么第一个二极管能点亮吗?” 你这是并行输出,不是串行. 如果用P0口做输出,程序就是这样写.单片机的输出口只能带8个LSTTL的输入,电流只有几mA,直接带LED不够,需要加缓冲.是0还是1点亮就要看你的缓冲电路.“1.假如我编一个程序如何知道在烧写后占用了程序储存器的多少空间” 编译完成后就可看到目标文件的长度,就是占用的空间.“2.MOVX,访问外部存储器如何知道外部存储器的地址的,又如何编写外部存储器的程序,” MOVX是访问外部*数据*存储器,这和硬件设计有关.如果是数据存储器你只要知道大小就行了,如果作为IO口就要看硬件是怎么做的. 外部数据存储器只要用MOVX去读写就行了. 如果是程序存储器,就由EA脚电平(硬件接高电平还是低电平)决定. 如果EA脚高电平而且程序计数器不高于内部ROM的大小,则是访问内部ROM. 如果EA脚低电平则全部是访问外部ROM. 如果程序计数器高于内部ROM的大小,不论EA脚电平高低都访问外部ROM. 使用内外程序存储器的程序编写没有不同之处.
我知道了
就是外部程序存储器的编写我还是有点模糊,我也不知道在哪里模糊能给我编个具体的例子吗?
就是外部程序存储器的编写我还是有点模糊,我也不知道在哪里模糊能给我编个具体的例子吗?
0
回复
提示
@hyjs
我还有一个问题要请教,就是假如有一程序是时钟程序但是我现在单片机需要进行其它的程序而产生中断,时钟程序进行压栈后是否还会计时程序操作,如果不的话,显示是否就不准了.
定时准不准主要在定时(计数)器,只要定时器的运行方式正确不管你运行什么程序计时器一直在工作.只要在两次定时中断间能响应中断,时钟就不会不准.
程序影响到时钟精确度有以下几个原因:
1、较高等级中断执行时间过长,造成两次定时中断间不能响应定时中断,因此少了一段时间.
解决方法:把定时器中断等级设为最高;或者减短中断执行程序,最极端的是在中断执行程序中只记个中断次数标记,到主程序中根据标记作其他操作.
具体到你的问题,其他中断返回后继续执行被中断的时钟程序,只要总的时间短于一次定时就不会影响时钟显示.
2、定时数据计算错误.
3、这个问题往往会被忽略.51系列单片机的定时器8位定时计数到零时可自动写入定时数.16位定时就不行,计数到零发出中断信号后继续计数,定时数据需要在每次中断时在程序中重新写入.一般来说定时中断不大可能在第一时间响应,这就产生了时间差.
解决方法是在每次写入定时数据前读一下计时器计数,这个数就是从发出中断信号到你准备重新写入定时数据的间,把你的定时数据减去这个数后再写入就行了.
当然也有不用定时器而是用一小段程序的执行时间来延时,这时如果响应了中断当然时间就不准了.这种方法只用于需要等待一段很短时间的时候,用于时钟显示肯定是不行的.除非你的单片机除了时钟外其他什么都没有,但计算起来也是很麻烦.
程序影响到时钟精确度有以下几个原因:
1、较高等级中断执行时间过长,造成两次定时中断间不能响应定时中断,因此少了一段时间.
解决方法:把定时器中断等级设为最高;或者减短中断执行程序,最极端的是在中断执行程序中只记个中断次数标记,到主程序中根据标记作其他操作.
具体到你的问题,其他中断返回后继续执行被中断的时钟程序,只要总的时间短于一次定时就不会影响时钟显示.
2、定时数据计算错误.
3、这个问题往往会被忽略.51系列单片机的定时器8位定时计数到零时可自动写入定时数.16位定时就不行,计数到零发出中断信号后继续计数,定时数据需要在每次中断时在程序中重新写入.一般来说定时中断不大可能在第一时间响应,这就产生了时间差.
解决方法是在每次写入定时数据前读一下计时器计数,这个数就是从发出中断信号到你准备重新写入定时数据的间,把你的定时数据减去这个数后再写入就行了.
当然也有不用定时器而是用一小段程序的执行时间来延时,这时如果响应了中断当然时间就不准了.这种方法只用于需要等待一段很短时间的时候,用于时钟显示肯定是不行的.除非你的单片机除了时钟外其他什么都没有,但计算起来也是很麻烦.
0
回复
提示
@njyd
定时准不准主要在定时(计数)器,只要定时器的运行方式正确不管你运行什么程序计时器一直在工作.只要在两次定时中断间能响应中断,时钟就不会不准. 程序影响到时钟精确度有以下几个原因: 1、较高等级中断执行时间过长,造成两次定时中断间不能响应定时中断,因此少了一段时间. 解决方法:把定时器中断等级设为最高;或者减短中断执行程序,最极端的是在中断执行程序中只记个中断次数标记,到主程序中根据标记作其他操作. 具体到你的问题,其他中断返回后继续执行被中断的时钟程序,只要总的时间短于一次定时就不会影响时钟显示. 2、定时数据计算错误. 3、这个问题往往会被忽略.51系列单片机的定时器8位定时计数到零时可自动写入定时数.16位定时就不行,计数到零发出中断信号后继续计数,定时数据需要在每次中断时在程序中重新写入.一般来说定时中断不大可能在第一时间响应,这就产生了时间差. 解决方法是在每次写入定时数据前读一下计时器计数,这个数就是从发出中断信号到你准备重新写入定时数据的间,把你的定时数据减去这个数后再写入就行了. 当然也有不用定时器而是用一小段程序的执行时间来延时,这时如果响应了中断当然时间就不准了.这种方法只用于需要等待一段很短时间的时候,用于时钟显示肯定是不行的.除非你的单片机除了时钟外其他什么都没有,但计算起来也是很麻烦.
谢谢!我明白了
我是做汽车音响的其中有的是电调谐的,有时钟显示,电子调频,音频频率显示,频谱显示,正反转显示...工作是这样的时钟显示和音频频率显示是LCD同一地方显示,其余的不在同一地方显示,在不开收音的情况下是优显时钟(放音也显时钟)在放音时显频率的其中有一个开关是控制时钟(CLOCK)和调频调幅(AM/FM)的,在音频显示时只要按下CLOCK的键就会显时钟,不管收音正在进行还是在其它状态,在显示频率的这一段时间内(很长)会不会对时钟精度影响
我是做汽车音响的其中有的是电调谐的,有时钟显示,电子调频,音频频率显示,频谱显示,正反转显示...工作是这样的时钟显示和音频频率显示是LCD同一地方显示,其余的不在同一地方显示,在不开收音的情况下是优显时钟(放音也显时钟)在放音时显频率的其中有一个开关是控制时钟(CLOCK)和调频调幅(AM/FM)的,在音频显示时只要按下CLOCK的键就会显时钟,不管收音正在进行还是在其它状态,在显示频率的这一段时间内(很长)会不会对时钟精度影响
0
回复
提示
@hyjs111
谢谢!我明白了我是做汽车音响的其中有的是电调谐的,有时钟显示,电子调频,音频频率显示,频谱显示,正反转显示...工作是这样的时钟显示和音频频率显示是LCD同一地方显示,其余的不在同一地方显示,在不开收音的情况下是优显时钟(放音也显时钟)在放音时显频率的其中有一个开关是控制时钟(CLOCK)和调频调幅(AM/FM)的,在音频显示时只要按下CLOCK的键就会显时钟,不管收音正在进行还是在其它状态,在显示频率的这一段时间内(很长)会不会对时钟精度影响
时钟程序是单独的,用一个实时器定时,定时器中断程序中计总定时数,需要显示时读出总定时数经计算后显示.不管当时显示的是什么内容内部定时器中断还在不断地运行,所以不会对时钟有影响.
以上是只用单片机计时的情况,单片机一断电计时就停止,下一次开机又从零开始,所以现在不用此办法.
现在电器中的时钟(不是指计算机时序的是钟)是单独一个时钟芯片,有充电电池供电,计时与计算机无关.可以单独显示,也可以用计算机(单片机)读出时钟芯片中的时间数据后再送到显示单元.这样即使断电很长时间是钟还是在正常走.
你的汽车音响肯定是用的后一种方法,任何操作不会影响时间精度.
以上是只用单片机计时的情况,单片机一断电计时就停止,下一次开机又从零开始,所以现在不用此办法.
现在电器中的时钟(不是指计算机时序的是钟)是单独一个时钟芯片,有充电电池供电,计时与计算机无关.可以单独显示,也可以用计算机(单片机)读出时钟芯片中的时间数据后再送到显示单元.这样即使断电很长时间是钟还是在正常走.
你的汽车音响肯定是用的后一种方法,任何操作不会影响时间精度.
0
回复
提示
@njyd
时钟程序是单独的,用一个实时器定时,定时器中断程序中计总定时数,需要显示时读出总定时数经计算后显示.不管当时显示的是什么内容内部定时器中断还在不断地运行,所以不会对时钟有影响. 以上是只用单片机计时的情况,单片机一断电计时就停止,下一次开机又从零开始,所以现在不用此办法. 现在电器中的时钟(不是指计算机时序的是钟)是单独一个时钟芯片,有充电电池供电,计时与计算机无关.可以单独显示,也可以用计算机(单片机)读出时钟芯片中的时间数据后再送到显示单元.这样即使断电很长时间是钟还是在正常走. 你的汽车音响肯定是用的后一种方法,任何操作不会影响时间精度.
是的我们用的时钟备用电源,时钟显示是单独的一根电源线不经过车钥匙控制
0
回复
提示
@hyjs111
我还想问下伪指令问题,STA EQU 3编译过来是将3赋给STA吗3表示的是十进制数吗?说真的我连编程器都不会用呢?到现在我学的都是理论,您能给我解释一下吗?
STA EQU 3
EQU编译后不产生代码.
这句的作用是使“STA”这个字符串代表3,或者说是代替3这个数.编译程序在这句以后都把这个字符串看成是3.
也可以认为是将3这个数赋值给STA,但是在编译过程中而不是编译后.
一般用法:
如果你的源程序中经常用到一个直接数,用它以后所有这个数都可以用同一个字符串代替,有利于注释、读程序.
如果有一个数或多次用到的数在调试中可能要经常改变,比如说某个值的上限、下限等.如果直接写这个数在调试中需要改变时就要找到它修改,如果多处用到还要全部找到,很容易漏掉.使用EQU后需要修改时只要把这一句改一下就行了.
EQU编译后不产生代码.
这句的作用是使“STA”这个字符串代表3,或者说是代替3这个数.编译程序在这句以后都把这个字符串看成是3.
也可以认为是将3这个数赋值给STA,但是在编译过程中而不是编译后.
一般用法:
如果你的源程序中经常用到一个直接数,用它以后所有这个数都可以用同一个字符串代替,有利于注释、读程序.
如果有一个数或多次用到的数在调试中可能要经常改变,比如说某个值的上限、下限等.如果直接写这个数在调试中需要改变时就要找到它修改,如果多处用到还要全部找到,很容易漏掉.使用EQU后需要修改时只要把这一句改一下就行了.
0
回复
提示
@hyjs111
谢谢您的热心回复,我还有一个问题,就是TABLE指针的问题,表是存在堆栈里呢?还是在ROM中的我一直很迷糊.有这样的一个程序您帮我解释下:(这是一个99秒倒计数程序,8051+7447的硬件电路全文我没有全部上传只是倒计时部份)A1:MOV 20H,#10 MOV 21H,#10 MOV A,20H MOV DPTR,#TABLE MOVCA.@A+DPTR ADD A,#10H 数据码加上扫描值 MOV P2,A 显示 CALLDELAY 调用延时扫描 ANL P2,#00H 屏幕清零 MOV A,21H MOV DPTR,#TABLE MOVCA.@A+DPTR ADD,#20H MOV P2,A CALLDELAY 调用延时 ANL P2,#00H MOV A,#01 从这一步我就有点模糊了 CJNEA,21H,A1 #10与#01比较不相等转到A1我是这里 MOV A,01 不懂,是不是表被压在堆栈里了,我 CJNEA,20H,A1 想只有压在堆栈里时才有取一个数码 JMP START 跳到启始 堆栈指针才会减一呀.如果在ROM里 指针只会加一呀(我有点晕)TABLE:DB 00H,00H,01H,02H,03H,04H DB 05H,06H,07H,08H,09H
你的程序能编译通过就怪了
0
回复
提示