📄 adc.asm
字号:
;********************************************************************************
;* *
;* File : 实验板ADC.ASM *
;* Function : 单通道ADC输入显示练习 *
;* Date : 2006-05-05 *
;* Version : 1.0 *
;* *
;* Author : 开关电源 hongtusy@163.com *
;* Company : 电子信息技术咨询网 http://www.itsn.cn *
;* *
;****************************描述与记事******************************************
;实验板的AVR程序,单通道模拟电压输入,并用LED做转换后数字显示实验练习。
;接线定义:使用PC和PD口驱动LED数码管显示,PD口接138的输入端。数据位为PC口。
; 开关位置:SW2-1,2,3,4.SW1-1~8.SW2-6为LED电源。SW3-8为系统复位端。
; PA0(SW3-1)和PA1(SW3-2)作为两个通道的模拟量输入端。
;记事:本程序旨在对ADC及LED驱动的理解与演示,程序适合初学者使用。
;具体电路可参照使用指南里的说明。调节电位器VR1,即可将改变后的电压值显示在LED上。
;使用器件:ATMEGA8535,可更换。 使用片内1MHz晶振
;说明:程序中的将数值处理的程序须完善,时间关系就不处理了,读者可自行处理,更详细
; 的ADC程序见本实验的C程序集。
;********************************************************************************
.include "m8535def.inc" ;定义头文件。
.org 0x0000 ;指定开始地址。
rjmp reset ;转移到“RESET”句。
.org 0x10
reset: ldi r16,0x02 ;设置堆栈指针0x025f
out sph,r16
ldi r16,0x5f
out spl,r16
ldi r16,0xff ;加载立即数,把立即数0XFF放到定义过的Temp中,作数据方向参数。
out ddrd,r16 ;PD口为输出,驱动LED时的位码端
out ddrc,r16 ;PC口为输出,数码管的段码端
ldi r16,0x00
out ddra,r16 ;a口输入
out porta,r16 ;内部不接上拉电阻
;***************ADC初始化***********************
ldi r16,0b11101011 ; //ADC使能、启动转换、自由转换、中断使能、8分频。
out adcsra,r16
ldi r16,0b11000000
out admux,r16 ;内参2.56V参考电压源选择0通道、内参考源、右对齐、单输入。
;---------------------------------------------------------------------------------
main: rcall display ;多显示几次,故意缩短测量读数频率,字跳动小些。但是精度差了,实际中不能这样使用。
rcall display
rcall display
rcall display
rcall display
rcall display
rcall display
rcall display
rcall display
rcall intermit ;ADC转换处理
rjmp main
;**************ADC转换处理程序***************
intermit: in r30,adcl ;中断后,读取ADC低部分数据
in r31,adch
cbr r31,0b11111100 ;高6位清0,因为是10位ADC,高数据无效。
;rcall average ;计算10次测量结果的平均值。 待完善
;rcall cal ;调软件校准程序 待完善
;rcall zero ;零位处理 待完善
rcall b16td5 ;数制转换
ret ;中断返回
;*******************软件校准程序********************
;在单端输入方式下,数据转换为10位精度,参考电压是2.56V时,输入0V=0,输入2.56V=输出1024。
;即分辨力是2.56V/1024=0.0025V=2.5mV.要想显示真实电压值,就需要将输出结果乘以2.5mV,单位为mV.
;这里讲的校准程序就是引入这个比例的意思。另外如果存在系统误差,还可以适当改变这个比例来修正测量结果。
;程序思想:2.5就是5/2,因此将结果先乘以5,再除以2。
cal: nop
ret
;**************零位处理程序*********************
;通过加上或减去一个底数来消除系统线性误差或归零处理的影响
zero: nop
ret
;***************计算平均值程序*********************
;通过计算10次结果的平均值可以适当滤波,得到较稳定的测量结果。
average: nop
ret
;********16位二进制数转换为5位BCD码,就是十进制*******************
;程序功能:将(r18,r17)中16位二进制数转换成5位BCD码,个十百千万位分别
;存放在r17,r18,r19,r20及r21中。
;程序思想:(r18,r17)减去10000够减X次,则万位为X;差值减去1000够减Y次,则
;千位就是Y;差值减去100够减Z次,则Z就是百位;然后减10,U为十位,最后差为个位。
b16td5: mov r17,zl ;原数据在Z中。
mov r18,zh
ser r21 ;r21先送全1
b16td5_1: inc r21 ;r21增1
subi r17,low(10000) ;(r18,r17)减10000
sbci r18,high(10000)
brcc b16td5_1 ;够减则返回b16td5_1
subi r17,low(-10000) ;不够减+10000,恢复余数
sbci r18,high(-10000)
ser r20 ;r20先送-1
b16td5_2: inc r20 ;r20增1
subi r17,low(1000) ;(r18,r17)减1000
sbci r18,high(1000)
brcc b16td5_2 ;够减则返回b16td5_2
subi r17,low(-1000) ;不够减+1000,恢复余数
sbci r18,high(-1000)
ser r19 ;r19先送-1
b16td5_3: inc r19 ;r19增1
subi r17,low(100) ;(r18,r17)减100
sbci r18,high(100)
brcc b16td5_3 ;够减则返回b16td5_3
subi r17,low(-100) ;不够减+100,恢复余数
sbci r18,high(-100)
ser r18 ;r18先送-1
b16td5_4: inc r18 ;r18增1
subi r17,10 ;(r18,r17)减10
brcc b16td5_4 ;够减则返回b16td5_4
subi r17,-10 ;不够减+10,恢复余数
;***************把转换好的数据放显示存储器****************
mout: mov r0,r17 ;个位
mov r1,r18
mov r2,r19
mov r3,r20
mov r4,r21 ;万位
mov r24,r0
mov r23,r1
mov r22,r2
mov r21,r3
mov r20,r4
ret
;**************************************************************************
;----------r20-r29单元是显示存储区,只要把数据装入这些寄存器,调动态扫描程序就可以显示了。
datin: ldi r20,0 ;1
ldi r21,1 ;2
ldi r22,1 ;3
ldi r23,0 ;4
ldi r24,8 ;5
ldi r25,5 ;6
ldi r26,8 ;7
ldi r27,1 ;8
ret
;################led动态扫描显示子程序,使用前把显示数据装入显示存储器中##########
;可显示的字符包括:0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F、-、_、P、X、
display: ldi r16,0B10000000 ;作共阳的公共脚。
out portd,r16 ;位号,第1位。
mov r16,r20 ;数据1
rcall dxaa ;显示
;----------------------------
ldi r16,0B10010000
out portd,r16 ;位号,第2位。
mov r16,r21 ;数据2
rcall dxaa ;显示
;----------------------------
ldi r16,0B10100000
out portd,r16 ;位号,第3位。
mov r16,r22 ;数据3
rcall dxaa ;显示
;----------------------------
ldi r16,0B10110000
out portd,r16 ;位号,第4位。
mov r16,r23 ;数据4
rcall dxaa ;显示
;----------------------------
ldi r16,0B11000000
out portd,r16 ;位号,第5位。
mov r16,r24 ;数据5
rcall dxaa ;显示
ret
;------取码/延迟/消隐多功能程序---------
dxaa: ldi zh, high(Table_1<<1); 初始化Z指针
ldi zl, low(Table_1<<1)
clc ;清进位标志
add r30,r16 ;r16放的是要显示的数据,处理低字节数据
clr r16 ;r16清0
adc r31,r16 ;处理高字节数据
lpm r16,z ;从程序存储器中装入Z指针(r31:r30)指向的常量
out portc,r16
rcall londel ;长延时
ser r16 ;消隐
out portc,r16
rcall del
ret
;------------------------
Table_1:
.db 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0x40,0x08,0x8C,0xFF
;共阳 0 1 2 3 4 5 6 7 8 9 A b C d E F - _ P X
;***************************************************************************************************
;#################短延迟程序##################
del: ldi r16,0x28 ;使用内部1MHz震荡器
Loop1: dec r16
brne Loop1
nop
ret
;###################钳套的延迟程序################
londel: ldi r17,0x12
Loop2: rcall del
rcall del
dec r17
brne Loop2
ret
;##################end###############
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -