学习单片机一个月了,今天写的第一个接近实用的程序编译获得的通过发帖庆祝:
说明:此程序通过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);">
今天写的第一个接近实用的程序编译获得的通过发帖庆祝,并附上原程序恳请各位DX指教
全部回复(23)
正序查看
倒序查看
现在还没有回复呢,说说你的想法
@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,不在合理范围内限制功耗长期运行的话,易造成器件损坏
要学就学正确的,开始时接触错误的东西后患无穷.以上是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
回复
提示
@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才几毛钱
(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
同样,很丑陋的硬件电路也表现在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
回复
提示
@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
伪指令除了帮助记忆外,更方便更改和重新定位
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
回复
提示
@northeasttigar
多谢DX指点,你说的对,由于刚接触对于单片机系统的指令系统等各方面都不熟悉.暂时还只有这样的水准了,还请多多指教,谢谢!硬件系统是开发板固定的所以暂时没办法变更.
关于显示方面程序的问题是很多的:
(1)相同符号显示情况下,最后送出的显示位亮度要高于前面两位,其原因在于最后一位的显示时间为:相同的调用子程序延时时间+主程序运行时间.
如果要达到相同的亮度,最后一位的显示时间应与前两位相同,因此最后一位显示,应在调用延时程序后,清除这一位的显示.
(2)存在花屏即俗话所说的“鬼影”现象,此现象表现为正常的显示符号外,其它不应该显示的段有较暗亮度的显示.
正确的做法是:先关掉前一显示的位驱动,然后再送本次显示位的段码,最后再送本次显示位的位驱动.
(3)效率低造成显示亮度低,甚至会产生显示闪烁或者现象.
由于在检测AD和AD数据处理的运行期间没有显示,降低了显示时间比,从而降低了显示亮度.
如果显示以外的程序运行时间过长,以至于引起扫描显示频率过低后,会产生显示闪烁或者跳动的现象,通常这个频率不要低于50Hz,即一个显示周期不要大于20mS.
由于系统中可能存在各种各样的事件需要处理,因此处理时间长短难以估量,为了保障动态扫描方式下的显示效率和显示的稳定性,应采用定时中断扫描显示方式.
(4)MCU中,中断的应用往往是必须的重要的,如果不能很好的应用中断,将无法坐到设计工程师的位置上,在学习中一定要重视中断的学习和练习
(1)相同符号显示情况下,最后送出的显示位亮度要高于前面两位,其原因在于最后一位的显示时间为:相同的调用子程序延时时间+主程序运行时间.
如果要达到相同的亮度,最后一位的显示时间应与前两位相同,因此最后一位显示,应在调用延时程序后,清除这一位的显示.
(2)存在花屏即俗话所说的“鬼影”现象,此现象表现为正常的显示符号外,其它不应该显示的段有较暗亮度的显示.
正确的做法是:先关掉前一显示的位驱动,然后再送本次显示位的段码,最后再送本次显示位的位驱动.
(3)效率低造成显示亮度低,甚至会产生显示闪烁或者现象.
由于在检测AD和AD数据处理的运行期间没有显示,降低了显示时间比,从而降低了显示亮度.
如果显示以外的程序运行时间过长,以至于引起扫描显示频率过低后,会产生显示闪烁或者跳动的现象,通常这个频率不要低于50Hz,即一个显示周期不要大于20mS.
由于系统中可能存在各种各样的事件需要处理,因此处理时间长短难以估量,为了保障动态扫描方式下的显示效率和显示的稳定性,应采用定时中断扫描显示方式.
(4)MCU中,中断的应用往往是必须的重要的,如果不能很好的应用中断,将无法坐到设计工程师的位置上,在学习中一定要重视中断的学习和练习
0
回复
提示
@northeasttigar
多谢DX指点,你说的对,由于刚接触对于单片机系统的指令系统等各方面都不熟悉.暂时还只有这样的水准了,还请多多指教,谢谢!硬件系统是开发板固定的所以暂时没办法变更.
必须要说的话:
学习一个月,能写出这样的程序已经很不错了,可以看出很努力,至少我开始学习的头一个月里没做到.
学习单片机,只学习或者更热衷于编程今后很难进行产品设计,MCU的应用设计从比重上更倾向硬件,外围硬件设计能力将决定设计之路会走多远.
另外一个往往被初学者忽视的方面是时序,这在MCU和数字电路方面是至关重要的.
从实验角度,初学者更宜从单个实验方面来进行,不宜开始就从系统编程方面入手,初始的认识和能力容易把自己搞的很混乱,从而引起焦虑影响信心.当单个问题都有实践、认识和基本能力后,再进行系统实验和练习更容易些.
学习一个月,能写出这样的程序已经很不错了,可以看出很努力,至少我开始学习的头一个月里没做到.
学习单片机,只学习或者更热衷于编程今后很难进行产品设计,MCU的应用设计从比重上更倾向硬件,外围硬件设计能力将决定设计之路会走多远.
另外一个往往被初学者忽视的方面是时序,这在MCU和数字电路方面是至关重要的.
从实验角度,初学者更宜从单个实验方面来进行,不宜开始就从系统编程方面入手,初始的认识和能力容易把自己搞的很混乱,从而引起焦虑影响信心.当单个问题都有实践、认识和基本能力后,再进行系统实验和练习更容易些.
0
回复
提示
@红心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
回复
提示
@红心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
回复
提示
@红心j
关于显示方面程序的问题是很多的:(1)相同符号显示情况下,最后送出的显示位亮度要高于前面两位,其原因在于最后一位的显示时间为:相同的调用子程序延时时间+主程序运行时间. 如果要达到相同的亮度,最后一位的显示时间应与前两位相同,因此最后一位显示,应在调用延时程序后,清除这一位的显示.(2)存在花屏即俗话所说的“鬼影”现象,此现象表现为正常的显示符号外,其它不应该显示的段有较暗亮度的显示. 正确的做法是:先关掉前一显示的位驱动,然后再送本次显示位的段码,最后再送本次显示位的位驱动.(3)效率低造成显示亮度低,甚至会产生显示闪烁或者现象. 由于在检测AD和AD数据处理的运行期间没有显示,降低了显示时间比,从而降低了显示亮度. 如果显示以外的程序运行时间过长,以至于引起扫描显示频率过低后,会产生显示闪烁或者跳动的现象,通常这个频率不要低于50Hz,即一个显示周期不要大于20mS. 由于系统中可能存在各种各样的事件需要处理,因此处理时间长短难以估量,为了保障动态扫描方式下的显示效率和显示的稳定性,应采用定时中断扫描显示方式.(4)MCU中,中断的应用往往是必须的重要的,如果不能很好的应用中断,将无法坐到设计工程师的位置上,在学习中一定要重视中断的学习和练习
這些都是經驗的體現,我只能學習,學習,再練習.中斷部份還在學習中,不太熟,重新修改的程序會用到,還請多指教.
0
回复
提示
@红心j
必须要说的话: 学习一个月,能写出这样的程序已经很不错了,可以看出很努力,至少我开始学习的头一个月里没做到. 学习单片机,只学习或者更热衷于编程今后很难进行产品设计,MCU的应用设计从比重上更倾向硬件,外围硬件设计能力将决定设计之路会走多远. 另外一个往往被初学者忽视的方面是时序,这在MCU和数字电路方面是至关重要的. 从实验角度,初学者更宜从单个实验方面来进行,不宜开始就从系统编程方面入手,初始的认识和能力容易把自己搞的很混乱,从而引起焦虑影响信心.当单个问题都有实践、认识和基本能力后,再进行系统实验和练习更容易些.
謝謝你耐心細緻回復這么多,也謝謝你對一個初學者的鼓勵,這些都讓我受益菲淺,現時由於經驗缺少和對系統不熟在考慮複雜程序時確實會有頭腦短路的現象.我會仔細考慮您的建議.
0
回复
提示
@红心j
必须要说的话: 学习一个月,能写出这样的程序已经很不错了,可以看出很努力,至少我开始学习的头一个月里没做到. 学习单片机,只学习或者更热衷于编程今后很难进行产品设计,MCU的应用设计从比重上更倾向硬件,外围硬件设计能力将决定设计之路会走多远. 另外一个往往被初学者忽视的方面是时序,这在MCU和数字电路方面是至关重要的. 从实验角度,初学者更宜从单个实验方面来进行,不宜开始就从系统编程方面入手,初始的认识和能力容易把自己搞的很混乱,从而引起焦虑影响信心.当单个问题都有实践、认识和基本能力后,再进行系统实验和练习更容易些.
回复的很仔细啊.
0
回复
提示
@红心j
必须要说的话: 学习一个月,能写出这样的程序已经很不错了,可以看出很努力,至少我开始学习的头一个月里没做到. 学习单片机,只学习或者更热衷于编程今后很难进行产品设计,MCU的应用设计从比重上更倾向硬件,外围硬件设计能力将决定设计之路会走多远. 另外一个往往被初学者忽视的方面是时序,这在MCU和数字电路方面是至关重要的. 从实验角度,初学者更宜从单个实验方面来进行,不宜开始就从系统编程方面入手,初始的认识和能力容易把自己搞的很混乱,从而引起焦虑影响信心.当单个问题都有实践、认识和基本能力后,再进行系统实验和练习更容易些.
从实验角度,初学者更宜从单个实验方面来进行,不宜开始就从系统编程方面入手,初始的认识和能力容易把自己搞的很混乱,从而引起焦虑影响信心.当单个问题都有实践、认识和基本能力后,再进行系统实验和练习更容易些.
我觉得这句话说的最好,我也是刚学单片机,是工作需要,要做一款电子钟,虽然现在勉强把电子钟也完成了,不过我觉得我现在头脑很乱,究其原因就是隔着锅台上炕了,很多基础的东西还不是很清楚,谢谢这位好心人,
你是个好人 啊!!!!
我觉得这句话说的最好,我也是刚学单片机,是工作需要,要做一款电子钟,虽然现在勉强把电子钟也完成了,不过我觉得我现在头脑很乱,究其原因就是隔着锅台上炕了,很多基础的东西还不是很清楚,谢谢这位好心人,
你是个好人 啊!!!!
0
回复
提示