本帖最后由 51黑黑黑 于 2016-3-3 00:51 编辑
(一)STC12C2052 系列单片机简介
STC12C2052 系列单片机是单时钟/机器周期(1T)的兼容8051内核的单片机,是高速/低功耗的新一代8051单片机,全新的流水线/精简指令集结构,其特点是: 1.增强型 1T流水线/ 精简指令集结构 8051 CPU 2.工作电压:2.4V -3.8V / 3.4V - 5.5V 3.工作频率范围:0 - 35MHz,相当于普通8051 的0~420MHz 4.用户应用程序空间512 /1K / 2K / 3K / 4K / 5K 字节 5.片上集成 256字节RAM 6.15 个通用I/O 口,复位后为:准双向口/ 弱上拉 可设置成四种模式:准双向口/弱上拉,推挽/强上拉,仅为输入/高阻,开漏 7.EEPROM 功能 8.共2个16 位定时器/ 计数器 9.PWM(2 路)/PCA(可编程计数器阵列) 10.ADC, 8 路8位精度 11. 通用异步串行口(UART) 12. SPI 同步通信口, 主模式/ 从模式 13.看门狗 14.内部集成 R/C振荡器,精度要求不高时可省外部晶体 15.ISP/IAP 16.工作温度范围: 0 -75℃ / -40 -+85℃ 17.封装: PDIP-20,SOP-20(宽体),TSSOP-20 STC12C2052AD 系列带A/D转换的单片机在P1 口,有8 路8 位高精度的高速A/D 转换器,速度可达100KHz。P1.7 - P1.0 共8 路电压输入型A/D,可做温度检测、电池电压检测、按键扫描、频谱检测等。上电复位后P1 口为弱上拉型I/O 口,用户可以通过软件设置将8 路中的任何一路设置为A/D 转换,不需作为A/D 使用的口可继续作为I/O 口使用。需作为A/D使用的口需先将其设置为高阻输入或开漏模式。在P1M0、P1M1 中对相应的位进行设置。 ADC_START: 模数转换器(ADC)转换启动控制位,设置为“1”时,开始转换 ADC_FLAG: 模数转换器转换结束标志位,当A/D转换完成后,ADC_FLAG =1。 STC12C2052AD 系列单片机内部有256 字节常规的RAM。器件的内部常规数据存储器由3 部分组成: 1.低128字节RAM(00H~7FH),可直接和间接寻址, 用“MOV”和“MOV@Ri” 2.高128字节RAM(80H~FFH),间接寻址,用“MOV@Ri” 3.特殊功能寄存器(80H~FFH),只可直接寻址, 用“MOV” 由于高128字节RAM 和SFR(特殊功能寄存器)占用相同的地址,因此高128 字节RAM 空间必须用间接寻址(MOV @Ri)来区分。特殊功能寄存器(80H ~FFH),只可直接寻址(用“MOV”)来区分。尽管R AM和SFR的地址相同,但它们在物理上是独立的。 (一)STC12C2052 系列单片机应用实例 ;下面是利用STC12C4052AD单片机A/D转换器采集数据,通过串口收到的TPH值决定是几个通道采集数据,"AA"双通道,"CC"三通道,默认一个通道,每采集完128个数据后,通过串口发送到主机,主机收到数据后显示波形,STC12C4052AD单片机比STC12C2052AD单片机FLASH程序存储器大,其它相同。
ORG0000H
AJMP MAIN;转入主程序
ORG 0003H ;外部中断P3.2脚INT0入口地址
RETI
ORG000BH;
RETI
ORG 0013H;
RETI
ORG 0023H
LJMP S
WDT_CONTR EQU0C1H
ADC_CONTR EQU 0C5H ;A/D转换寄存器
ADC_DATA EQU 0C6H ;8位A/D转换结果寄存器
P1M0 DATA 91H
P1M1 DATA 92H
TPHDATA 30H ;根据TPH值决定是几个通道采集数据,"AA"双通道
ADC_Channel_1_Result EQU 33H ;1通道A/D转换结果
ADC_Power_On_Speed_Channel_0 EQU11100000B ;;B7=power,B6B5=speed,B4=flag,B3=start;B2B1B0=ch0-ch7, 000是P1.0作为A/D输入,000是P1.0输入
ADC_Power_On_Speed_Channel_1 EQU 11100001B ;001是P1.1作为A/D输入
ADC_Power_On_Speed_Channel_2 EQU 11100010B ;010是P1.2作为A/D输入
MAIN: MOV ADC_CONTR, #ADC_Power_On_Speed_Channel_0
; SETB IT0 ;设定INT0de触发方式为脉冲负边沿触发
MOV SCon,#50h; 方式1,REN=1.SM0,SM1,SM2,REN,TB8,RB8,TI,RI
MOV TMOD,#21H;波特率发生器T1工作在模式2上
MOV TH1,#0FFH;0E6H;预置初值(按照波特率1200BPS预置初值)24.576=12800
MOV TL1,TH1;预置初值(按照波特率1200BPS预置初值)
MOV PCON,#80H ;SMOD=1倍频
MOV TH0, #10H ;3.6864M最大定时213.3ms,1000h定时200ms
MOV TL0, #00H
SETB TR1;启动定时器T1
; MOV WDT_CONTR ,#25H;;;;;;看门狗设置使能
MOVP1M0,#10000111b ; P1M0=0 P1M1=0双向口 P1M0=1 P1M1=0输入口 P1M0=0 P1M1=1推挽输出20ma
MOV P1M1,#01111000b
MOV A,#0H
MOV R0,#80H
MOV R2,#128
CLEAR: MOV @R0,A
INC R0
INC A
DJNZ R2,CLEAR
CALL YSC
CALL YSC
MOVTPH,#22D ;4个正弦波=11
SETB EA
SETBES
DS18B10: MOV A,TPH
XRLA,#0AAH ;根据TPH值决定是几个通道采集数据,"AA"双通道
JZ DS18B2
MOV A,TPH
XRLA,#0CCH ;根据TPH值决定是几个通道采集数据,"CC"三通道
JZ DS18B3
DS18B20: JBP3.7,DS18B10 ;单通道采集数据
CLR EA
MOV R0,#80h;CLR EA
MOV R2,#128
;ACALLADC_Power_On ;开ADC电源,第一次使用时要打开内部模拟电源
JB P1.7,DS17 ;根据p1.7 选择AD通道
ACALLSet_ADC_Channel_1 ;设置 P1.1 作为A/D转换通道 MOV ADC_CONTR,#ADC_Power_On_Speed_Channel_1
AJMP DS18B
DS17: MOV ADC_CONTR,#ADC_Power_On_Speed_Channel_0
ACALL CH0
DS18B: ACALLGet_AD_Result ;测量电压并且取A/D转换结果
MOV A,ADC_Channel_1_Result ;取 AD 转换结果
MOV @R0,A;
INC R0
; JNB P1.7 ,DS18
ACALL YS
DS18: DJNZ R2,DS18B
CALL FXL1
; MOV ADC_CONTR,#10000000B
CALL YSC
CALL YSC
CALL YSC
CALL YSC
SETB EA
SJMP DS18B20
DS18B2: JBP3.7,$ ;双通道采集数据
CLR EA
MOV R0,#80h;80H--0FFH128个RAM
MOV R2,#128
DS2: MOV A, ADC_CONTR
JB ACC.0, DS1
ACALLSet_ADC_Channel_1 ;设置 P1.1 作为A/D转换通道 MOV ADC_CONTR,#ADC_Power_On_Speed_Channel_1
AJMP DS18B1
DS1: MOV ADC_CONTR,#ADC_Power_On_Speed_Channel_0
ACALL CH0
DS18B1: ACALLGet_AD_Result ;测量电压并且取A/D转换结果
MOV A,ADC_Channel_1_Result ;取 AD 转换结果
MOV @R0,A;
INC R0
; ACALL YS
DJNZ R2,DS2
CALL FXL1
CALL YSC
CALL YSC
CALL YSC
CALL YSC
SETB EA
SJMP DS18B10;DS2
DS18B3: JBP3.7,$ ;三通道采集数据
CLR EA
MOV R0,#80h;CLR EA
MOV R2,#128
MOV ADC_CONTR,#ADC_Power_On_Speed_Channel_2
ACALL CH0
DS18B4: ACALLGet_AD_Result ;测量电压并且取A/D转换结果
MOV A,ADC_Channel_1_Result ;取 AD 转换结果
JZ DS18B5
SUBB A,#64H
DS18B5: ADD A,#32H
MOV @R0,A;
INC R0
ACALLYS ;TPH=CCH
DJNZ R2,DS18B4
CALL FXL1
CALL YSC
CALL YSC
CALL YSC
CALL YSC
SETB EA
LJMP DS18B10;
S: PUSH ACC
PUSHPSW
PUSH04H
PUSHDPH
PUSHDPL
CLR ES
S1: SETB REN
JNBRI,$ ;判断特征字
CLR RI
MOV A,SBUF
MOV TPH,A
POP DPL
POPDPH
POP04H
POPPSW
POPACC
SOVER: SETB ES
RETI
FXL1: MOV R0,#80H
MOV R2,#128D
FXL1B: MOVSBUF,@R0
JNB TI,$
CLR TI
INC R0
JB P3.7,$
DJNZ R2,FXL1B
RET
;--------------------------------------------------------------
ADC_Power_On:
PUSH ACC
ORL ADC_CONTR,#80H ;开A/D转换电源
MOV A, #20H
ACALLDelay8 ;开A/D转换电源后要加延时,1mS以内就足够了
POP ACC
RET
;-------------------------------------------------------------
Set_ADC_Channel_1:
MOV ADC_CONTR,#ADC_Power_On_Speed_Channel_1 ;选择P1.1作为A/D转换通道
CH0: MOV A,#05H ;更换 A/D 转换通道后要适当延时, 使输入电压稳定 ;以后如果不更换 A/D 转换通道的话, 不需要加延时
ACALLDelay8 ;切换 A/D 转换通道,加延时20uS~200uS就可以了,与输入电压源的内阻有关 ;如果输入电压信号源的内阻在10K以下,可不加延时
;ACALL DELAY20US
RET
;----------------------------------------------------------
Get_AD_Result:
PUSH ACC ;入栈保护
MOV ADC_DATA, #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_DATA
MOV ADC_Channel_1_Result,A ;保存 AD 转换结果
POP ACC
RET
;---------------------------------------------------------------
Delay8:
PUSH 02 ;将寄存器组0 的 R2入栈
PUSH 03 ;将寄存器组0 的 R3入栈
PUSH 04 ;将寄存器组0 的 R4入栈
MOV R4, A
Delay_Loop0:
MOV R3,#100;200 ;2 CLOCK ---------------------+
Delay_Loop1: ; |
MOV R2,#249 ;2 CLOCK ------+ |
Delay_Loop: ; | 1002 CLOCK |200406CLOCK
DJNZ R2,Delay_Loop ;4CLOCK | |
DJNZ R3,Delay_Loop1 ;4 CLOCK ------+ |
DJNZ R4,Delay_Loop0 ;4 CLOCK ---------------------+
POP 04
POP 03
POP 02
RET
;----------------------------------------------------------------
YS: MOV 7EH, TPH;#64H
YS1: MOV 7FH, #40D;0FFH
YS2: DJNZ 7FH, YS2
DJNZ 7EH, YS1
RET
YSC: MOV 7EH, #0FFH
YSC1: MOV 7FH, #0FFH
YSC2: DJNZ 7FH, YSC2
DJNZ 7EH, YSC1
RET
end
|