📄 armok0137229.txt
字号:
;******************** 多功能测量计 FOR ATmega8 *****************************************
;*
;* File : 多功能测量计.asm
;* Version : 1.0
;* Compiler : AVR Studio
;* Target : ATmega8
;* Output size : 207 words (414 bytes)
;* Author : 陈海强 ;Email-to: haikang@21cn.com
;* website:
;***************************************************************************************
;***************************************************************************************
;*说明:
;* 1、频率计(T0计数,T1作1S定时器,PWM输出(OC1A)作时间闸,
; PC5为外部计数器(74HC393)清零CLEAR。
; 外部计数器bit0-PD2,bit1-PD3,bit2-PD5,bit3-PD4(T0)。)
; 1)0~60MHz直接输入,VHF_CY(PD7)为1。
; 2)60MHz~1.2GHz经MB501 64分频输入,UHF_LC(PD6)为1。
;
; 2、LC与晶振测试输入,CY&LC(PB0)为1。电容单位为pF,电感单位为nH
; 1)LC测试,UHF_LC(PD6)为1;内部电容CAP校正,CAP(PB2)为1;
; 电容测试,CX(PB5)为1;电感测试,LX(PB4)为1。
; 2)晶振测试,VHF_CY(PD7)为1。
;
; 3、电压输入(与频率共用输入端),AD0。
; 4、LCD输出,PC3--LCD_LED_RED,PC2--LCD_DATA,PC1--LCD_CLK。
; 5、编程允许脚,PC4接地(跳线块接通)。使用AVRprog编程。
;***************************************************************************************
;**************************** 子程序列表 *********************
;1、delay(temp0)时子程序(t=(8+temp0*2)*单系统时间)。使用变量temp0无保护
;2、LCD_BYTESoutput(SRAM(LCDBufferBegin))
; 显示SRAM缓冲区LCDBufferBegin 10字节的内容.使用变量temp0,temp1,X有保护
;
;3、LCD_BIToutput(temp0) 将temp0 低4Bit内容串行输出到LCD 显示.使用变量temp0,temp1有保护
;
;4、HEXtoDEC(R(hData0,hData1,hData2,hData3),R(dData0,dData1,dData2,dData3,dData4))
; 4Bytes(32Bit)十六进制转成5Bytes(40Bit)十进制子程序将cntxh转成cntxd. 使用变量temp0,temp1,temp2有保护
;
;5、SendDECtoLCDBuffer(R(dData0,dData1,dData2,dData3,dData4),SRAM(LCDBufferBegin))
; 将5Bytes(40Bit)十进制cntxd送到LCD缓冲区LCDBufferBegin. 使用变量temp0,temp1,X有保护
;
;6、LCDTest LCD测试.
;
;7、InitSRAM 初始化 清空SRAM. 使用变量temp0,temp1,temp2,X有保护
;
;8、InitIOPort 初识化I/O口
;
;9、InitTime 初识化设定T/C0、T/C1、T/C2的工作方式。T0作计数器,
; T1作PWM定时器(1S宽度正脉冲OC1A输出),T2作CLKio/2频率OC2输出
;
;
;
;
;****************************************************************************
;****************************************************
; AVRProg编程定义Mega8识别代码、电子标签字节和其它
;****************************************************
.equ DT = 0x77 ; Mega8识别代码(Mega8 bootloader)
.equ SB1 = 0x07 ; 电子标签字节 1
.equ SB2 = 0x93 ; 电子标签字节 2
.equ SB3 = 0x1e ; 电子标签字节 3
.equ E2END = $1FF ; EEEPROM尾
.equ CLKio = 12000000 ; 晶振 = 12 MHz。
.equ UBR = 38 ; 波特率 = 19.200 bps ,晶振 = 12 MHz。
; AVRProg 能接受的波特率是 19200 和 115200
;***************************************************END
.include "m8def.inc" ; 包含 mega8 器件配置文件
.equ SRAMSTART =96 ;SRAM头
.equ RAMEND128 =96+127
.equ Tpwm =1 ;T1 PWM正脉冲宽度1S。
;**** I/O初始化定义
.equ InitDDRB =0b00001010 ;PB1(OC1A)、PB3(OC2)输出
.equ InitPORTB =0b00110100 ;
.equ InitDDRC =0b00101110 ;PC5--CLEAR,PC3、2、1--LCD输出
.equ InitPORTC =0b00001110 ;PC3=1,点亮LCD_LED_RED,PC1--LCD_CLK=1
.equ InitDDRD =0b00000010 ;TXD输出
.equ InitPORTD =0b00000000
;**** 定时器初始化定义
.equ InitTIMSK =0b00000101 ;定时器中断允许(T/C0溢出中断T允许TOIE0=1,
;T/C1溢出中断允许TOIE1=1)
.equ InitTCCR0 =0b00000110 ;T/C0控制(外部时钟T0脚,下降沿驱动)
;.equ InitTCCR0 =0b00000001 ;T/C0控制(内部时钟CLKio)
;.equ InitTCCR0 =0b00000000 ;T/C0控制(无时钟)
.equ InitTCCR1A =0b11000010 ;T/C1控制A(快速PWM模式14,匹配置位、TOP时清零,TOP=ICR1)
.equ InitTCCR1B =0b00011100 ;T/C1控制B(内部时钟(CLKio÷256))
.equ InitOCR1A =1 ;T1 PWM正脉冲宽度1S。
.equ InitICR1 =CLKio/256*Tpwm+1 ;TOP=ICR1=OCR1A+宽度1S正脉冲
.equ InitTCCR2 =0b00011000 ;T/C2控制(无时钟)
;.equ InitTCCR2 =0b00011001 ;T/C2控制(CTC模式,匹配触发OC2,内部时钟(CLKio)
;.equ InitOCR2 =0 ;OC2输出频率=Fclkio/2。
;.equ InitTCCR2 =0b00011110 ;T/C2控制(CTC模式,匹配触发OC2,内部时钟(CLKio)
.equ InitOCR2 =233 ;OC2输出频率=Fclkio/(2*256*(233+1))=100.16Hz。
.equ LCMeter =PINB ;LC与晶振测试
.equ Cx =5 ;
.equ Lx =4 ;
.equ CAP =2 ;
.equ CY_LC =0 ;
.equ LCMeterMask =0b00110101
.equ FMeter =PIND ;频率计
.equ VHF_CY =7 ;
.equ UHF_LC =6 ;
.equ FMeterMask =0b11000000
.equ LCDoutputport =PORTC ;10位LCD 显示输出定义
.equ LCDinputport =PINC
.equ LCD_LED_RED =3 ;
.equ LCD_DATA =2 ;
.equ LCD_CLOCK =1 ;
.equ LCDpinMask =0b00001110 ;LCD掩模
.equ EXTCountControl =PORTC ;外部计数器控制定义
.equ CLEAR =5 ;
.equ EXTCountData =PIND ;外部计数器数据定义
.equ EXTCountDataBit0 =2 ;
.equ EXTCountDataBit1 =3 ;
.equ EXTCountDataBit2 =5 ;
.equ EXTCountDataBit3 =4 ;
.equ EXTCountDataMask =0b00111100 ;外部计数器数据掩模
;************************* 常量 定义 *********************************
.equ MAXLCDBYTES =10 ;LCD 显示长度10位
.equ CAPData =1000 ;CAP=1000pF
.equ pi =3.141592654
;**** ActionFlag 值
.equ CountDataReady =1
;**** ProgramSelect 值
.equ SelectVHF =0b10110100
.equ SelectUHF =0b01110100
.equ SelectCY =0b10110101
.equ SelectLC =0b01110101
.equ SelectCAP =0b01110001
.equ SelectCx =0b01010101
.equ SelectLx =0b01100101
;************************* 常量 定义 ******************************END
;************************* SRAM 定义 *********************************
;**** LCD数据区
.equ LCDBufferBegin =SRAMSTART ;LCD 缓冲区开始位置
.equ LCDShiftBufferBegin =LCDBufferBegin+MAXLCDBYTES ;LCD 显示转换前缓冲区
.equ LCDtestCount =LCDShiftBufferBegin+MAXLCDBYTES
;**** 计数运算数据区
.equ FloatCrefData =LCDtestCount+1 ;内部电容Cref计算浮点值(pF)
.equ FloatCrefDataByte0 =FloatCrefData
.equ FloatCrefDataByte1 =FloatCrefData+1
.equ FloatCrefDataByte2 =FloatCrefData+2
.equ FloatCrefDataByte3 =FloatCrefData+3
.equ FloatLrefData =FloatCrefDataByte3+1 ;内部电感Lref计算浮点值(nH)
.equ FloatLrefDataByte0 =FloatLrefData
.equ FloatLrefDataByte1 =FloatLrefData+1
.equ FloatLrefDataByte2 =FloatLrefData+2
.equ FloatLrefDataByte3 =FloatLrefData+3
.equ LxData =FloatLrefDataByte3+1 ;外部电感Lx计算值(nH)
.equ LxDataByte0 =LxData
.equ LxDataByte1 =LxData+1
.equ LxDataByte2 =LxData+2
.equ LxDataByte3 =LxData+3
.equ CxData =LxDataByte3+1 ;外部电容Cx计算值(pF)
.equ CxDataByte0 =CxData
.equ CxDataByte1 =CxData+1
.equ CxDataByte2 =CxData+2
.equ CxDataByte3 =CxData+3
.equ FloatFLCData =CxDataByte3+1 ;内部LC频率浮点值(Hz)
.equ FloatFLCDataByte0 =FloatFLCData
.equ FloatFLCDataByte1 =FloatFLCData+1
.equ FloatFLCDataByte2 =FloatFLCData+2
.equ FloatFLCDataByte3 =FloatFLCData+3
.equ FloatFCAPData =FloatFLCDataByte3+1 ;内部校正电容CAP频率浮点值(Hz)
.equ FloatFCAPDataByte0 =FloatFCAPData
.equ FloatFCAPDataByte1 =FloatFCAPData+1
.equ FloatFCAPDataByte2 =FloatFCAPData+2
.equ FloatFCAPDataByte3 =FloatFCAPData+3
.equ FloatFCxData =FloatFCAPDataByte3+1 ;外部电容Cx频率浮点值(Hz)
.equ FloatFCxDataByte0 =FloatFCxData
.equ FloatFCxDataByte1 =FloatFCxData+1
.equ FloatFCxDataByte2 =FloatFCxData+2
.equ FloatFCxDataByte3 =FloatFCxData+3
.equ FloatFLxData =FloatFCxDataByte3+1 ;外部电感Lx频率浮点值(Hz)
.equ FloatFLxDataByte0 =FloatFLxData
.equ FloatFLxDataByte1 =FloatFLxData+1
.equ FloatFLxDataByte2 =FloatFLxData+2
.equ FloatFLxDataByte3 =FloatFLxData+3
.equ Floatpi =FloatFLxDataByte3+1 ;pi的浮点值
.equ FloatpiByte0 =Floatpi
.equ FloatpiByte1 =Floatpi+1
.equ FloatpiByte2 =Floatpi+2
.equ FloatpiByte3 =Floatpi+3
.equ Float4Byte0 =FloatpiByte3+1 ;4的浮点值
.equ Float4Byte1 =Float4Byte0+1
.equ Float4Byte2 =Float4Byte0+2
.equ Float4Byte3 =Float4Byte0+3
.equ Float10E0Byte0 =Float4Byte3+1 ;1的浮点值
.equ Float10E0Byte1 =Float10E0Byte0+1
.equ Float10E0Byte2 =Float10E0Byte0+2
.equ Float10E0Byte3 =Float10E0Byte0+3
.equ Float10E3Byte0 =Float10E0Byte3+1 ;1000的浮点值
.equ Float10E3Byte1 =Float10E3Byte0+1
.equ Float10E3Byte2 =Float10E3Byte0+2
.equ Float10E3Byte3 =Float10E3Byte0+3
.equ Float10E8Byte0 =Float10E3Byte3+1 ;10的9次方浮点值
.equ Float10E8Byte1 =Float10E8Byte0+1
.equ Float10E8Byte2 =Float10E8Byte0+2
.equ Float10E8Byte3 =Float10E8Byte0+3
.equ Float10E21Byte0 =Float10E8Byte3+1 ;10的21次方浮点值
.equ Float10E21Byte1 =Float10E21Byte0+1
.equ Float10E21Byte2 =Float10E21Byte0+2
.equ Float10E21Byte3 =Float10E21Byte0+3
.equ DataBuffer =Float10E21Byte3+1 ;
.equ DataBuffer10 =DataBuffer ;计数结果的十六进制
.equ DataBuffer11 =DataBuffer+1
.equ DataBuffer12 =DataBuffer+2
.equ DataBuffer13 =DataBuffer+3
.equ DataBuffer20 =DataBuffer+4
.equ DataBuffer21 =DataBuffer+5
.equ DataBuffer22 =DataBuffer+6
.equ DataBuffer23 =DataBuffer+7
.equ DataBuffer30 =DataBuffer+8
.equ DataBuffer31 =DataBuffer+9
.equ DataBuffer32 =DataBuffer+10
.equ DataBuffer33 =DataBuffer+11
.equ DataBuffer40 =DataBuffer+12
.equ DataBuffer41 =DataBuffer+13
.equ DataBuffer42 =DataBuffer+14
.equ DataBuffer43 =DataBuffer+15
.equ DataStack =DataBuffer43+32
.equ StackBegin =RAMEND ;栈缓冲区
;************************* SRAM 定义 ******************************END
;************************* Rn 定义 *********************************
.def backupSREGTimer0 =R2 ;产生T/C0溢出中断时保存状态寄存器(SREG)
.def backupSREGTimer1 =R3 ;产生T/C1溢出中断时保存状态寄存器(SREG)
.def Time0OVFCount =R4 ;定时器0 溢出计数
.def Time0OVFCountH =R5 ;
.def CountDataBuffer0 =R6 ;内外计数值
.def CountDataBuffer1 =R7 ;
.def CountDataBuffer2 =R8 ;
.def CountDataBuffer3 =R9 ;
.def ExtCountCap =R10 ;外部计数器(74HC393)值捕捉
.def dData0 =R10 ;存放当前计数结果的十进制
.def dData1 =R11
.def dData2 =R12
.def dData3 =R13
.def dData4 =R14
.def hData0 =R15 ;存放当前计数结果的十六进制
.def hData1 =R24
.def hData2 =R25
.def hData3 =R1
;****
.def temp0 =R16 ;暂存器
.def temp1 =R17 ;暂存器
.def temp2 =R18 ;暂存器
.def temp3 =R19 ;暂存器
.def temp4 =R20 ;暂存器
.def ProgramSelect =R22 ;功能选择
.def ActionFlag =R23 ;
;******************* Rn定义 ***************************************** end *****
.CSEG
;********************************************************************
;* 中断表
;********************************************************************
.org 0x000 ;
rjmp reset
.org INT0addr ;
; rjmp INT0Handler
reti
.org INT1addr ;
reti
.org OC2addr ;Time2比较中断
reti
.org OVF2addr ;Time2溢出中断。
reti
.org ICP1addr ;
reti
.org OC1Aaddr ;
reti
.org OC1Baddr
reti
.org OVF1addr ;Time1 溢出中断向量。1S宽度正脉冲PWM
rjmp OVF1Handler
.org OVF0addr ;Time0 溢出中断。计数器
rjmp OVF0Handler
;.org SPIaddr
; reti
;.org URXCaddr
; reti
;.org UDREaddr
; reti
;.org UTXCaddr
; reti
;.org ADCCaddr
; reti
;.org ERDYaddr
; reti
;.org ACIaddr
; reti
;.org TWIaddr
; reti
;.org SPMaddr
; reti
;******************* 中断表 ****************************************** end ****
.org 0x013
;**** Time0 溢出中断。计数器
OVF0Handler:
in backupSREGTimer0,SREG
push temp0
ldi temp0,1
add Time0OVFCount,temp0
clr temp0
adc Time0OVFCountH,temp0
pop temp0
out SREG,backupSREGTimer0
reti
;**** Time1 溢出中断。1秒定时器
OVF1Handler:
in backupSREGTimer1,SREG
push temp0
sei
in ExtCountCap,EXTCountData
in CountDataBuffer0,TCNT0
mov CountDataBuffer1,Time0OVFCount
mov CountDataBuffer2,Time0OVFCountH
clr CountDataBuffer3
sbi ExtCountControl,CLEAR ;外部计数器清零
cbi ExtCountControl,CLEAR
clr temp0
out TCNT0,temp0 ;T0计数器清零
clr Time0OVFCount ;T0计数器溢出计数清零
clr Time0OVFCountH
;**** CountBuffer 乘16 移位4次***********
ldi temp0,4
CountDataBufferLoop:
lsl CountDataBuffer0
rol CountDataBuffer1
rol CountDataBuffer2
rol CountDataBuffer3
dec temp0
brne CountDataBufferLoop
;**** CountBuffer 乘16 移位4次********END
;**** 取出外部计数器的值 作为CountBuffer0低四位值
bst ExtCountCap,ExtCountDataBit0
bld CountDataBuffer0,0
bst ExtCountCap,ExtCountDataBit1
bld CountDataBuffer0,1
bst ExtCountCap,ExtCountDataBit2
bld CountDataBuffer0,2
bst ExtCountCap,ExtCountDataBit3
bld CountDataBuffer0,3
;**** 取出外部计数器的值*****************END
;***** LCD_LED_RED闪动 ***********
sbis LCDinputport,LCD_LED_RED
rjmp LCD_LED_REDSet1
cbi LCDoutputport,LCD_LED_RED
rjmp LCD_LED_REDSetEnd
LCD_LED_REDSet1:
sbi LCDoutputport,LCD_LED_RED
LCD_LED_REDSetEnd:
;***** LCD_LED_RED闪动 ********END
ldi ActionFlag,CountDataReady
; rcall LCDtest
OVF1HandlerEnd:
pop temp0
out SREG,backupSREGTimer1
reti
;*************************************************************************
; 子函数
;*************************************************************************
;1、**** 延时子程序(t=(8+temp0*2)*单系统时间)。temp0=0,循环256次*******
delay:
dec temp0 ;复位后temp0=0X00
brne delay ;temp0不为0转,为0按顺序执行
ret ;子程序返回
;2、**** 显示SRAM缓冲区LCDBufferBegin 10字节的内容子程序
LCD_BYTESoutput:
push temp0
push temp1
ldi XL,low(LCDBufferBegin) ;X=显示缓冲区(10字节)
ldi XH,high(LCDBufferBegin)
ldi temp1,10 ;循环显示10位缓冲区的内容
LCD_BYTESoutputloop:
ld temp0,X+
;****显示转换
;temp :A 1 2 3 4 5 6 7 8 9 B C D E F 0
;转换前LCD显示:0 1 2 3 4 5 6 7 8 9 F ┘└ P ─ 空格
;转换后LCD显示:空格 1 2 3 4 5 6 7 8 9 F ┘└ P ─ 0
;***************令temp:0,a交换
cpi temp0,0 ;temp =0时,令temp =0x0a;temp ≠ 0时,跳到N2
brne LCD_BYTESoutput1 ;
ldi temp0,0x0a ;
rjmp LCD_BYTESoutput2
LCD_BYTESoutput1:
cpi temp0,0x0a ;temp =0x0a时,令temp =0x00;temp ≠ 0x0a时,跳到N3
brne LCD_BYTESoutput2 ;
ldi temp0,0x00 ;
LCD_BYTESoutput2:
rcall LCD_BIToutput
dec temp1
brne LCD_BYTESoutputloop ;temp1不等于0,则跳到LCD_BYTESoutputloop
pop temp1
pop temp0
ret
;2、**** 显示SRAM缓冲区LCDBufferBegin 10字节的内容子程序********END
;3、***** 将temp0 内容串行输出到LCD 显示(LCD_CLOCK,LCD_DATA)******
LCD_BIToutput: ;LCD 显示输出(PC5-LCD CLK,PC4-LCD DATA)
push temp0
push temp1
andi temp0,0x0f ;取低4位
ldi temp1,4 ;循环在PC4口串行输出4位LCD DATA
LCD_BIToutputloop:
sbrc temp0,3 ;temp0(3位) =0时,PC+1
rjmp LCD_DATAout1
LCD_DATAout0:
cbi LCDoutputport,LCD_DATA ;temp0(3位) =0时,LCD_DATA=0
rjmp LCD_BIToutputloop1
LCD_DATAout1:
sbi LCDoutputport,LCD_DATA ;temp0(3位) =1时,LCD_DATA=1
LCD_BIToutputloop1:
cbi LCDoutputport,LCD_CLOCK ;输出LCD_CLOCK "L"
push temp0
ldi temp0,0xff ;输出一定的脉宽(38个系统时间)
rcall delay
pop temp0
sbi LCDoutputport,LCD_CLOCK ;输出LCD_CLOCK "H"
push temp0
ldi temp0,0xff ;输出一定的脉宽(38个系统时间)
rcall delay
pop temp0
rol temp0 ;temp0左循环
dec temp1
brne LCD_BIToutputloop ;temp1 ≠ 0时,跳到LCD_BIToutputloop
cbi LCDoutputport,LCD_DATA ;LCD_DATA=0
pop temp1
pop temp0
ret
;3、***** 将temp0 内容串行输出到LCD 显示(LCD_CLOCK,LCD_DATA)*****END
;4、**** 4Bytes(32Bit)十六进制转成5Bytes(40Bit)十进制子程序****************
HEXtoDEC:
push temp0
push temp1
push temp2
clr temp0
clr dData0
clr dData1
clr dData2
clr dData3
clr dData4
ldi temp1,32
clc
HEXtoDECloop:
rol hData0
rol hData1
rol hData2
rol hData3
rol dData0
rol dData1
rol dData2
rol dData3
rol dData4
dec temp1
breq HEXtoDECend
rcall HEXtoDECadjn
rjmp HEXtoDECloop
HEXtoDECend:
pop temp2
pop temp1
pop temp0
ret
;****
HEXtoDECadjn:
mov temp0,dData0
rcall HEXtoDECadjd1
mov dData0,temp0
mov temp0,dData1
rcall HEXtoDECadjd1
mov dData1,temp0
mov temp0,dData2
rcall HEXtoDECadjd1
mov dData2,temp0
mov temp0,dData3
rcall HEXtoDECadjd1
mov dData3,temp0
mov temp0,dData4
rcall HEXtoDECadjd1
mov dData4,temp0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -