|
发表于 2008-6-13 10:13:42
|
显示全部楼层
[转帖]定时ADC编程举例
该例程主要说明如何利用ADC的单次转换功能实现定时采样的目的。定时器T0用于1.25ms定时,8个通道完成一次数据采集需要10ms。为增加抗干扰的能力,软件中还加入了数字滤波功能。每个通道连续采样16次后再进行平均处理,然后将高8位结果送出,其汇编语言源程序清单如下:
$NOMOD51
$INCLUDE() ;使用ADμC812(http://www.dzsc.com.cn/stock5/C812.html)预定义符
Timer_ms_const equ(65536-9216/8);当晶振频率为11.0592MHZ时,10ms对应9216个周期
ADC_tlag equ 20H.0;AD转换标志,=1时表示采样的8路AD值有效
ADC_coun equ 30H;用于指示当前正在处理的ADC通道
ADC_result equ 38H;38H~3FH存入0~7通道的ADC结果
ADC_acc equ 40H;40~4FH存入0~7通道的累加值
ORG 0000H
start:
jmp Begin
ORG start+0BH
Jmp Timer0_interrupt
ORG start+100h
Begin;
mov SP,#60H
mov R0,#20H;清工作单元
mov R7,#40H
clr A
iRAM_init;
mov @R0,A
inc R0
djnz R7,iRAM_init
call Timer0_init;初始化T0为1.25ms中断一次
call ADC_init;初始化ADC为单次转换
SETB EA
Controlloop:
Jnb ADC_flag,Controlloop
…… ;将AD转换的结果取走
clr ADC_flag;允许开始下一次转换
jmp Controlloop
ADC_init:
mov ADCCON1,#01101100B;上电ADC
mov ADCCON2,ADC_count;选择转换通道
ret
Timer0_interrupt:
SETB SCONV;开始单次ADC转换
mov TL0,#LOW(Timer_ms_const);装入定时常数
mov TH0,#HIGH(Timer_ms_const)
PUSH PSW
mov PSW,#00001000B;使用page1
mov R2,A;暂存A累
Timer0_int_ADC:
jb ADC_flag,Timer0_int_ADC_end;数据(http://www.weeqoo.com/bbs/list-11-0.html)未取走则退出
Mov A,ADCCON3;读ADC状态
jb ACC.7,Timer0_int_ADC
mov A,ADC_count
anl A,#07H
rl A
add A,#ADC_acc
mov R0,A
mov A,ADCDATAL;将ADC转换结果加入累加单元
add A,@R0
mov @R0,A
inc R0
mov A,ADCDATAH
anl A,#0FH
addc A,@R0
mov #R0,A
inc ADC_count
mov A,ADC_count
anl A,#07H
mov ADCCON2,A;选择下一通道
mov A,ADC_count
cjne A,#80H,Timer0_int_ADC_end
mov ADC_count,#0
mov R0,#ADC_acc;数字滤波后存入ADC结果
mov R1,#ADC_result
mov R7,#08
Timer0_int_save_ADC:
clr A
mov #R0,A
inc R0
xch A,#R0
mov @R1,A
inc R0
inc R1
djnz,R7,Timer0_int_save_ADC
SETB ADC_flag
Timer0_int_ADC_end:
Mov A,R2
Pop PSW
Reti
Timer0_init;
mov TH0,#HIGH(Timer_ms_const);装入定时常数
mov TL0,#LOW(Timer_ms_const)
anl TMOD,#11110000B
orl TMDD,#00000001B
SETB ET0;允许T0中断
SETB TR0;T0开始运行
Ret
END
[本贴已被 作者 于 2008年06月13日 10时16分35秒 编辑过][/COLOR][/ALIGN] |
|