下载

2下载券

加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 PIC单片机应用开发典型模块各章程序第一章程序

PIC单片机应用开发典型模块各章程序第一章程序.doc

PIC单片机应用开发典型模块各章程序第一章程序

WindomZhong
2018-09-08 0人阅读 举报 0 0 0 暂无简介

简介:本文档为《PIC单片机应用开发典型模块各章程序第一章程序doc》,可适用于IT/计算机领域

PIC单片机IO模块的应用PORTC的个引脚RC~RC分别通过只电阻(起限流作用)与发光二极管相连从而控制发光二极管的点亮与熄灭。程序代码如下:#include<pich>main(){TRISC=X*TRISC寄存器被赋值PORTD每一位都为输出*while()*循环执行点亮发光二极管的语句*{PORTC=XF*向PORTC送数据点亮LED(由实验模板**的设计决定相应位置低时LED点亮)*}}PIC单片机主控同步串行端口MSSP模块的应用()SPI工作方式配置PIC单片机的MSSP模块工作于SPI主控方式下通过一个串并行转换移位寄存器(HC)将SD口送出的串行数据转换为并行数据驱动LED数码管依次显示~等个字符。程序代码如下:#include<picxh>staticvolatileinttable={xcxfxaxbxxxXDxxxxxcxaxxexfxbfxxff}volatileunsignedchardata#definePORTAIT(adrbit)((unsigned)(adr)*(bit))*绝对寻址位操作指令*staticbitPORTAPORTAIT(PORTA)**************************************************************************函数名:SPIINT()**功能:SPIi初始化**************************************************************************voidSPIINIT(){PIR=SSPCON=x*允许SPI工作在主控方式下SSPEN=CKP=*FOSC*SSPSTAT=xCTRISC=x*SDO引脚为输出SCK引脚为输出*}**************************************************************************函数名:initial()**功能:系统各输入输出口初始化**************************************************************************voidinitial(){TRISA=x*A口设置为输出*INTCON=x*关闭所有中断*PORTA=*LACK送cstart()        icwrite(xa)        data=icread()        icstop()        return(data)}endeepromcread()inteepromctest(void){        inti        writextest        for(i=i<EEPROMCSIZEi)                {                eepromcwrite(i,x)                }        for(i=i<EEPROMCSIZEi)                {                if(x!=eepromcread(i))return                }        writexaatest        for(i=i<EEPROMCSIZEi)                {                eepromcwrite(i,xaa)                }        for(i=i<EEPROMCSIZEi)                {                if(xaa!=eepromcread(i))return                }                writeeeprom        for(i=i<EEPROMCSIZEi)                {                eepromcwrite(i,x)                }        returnxff}endeepromctest()voidmain(void){        initeepromc()        cisready        if(!=eepromcready())                {                outputhigh(PINC)                }        testc        if(!=eepromctest())                {                outputhigh(PINC)                delayms()                                }                writec        eepromcwrite(,xaa)                readc        outputc(eepromcread())}endmain()PIC单片机的定时器计数器模块的应用通过配置PIC单片机寄存器使TIMER定时来实现秒表的功能。程序代码如下:#include<pich>#include<mathh>此程序实现计时秒表功能时钟显示范围~s分辨度:sunsignedcharssss定义s、s、s、s计时器unsignedcharsunsignedcharkdatasregunsignedinticonsttable={xcxfxaxbxxxXDxx}不带小数点的显示段码表consttable={XXXXXXXXXX}带小数点的显示段码表******************************************************************************函数名:tmint()**功能:TMR初始化子程序使TMR工作于定时器方式******************************************************************************voidtmint(){TCS=TMR工作于定时器方式PSA=TMR不用分频TIF=清除TMR的中断标志TIE=TMR中断允许}******************************************************************************函数名:SPIINIT()**功能:spi显示初始化子程序******************************************************************************voidSPIINIT(){PIR=SSPCON=xSSPSTAT=xC设置SPI的控制方式允许SSP方式并且时钟下降沿发送。与"HC当其SCLK从低到高跳变时串行输入*TRISC=xDSDO引脚为输出SCK引脚为输出TRISA=RA引脚置为输出输出显示锁存信号}******************************************************************************函数名:initial()**功能:系统其它部分初始化子程序******************************************************************************voidinitial(){TRISB=TRISB=TRISB=TRISB=设置与键盘有关的各口的输入输出方式RB=RB=建立键盘扫描的初始条件}******************************************************************************函数名SPILED()**功能SPI传输数据子程序******************************************************************************voidSPILED(data){SSPBUF=data启动发送do{}while(SSPIF==)SSPIF=}******************************************************************************函数名:disply()**功能:显示子程序显示位数******************************************************************************voiddispaly(){RA=准备锁存for(k=k>k){data=skif(k==)data=tabledata第二位需要显示小数点elsedata=tabledataSPILED(data)发送显示段码}for(k=k<k){data=xFFSPILED(data)连续发送个DARK使显示美观}RA=最后给锁存信号代表显示任务完成}******************************************************************************函数名:DELAY()*功能:软件延时子程序******************************************************************************voidDELAY(){for(i=i)continue}******************************************************************************函数名:KEYSCAN()**功能:键扫描子程序******************************************************************************voidKEYSCAN(){while(){while(){dispaly()调用一次显示子程序if((RB==)||(RB==))break}DELAY()若有键按下则软件延时if((RB==)||(RB==))break若还有键按下则终止循环扫描返回}}******************************************************************************函数名:keyrelax()*功能:等键松开子程序******************************************************************************voidkeyrelax(){while(){dispaly()调用一次显示子程序if((RB==)(RB==))break}为防止按键过于灵敏每次等键松开才返回}******************************************************************************函数名:initial()**功能:系统赋值初始化子程序******************************************************************************voidinitial(){s=xs=ss=xs=ss=xs=ss=xs=ss=s=s=s=并放入显示缓冲数组中sreg=xtmr中断次数寄存器清}*****************************************************************************函数名:interruptclkint()**功能:处理定时器中断服务程序*****************************************************************************voidinterruptclkint(void){TMR=X对TMR写入一个调整值。因为写入TMR后接着的两个周期不能增量中断需要个周期的响应时间以及C语言自动进行现场保护要消耗周期TIF=清除中断标志CLRWDT()sreg=sreg中断计数器加if(sreg==)中断次数为后才对SSSS操作{sreg=s=sif(s==){s=s=sif(s==){s=s=sif(s==){s=s=sif(s==)s=}}}}s=ss=ss=ss=s}**************************************************************************函数名:main()*功能:主程序**************************************************************************main(){OPTION=XFFtmint()TMR初始化SPIINIT()SPI显示初始化initial()系统其它部分初始化di()总中断禁止while(){inizhi()系统赋值初始化KEYSCAN()键扫描直到开始键按下keyrelax()等键松开ei()总中断允许KEYSCAN()键扫描直到停止键按下在键扫描时有显示keyrelax()等键松开di()总中断禁止KEYSCAN()键扫描到清键按下在键扫描时有显示keyrelax()等键松开}}PIC单片机捕捉模块的应用()捕捉模块应用配置PIC单片机令其CCP模块工作在捕捉模式下检测测量对象为~Hz的TTL电平信号实现一个简易数字频率计的功能。程序代码如下:#include<pich>#include<stdioh>#include<mathh>不带小数点的显示段码表constchartable={xcxfxaxbxxxXDxxxFF}带小数点的显示段码表constchartable={XXXXXXXXXXxFF}定义一个数组用于存放各次的捕捉值bankintcpz定义一个共用体unioncp{intyunsignedcharcpe}cpuunsignedcharCOUNTWCOUNT测量脉冲个数寄存器unsignedcharCOUNTERdatakunsignedcharFLAGXEF#defineFLAGIT(adrbit)((unsigned)(adr)*(bit))绝对寻址位操作指令staticbitFLAGFLAGIT(FLAG)staticbitFLAGFLAGIT(FLAG)staticbitFLAGFLAGIT(FLAG)unsignedchars定义一个显示缓冲数组intTuodoubleREdoublepuad****************************************************************************函数名:SPIINIT()**功能:spi显示初始化子程序****************************************************************************voidSPIINIT(){PIR=SSPCON=xSSPSTAT=xC设置SPI的控制方式允许SSP方式并且时钟下降沿发送与"HC当其SCLk从低到高跳变时串行输入寄存器"的特点相对应TRISC=xDSDO引脚为输出SCK引脚为输出TRISA=RA引脚设置为输出以输出显示锁存信号FLAG=FLAG=FLAG=COUNTER=X}****************************************************************************函数名:ccpint()**功能:CCP模块工作于捕捉方式初始化子程序****************************************************************************voidccpint(){CCPCON=X首先设置CCP捕捉每个脉冲的上升沿TCON=X关闭TMR震荡器PEIE=外围中断允许(此时总中断关闭)CCPIE=允许CCP中断TRISC=设置RC为输入}****************************************************************************函数名:initial()**功能:系统其它部分初始化子程序****************************************************************************voidinitial(){COUNT=XB为保证测试精度测试个脉冲的参数后求平均值每个脉冲都要捕捉其上升、下降沿故需要有次中断TRISB=TRISB=TRISB=TRISB=设置与键盘有关的各口的输入、输出方式RB=RB=建立键盘扫描的初始条件}****************************************************************************函数名SPILED()**功能SPI传输数据子程序****************************************************************************voidSPILED(data){SSPBUF=data启动发送do{}while(SSPIF==)SSPIF=}*****************************************************************************函数名:disply()**功能:显示子程序显示位数****************************************************************************voiddisplay(){RA=准备锁存for(COUNTW=COUNTW<COUNTW){data=sCOUNTWdata=dataxFif(COUNTW==k)data=tabledata第二位需要显示小数点elsedata=tabledataSPILED(data)发送显示段码}for(COUNTW=COUNTW<COUNTW){data=xFFSPILED(data)连续发送个DARK使显示好看一些}RA=最后给一个锁存信号代表显示任务完成}****************************************************************************函数名:keyscan()**功能:键盘扫描子程序****************************************************************************voidkeyscan(){if((RB==)||(RB==))FLAG=若有键按下则建立标志FLAGelseFLAG=若无键按下则清除标志FLAG}****************************************************************************函数名:keyserve()**功能:键服务子程序****************************************************************************voidkeyserve(){PORTB=XFDif(RB==)data=Xif(RB==)data=XPORTB=XFBif(RB==)data=Xif(RB==)data=X以上确定是哪个键按下PORTB=X恢复PORTB的值if(data==x){COUNTER=COUNTER若按下S键则COUNTER加if(COUNTER>)COUNTER=x若COUNTER超过则又从计起}if(data==x){COUNTER=COUNTER若按下S键则COUNTER减if(COUNTER<)COUNTER=x若COUNTER小于则又循环从计起}if(data==x)FLAG=若按下S键则建立标志FLAGif(data==x)FLAG=若按下S键则清除标志FLAG}****************************************************************************函数名:interruptcpint()**功能:捕捉中断服务程序****************************************************************************voidinterruptcpint(void){CCPIF=清除中断标志cpucpe=CCPRLcpucpe=CCPRHcpzdata=cpuy存储次捕捉值CCPCON=CCPCON^X把CCP模块改变成捕捉相反的脉冲沿dataCOUNT}****************************************************************************函数名:PERIOD()**功能:周期处理子程序****************************************************************************voidPERIOD(){T=cpzcpz求得个周期的值RE=(double)T强制转换成双精度数RE=RE求得平均周期单位为μs}****************************************************************************函数名:FREQUENCY()**功能:频率处理子程序****************************************************************************voidFREQUENCY(){PERIOD()先求周期RE=RE周期值求倒数再乘以得频率单位为HZ}****************************************************************************函数名:PULSE()**功能:脉宽处理子程序****************************************************************************voidPULSE(){intpufor(data=puad=data<=data){pu=cpzdatacpzdatapuad=(double)pupuaddata=data}求得个脉宽的和值RE=puad求得平均脉宽}****************************************************************************函数名:OCCUPATIONAL()**功能:占空比处理子程序****************************************************************************voidOCCUPATIONAL(){PULSE()先求脉宽puad=RE暂存脉宽值PERIOD()再求周期RE=puadRE求得占空比}************************************************************************函数名:main()*功能:主程序************************************************************************main(){SPIINIT()SPI方式显示初始化while(){ccpint()CCP模块工作于捕捉方式初始化initial()系统其它部分初始化if(FLAG==){s=COUNTER第一个存储COUNTER的值s=XAs=XAs=XA后面的LED将显示"DARK"}display()调用显示子程序keyscan()键盘扫描data=x存储数组指针赋初值TMRH=TMRL=定时器清CCPIF=清除CCP的中断标志以免中断一打开就进入中断ei()中断允许TMRON=定时器开while(){if(COUNT==)break}等待中断次数结束di()禁止中断TMRON=关闭定时器keyscan()键盘扫描if(FLAG==)keyserve()若确实有键按下则调用键服务程序if(FLAG==)continue如果没有按下确定键则终止此次循环继续进行测量如果按下了确定键则进行下面的数值转换和显示工作if(COUNTER==x)FREQUENCY()COUNTER=则需要进行频率处理if(COUNTER==x)PERIOD()COUNTER=则需要进行周期处理if(COUNTER==x)OCCUPATIONAL()COUNTER=则需要进行占空比处理if(COUNTER==x)PULSE()COUNTER=则需要进行脉宽处理k=if(RE<){RE=RE*若RE<则乘以保证小数点的精度k=x}elseif(RE<){RE=RE*若RE<则乘以保证小数点的精度k=x}elseif(RE<){RE=RE*若RE<则乘以保证小数点的精度k=x}elseif(RE<){RE=RE*若RE<则乘以保证小数点的精度k=x}elseRE=REuo=(int)REsprintf(s"d"uo)把需要显示的数据转换成位ASII码且放入数组S中display()}}()PWM工作方式应用程序#include<pich>*****************************************************************************函数名:CCPINIT()**功能:CCP模块设置为PWM工作方式初始化子程序*****************************************************************************voidCCPINIT(){CCPRL=XFCCPCON=XC*设置CCP模块为PWM工作方式且其工作循环的低位为高位为=F*INTCON=X*禁止总中断和外围中断*PR=XFF*设置PWM的工作周期*TRISC=XFB*设置CCP引脚为输出方式*}************************************************************************函数名:main()*功能:主程序************************************************************************main(){CCPINIT()*CCP模块的PWM工作方式初始化*TCON=X*打开TMR且使其前分频为*同时开始输出PWM波形*do{}while()*系统开始输出PWM波形。如果系统是多任务的则可以在此执行其它任务*而不会影响PWM波形的产生*}PIC单片机模数转换器ADC模块的应用配置PIC单片机的ADC模块寄存器检测模拟量电压然后通过个LED把检测的结果输出当检测到的值达到或超过警戒值的话发出报警信号。程序代码如下:#include<pich>定义一个共用体用于存放AD转换的结果unionadres{intyunsignedcharadre}adresultunsignedchariunsignedintj****************************************************************************函数名:initial()**功能:系统各IO口初始化子程序****************************************************************************voidinitial(){TRISD=XD口为输出i=x}*****************************************************************************函数名:adinitial()**功能:AD转化初始化子程序*****************************************************************************voidadinitial(){ADCON=x选择AD通道为RA打开AD转换器在工作状态且使AD转换时钟为toscADCON=X转换结果右移及ADRESH寄存器的高位为""且把RA口设置为模拟量输入方式PIE=XPIE=XADIE=AD转换中断允许PEIE=外围中断允许TRISA=设置RA为输入方式}************************************************************************函数名:delay()*功能:延时子程序************************************************************************voiddelay(){for(j=j)continue}************************************************************************函数名:alarm()*功能:报警子程序************************************************************************voidalarm(){i=i^xFF通过异或方式每次把i的各位值取反PORTD=iD口输出i的值}************************************************************************函数名:interruptadint()*功能:AD处理中断服务子程序************************************************************************voidinterruptadint(void){ADIF=清除中断标志adresultadre=ADRESLadresultadre=ADRESH读取并存储AD转换结果AD转换的结果通过共用体的形式放入了变量y中if(adresulty>x){alarm()如果输入的模拟量大于V(对应数字量Xh)则调用报警子程序delay()调用延时子程序使电压检测不要过于频繁}elsePORTD=XF如果输入的模拟量小于V则与D口相连的个发光二极管的低个发亮表示系统正常ADGO=启动下一次AD转换}************************************************************************函数名:main()*功能:主程序************************************************************************main(){adinitial()AD转换初始化initial()系统各IO口初始化ei()总中断允许ADGO=启动AD转换while(){}等待中断在中断中循环检测外部电压}PIC单片机看门狗模块首先设置ICDOption中的WatchdogTimer为OnEnable然后分别改变分频比为、、、、、、和运行程序并记录PORTA<>引脚的高低电平宽度和RSTREC寄存器值。然后删除例程中CLRWDT指令重复前一步操作。最后比较前两种情况下对应于不同分频比条件的高低电平宽度是否一致及RSTREC值的变化情况。程序代码如下:LISTP=FINCLUDE“PFINC”RSTRECEQUxORGxMAINBSFSTATUSRP选存储体BCFSTATUS,RPMOVLWx将预分频器分配给TMR,分频比:MOVWFOPTIONREGMOVLWxfc置PORTC<:>输出MOVWFTRISCBCFINTCON,GIE禁止中断BCFSTATUS,RP选存储体INCFRSTREC,FBTFSSRSTREC,PORTC<>端口电平取反BCFPORTCLOOPCLRWDTBSFPORTC,置端口高电平WAITBTFSSTMRGOTOWAITBCFPORTC,置端口低电平WAITBTFSSINTCON,TOIF等待TMR中断GOTOWAITBCFINTCON,TIFGOTOLOOPENDPIC单片机中断模块()定时器溢出中断模块应用程序LISTP=FINCLUDE“PFINC”INTCNTEQUxTCNT一EQU一x,ORGxGOTOMAIN中断服务程序ORG,xINTSERBCFINTCON,GIE禁止中断BTFSCINTCON,TGIFGOTOTOINT定时器中断BTFSCINTCON,INTFGOTOQUITINTEXINTINCFINTCNT外部中断BTFSSINTCNTBCFPORTC,偶数次中断置低电平BTFSCINTCNTBSFPORTC,奇数次中断置高电平BCFINTCON,INTF清中断标志GOTOQUITINTTOINTINCFTOINT定时器中断BTFSSTOINT,BCFPORTC,偶数次一中断置低电平BTFSCTOINT,BSFPORTC,奇数次中断置高电平BCFINTCON,TGIF清定时器中断标志OUITINTBSFINTCON,GIERETFIEORGx主程序MAINBCFSTATUS,RPBCFSTATUS,RPCLRFINTCNT清外部中断次数记数器CLRFTOINT清定时器中断次数计数器BSFSTATUS,RPMOVLWXfc置PORTA<:>为输出MOVWFTRISAMOVLWB''初始化定时器MOVWFOPTIONRECBCFSTATUS,RPGOTO$等待中断中断响应后返回此处END()端口RB中断应用程序intconequbh定义终端控制寄存器地址portcequh定义端口RC的数据寄存器地址triscequh定义端口RC的方向控制寄存器地址portbequh定义端口RB的数据寄存器地址trisbequh定义端口RB的方向控制寄存器地址cequ定义进位标志位的位地址zequ定义标志位的位地址wequ定义传送目标寄存器为W的指示位fequ定义传送目标寄存器为RAM的指示位tifequ定义TMR中断标志位的位地址tieequ定义TMR中断使能位的位地址inteequ定义外部中断使能位的位地址intfequ定义外部中断标志位的位地址rbifequ定义RB口变化中断标志位的位地址countequh定义一个计数器变量countequh定义一个计数器变甘countequh定义一个计数器变量countequh定义一个计数器变量countequh定义一个计数器变量portbbequh为PORTC定义一个备份寄存器wtempequfh为W在体和体定义两个备份寄存器wtempequffh(若是F则需保留FFH单元)statustempequh为STATUS定义一个备份寄存器rpequh定义状态寄存器中的页选位RP******************复位向量和中断向量*************************orgh定义程序存放区域的起始地址nop设置一条ICD必需的空操作指令gotomain跳转到一主程序orgh定义中断向量gotoserv跳转到中断服务子程序*********************主程序*****************************main主程序入口地址标号bsfstatus,rp设置文件寄存器的体movlw将端口RC的方向控制码H先送Wmovwftrisc再转到方向寄存器RC全部设为输出movlwffh设置端口RB的方向码FFH先送Wmovwftrisb再转到方间寄存器,RB全部设为输入movlwh没置选项寄存器:上拉电阻启用INT下降沿触发movwfoptionreg分频器给TMR:分频比值设为l:bcfstatus,rp恢复至文件寄存器的体movlwh开放INT中断和RB变化中断movwfintcon开放全局中断使能位clrfportcRC端口LED全熄灭movfportb,f通过读操作锁定此时RB端口电平作为基准电平befintcon,rbif清除RB端口电平变化中断标志位loopsleep进人睡眠节电模式nop空操作gotoloop跳回******************关中断服务子程序*****************************serv中断服务子程序名称即入口地址一一一一--一--一一保护现场部分一一-一一一一一一--一一一-一一--一一一一一movwfwtemp保护Wswapfstatus,w保护STATUSclrfstatus选择体movwfstatustemp将STATUS存入体的备份寄存器*****************调查中断源**********************************btfscintcon,intf检查不是INT中断跳一步gotointserv是跳转到INT中断处理部分btfscintcon,rbif检查不是RR端口中断跳一步gotorbserv是跳转到RB中断处理部分gotorettie其他情况均中断返回********************INT中断处理部分**************************intserv外部中断处理程序片段入口clrfportc令全部LED熄灭bsfports,点亮第只LED,表示就绪calltone调用高音子程序calldelay一调用s延时子程序calltone调用低音子程序bcfintcon,iritf清除INT中断标志位gotoretfie中断返回***********************RI中断处理部分**************************rbserv端口RB中断处理程序片段入口calldelaylms防抖动延时comfportb,w读取PORTB并取反movwfportbb保留到备份寄存器swapfportbb,w收到的RB值高低半字节颠倒存入Wandlwfh屏蔽掉W内容的高位movwfportc经过端口RC送显calltonet调用发声次子程序rbloopcomfportb,w将PORTB取反存入W并终结失配条件bcfintcon,rbif清除RB中断标志位andlwb''检测W内容的高位是否全为btfscstatus,z不全为,跳一步gotoretfie全为中断返回gotorbloop循环检测**********************恢复现场部分*******************************Retfieswapfstatusterilp,w恢复STATUSmovwfstatusswapfwtemp,f恢复Wswapfwtempwretfie中断返回**************低音调发生子程序(Hzms)*****************tone子程序名也是子程序入口地址movlw,循环次数计数器赋予初值movwfcounttlopbctintcon,tif清除TMR溢出中断标志位movlwl给TMR装入初始值=movwftmr启动定时器therebtfssintcon,tif定时器溢出否gotothere否!循环检测movlwb''只将BIT置位xorwfportc,f只将RC脚电平反转其余不变decfszcountf循环次数递减为跳一步gototlop不为,跳回return返回主程序************高音调发生子程序(Hzms)****************tone子程序名也是子程序人口地址movlw.循环次数计数器赋予初值movwlcountl=Hz*sXtlopbcfintcon,tif清除TMRO溢出中断标志位movlw.给TMR装人初始值=movwftmr启动定时器therebtfssintcon,tif定时器溢出否gotothere否!循环检测movlwb'只将BIT置位xorwfportc,f只将RC脚电平反转其余不变decfszcountl,f循环次数递减为跳一步gototop不为跳回return返回主程序**********************发声s子程序***********************tonelsmovlw.循环次数计数器赋予初值movwfcounttllopcalltone调用低音子程序calltone调用高音子程序decfszcount,f循环次数递减为跳一步gototllop不为,跳回return返回主程序*************关TMR延时子程序********************delay子程序名也是子程序人口地址bsfstatus,rp设置文件寄存器的体movfoptionreg,w保护选项寄存器内容movwfoptiontempmovlwh重设选项寄存器:上拉电阻启用INT下降沿触发movwfoptionreg分频器给TMRO分频比值设为:bcfstatus,rp恢复到文件寄存器的体movlw.利用TMRO定时次movwfcount出次数计数器dopbcfintcon,tifTMRO溢出中断标志位bcfintcon,tOie除TMR溢出中断使能位movlw.TMR装人初值=movwftmr动定时器herebtfssintcon,tf询法检测TMR溢出否gotohere回decfszcount,f是出次数减为则跳一步gotodllop环利用TMRbsfstatus,rp设置文件寄存器的体movfoptiontemp,w恢复选项寄存器内容movwfoptionregbcfstatus,rp恢复到文件寄存器的体return回主程序******************断续发声次报警子程序*************************tone,t序名也是子程序人口地址movlw.循环次数计数器赋予初值movwfcounttlopcalltonels声s子程序calldelay时s子程序decfszcount,f次数递减为跳一步gototlop不为跳回return返回主程序****************关软件延时子程序ms*************************Delaylms子程序名也是子程序入口地址movlw.将外层循环参数值nl经过Wmovwfh送入用作外循环变量的h单元lPmovlwffh将内层循环参数值n经过movwfh送人用作内循环变量的h单元lpdecfszh,变量h内容递减若为跳跃gotolpl跳转到lP处decfszh,变量h内容递减若为跳跃gotolp跳转到lp处return返回主程序end源程序结束()INT中断程序应用optionregequh定义选项寄存器地址intconequbh定义中断控制寄存器地址portcequh定义端口RC的数据寄存器地址triscequh定义端口RC的方向控制寄存器地址portbequh定义端口RB的数据寄存器地址trisbequh定义端口RB的方向控制寄存器地cequ定义标志位的位地址wequ定义传送目标寄存器为W的指示位fequ定义传送目标寄存器为RAM的指示位tifequ定义TMR中断标志位的位地址tequ定义TMR中断使能位的位地址inteequ定义外部中断使能位的位地址intfequ定义外部中断标志位的位地址countequh定义一个定时器溢出次数计数器变量countequh定义一个查表偏移量位计数器变量portcbequh为PORTC定义一个备份寄存器wtempequffh(若是F则需保留FFH单元)statustempequh为STATUS定义一个备份寄存器rpequh定义状态寄存器中的页选择位RP*****************复位向量和中断向量***************************orgh定义程序存放区域的起始地址nop设置一条ICD必需的空操作指令gotomain跳转到主程序orgh定义中断向量gotoserv跳转到中断服务子程序***********************主程序**************************main主程序入口地址标号bsfstatus,rp设置文件寄存器的体movlwh将端口RC的方向控制码h先送Wmovwftrisc再转到方向寄存器RC全部设为输出movlwffh设置端口RB的方向码FFH先送Wmovwftrisb再转到方向寄存器RB全部设为输入movlwh设置选项寄存器:INT下降沿出发分频器给TMRmovwfoptionreg分频比值设为:bcfstatus,rp恢复到文件寄存器的体movlwhmovwfintcon开放INT和全局中断使能位clrfcountl清查表偏移量寄存器loopmovfcountl,w将偏移量复制到Wcallconvert调用查表子程序movwfportc将查得的显示码送显incfcountl,f偏移量递增movlwh只保留偏移量低位andwfcountl,fcalldelayl调用延时子程序clrfcount清除定时器溢出次数计数器bsfintcon,rote开放INT中断使能住gotoloop跳回继续移动LED中断服务子程序serv中断服务子程序名称保护现场部分movwfwtemp保护Wswapfstatus,w保护STATUSclrfstatus选择体movwfstatustemp将STATUS保存到备份寄存器movfportc,w保护中断时LED的状态movwfportcb到备份寄存器INT中断处理部分intserv外部中断服务程序名称clrfportc令全部LED熄灭comfportc,f驱动光藕合点亮只LEDlopmovlwfehxorwfportc,f反转只LED维持光耦的驱动calldelay调用延时子程序clrfcount清除定时器溢出次数计数器btfscportb,检测电源恢复正常否gotolop已正常!中断返回gotolop否!让LED继续一起闪烁loplbcfintcon,intf清除INT中断标志位gotoretfie中断返回恢复现场部分retfiemovfportcb,w恢复LED的状态movwfportc到端口RCswapfstatustemp,w恢复STATUSmovwfstatusswapfwtemp,f恢复Wswapfwtemp,wretfie中断返回延时子程序delayl子程序名也是子程序人口地址dllopbcfintcon,tif清除TAR溢出中断标志位movlwh给TAR装人初始值rnovwftmr启动定时器herebtfssintcon,tif循环查询检测TAR溢出否gotohere否!返回incfcount,f是!溢出次数计数器加btfsscount,定时器溢出够次否gotodlop否!循环利用TARreturn返回主程序延时子程序delay子程序名也是子程序入口地址bcfintcon,tif清除TMR溢出中断标志位movlwh给TAR装入初始值movwftmr启动定时器dlopbtfssintcon,tif循环查询定时器溢出否gotodlop否!循环检测return返回主程序显示码查表子程序convert查表转换子程序addwfpcl,f偏移量与PC相加tableretlwb''显示码下同retlwb''retlwb''retlwb''end程序结

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

评分:

/27

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利