能给个STC单片机内部ad转换的程序吗?万谢。。
发布网友
发布时间:2023-06-21 14:13
我来回答
共3个回答
热心网友
时间:2023-12-18 00:20
ORG 0000H
AJMP START1
ORG 0040H
START1:
MOV SP,#80H
MOV 0E1H,#00110100B ;启动看门狗
ACALL ADC_Power_On ;开ADC电源, 第一次使用时要打开内部模拟电源
;开ADC电源, 可适当加延时,1mS以内就足够了
ACALL Set_P17_ASF ;设置 P1.7 为模拟功能口
ACALL Set_ADC_Channel_7 ;设置 P1.7 作为A/D转换通道
MOV TL0,#0B0H
MOV TH0,#3CH
MOV TMOD,#21H ;置计数器模式
MOV IE,#8AH ;;EA,ET0,ET1
SETB TR0 ;启动定时器
START2:
NOP
NOP
ACALL Get_AD_Result
MOV 30H, ADC_Channel_7_Result
ACALL DISP ;调入其他程序,或AD取值在中断中
;------------------------------
ADC_CONTR EQU 0BCH ;A/D转换寄存器
ADC_RES EQU 0BDH ;8位A/D转换结果寄存器
P1ASF EQU 9DH ;P1口中的相应位作为模拟功能使用时的控制寄存器,如做A/D用,相应位要置1
ADC_Power_On_Speed_Channel_7 EQU 10100111 ;P1.7作为A/D输入
ADC_Channel_7_Result EQU 32H ;7通道A/D转换结果(32H,31H)
;数据在A中,地址按8951芯片 10H
BYTE_ADDR_HIGH EQU 00H ;字节地址高位
BYTE_ADDR_LOW EQU 00H
SECTOR_ADDR_HIGH EQU 00H ;扇区地址高位
SECTOR_ADDR_LOW EQU 00H
IAP_DATA EQU 0C2H
IAP_ADDRH EQU 0C3H
IAP_ADDRL EQU 0C4H
IAP_CMD EQU 0C5H
IAP_TRIG EQU 0C6H
IAP_CONTR EQU 0C7H
;定义ISP/IAP命令及等待时间
ISP_IAP_BYTE_READ EQU 1 ;字节读
ISP_IAP_BYTE_PROGRAM EQU 2 ;字节写
ISP_IAP_SECTOR_ERASE EQU 3 ;扇区擦除
WAIT_TIME EQU 3 ;等待时间
;--------------------------------------------------------------
ADC_Power_On:
PUSH ACC
ORL ADC_CONTR, #80H ;开A/D转换电源
;MOV A, #20H
ACALL Delay ;开A/D转换电源后要加延时,1mS以内就足够了
POP ACC
RET
;-------------------------------------------------------------
;设置P1.7为模拟功能
Set_P17_ASF:
PUSH ACC
MOV A, #10000000B
ORL P1ASF, A
POP ACC
RET
;-------------------------------------------------------------
;设置 P1.7 为普通IO
Set_P17_Normal_IO:
PUSH ACC
MOV A, #01111111B
ANL P1ASF, A
POP ACC
RET
;-------------------------------------------------------------
Set_ADC_Channel_7:
MOV ADC_CONTR, #ADC_Power_On_Speed_Channel_7
;选择P1.7作为A/D转换通道
;MOV A, #05H ;更换 A/D 转换通道后要适当延时, 使输入电压稳定
;以后如果不更换 A/D 转换通道的话, 不需要加延时
ACALL Delay ;切换 A/D 转换通道,加延时20uS~200uS就可以了,与输入电压源的内阻有关
;如果输入电压信号源的内阻在10K以下,可不加延时
RET
;-------------------------------------------------------------
Get_AD_Result:
PUSH ACC ;入栈保护
MOV ADC_RES, #0
ORL ADC_CONTR, #00001000B ;启动 AD 转换
NOP ;在对ADC_CONTR寄存器进行写操作后,要加4个空操作延时,才能够正确读到ADC_CONTR的值
NOP
NOP
NOP
Wait_AD_Finishe:
MOV A, #00010000B ;判断 AD 转换是否完成
ANL A, ADC_CONTR
JZ Wait_AD_Finishe ;AD 转换尚未完成, 继续等待
ANL ADC_CONTR, #11100111B ;清0 ADC_FLAG, ADC_START 位, 停止A/D转换
MOV A, ADC_RES
MOV ADC_Channel_7_Result, A ;保存 AD 转换结果
POP ACC
RET
;---------------------------------------------------------------
Delay:
PUSH 02 ;将寄存器组0 的 R2 入栈
PUSH 03 ;将寄存器组0 的 R3 入栈
MOV R3, #02 ;2 CLOCK ---------------------+
Delay_Loop1: ;
MOV R2, #249 ;2 CLOCK ------+
Delay_Loop: ; | 1002 CLOCK
DJNZ R2, Delay_Loop ;4 CLOCK |
DJNZ R3, Delay_Loop1 ;4 CLOCK ------+
POP 03
POP 02
RET
;-------------------------------------------------------
END
热心网友
时间:2023-12-18 00:20
#include <intrins.h>
sfr ADC_CONTR= 0XBC;
sfr P1ASF= 0X9D;
sfr ADC_RES= 0XBD;
sfr ADC_RESL= 0XBE;
#define AD_SPEED 0x60
void init_adc()
{
ADC_CONTR = ADC_CONTR|0x80; //打开adc电源
P1ASF = 0X01; //设置P1.7为模拟功能
}
void adc_delay(unsigned char delay_time) // 延时函数
{
unsigned int n;
while(delay_time--)
{
n = 6000;
while(--n);
}
}
unsigned int get_AD_result(unsigned char channel)
{
unsigned char AD_finished=0;
unsigned int h_val;
unsigned int l_val;
ADC_RES = 0;
ADC_RESL = 0;
channel &= 0x07;
ADC_CONTR = AD_SPEED;
_nop_();
ADC_CONTR |= channel;
_nop_();
ADC_CONTR |= 0x80;
adc_delay(1);
ADC_CONTR |= 0x08;
AD_finished = 0;
while ( AD_finished ==0 )
{
AD_finished = (ADC_CONTR & 0x10);
}
ADC_CONTR &= 0xE7;
h_val = ADC_RES;
h_val = h_val<<2;
l_val = ADC_RESL & 0X03;
h_val = h_val | l_val;
return (h_val);
}
热心网友
时间:2023-12-18 00:20
单片机型号呢