|
3#
楼主 |
发表于 2012-6-19 12:22:05
|
只看该作者
本帖最后由 joyrus 于 2012-6-19 12:57 编辑
所有程序内容:
;**************************************************
;程序功能说明
;本程序通过对PROTD0引脚的输入脉宽信号(周期20ms,脉宽变化1.5ms+/-0.5ms)
;进行转换为PWM调制脉宽信号(周期250us,脉宽变化约为0%-100%)
;由PORTD1输出,可用与驱动直流电动机的匀速调速
;本程序有很大的优化空间和存在安全漏洞,这个程序只是本人的学习过程,和大家共同探讨的载体
;本人联系方法:沈毅;joyrus@163.net,www.joyrus.com,QQ:15953321
;**************************************************
#include <p16f877A.inc> ;使用PIC16F877A单片机
;根据需要在这里配置单片机,也可以在MPLAB IDE中配置
;__CONFIG
;定义变量寄存器
;**************************************************
itp equ 0x20 ;输入脉冲宽度
otp equ 0x21 ;输出PMW脉冲宽度
itm1 equ 0x22 ;输入脉冲高电平TMR0起始记数
itm0 equ 0x23 ;输入脉冲高电平TMR0结尾记数
itmf equ 0x24 ;itmf[2:0],
;itmf.0输入脉冲低电平标志位
;itmf.1输入脉冲高电平标志位,实际上次位可以不用,而只用itmf.0这一位即可
;即减少的指令数量,又避免了[1:0]这两位由于意外同时为1而造成程序的错误,类似
;情况在本程序中还有其他地方会出现可以优化省略的变量和代码,就不一一指出了
;itmf.2输出PWM脉冲周期溢出标志位
otm equ 0x25 ; PWM脉冲高电平输出TMR0起始记数
otpwm equ 0x26 ; PWM脉冲周期+TMR0
pwm_tmr0_otp equ 0x27 ;保存TMR0计数值的初值用于计算PWM脉冲宽度与周期
;定义常量
;**************************************************
pwm_cycle equ 0xFA ; PWM周期数250个计数周期共4ms
;程序起始
;****************************************************
org 000h ;定义程序存放区域的起始地址
nop ;放置一条ICD必须的空操用指令
;Bank1 初始化配置
;*******************************************************
banksel OPTION_REG ;选择Bank1
movlw b'10000011' ;TMR0配置数
movwf OPTION_REG ;TMR0配置寄存器
;movlw 0x00 ;中断配置数,禁止所有中断,可省略
;movwf INTCON ;中断配置寄存器,可省略
;bcf TRISE,PSPMODE ;设定PORTD为普通数字I/O,可省略
bcf TRISD,1 ;设定PORTD1为输出,PORTD其他口全为输入
;Bank0 初始化变量
;*******************************************************
banksel itmf ;选择Bank0初始化变量
;*********************************************
movlw b'00000001' ;初始化itmf,假设已经处理过输入脉冲的低电平
movwf itmf ;初始化itmf
;*********************************************
;movlw 0x00
;movwf itm0
;movwf itm1
;movwf itp
;movwf otp
;movwf otm
;movwf otpwm
;...............
;建议对所有的变量寄存器进行初始化
;Bank0 主程序入口
;*************************************************************
Main_esc ;如有需要可以在这里进行电池电压的检查
;根据检查结果选择需要执行的程序段
;另外在程序的相应位置还应该插入对首次
;上电后的高油门位置的输出保护代码
;以防止一上电后电动机即可启动的危险!
;开始捕捉处理输入脉冲的高电平
;*************************************************************
Process_hige btfsc itmf,1 ;检查itmf1标志位,为0则执行本段代码
goto Process_low ;如果itmf1为1说明已经处理过本代码,跳转处理低电平
btfss PORTD,0 ;如果PORTD0输入是低电平则不执行本段代码
goto Process_low ;跳转处理低电平
movf TMR0,w ;从TMR0读入高电平计数初始数
movwf itm1 ;初始数存入itm1
bsf itmf,1 ;设置itmf1为1说明已经处理了高电平,不再处理
bcf itmf,0 ;设置itml0为0说明需要处理低电平
;开始捕捉处理输入脉冲的低电平,说明高电平已经结束,完成检测输入脉冲的宽度
;**********************************************************
Process_low btfsc itmf,0 ;检查itmf0标志位,为0则执行本段代码
goto Count_itp ;如果itmf0为1说明已经处理过本代码,跳转计算输入脉冲宽度
btfsc PORTD,0 ;如果PORTD0输入是高电平则不处理本代码
goto Count_itp ;跳转处理计算输入脉冲宽度
movf TMR0,w ;从TMR0读入高电平计数结尾数
movwf itm0 ;结尾数存入itm0
bsf itmf,0 ;设置itmf0为1说明已经处理了低电平,不再处理
bcf itmf,1 ;设置itmf1为0说明需要处理高电平
;开始计算输入脉冲宽度
;*********************************************************
Count_itp btfss itmf,0 ;检查itmf0标志位,为1则计算输入脉冲宽度,说明低电平已经出现
goto Output_pwm ;跳转计算PWM输出脉冲
movf itm1,w ;itm0-itm1
subwf itm0,w ;itm0-itm1
movwf itp ;itp=itm0-itm1为输入脉冲宽度
;得到itp后开始输出PWM的过程
;********************************************************
Output_pwm call Count_pwm ;通过itp查表得到otp脉冲宽度值由w寄存器带出
movwf otp ;w->otp
;如果查表结果为0%输出则关闭PWM中断输出,恒定输出低电平
;***********************************************
movf otp,w
btfsc STATUS,Z
goto Int_pwm
;如果查表结果为100%输出则PWM直接输出恒定高电平
;***********************************************
sublw pwm_cycle
btfsc STATUS,Z
goto Pwm_full
;*******************************************************
;保存进入PWM计数前的TMR0计数值的初值
;在每一个PWM周期内只处理和计算一次
;*****************************************
btfss itmf,2 ;检查PWM周期是否溢出标志位,为1则溢出
goto Figure_pwm ;没有溢出不需要重新计算PWM的脉宽和周期,直接输出PWM
movf TMR0,w
movwf pwm_tmr0_otp
;*****************************************
;初始化otp和otpwm,以便于和TMR0进行比较计算PWM脉冲宽度
;*******************************************************
movf pwm_tmr0_otp,w ;从TMR0->w读入PWM脉冲输出高电平计数起始数
addwf otp,w ;w+otp->w得到PWM脉冲输出宽度比较数
movwf otm ;w->otm保存比较数到otm
;初始化otp和otpwm,以便于和TMR0进行比较计算PWM脉冲周期
;************************************************************
movf pwm_tmr0_otp,w ;计算otpwm脉冲周期溢出计数
addlw pwm_cycle ;加PWM脉冲周期到初始计数值
movwf otpwm ;得到PWM脉冲周期溢出计数放入otpwm
;***********************************************************
;计算PWM的脉宽和周期过程
;*****************************************************************
Figure_pwm movf TMR0,w ;采集实时计数脉冲
subwf otm,w ;otm-TMR0比较计算PWM脉冲宽度
btfss STATUS,C ;比较计算PWM脉冲宽度
goto Pwm_low ;otm<TMR0则PWM脉宽到达otm指定宽度PWM输出低电平
goto Pwm_high ;otm>TMR0则PWM脉宽未到达otm指定宽度PWM输出高电平
Pwm_low bcf PORTD,1 ; PWM输出低电平
goto Check_pwm_out ;goto检查PWM周期是否溢出
Pwm_high bsf PORTD,1 ; PWM输出高电平
Check_pwm_out movf TMR0,w ;采集实时计数脉冲
subwf otpwm,w ;比较计算otpwm脉冲周期是否溢出
btfss STATUS,C ;检查PWM周期是否溢出
goto unPwm_out ;otpwm>TMR0则PWM周期未到达otpwm指定宽度
bsf itmf,2 ; PWM周期已经溢出设置标志位为1
goto Int_pwm ;otpwm<TMR0则PWM周期到达otpwm指定宽度中断PWM输出脉冲
unPwm_out bcf itmf,2 ; PWM周期没有溢出设置标志位为0
goto Main_esc ;返回主程序入口
Int_pwm bcf PORTD,1 ;终止输出,PWM输出低电平
goto Main_esc ;返回主程序入口
Pwm_full bsf PORTD,1 ; PWM输出高电平
goto Main_esc ;返回主程序入口
;查表pwm脉冲宽度 子程序
;******************************************************************
Count_pwm
movlw high(Table_pwm) ;查表代码
movwf PCLATH
movf itp,w
addlw low(Table_pwm)
btfsc STATUS,C
incf PCLATH,f
movwf PCL
Table_pwm
retlw 0x00 ;0
retlw 0x00 ;1
retlw 0x00 ;2
retlw 0x00 ;3
retlw 0x00 ;4
retlw 0x00 ;5
retlw 0x00 ;6
retlw 0x00 ;7
retlw 0x00 ;8
retlw 0x00 ;9
retlw 0x00 ;10
retlw 0x00 ;11
retlw 0x00 ;12
retlw 0x00 ;13
retlw 0x00 ;14
retlw 0x00 ;15
retlw 0x00 ;16
retlw 0x00 ;17
retlw 0x00 ;18
retlw 0x00 ;19
retlw 0x00 ;20
retlw 0x00 ;21
retlw 0x00 ;22
retlw 0x00 ;23
retlw 0x00 ;24
retlw 0x00 ;25
retlw 0x00 ;26
retlw 0x00 ;27
retlw 0x00 ;28
retlw 0x00 ;29
retlw 0x00 ;30
retlw 0x00 ;31
retlw 0x00 ;32
retlw 0x00 ;33
retlw 0x00 ;34
retlw 0x00 ;35
retlw 0x00 ;36
retlw 0x00 ;37
retlw 0x00 ;38
retlw 0x00 ;39
retlw 0x00 ;40
retlw 0x00 ;41
retlw 0x00 ;42
retlw 0x00 ;43
retlw 0x00 ;44
retlw 0x00 ;45
retlw 0x00 ;46
retlw 0x00 ;47
retlw 0x00 ;48
retlw 0x00 ;49
retlw 0x00 ;50
retlw 0x00 ;51
retlw 0x00 ;52
retlw 0x00 ;53 itp可能出现的值其他值为非法值,一律返回0
retlw 0x00 ;54 ;*********************
retlw 0x00 ;55 ;0x37
retlw 0x00 ;56 ;0x38
retlw 0x00 ;57 ;0x39
retlw 0x00 ;58 ;0x3A
retlw 0x00 ;59 ;0x3B
retlw 0x00 ;60 ;0x3C 输入脉宽有效范围取值
retlw 0x00 ;61 ;0x3D ************************
retlw 0x00 ;62 ;0x3E 0%
retlw 0x04 ;63 ;0x3F 1
retlw 0x08 ;64 ;0x40 2
retlw 0x0C ;65 ;0x41 3
retlw 0x10 ;66 ;0x42 4
retlw 0x14 ;67 ;0x43 5
retlw 0x17 ;68 ;0x44 6
retlw 0x1A ;69 ;0x45 7
retlw 0x1F ;70 ;0x46 8
retlw 0x24 ;71 ;0x47 9
retlw 0x29 ;72 ;0x48 10
retlw 0x2E ;73 ;0x49 11
retlw 0x33 ;74 ;0x4A 12
retlw 0x38 ;75 ;0x4B 13
retlw 0x3A ;76 ;0x4C 14
retlw 0x3D ;77 ;0x4D 15
retlw 0x41 ;78 ;0x4E 16
retlw 0x45 ;79 ;0x4F 17
retlw 0x49 ;80 ;0x50 18
retlw 0x4D ;81 ;0x51 19
retlw 0x51 ;82 ;0x52 20
retlw 0x55 ;83 ;0x53 21
retlw 0x59 ;84 ;0x54 22
retlw 0x5D ;85 ;0x55 23
retlw 0x61 ;86 ;0x56 24
retlw 0x65 ;87 ;0x57 25
retlw 0x69 ;88 ;0x58 26
retlw 0x6D ;89 ;0x59 27
retlw 0x71 ;90 ;0x5A 28
retlw 0x75 ;91 ;0x5B 29
retlw 0x79 ;92 ;0x5C 30
retlw 0x7D ;93 ;0x5D 50%
retlw 0x7D ;94 ;0x5E 50%
retlw 0x81 ;95 ;0x5F 30
retlw 0x85 ;96 ;0x60 29
retlw 0x89 ;97 ;0x61 28
retlw 0x8D ;98 ;0x62 27
retlw 0x91 ;99 ;0x63 26
retlw 0x95 ;100 ;0x64 25
retlw 0x99 ;101 ;0x65 24
retlw 0x9D ;102 ;0x66 23
retlw 0xA1 ;103 ;0x67 22
retlw 0xA5 ;104 ;0x68 21
retlw 0xA9 ;105 ;0x69 20
retlw 0xAD ;106 ;0x6A 19
retlw 0xB1 ;107 ;0x6B 18
retlw 0xB5 ;108 ;0x6C 17
retlw 0xB9 ;109 ;0x6D 16
retlw 0xBD ;110 ;0x6E 15
retlw 0xC0 ;111 ;0x6F 14
retlw 0xC5 ;112 ;0x70 13
retlw 0xCA ;113 ;0x71 12
retlw 0xCF ;114 ;0x72 11
retlw 0xD4 ;115 ;0x73 10
retlw 0xD9 ;116 ;0x74 9
retlw 0xDE ;117 ;0x75 8
retlw 0xE3 ;118 ;0x76 7
retlw 0xE5 ;119 ;0x77 6
retlw 0xE6 ;120 ;0x78 5
retlw 0xEA ;121 ;0x79 4
retlw 0xEE ;122 ;0x7A 3
retlw 0xF2 ;123 ;0x7B 2
retlw 0xF6 ;124 ;0x7C 1
retlw 0xFA ;125 ;0x7D 100%
retlw 0xFA ;126 ;0x7E
retlw 0xFA ;127 ;0x7F
retlw 0xFA ;128 ;0x80
retlw 0xFA ;129 ;0x81
retlw 0xFA ;130 ;0x82
retlw 0xFA ;131 ;0x83
retlw 0x00 ;132
retlw 0x00 ;133
retlw 0x00 ;134
retlw 0x00 ;135
retlw 0x00 ;136
retlw 0x00 ;137
retlw 0x00 ;138
retlw 0x00 ;139
retlw 0x00 ;140
retlw 0x00 ;141
retlw 0x00 ;142
retlw 0x00 ;143
retlw 0x00 ;144
retlw 0x00 ;145
retlw 0x00 ;146
retlw 0x00 ;147
retlw 0x00 ;148
retlw 0x00 ;149
retlw 0x00 ;150
retlw 0x00 ;151
retlw 0x00 ;152
retlw 0x00 ;153
retlw 0x00 ;154
retlw 0x00 ;155
retlw 0x00 ;156
retlw 0x00 ;157
retlw 0x00 ;158
retlw 0x00 ;159
retlw 0x00 ;160
retlw 0x00 ;161
retlw 0x00 ;162
retlw 0x00 ;163
retlw 0x00 ;164
retlw 0x00 ;165
retlw 0x00 ;166
retlw 0x00 ;167
retlw 0x00 ;168
retlw 0x00 ;169
retlw 0x00 ;170
retlw 0x00 ;171
retlw 0x00 ;172
retlw 0x00 ;173
retlw 0x00 ;174
retlw 0x00 ;175
retlw 0x00 ;176
retlw 0x00 ;177
retlw 0x00 ;178
retlw 0x00 ;179
retlw 0x00 ;180
retlw 0x00 ;181
retlw 0x00 ;182
retlw 0x00 ;183
retlw 0x00 ;184
retlw 0x00 ;185
retlw 0x00 ;186
retlw 0x00 ;187
retlw 0x00 ;188
retlw 0x00 ;189
retlw 0x00 ;190
retlw 0x00 ;191
retlw 0x00 ;192
retlw 0x00 ;193
retlw 0x00 ;194
retlw 0x00 ;195
retlw 0x00 ;196
retlw 0x00 ;197
retlw 0x00 ;198
retlw 0x00 ;199
retlw 0x00 ;200
retlw 0x00 ;201
retlw 0x00 ;202
retlw 0x00 ;203
retlw 0x00 ;204
retlw 0x00 ;205
retlw 0x00 ;206
retlw 0x00 ;207
retlw 0x00 ;208
retlw 0x00 ;209
retlw 0x00 ;210
retlw 0x00 ;211
retlw 0x00 ;212
retlw 0x00 ;213
retlw 0x00 ;214
retlw 0x00 ;215
retlw 0x00 ;216
retlw 0x00 ;217
retlw 0x00 ;218
retlw 0x00 ;219
retlw 0x00 ;220
retlw 0x00 ;221
retlw 0x00 ;222
retlw 0x00 ;223
retlw 0x00 ;224
retlw 0x00 ;225
retlw 0x00 ;226
retlw 0x00 ;227
retlw 0x00 ;228
retlw 0x00 ;229
retlw 0x00 ;230
retlw 0x00 ;231
retlw 0x00 ;232
retlw 0x00 ;233
retlw 0x00 ;234
retlw 0x00 ;235
retlw 0x00 ;236
retlw 0x00 ;237
retlw 0x00 ;238
retlw 0x00 ;239
retlw 0x00 ;240
retlw 0x00 ;241
retlw 0x00 ;242
retlw 0x00 ;243
retlw 0x00 ;244
retlw 0x00 ;245
retlw 0x00 ;246
retlw 0x00 ;247
retlw 0x00 ;248
retlw 0x00 ;249
retlw 0x00 ;250
retlw 0x00 ;251
retlw 0x00 ;252
retlw 0x00 ;253
retlw 0x00 ;254
retlw 0x00 ;255
goto Main_esc
END |
|