• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

今天写的第一个接近实用的程序编译获得的通过发帖庆祝,并附上原程序恳请各位DX指教

学习单片机一个月了,今天写的第一个接近实用的程序编译获得的通过发帖庆祝:
说明:此程序通过AD转换器检测输入的电压,然后经过处理转换成3位十进制数由3个8段数码管输出显示.
注:此程序只适用于8位AD检测10V以内的电压,超出此范围都会显示错误的数据.ADC芯片检测脚要有1比3电阻分压.
adval equ 44H
org  0000H
ajmp main
main:   mov adval,#00H
        clr p2.5
main1:  clr p3.6
        nop
        setb p3.6
        clr p3.7
        mov adval,p1
        setb p3.7
        mov a,adval
        mov b,#04H
        mul ab
        mov r6,b
        mov r7,a

CHANGE16_10:
        CLR   A          ;BCD码初始化
        MOV   R3,   A
        MOV   R4,   A
        MOV   R5,   A
        MOV   R2,   #10H ;转换双字节十六进制整数
CHANG_1:
        MOV   A,    R7    ;从高端移出待转换数的一位到CY中
        RLC   A
        MOV   R7,   A
        MOV   A,    R6
        RLC   A
        MOV   R6,   A
        MOV   A,    R5    ;BCD码带进位自身相加,相当于乘2
        ADDC  A,    R5
        DA    A           ;十进制调整
        MOV   R5,   A
        MOV   A,    R4
        ADDC  A,    R4
        DA    A
        MOV   R4,   A
        MOV   A,    R3
        ADDC  A,    R3
        MOV   R3,   A     ;双字节十六进制数的万位数不超过6,不用调整
        DJNZ  R2,   CHANG_1   ;处理完16bit
        

        mov 40h,r4
        mov a,r5
        anl a,#0fh
        mov 42h,a
        clr a
        mov a,r5
        anl a,#0f0h
        rl a
        rl a
        rl a
        rl a
        mov 41h,a

mov  r1,#20    
loop1:call display
   djnz r1,loop1
   ajmp main1


display:
   MOV DPTR,#TABLE1
   clr p2.6
   mov a,40h
   MOVC a,@A+DPTR
   mov p0,a    
   setb p2.6
   clr p2.6

   clr p2.7
   mov P0,#7eh;
   setb p2.7
   clr p2.7
   mov 50h,#5h
   call delayxms

   mov dptr,#table
   clr p2.6
   mov a,41h
   MOVC a,@A+DPTR
   mov p0,a
   setb p2.6
   clr p2.6

   clr p2.7
   mov P0,#7dh;
   setb p2.7
   clr p2.7
   mov 50h,#5h
   call delayxms

   mov dptr,#table
   mov a,42h
   MOVC a,@A+DPTR
   mov p0,a ;
   setb p2.6
   clr p2.6

   clr p2.7
   mov P0,#7bh;
   setb p2.7
   clr p2.7
   mov 50h,#4h
   call delayxms
   ret

delayxms:mov 52h,#4        
delaya: mov 51h,#60
        djnz 51h,$
        djnz 52h,delaya
        djnz 50h,delayxms
        ret


table:db   3fh,30h,5bh,4fh,66h,6dh,7dh,07h
      db   7fh,6fh,77h,7ch,39h,5eh,79h,71h

table1:db  0bfh,0b0h,0dbh,0cfh,0e6h,0edh,0fdh,87h
       db  0ffh,0efh


end500) {this.resized=true; this.width=500; this.alt='这是一张缩略图,点击可放大。\n按住CTRL,滚动鼠标滚轮可自由缩放';this.style.cursor='hand'}" onclick="if(!this.resized) {return true;} else {window.open('http://u.dianyuan.com/bbs/u/72/107361230127830.gif');}" onmousewheel="return imgzoom(this);">500) {this.resized=true; this.width=500; this.alt='这是一张缩略图,点击可放大。\n按住CTRL,滚动鼠标滚轮可自由缩放';this.style.cursor='hand'}" onclick="if(!this.resized) {return true;} else {window.open('http://u.dianyuan.com/bbs/u/72/107361230127889.gif');}" onmousewheel="return imgzoom(this);">
全部回复(23)
正序查看
倒序查看
红心j
LV.3
2
2008-12-25 10:58
硬件、软件错误多多,一时难以评说.

如果将每一点错误和不当都指出并说明原因、列出正确做法,恐怕比你的原文会长很多.

当然,可以看出你很努力,现在的不足也仅仅是初学者认识尚浅.

说一个软件上出现的最最小的小事:
        anl a,#0f0h
        rl a
        rl a
        rl a
        rl a
可以写成
        anl a,#0f0h
       swap a

忙,有时间再来说.
0
回复
2008-12-26 19:55
@红心j
硬件、软件错误多多,一时难以评说.如果将每一点错误和不当都指出并说明原因、列出正确做法,恐怕比你的原文会长很多.当然,可以看出你很努力,现在的不足也仅仅是初学者认识尚浅.说一个软件上出现的最最小的小事:        anla,#0f0h        rla        rla        rla        rla可以写成        anla,#0f0h      swapa忙,有时间再来说.
多谢DX指点,你说的对,由于刚接触对于单片机系统的指令系统等各方面都不熟悉 .暂时还只有这样的水准了,还请多多指教,谢谢!硬件系统是开发板固定的所以暂时没办法变更.
0
回复
红心j
LV.3
4
2008-12-26 21:16
@northeasttigar
多谢DX指点,你说的对,由于刚接触对于单片机系统的指令系统等各方面都不熟悉.暂时还只有这样的水准了,还请多多指教,谢谢!硬件系统是开发板固定的所以暂时没办法变更.
晕倒,这种硬件电路居然能是开发板?我以为是外行初学者尝试画的!!!
0
回复
红心j
LV.3
5
2008-12-26 22:32
@northeasttigar
多谢DX指点,你说的对,由于刚接触对于单片机系统的指令系统等各方面都不熟悉.暂时还只有这样的水准了,还请多多指教,谢谢!硬件系统是开发板固定的所以暂时没办法变更.
500) {this.resized=true; this.width=500; this.alt='这是一张缩略图,点击可放大。\n按住CTRL,滚动鼠标滚轮可自由缩放';this.style.cursor='hand'}" onclick="if(!this.resized) {return true;} else {window.open('http://u.dianyuan.com/bbs/u/72/3080241230300106.jpg');}" onmousewheel="return imgzoom(this);">

要学就学正确的,开始时接触错误的东西后患无穷.以上是MCU普通I/O口方式下控制数码管显示的一种电路.

【评论你的显示电路】
(1)对于最小系统而言,当MCU的I/O口够用时,无需使用I/O扩展器件
(2)对于并行扩展输出口时,一般使用边沿锁存的触发器,比如74HC273、74HC574,而通常不使用电平锁存的触发器,比如74HC373、74HC573
(3)普通数字电路(比如74HC573),其输出驱动能力有限,不适合作为LED数码管位驱动
(4)数码管段驱动未加限流电阻时,会造成显示符号段数不同则亮度不同,尤其显示“1”和“8.”时亮度相差最大,如果六个数码管用来显示时钟18点18分18秒,那将是最丑陋的显示
(5)无论数字电路还是LED,不在合理范围内限制功耗长期运行的话,易造成器件损坏
0
回复
红心j
LV.3
6
2008-12-26 23:01
@northeasttigar
多谢DX指点,你说的对,由于刚接触对于单片机系统的指令系统等各方面都不熟悉.暂时还只有这样的水准了,还请多多指教,谢谢!硬件系统是开发板固定的所以暂时没办法变更.
同样,很丑陋的硬件电路也表现在ADC0804的控制
(1)通过P2.7来控制一个8位锁存器(74HC573)来产生一个信号“CSAD”,这就如同俗话所言——脱裤子放P一样,要知道用P2.7本身来做信号“CSAD”就可以了,本身目标离你一步之遥,但你朝反方向走,只能绕过地球一圈才能到达目标
(2)ADC0804的启动转换和数据读出无需连到MCU的RD/WR管脚,因为当前方式下,RD/WR管脚也只能使用普通I/O方式,因此这两个信号同样也可以连接到其他I/O管脚上
(3)AD转换需要精准、稳定的参考电压,使用VCC无法保证测量精度,成本不是这样省的,其实能适合8位AD的基准电压源也很便宜,比如TL431才几毛钱
0
回复
红心j
LV.3
7
2008-12-26 23:04
@northeasttigar
多谢DX指点,你说的对,由于刚接触对于单片机系统的指令系统等各方面都不熟悉.暂时还只有这样的水准了,还请多多指教,谢谢!硬件系统是开发板固定的所以暂时没办法变更.
纵观这个所谓的开发板,就是一个骗钱坑人的东西
0
回复
红心j
LV.3
8
2008-12-26 23:32
@红心j
同样,很丑陋的硬件电路也表现在ADC0804的控制(1)通过P2.7来控制一个8位锁存器(74HC573)来产生一个信号“CSAD”,这就如同俗话所言——脱裤子放P一样,要知道用P2.7本身来做信号“CSAD”就可以了,本身目标离你一步之遥,但你朝反方向走,只能绕过地球一圈才能到达目标(2)ADC0804的启动转换和数据读出无需连到MCU的RD/WR管脚,因为当前方式下,RD/WR管脚也只能使用普通I/O方式,因此这两个信号同样也可以连接到其他I/O管脚上(3)AD转换需要精准、稳定的参考电压,使用VCC无法保证测量精度,成本不是这样省的,其实能适合8位AD的基准电压源也很便宜,比如TL431才几毛钱
由于你在两张图上重复了一个74HC573,所以看错一个,因此上述(1)言论收回,并表歉意
0
回复
红心j
LV.3
9
2008-12-26 23:42
@northeasttigar
多谢DX指点,你说的对,由于刚接触对于单片机系统的指令系统等各方面都不熟悉.暂时还只有这样的水准了,还请多多指教,谢谢!硬件系统是开发板固定的所以暂时没办法变更.
补充一条:
当MCU的P0口以普通I/O方式输出外界数字电路U1、U2时,P0口应外接上拉电阻
0
回复
红心j
LV.3
10
2008-12-26 23:59
@northeasttigar
多谢DX指点,你说的对,由于刚接触对于单片机系统的指令系统等各方面都不熟悉.暂时还只有这样的水准了,还请多多指教,谢谢!硬件系统是开发板固定的所以暂时没办法变更.
也可能受所谓的开发板限制,也可能I/O口都已被其他功能占用,我之所以说了很多,只是希望不要学习这个开发板的电路,否则会带来错误的认识.

顺便说一句,如果I/O口真的很不够用的话,ADC0804的数据是可以与U1、U2共享P0口的,不必占用P1口.
0
回复
红心j
LV.3
11
2008-12-27 00:09
@northeasttigar
多谢DX指点,你说的对,由于刚接触对于单片机系统的指令系统等各方面都不熟悉.暂时还只有这样的水准了,还请多多指教,谢谢!硬件系统是开发板固定的所以暂时没办法变更.
软件方面,你首先在AD转换控制方面犯了一个错误:
ADC0804启动转化后,马上读取数据是错误的,通常的方法是检查AD是否转换结束,一般采用查询或者中断处理的方法,如果不想增加这一硬件接口,也可以根据一次转换可能的最大所需时间,在启动AD转换后进行延时,然后再读取AD转换的数据
0
回复
红心j
LV.3
12
2008-12-27 00:50
@northeasttigar
多谢DX指点,你说的对,由于刚接触对于单片机系统的指令系统等各方面都不熟悉.暂时还只有这样的水准了,还请多多指教,谢谢!硬件系统是开发板固定的所以暂时没办法变更.
adval equ 44H ,这是好的做法,遗憾的是仅仅就这一个,其它的单元以及I/O口就没有如法炮制,比如可以

M_DISP1   EQU  40H
M_DISP2   EQU  M_DISP1+1
M_DISP3   EQU  M_DISP1+2
M_DELAY1  EQU  50H
M_DALAY2  EQU  M_DELAY1+1
M_DELAY3  EQU  M_DELAY2+1
......
DATA_OUT  EQU  P0
DATA_IN   EQU  P1
......
DULA      EQU  P2.6
WELA      EQU  P2.7
......
DATA_DELAY1  EQU  4
DATA_DELAY2  EQU  60
DATA_DELAY3  EQU  4
......

DELAYXMS:  MOV    M_DELAY1,#DATA_DELAY1  ;子程序调用前都有此句,通常公共部分也放在子程序中
DELAYXMS_1:MOV    M_DELAY3,#DATA_DELAY3
DELAYA:    MOV    M_DELAY2,#DATA_DELAY2
           DJNZ   M_DELAY2,$
           DJNZ   M_DELAY3,DELAYA
           DJNZ   M_DELAY1,DELAYXMS_1

伪指令除了帮助记忆外,更方便更改和重新定位
0
回复
红心j
LV.3
13
2008-12-27 01:26
@northeasttigar
多谢DX指点,你说的对,由于刚接触对于单片机系统的指令系统等各方面都不熟悉.暂时还只有这样的水准了,还请多多指教,谢谢!硬件系统是开发板固定的所以暂时没办法变更.
关于显示方面程序的问题是很多的:
(1)相同符号显示情况下,最后送出的显示位亮度要高于前面两位,其原因在于最后一位的显示时间为:相同的调用子程序延时时间+主程序运行时间.
    如果要达到相同的亮度,最后一位的显示时间应与前两位相同,因此最后一位显示,应在调用延时程序后,清除这一位的显示.
(2)存在花屏即俗话所说的“鬼影”现象,此现象表现为正常的显示符号外,其它不应该显示的段有较暗亮度的显示.
    正确的做法是:先关掉前一显示的位驱动,然后再送本次显示位的段码,最后再送本次显示位的位驱动.
(3)效率低造成显示亮度低,甚至会产生显示闪烁或者现象.
    由于在检测AD和AD数据处理的运行期间没有显示,降低了显示时间比,从而降低了显示亮度.
    如果显示以外的程序运行时间过长,以至于引起扫描显示频率过低后,会产生显示闪烁或者跳动的现象,通常这个频率不要低于50Hz,即一个显示周期不要大于20mS.
    由于系统中可能存在各种各样的事件需要处理,因此处理时间长短难以估量,为了保障动态扫描方式下的显示效率和显示的稳定性,应采用定时中断扫描显示方式.
(4)MCU中,中断的应用往往是必须的重要的,如果不能很好的应用中断,将无法坐到设计工程师的位置上,在学习中一定要重视中断的学习和练习
0
回复
红心j
LV.3
14
2008-12-27 01:40
@northeasttigar
多谢DX指点,你说的对,由于刚接触对于单片机系统的指令系统等各方面都不熟悉.暂时还只有这样的水准了,还请多多指教,谢谢!硬件系统是开发板固定的所以暂时没办法变更.
关于数据处理那段程序,我判断你是借用他人的,我也不做测试了,简单就此说两句:
(1)借鉴、借用现成的子程序是提高效率办法,是不错的方法
(2)借用他人的子程序应做仔细的测试,以免出错,网上经常会看到这样的错误,不可盲信盲从,包括我对你说的每一句话.
(3)只借用而不借鉴不会成为好的设计者,不明其理的借用,只能应急,不会对你产生更有益的东西
0
回复
红心j
LV.3
15
2008-12-27 02:03
@northeasttigar
多谢DX指点,你说的对,由于刚接触对于单片机系统的指令系统等各方面都不熟悉.暂时还只有这样的水准了,还请多多指教,谢谢!硬件系统是开发板固定的所以暂时没办法变更.
必须要说的话:
    学习一个月,能写出这样的程序已经很不错了,可以看出很努力,至少我开始学习的头一个月里没做到.
    学习单片机,只学习或者更热衷于编程今后很难进行产品设计,MCU的应用设计从比重上更倾向硬件,外围硬件设计能力将决定设计之路会走多远.
    另外一个往往被初学者忽视的方面是时序,这在MCU和数字电路方面是至关重要的.
    从实验角度,初学者更宜从单个实验方面来进行,不宜开始就从系统编程方面入手,初始的认识和能力容易把自己搞的很混乱,从而引起焦虑影响信心.当单个问题都有实践、认识和基本能力后,再进行系统实验和练习更容易些.
0
回复
2008-12-28 14:55
@红心j
晕倒,这种硬件电路居然能是开发板?我以为是外行初学者尝试画的!!!
首先,謝謝您的回復,從中我學到很多在書本上學不到的東西.可以看出你是一位有"德"之人.這個開發板確實存在一些資源配置上不合理的地方.我都可以找出它的一些問題.
0
回复
2008-12-28 15:06
@红心j
[图片]500){this.resized=true;this.width=500;this.alt='这是一张缩略图,点击可放大。\n按住CTRL,滚动鼠标滚轮可自由缩放';this.style.cursor='hand'}"onclick="if(!this.resized){returntrue;}else{window.open('http://u.dianyuan.com/bbs/u/72/3080241230300106.jpg');}"onmousewheel="returnimgzoom(this);">要学就学正确的,开始时接触错误的东西后患无穷.以上是MCU普通I/O口方式下控制数码管显示的一种电路.【评论你的显示电路】(1)对于最小系统而言,当MCU的I/O口够用时,无需使用I/O扩展器件(2)对于并行扩展输出口时,一般使用边沿锁存的触发器,比如74HC273、74HC574,而通常不使用电平锁存的触发器,比如74HC373、74HC573(3)普通数字电路(比如74HC573),其输出驱动能力有限,不适合作为LED数码管位驱动(4)数码管段驱动未加限流电阻时,会造成显示符号段数不同则亮度不同,尤其显示“1”和“8.”时亮度相差最大,如果六个数码管用来显示时钟18点18分18秒,那将是最丑陋的显示(5)无论数字电路还是LED,不在合理范围内限制功耗长期运行的话,易造成器件损坏
整個開發板還有很多其他的外圍電路及資源,但是i/O口還是夠用正如您說這些都是資源配置的問題.以及硬件問題,這只是我用來做初始學習的工具,等對MCU有一定了解,會自己動手做適合的實驗板.對於亮度的問題,昨天我做過實驗確實存在這些問題,我又修改了電路,但沒通過編譯,所以暫不貼出.
0
回复
2008-12-28 15:11
@红心j
同样,很丑陋的硬件电路也表现在ADC0804的控制(1)通过P2.7来控制一个8位锁存器(74HC573)来产生一个信号“CSAD”,这就如同俗话所言——脱裤子放P一样,要知道用P2.7本身来做信号“CSAD”就可以了,本身目标离你一步之遥,但你朝反方向走,只能绕过地球一圈才能到达目标(2)ADC0804的启动转换和数据读出无需连到MCU的RD/WR管脚,因为当前方式下,RD/WR管脚也只能使用普通I/O方式,因此这两个信号同样也可以连接到其他I/O管脚上(3)AD转换需要精准、稳定的参考电压,使用VCC无法保证测量精度,成本不是这样省的,其实能适合8位AD的基准电压源也很便宜,比如TL431才几毛钱
基準問題在寫和序前我就自己調整電阻加上了431穩壓.對于第二點,我在看電路時確實陏悶了好久,因書上介紹都是使用p3口的第二功能,由此思考就是找不出控制ad0804的方式.
0
回复
2008-12-28 15:13
@红心j
软件方面,你首先在AD转换控制方面犯了一个错误:ADC0804启动转化后,马上读取数据是错误的,通常的方法是检查AD是否转换结束,一般采用查询或者中断处理的方法,如果不想增加这一硬件接口,也可以根据一次转换可能的最大所需时间,在启动AD转换后进行延时,然后再读取AD转换的数据
確實如此,學習.吸收
0
回复
2008-12-28 15:18
@红心j
关于显示方面程序的问题是很多的:(1)相同符号显示情况下,最后送出的显示位亮度要高于前面两位,其原因在于最后一位的显示时间为:相同的调用子程序延时时间+主程序运行时间.    如果要达到相同的亮度,最后一位的显示时间应与前两位相同,因此最后一位显示,应在调用延时程序后,清除这一位的显示.(2)存在花屏即俗话所说的“鬼影”现象,此现象表现为正常的显示符号外,其它不应该显示的段有较暗亮度的显示.    正确的做法是:先关掉前一显示的位驱动,然后再送本次显示位的段码,最后再送本次显示位的位驱动.(3)效率低造成显示亮度低,甚至会产生显示闪烁或者现象.    由于在检测AD和AD数据处理的运行期间没有显示,降低了显示时间比,从而降低了显示亮度.    如果显示以外的程序运行时间过长,以至于引起扫描显示频率过低后,会产生显示闪烁或者跳动的现象,通常这个频率不要低于50Hz,即一个显示周期不要大于20mS.    由于系统中可能存在各种各样的事件需要处理,因此处理时间长短难以估量,为了保障动态扫描方式下的显示效率和显示的稳定性,应采用定时中断扫描显示方式.(4)MCU中,中断的应用往往是必须的重要的,如果不能很好的应用中断,将无法坐到设计工程师的位置上,在学习中一定要重视中断的学习和练习
這些都是經驗的體現,我只能學習,學習,再練習.中斷部份還在學習中,不太熟,重新修改的程序會用到,還請多指教.
0
回复
2008-12-28 15:23
@红心j
必须要说的话:    学习一个月,能写出这样的程序已经很不错了,可以看出很努力,至少我开始学习的头一个月里没做到.    学习单片机,只学习或者更热衷于编程今后很难进行产品设计,MCU的应用设计从比重上更倾向硬件,外围硬件设计能力将决定设计之路会走多远.    另外一个往往被初学者忽视的方面是时序,这在MCU和数字电路方面是至关重要的.    从实验角度,初学者更宜从单个实验方面来进行,不宜开始就从系统编程方面入手,初始的认识和能力容易把自己搞的很混乱,从而引起焦虑影响信心.当单个问题都有实践、认识和基本能力后,再进行系统实验和练习更容易些.
謝謝你耐心細緻回復這么多,也謝謝你對一個初學者的鼓勵,這些都讓我受益菲淺,現時由於經驗缺少和對系統不熟在考慮複雜程序時確實會有頭腦短路的現象.我會仔細考慮您的建議.
0
回复
whatcall
LV.5
22
2008-12-29 08:54
@红心j
必须要说的话:    学习一个月,能写出这样的程序已经很不错了,可以看出很努力,至少我开始学习的头一个月里没做到.    学习单片机,只学习或者更热衷于编程今后很难进行产品设计,MCU的应用设计从比重上更倾向硬件,外围硬件设计能力将决定设计之路会走多远.    另外一个往往被初学者忽视的方面是时序,这在MCU和数字电路方面是至关重要的.    从实验角度,初学者更宜从单个实验方面来进行,不宜开始就从系统编程方面入手,初始的认识和能力容易把自己搞的很混乱,从而引起焦虑影响信心.当单个问题都有实践、认识和基本能力后,再进行系统实验和练习更容易些.
回复的很仔细啊.
0
回复
2009-01-11 20:44
@whatcall
回复的很仔细啊.
是啊   真是个好人啊
0
回复
山石
LV.4
24
2009-02-03 16:34
@红心j
必须要说的话:    学习一个月,能写出这样的程序已经很不错了,可以看出很努力,至少我开始学习的头一个月里没做到.    学习单片机,只学习或者更热衷于编程今后很难进行产品设计,MCU的应用设计从比重上更倾向硬件,外围硬件设计能力将决定设计之路会走多远.    另外一个往往被初学者忽视的方面是时序,这在MCU和数字电路方面是至关重要的.    从实验角度,初学者更宜从单个实验方面来进行,不宜开始就从系统编程方面入手,初始的认识和能力容易把自己搞的很混乱,从而引起焦虑影响信心.当单个问题都有实践、认识和基本能力后,再进行系统实验和练习更容易些.
从实验角度,初学者更宜从单个实验方面来进行,不宜开始就从系统编程方面入手,初始的认识和能力容易把自己搞的很混乱,从而引起焦虑影响信心.当单个问题都有实践、认识和基本能力后,再进行系统实验和练习更容易些.
我觉得这句话说的最好,我也是刚学单片机,是工作需要,要做一款电子钟,虽然现在勉强把电子钟也完成了,不过我觉得我现在头脑很乱,究其原因就是隔着锅台上炕了,很多基础的东西还不是很清楚,谢谢这位好心人,
你是个好人 啊!!!!
0
回复