📄 pwm.src
字号:
; 8051 C compiler (DEMO) v6.0 r1 SN????????-098 (c) 2001 TASKING, Inc.
; options: -ne -Ic:\dcc51\include -Ms -ivo=0x0000 -Cat8x2051 -s -wstrict -O1 -c0
; -b0 -a20 -g -A1 -mid=128
$DEBUGINFO(0F9H)
$CASE
NAME PWM
?SYMB 'pwm.c',16,80,16
?SYMB '',1,82,0
?SYMB '8051',0,84,0
?SYMB 'r0',2,83,0
?SYMB 'r1',2,83,1
?SYMB 'r2',2,83,2
?SYMB 'r3',2,83,3
?SYMB 'r4',2,83,4
?SYMB 'r5',2,83,5
?SYMB 'r6',2,83,6
?SYMB 'r7',2,83,7
?SYMB 'b',2,83,10
?SYMB '',0,81,0
?SYMB 'void',00H,45,1
?SYMB 'char',080000H,45,2
?SYMB 'unsigned char',080000H,45,3
?SYMB 'short',0100000H,45,4
?SYMB 'unsigned short',0100000H,45,5
?SYMB 'long',0200000H,45,6
?SYMB 'unsigned long',0200000H,45,7
?SYMB 'float',0200000H,45,10
?SYMB 'double',0400000H,45,11
?SYMB 'int',0100000H,45,16
?SYMB 'unsigned int',0100000H,45,18
?SYMB 'bit',010000H,7,256
?SYMB 'pwm.c',0,29,1
?SYMB '',0,86,1
; pwm.c 1 /*==============================================================
; pwm.c 2 at12c2052所带的PWM功能演示,内部公用了一个定时器,当启动PWM时PCA
; pwm.c 3 定时器只工作在8位模式,匹配比较器也是按8位的。本程序演示了PWM启动
; pwm.c 4 的设置和调节。
; pwm.c 5 改用在tasking c51下面编译,并尝试了tasking 方便的在线汇编方式
; pwm.c 6 ------- 晓奇 2006.01.12 --xiaoqi 2005.12.21
; pwm.c 7 ===============================================================*/
; pwm.c 8 #include "STC12C2052AD.h"
?SYMB 'STC12C2052AD.h',0,29,2
?SYMB '',0,86,2
?SYMB '',0,86,1
; pwm.c 9 /*#include<INTRINS.h>*/
; pwm.c 10 #define uint unsigned int
; pwm.c 11 #define uchar unsigned char
; pwm.c 12
; pwm.c 13 uint i;
PUBLIC _i
C51_DA SEGMENT DATA
RSEG C51_DA
_i: DS 2
?SYMB 'i',_i,22,18
; pwm.c 14 uchar upordn; /* 升降标志,1=上升 */
PUBLIC _upordn
_upordn: DS 1
?SYMB 'upordn',_upordn,22,3
; pwm.c 15 void initall(void);
; pwm.c 16 _interrupt(1) void timers0(void);
; pwm.c 17 _interrupt (6) void PCA_LVD(void);
; pwm.c 18 void initall(void)
; pwm.c 19 {
PWM_INITALL_PR SEGMENT CODE
RSEG PWM_INITALL_PR
?LINE 19
PUBLIC _?initall
?SYMB 'initall',_?initall,37,1
?SYMB '',19,8,2
?SYMB '',00H,95,0
_?initall:
USING 0
; pwm.c 20 TMOD= 0x11; /* 0000 0001 T0作为16位计数器 */
?LINE 20
MOV 089H,#011H
; pwm.c 21 TH0 = 0xc0; /* 定时器0初始值装入 */
?LINE 21
MOV 08CH,#0C0H
; pwm.c 22 TL0 = 0x00;
?LINE 22
MOV 08AH,#00H
; pwm.c 23 ET0 = 1; //开中断
?LINE 23
SETB 0A9H
; pwm.c 24 IE |= 0x40; /* 使能PCA定时功能 */
?LINE 24
ORL 0A8H,#040H
; pwm.c 25 EA = 1;
?LINE 25
SETB 0AFH
; pwm.c 26 AUXR = 0x80;
?LINE 26
MOV 08EH,#080H
; pwm.c 27 /* 1000 0000
; pwm.c 28 |||| ||++-保留
; pwm.c 29 |||| |+---低电压中断允许:0=禁止,1=允许,5V..3.7V,3V..2.4V以下
; pwm.c 30 |||| +----SPI中断允许位:0=禁止,1=允许
; pwm.c 31 |||+------ADC中断允许位:0=禁止,1=允许
; pwm.c 32 ||+-------串口模式0时时钟设定:0=传统1/12, 1=1/2 2分频;
; pwm.c 33 |+--------定时器ct1时钟源设定:0=传统1/12,1=1:1不分频;
; pwm.c 34 +---------定时器ct0时钟源设定:0=传统1/12,1=1:1不分频;
; pwm.c 35 */
; pwm.c 36 P1 = 0xff;
?LINE 36
MOV 090H,#0FFH
; pwm.c 37 P1M0 = 0x00; /* P1口用传统51准双向口模式 */
?LINE 37
MOV 091H,#00H
; pwm.c 38 P1M1 = 0x00;
?LINE 38
MOV 092H,#00H
; pwm.c 39 CMOD = 0x03; /* 内部时钟,Fosc/2, PCA计数溢出中断使能*/
?LINE 39
MOV 0D9H,#03H
; pwm.c 40 /* 0000 0011 PCA 模式寄存器
; pwm.c 41 |||| |||+--ECF...PCA计数溢出中断使能:ECF=1时,使能寄存器CCON CF位的
; pwm.c 42 |||| ||| 中断。ECF=0时,禁止该功能。
; pwm.c 43 |||| |++---CPS1,CPS0 选择PCA 时钟源输入(PCA计数脉冲选择)
; pwm.c 44 |||| | 0 0 0,内部时钟,Fosc/12
; pwm.c 45 |||| | 0 1 1,内部时钟,Fosc/2
; pwm.c 46 |||| | 1 0 2,定时器0溢出,由于定时器0可以工作在1T方式,
; pwm.c 47 |||| | 所以可以达到计一个时钟就溢出, 频率反而
; pwm.c 48 |||| | 是最高的,可达到Fosc
; pwm.c 49 |||| | 1 1 3,ECI/P3.4脚的外部时钟输入(最大速率=Fosc/2)
; pwm.c 50 |+++-+-----保留
; pwm.c 51 +----------CIDL...计数器阵列空闲控制:CIDL=0时,空闲模式下PCA计数器
; pwm.c 52 继续工作。CIDL=1时,空闲模式下PCA计数器停止工作。
; pwm.c 53 */
; pwm.c 54
; pwm.c 55 CH = 0x00; /* PCA计数器初始值高8位 */
?LINE 55
MOV 0F9H,#00H
; pwm.c 56 CL = 0x00; /* PCA计数器初始值低8位 */
?LINE 56
MOV 0E9H,#00H
; pwm.c 57 CCAP0H = 0x00; /* 当出现捕获或比较时,它们用来保存16 位的计数值。
?LINE 57
MOV 0FAH,#00H
; pwm.c 58 当PCA 模块用在PWM 模式中时,它们用来控制输出的
; pwm.c 59 占空比。CCAP0H.CCAP0L分别为高低8位,组合使用
; pwm.c 60 */
; pwm.c 61 CCAP0L = 0x00;
?LINE 61
MOV 0EAH,#00H
; pwm.c 62
; pwm.c 63 CCAP1H = 0x00; /* 当出现捕获或比较时,它们用来保存16 位的计数值。
?LINE 63
MOV 0FBH,#00H
; pwm.c 64 当PCA 模块用在PWM 模式中时,它们用来控制输出的
; pwm.c 65 占空比。CCAP1H.CCAP1L分别为高低8位,组合使用
; pwm.c 66 */
; pwm.c 67 CCAP1L = 0x00;
?LINE 67
MOV 0EBH,#00H
; pwm.c 68
; pwm.c 69 CCAPM1 = 0x4c; /* PCA 比较/捕获模块寄存器1作为16位软件定时器。使能
?LINE 69
MOV 0DBH,#04CH
; pwm.c 70 比较器,PCA计数值与模块的比较/捕获寄存器的值的匹配将
; pwm.c 71 置位CCON寄存器的中断标志位CCF1,使能CCF1中断 */
; pwm.c 72 /*
; pwm.c 73 0100 1100 功能说明
; pwm.c 74 |||| |||+---ECCF1.. 使能CCF1中断。使能寄存器CCON的比较/捕获标志CCF1,
; pwm.c 75 |||| ||| 用来产生中断。
; pwm.c 76 |||| ||+----PWM1... 脉宽调节模式。当PWMn=1时,使能CEXn脚用作脉宽调节输出。
; pwm.c 77 |||| |+-----TOG1... 翻转。当TOG1= 1时, PCA计数值与模块的比较/捕获寄存
; pwm.c 78 |||| | 器的值的匹配将使CEXn脚翻转。(CEX1/P3.5)
; pwm.c 79 |||| +------MAT1... 匹配。当=1时, PCA计数值与模块的比较/捕获寄存器的值
; pwm.c 80 |||| 的匹配将置位CCON寄存器的中断标志位CCF1。
; pwm.c 81 |||+--------CAPN1.. 负捕获。CAPN1= 1时使能下降沿捕获。
; pwm.c 82 ||+---------CAPP1.. 正捕获。CAPP1= 1时使能上升沿捕获。
; pwm.c 83 |+----------ECOM1.. 使能比较器。ECOM1= 1时使能比较器功能。
; pwm.c 84 +-----------CCAPM1^7保留
; pwm.c 85
; pwm.c 86 使用的机种基本模式组合:
; pwm.c 87 ECOM1 CAPP1 CAPN1 MAT1 TOG1 PWM1 ECCF1 模块功能
; pwm.c 88 0 0 0 0 0 0 0 无此操作
; pwm.c 89 X 1 0 0 0 0 X 16位捕获模式,由CEX1的上升沿触发
; pwm.c 90 X 0 1 0 0 0 X 16位捕获模式,由CEX1的下降沿触发
; pwm.c 91 X 1 1 0 0 0 X 16位捕获模式,由CEX1的跳变触发
; pwm.c 92 1 0 0 1 0 0 X 16位软件定时器
; pwm.c 93 1 0 0 1 1 0 X 16位高速输出
; pwm.c 94 1 0 0 0 0 1 0 8位PWM
; pwm.c 95 */
; pwm.c 96
; pwm.c 97 CCAPM0 = 0x42; /* PCA 比较/捕获模块寄存器0作为16位软件定时器。使能
?LINE 97
MOV 0DAH,#042H
; pwm.c 98 比较器,PCA计数值与模块的比较/捕获寄存器的值的匹配将
; pwm.c 99 置位CCON寄存器的中断标志位CCF0,使能CCF0中断 寄存器
; pwm.c 100 位功能同上*/
; pwm.c 101 CR = 1; //Start PCA Timer.
?LINE 101
SETB 0DEH
; pwm.c 102 TR0 = 1; //启动计时
?LINE 102
SETB 08CH
; pwm.c 103 i = 0;
?LINE 103
CLR A
MOV _i,A
MOV _i+1,A
; pwm.c 104 upordn = 1;
?LINE 104
MOV _upordn,#01H
; pwm.c 105 }
?LINE 105
RET
?SYMB '',$,17,105
; pwm.c 106
; pwm.c 107 /* ------------- 定时器0用来定时调节PWM的输出占空比 ------------- */
; pwm.c 108 _interrupt(1) void timers0(void)
; pwm.c 109 {
PWM_TIMERS0_PR SEGMENT CODE
RSEG PWM_TIMERS0_PR
?LINE 109
PUBLIC _?timers0
?SYMB 'timers0',_?timers0,37,1
?SYMB '',109,8,18
CSEG AT 0BH
LJMP _?timers0
?SYMB '',00H,95,0
RSEG PWM_TIMERS0_PR
_?timers0:
PUSH ACC
?SYMB '',$,96,1
PUSH AR0
?SYMB '',$,96,2
PUSH AR1
?SYMB '',$,96,3
PUSH AR2
?SYMB '',$,96,4
PUSH AR3
?SYMB '',$,96,5
PUSH PSW
?SYMB '',$,96,6
MOV PSW,#00H
; pwm.c 110 TL0 = 0x00;
?LINE 110
MOV 08AH,#00H
; pwm.c 111 TH0 = 0xc0;
?LINE 111
MOV 08CH,#0C0H
; pwm.c 112
; pwm.c 113 CCAP0H = i>>8; /* CCAP0L不用赋值,他不参与工作 */
?LINE 113
MOV 0FAH,_i
; pwm.c 114 if(upordn) /* 逐步加宽PWM、加快脉冲输出 */
?LINE 114
MOV A,_upordn
JZ _3
; pwm.c 115 {
; pwm.c 116 if(++i==65535) /* 到头 */
?LINE 116
INC _i+1
MOV A,_i+1
JNZ _7
INC _i
_7:
MOV R1,_i+1
MOV R0,_i
CJNE R1,#0FFH,_6
CJNE R0,#0FFH,_6
; pwm.c 117 {
; pwm.c 118 upordn=0; /* 调头 */
?LINE 118
MOV _upordn,#00H
; pwm.c 119 }
; pwm.c 120 }
?LINE 120
SJMP _6
_3:
; pwm.c 121 else /* 逐步减窄PWM、减慢脉冲输出 */
; pwm.c 122 {
; pwm.c 123 if(--i==0) /* 到头 */
?LINE 123
MOV A,_i+1
JNZ _8
DEC _i
_8:
DEC _i+1
MOV A,_i+1
ORL A,_i
JNZ _6
; pwm.c 124 {
; pwm.c 125 upordn=1; /* 调头 */
?LINE 125
MOV _upordn,#01H
; pwm.c 126 }
; pwm.c 127 }
?LINE 127
_6:
; pwm.c 128
; pwm.c 129 P1 = ~(i>>8); /* 高8位输出LED指示,作监视用 */
?LINE 129
MOV A,_i
CPL A
MOV 090H,A
; pwm.c 130 }
?LINE 130
POP PSW
?SYMB '',$,96,5
POP AR3
?SYMB '',$,96,4
POP AR2
?SYMB '',$,96,3
POP AR1
?SYMB '',$,96,2
POP AR0
?SYMB '',$,96,1
POP ACC
?SYMB '',$,96,0
RETI
?SYMB '',$,17,130
; pwm.c 131
; pwm.c 132 /* ------------ PCA 定时中断,负责清除溢出标志并赋初值 ------------- */
; pwm.c 133 /* 摇晃编程板可以看到P3.5连接的led闪亮频率的缓慢变化,虚线在变长变短 */
; pwm.c 134 _interrupt (6) void PCA_LVD(void)
; pwm.c 135 {
PWM_PCA_LVD_PR SEGMENT CODE
RSEG PWM_PCA_LVD_PR
?LINE 135
PUBLIC _?PCA_LVD
?SYMB 'PCA_LVD',_?PCA_LVD,37,1
?SYMB '',135,8,18
CSEG AT 033H
LJMP _?PCA_LVD
?SYMB '',00H,95,0
RSEG PWM_PCA_LVD_PR
_?PCA_LVD:
PUSH ACC
?SYMB '',$,96,1
PUSH PSW
?SYMB '',$,96,2
MOV PSW,#00H
; pwm.c 136 CH = i>>8;
?LINE 136
MOV 0F9H,_i
; pwm.c 137 CL = i&0xff;
?LINE 137
MOV A,_i+1
MOV 0E9H,A
; pwm.c 138 CF = 0;
?LINE 138
CLR 0DFH
; pwm.c 139 CCF0 = 0;
?LINE 139
CLR 0D8H
; pwm.c 140 // LedPCA ^= 1; /* 频率要求不高的时候这里可以插入用户代码 */
; pwm.c 141 }
?LINE 141
POP PSW
?SYMB '',$,96,1
POP ACC
?SYMB '',$,96,0
RETI
?SYMB '',$,17,141
; pwm.c 142
; pwm.c 143 void main(void)
; pwm.c 144 {
PWM_MAIN_PR SEGMENT CODE
RSEG PWM_MAIN_PR
?LINE 144
PUBLIC _?main
?SYMB 'main',_?main,37,1
?SYMB '',144,8,2
?SYMB '',00H,95,0
_?main:
; pwm.c 145 initall();
?LINE 145
LCALL _?initall
; pwm.c 146
; pwm.c 147 // 测试tasking c51的在线汇编功能
; pwm.c 148 #pragma asm
?LINE 148
$ASMLINEINFO
mov r0,#0f0h
v1: nop
nop
djnz r0,v1
nop
$NOASMLINEINFO
; pwm.c 154 #pragma endasm
; pwm.c 155 // 编译很顺利通过,不用作任何附加的设定
; pwm.c 156 while(1){};
?LINE 156
_9:
SJMP _9
; pwm.c 157 }
?LINE 157
RET
?SYMB '',$,17,157
; pwm.c 158
EXTRN IDATA(__STKSTART)
EXTRN CODE(SMALL)
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -