程序分主程序和PCA定時器。寫入器件(STC8G1K08A):按啟動開關(P3.3),PCA運行正常有輸出,而主程序有時有輸出,有時沒有輸出。且沒有輸出時,按啟動開關(P3.3)不起作用也不能關閉PCA。經判斷程序在(32位除16位 即程序:第2步算:雙字節無符號除法)處于死循環!但關閉PCA定時器,主程序輸出又正常,程序仿真也正常!這是為什么?用T0,T1 定時器也是這情況!
未開啟看門狗
程序用匯編寫的- ;器件STC8G1K08A
- ORG 0000H
- LJMP MAIN1
- ORG 003BH ;PCA中斷
- LJMP PCAISR
- ORG 0100H
- //************************IO口*************************
- P5 EQU 0C8H
- P5M1 EQU 0C9H
- P5M0 EQU 0CAH
- P3M1 EQU 0B1H
- P3M0 EQU 0B2H
- //************************ADC*************************
- AUXR EQU 8EH ;輔助寄存器
- ADC_CONTR EQU 0BCH ;ADC控制寄存器
- ADC_RES EQU 0BDH ;ADC高2位結果
- ADC_RESL EQU 0BEH ;ADC低8位結果
- ADCCFG EQU 0DEH //ADC 配置寄存器
- P_SW2 DATA 0BAH
- ADCTIM XDATA 0FEA8H //ADC速度控制器
- //************************PCA*************************
- CCON DATA 0D8H //PCA控制寄存器
- CF BIT CCON.7 //PCA控制寄存器B7位, 計數器溢出中斷標志
- CR BIT CCON.6 //PCA控制寄存器B6位. 計數器啟動控制位
- CCF2 BIT CCON.2 //PCA控制寄存器B2位, 模塊2中斷標志,需軟件清零
- CCF1 BIT CCON.1 //PCA控制寄存器B1位, 模塊1中斷標志,需軟件清零
- CCF0 BIT CCON.0 //PCA控制寄存器B0位, 模塊0中斷標志,需軟件清零
- CMOD DATA 0D9H //PCA模式寄存器, 空閑時是否繼續計數及時鐘設定
- CL DATA 0E9H //PCA計數器低字節
- CH DATA 0F9H //PCA計數器高字節
- CCAPM0 DATA 0DAH //PCA模塊0模式控制寄存器
- CCAP0L DATA 0EAH //PCA模塊0低字節
- CCAP0H DATA 0FAH //PCA模塊0高字節
- PCA_PWM0 DATA 0F2H //PCA0的PWM模式寄存器
- CCAPM1 DATA 0DBH //PCA模塊1模式控制寄存器
- CCAP1L DATA 0EBH //PCA模塊1低字節
- CCAP1H DATA 0FBH //PCA模塊1高字節
- PCA_PWM1 DATA 0F3H //PCA1的PWM模式寄存器
- CCAPM2 DATA 0DCH //PCA模塊2模式控制寄存器
- CCAP2L DATA 0ECH //PCA模塊2低字節
- CCAP2H DATA 0FCH //PCA模塊2高字節
- PCA_PWM2 DATA 0F4H //PCA2的PWM模式寄存器
- T50HZ EQU 0029H //此調頻率 0030H為10K
- //************************常用*************************
- E_DATAS_L EQU 34H ;有效定時器值L
- E_DATAS_H EQU 35H ;有效定時器值H
- E_DUTY_L EQU 37H //有效占空L
- E_DUTY_H EQU 38H //有效占空H
- I_DUTY_L EQU 39H //無效占空L
- I_DUTY_H EQU 3AH //無效占空H
- I_DATAS_L EQU 3DH ;無效定時器值L
- I_DATAS_H EQU 3EH ;無效定時器值H
- BUTTON EQU 3FH ;ADC按鈕控制
- IPH EQU 0B7H //高中斷優先級控制寄存器
- MAIN1: MOV SP, #5FH //設置堆棧指針為5FH
- SETB EA //開中斷
- MOV IP,#080H //PCA中斷最高級,T1中斷最低級
- MOV IPH,#080H //PCA中斷最高級,T1中斷最低級
- MOV P3M1,#00000100B
- MOV P3M0,#00000000B
- MOV P5M1,#00100000B
- MOV P5M0,#00000000B
- SETB P5.4
- CLR P3.0
- CLR P3.1
- MOV CCON ,#00H //PCA配置
- MOV CMOD ,#00H //PCA配置
- ANL AUXR,#0BFH ;定時器1時鐘12T模式
- ANL TMOD,#0FH ;設置定時器模式
- ORL TMOD,#10H ;設置定時器模式
- CALL GET_ADC //初始化,開ADC電源,
- ;.....................................................準備
- JSM06: SETB P5.4
- CLR TR1
- CLR CR
- CLR P3.0
- CLR P3.1
- CALL DELAY100MS
- JB P3.3,JSM06
- ;...................................................主程序
- JSM01: JNB P3.3,JSM01 ;防止開關抖動
- CALL DELAY100MS ;防止開關抖動
- JNB P3.3,JSM01
- LCALL PCA_ON //開PCA定時器
- CALL AUT_DUTY //占空計算
- CALL FREQUENCY //頻率計算
- MOV TH1,I_DATAS_H
- MOV TL1 ,I_DATAS_L
- SETB TR1
- SETB P5.4 ;關后級
-
- JSM04: JNB P3.3,JSM06 ;開關是否放開
- JNB TF1,JSM04
- CLR TR1
- CLR TF1
- JB P5.4,LLLL
- MOV TH1, I_DATAS_H
- MOV TL1, I_DATAS_L
- SETB TR1
- SETB P5.4
- ACALL AUT_DUTY //占空計算
- ACALL FREQUENCY //頻率計算
- AJMP JSM04
- RET
-
- LLLL:
- MOV TH1,E_DATAS_H
- MOV TL1,E_DATAS_L
- SETB TR1
- CLR P5.4 ;開后級
- AJMP JSM04
- RET
- //****************PCA啟動********************
- PCA_ON:
- MOV CL ,#00H
- MOV CH ,# 00H
- MOV CCAPM0,#49H
- MOV CCAP0L,#LOW T50HZ
- MOV CCAP0H,# HIGH T50HZ
- SETB CR
- SETB P3.0
- RET
- ;********************************************************************ADC初始化
- GET_ADC: //初始化
- MOV P_SW2,#80H
- MOV DPTR,#ADCTIM ;設置 ADC 內部時序
- MOV A,#3FH
- MOVX @DPTR,A
- MOV P_SW2,#00H
- MOV ADCCFG,#02FH ;設置 ADC 時鐘為系統時鐘/2/16/16, 結果右對齊
- MOV ADC_CONTR,#080H ;開啟 ADC 模塊電源,
- RET
- ;****************************************占空計算************************************
- AUT_DUTY:
- ;********************************************************************ADC2轉換
- GET_ADC2:
- MOV ADC_CONTR,#082H ;使能 ADC 模塊,設P3.2為ADC2
- ORL ADC_CONTR,#40H ;啟動 AD 轉換"ORL或運算=逢1等于1"
- NOP
- NOP
- MOV A,ADC_CONTR ;查詢 ADC 完成標志
- JNB ACC.5,$-2 ;ACC.5是否為‘1’,不為‘1’原址等待
- ANL ADC_CONTR,#NOT 20H ;清完成標志
- //單字節無符號數乘法
- MOV R3,ADC_RES
- MOV R4,ADC_RESL
- MOV R7,#00AH
- NMUL21 : MOV A,R4
- MOV B,R7
- MUL AB
- MOV R4,A
- MOV A,B
- XCH A,R3
- MOV B,R7
- MUL AB
- ADD A,R3
- MOV R3,A
- CLR A
- ADDC A,B
- MOV R2,A
- CLR OV
- //單字節無符號除法程序
- MOV R7,#066H
- NDIV31 : MOV A,R2
- MOV B,R7
- DIV AB
- PUSH ACC
- MOV R2,B
- MOV B,#10H
- NDV311 : CLR C
- MOV A,R4
- RLC A
- MOV R4,A
- MOV A,R3
- RLC A
- MOV R3,A
- MOV A,R2
- RLC A
- MOV R2,A
- MOV F0,C
- CLR C
- SUBB A,R7
- JB F0,NDV312
- JC NDV313
- NDV312 : MOV R2,A
- INC R4
- NDV313 : DJNZ B,NDV311
- POP ACC
- CLR OV
- JZ NDV314
- SETB OV
- NDV314 : XCH A,R2
- MOV R7,A
- MOV E_DUTY_L,R4
- MOV E_DUTY_H,R3
- //雙字節無符號數減法
- MOV R3,#03H
- MOV R4,#0E8H
- MOV R6,E_DUTY_H
- MOV R7,E_DUTY_L
- NSUB : MOV A,R4
- CLR C
- SUBB A,R7
- MOV R4,A
- MOV A,R3
- SUBB A,R6
- MOV R3,A
- MOV I_DUTY_L,R4
- MOV I_DUTY_H,R3
- RET
- //*********************************頻率計算***********************************
- FREQUENCY:
- ;**************************************ADC5轉換
- GET_ADC5:
- MOV ADC_CONTR,#085H ;使能 ADC 模塊,設P5.5為ADC5
- ORL ADC_CONTR,#40H ;啟動 AD 轉換"ORL或運算=逢1等于1"
- NOP
- NOP
- MOV A,ADC_CONTR ;查詢 ADC 完成標志
- JNB ACC.5,$-2 ;ACC.5是否為‘1’,不為‘1’原址等待
- ANL ADC_CONTR,#NOT 20H ;清完成標志
- ;計算有效定時器值。。。。。。。
- MOV R3,#01BH
- MOV R4,#058H
- MOV R6,E_DUTY_H
- MOV R7,E_DUTY_L
- ACALL STEP_1 //第1步算
- MOV R6,ADC_RES
- MOV R7,ADC_RESL
- ACALL STEP_2 //第2步算
- MOV A,R3
- MOV R6,A
- MOV A,R4
- MOV R7,A
- MOV R3,#0FFH
- MOV R4,#0FFH
- ACALL STEP_3 //第3步算
- MOV E_DATAS_L,R4
- MOV E_DATAS_H,R3
- ;計算無效定時器值。。。。。。。
- MOV R3,#01BH
- MOV R4,#058H
- MOV R6,I_DUTY_H
- MOV R7,I_DUTY_L
- ACALL STEP_1 //;第1步算
- MOV R6,ADC_RES
- MOV R7,ADC_RESL
- ACALL STEP_2 //第2步算
- MOV A,R3
- MOV R6,A
- MOV A,R4
- MOV R7,A
- MOV R3,#0FFH
- MOV R4,#0FFH
- ACALL STEP_3 //第3步算
- MOV I_DATAS_L,R4
- MOV I_DATAS_H,R3
- RET
- //第1步算:雙字節無符號數乘法
- STEP_1:
- NMUL22 : MOV A,R4
- MOV B,R7
- MUL AB
- XCH A,R4
- MOV R5,B
- MOV B,R6
- MUL AB
- ADD A,R5
- MOV R5,A
- CLR A
- ADDC A,B
- MOV R2,A
- MOV A,R3
- MOV B,R7
- MUL AB
- ADD A,R5
- MOV R5,A
- MOV A,B
- ADDC A,R2
- MOV R2,A
- CLR A
- ADDC A,#00H
- XCH A,R3
- MOV B,R6
- MUL AB
- ADD A,R2
- MOV R2,A
- MOV A,B
- ADDC A,R3
- XCH A,R5
- MOV R3,A
- CLR OV
- RET
- //第2步算:雙字節無符號除法
- STEP_2:
- NDIV42 : MOV A,R1
- PUSH ACC
- MOV B,#00H
- NDV421 : MOV A,R2
- CLR C
- SUBB A,R7
- MOV R1,A
- MOV A,R5
- SUBB A,R6
- JC NDV422
- MOV R5,A
- MOV A,R1
- MOV R2,A
- INC B
- SJMP NDV421
- NDV422 : PUSH B
- MOV B,#10H
- NDV423 : CLR C
- MOV A,R4
- RLC A
- MOV R4,A
- MOV A,R3
- RLC A
- MOV R3,A
- MOV A,R2
- RLC A
- MOV R2,A
- XCH A,R5
- RLC A
- XCH A,R5
- MOV F0,C
- CLR C
- SUBB A,R7
- MOV R1,A
- MOV A,R5
- SUBB A,R6
- JB F0,NCV424
- JC NDV425
- NCV424 : MOV R5,A
- MOV A,R1
- MOV R2,A
- INC R4
- NDV425 : DJNZ B,NDV423
- POP ACC
- CLR OV
- JNZ NDV426
- SETB OV
- NDV426 : XCH A,R2
- MOV R7,A
- MOV A,R5
- MOV R6,A
- POP ACC
- MOV R1,A
- RET
- //第3步算:雙字節無符號數減法程序
- STEP_3:
- MOV A,R4
- CLR C
- SUBB A,R7
- MOV R4,A
- MOV A,R3
- SUBB A,R6
- MOV R3,A
- RET
- //**************************PCA中斷***************************
- PCAISR : PUSH ACC //進堆棧
- PUSH PSW //進堆棧
- CLR CR //關PCA
- CLR CCF0 //模塊0中斷標志清零
- JB P3.0,JSMJSM
- CLR P3.1
- MOV CL ,#00H
- MOV CH ,# 00H
- MOV CCAPM0,#49H
- MOV CCAP0L,#LOW T50HZ
- MOV CCAP0H,# HIGH T50HZ
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- SETB CR
- SETB P3.0
- POP PSW //出堆棧
- POP ACC //出堆棧 ;恢復現場
- RETI
- JSMJSM:
- CLR P3.0
- MOV CL ,#00H
- MOV CH ,# 00H
- MOV CCAPM0,#49H
- MOV CCAP0L,#LOW T50HZ
- MOV CCAP0H,# HIGH T50HZ
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- SETB CR
- SETB P3.1
- POP PSW //出堆棧
- POP ACC //出堆棧 ;恢復現場
- RETI
- ;軟件延時
- DELAY100MS: ;@12.000MHz
- NOP
- PUSH 30H
- PUSH 31H
- PUSH 32H
- MOV 30H,#7
- MOV 31H,#23
- MOV 32H,#103
- NEXT:
- DJNZ 32H,NEXT
- DJNZ 31H,NEXT
- DJNZ 30H,NEXT
- POP 32H
- POP 31H
- POP 30H
- RET
- END
復制代碼
|