《PIC16系列单片机C程序设计与proteus仿真》学习之一----RB0/INT中断编程//用RB0/INT按键,每按一下,LED翻转亮,晶振4MHZ#includepic.h//#includepic16f8xx.h__CONFIG(0x3f71);//配置为设定:XT,WDT,off等#defineLEDRB1//所有有LED字符的地址实际上是RB1charA;//全局变量,保存LED的状态voidDELAY(unsignedint);voidinterruptISR(void);voidmain(){OPTION=0b00000000;//B口弱上拉,RB0为下降沿触发中断TRISB=0b00000001;//设定RB0为输入,RB1为输出(置1为输入,置0为输出)INTCON=0B10010000;//允许RB/INT中断LED=1;//RB1=1,先让LED灯亮A=1;while(1);//原地等待中断}//-------delaynmsvoidDELAY(unsignedintn){unsignedintj;chark;for(j=0;jn;j++)for(k=246;k0;k--)NOP();}//----interruptisrvoidinterruptISR(void){if(INTF==1)//如果是INT中断才执行以下程序{DELAY(30);//先延时消抖INTF=0;//消抖后才将INT中断标志清零if(A==1){A=0;LED=0;}else{A=1;LED=1;}}}-------------------------------------------------PROTEUS如下:PS:详情请参考《PIC系列单片机设计与PROTEUS仿真》一书P114/**用TMR0延时中断,产生脉冲**//**设定时器TMR0延时10MS,8位pic单片机晶振4MHZ,则指令周期Tcy=1us,计算如下:1.设预分频比为K,则256*K*Tcy=10_000us,得K=39.06,要取大于此值的最小分频比,即K=642.计算延时常数X,(256-X)*64*Tcy=10_000us,得X=99.75,四舍五入取整,得X=100.*/#includepic.h__CONFIG(0x3f71);#defineLEDRB0#defineT0_10MS100//定义TMR0延时10MS的时间常数charA;voidinterruptISR(void);voidmain(void){RISB0=0;//设定RB0位输出,其余B口未设置,采用上电默认值,为输入OPTION=0b10000101;//RBPU=1:B口上拉使能,INTEDG=0:下降沿触发,T0CS=0:对内部指令周期计数,T0SE=0:RA4/T0CKI的上升沿计数,PSA=0:预分频分配位给TMRO,PS2PS1PS0=101:TMR0比率为1:64INTCON=0b10100000;//GIE=1:允许全局中断使能,PEIE=0:禁止外设中断使能,T0IE/TMR0IE=1:允许TMR0溢出中断使能,INTE=0:禁止INT引脚中断使能//RBIE=0:禁止RB口高4位电平变化使能,T0IF/TMR0IF=0:TMR0溢出中断标志位--未溢出//INTF=0:未发生INT中断,RBIF=0:RB7:RB4引脚的逻辑状态未发生变化TMR0=T0_10MS;//TMR0赋初值LED=1;A=1;while(1);//原地等待}voidinterruptISR(void){if(T0IF==1){T0IF=0;TMR0=T0_10MS;//TMR0赋初值,必须if(A==1){A=0;LED=0;}else{A=1;LED=1;}}}proteus如下:(已修改)第一步:初步画好仿真图,设置好PIC参数(晶振,配置位)并运行,如下:第二步:设置ANALOGUEANALYSIS(我们主要看RB0的模拟电压情况),设置方法如下:1.右击---EditGraph---起始时间50m,终止时间150m---OK2.右击---AddTraces---Name为RB0,ProbeP1为RB0---OK3.右击---EditGraph---SetY-scales---若此时显示为灰色不可输入状态,那就点确定,会弹出一个窗口“Resimulate?”,点击确定,方波图就出来了,不过默认是0~5V,你现在就可以重新修改Y-scales,如下图:先打勾“Lockvalues”,在设置Min-1,Max6----Ok----又会弹出“resimulate?”,确定即可。最后效果图为:示波器图为:若示波器不小心X掉了,可以在运行的状态下(不运行不会出现该选项)通过菜单Debug---3.DigitalOscilloscope来调出来ps:详情请参见书P117。如有疑惑,可以互相讨论,共同进步!//用TMR0对外部计数作为按键,每按一下,LED闪亮//为了让RA4按键产生中断,则设置TMR0为外部计数,下降沿计数,预分频比为1:1,并将初值设置为0xFF,//这样只要一有按键,就产生中断,进入中断后,必须把TMR0重新赋值0xFF,这样下次一按键才能进入中断。//RA4引脚的接一上拉电阻是必须的#includepic.h#includeDELAY.h//把DELAY函数放在头文件中。__CONFIG(0x3f71);//配置为设定:XT,WDT,off等#defineLEDRB1charA;//全局变量,保存LED状态voidinterruptISR(void);voidDELAY(unsignedint);voidmain(void){TRISB1=0;//设RB1为输出,其余B口未设置,采用上电默认值,均为输入OPTION=0B00111000;//TMR0对外部脉冲计数,下降沿计数,预分频给WDT,则TMR0分频比为1:1INTCON=0B10100000;//允许TMR0溢出中断TMR0=0xFF;//TMR0赋初值LED=1;A=1;while(1);//原地等待}voidinterruptISR(void){if(T0IF==1){DELAY(30);//防抖,延时30MST0IF=0;TMR0=0xFF;//TMR0赋初值,必须!!!if(A==1){A=0;LED=0;}else{A=1;LED=1;}}}DELAY.h头文件中的内容:voidDELAY(unsignedintn){unsignedintj;chark;for(j=0;jn;j++)for(k=246;k0;k--)NOP();}PROTUES如下:若当按下按键后,LED灭,此时示波器波形为:可以看出每一格代表20MS,未按键时,RA4(蓝线)处于高电平,TMR0=0xFF,按下S1后,RA4从高变低,TMR0计数值加1,马上溢出进入中断,延时120ms(书上说是30ms,我想是执行了赋初值语句、IF语句等需要耗费一定时间)后让RB1(黄线)电平翻转。/**用TMR1延时中断,通过RB0输出脉冲,每隔100MS让LED闪亮,采用中断方式**//*若定时器TMR1延时100MS,8位pic单片机晶振4MHZ,则指令周期Tcy=1us,计算如下:1.设预分频比为K,则65536*K*Tcy=100_000us,得K=1.52,要取大于此值的最小分频比,即K=22.计算延时常数X,(65536-X)*2*Tcy=100_000us,四舍五入取整,得X=15536.*/#includepic.h__CONFIG(0x3F71);#defineT1_100MS15536#defineLEDRB0charA;voidinterruptISR(void);voidmain(void){TRISB0=0;TMR1H=T1_100MS8;//取延时常数的高字节TMR1L=T1_100MS;//取延时常数的低字节TMR1IE=1;//TMR1终端使能INTCON=0b11000000;//GIE、PEIE置1才能进入TMR1中断T1CON=0b00010001;//TMR1预分频系数为1:2,内部延时,开始工作A=1;LED=1;while(1);}voidinterruptISR(void){if(TMR1IF==1){TMR1IF=0;TMR1H=T1_100MS8;//延时常数重新赋值TMR1L=T1_100MS;//整型数赋给字符型变量,只赋整型的低字节if(A==1){A=0;LED=0;}else{A=1;LED=1;}}}ROTUES如下图:示波器波形:照理说,应该脉冲周期是200ms,可为什么示波器显示的不对呢???有空好好研究下PS:见书P121-P123TMR1可以外接低频振荡器,当TMR1的振荡器使能时(T1OSCEN位置1),T1OSI和T1OSO引脚自动被设定为输入,此时其相应的TRIS值被忽略。外接低频振荡器通常选用32.768kHz作为时钟源,这是作为时钟用的特殊频率,在1S时间内,此振荡器的输出脉冲数位32768=0x8000,即把TMR1初值设置为0x8000,溢出时间就是1s,初值设置为0就是2s//利用TMR2的前后分频和PR2设定,延时10MS.通过RB0输出脉冲,每隔10ms让LED闪亮,采用中断方式/*如果只用到预分频,则TMR2的最大延时时间为256*16*Tcy=4096Tcy,4MHz晶振时为1096us,无法满足延时10ms的要求,因此要用到后分频,令预分频系数为16,后分频系数为K2,则有256*16*Tcy*K2=10_000us,Tcy=1,得K2=2.44,取K=3,即三次溢出中断一次,再求PR2的值:(PR2+1)*16*Tcy*K2=10_000us,得PR2=207.33,取207计算结果为:TMR2的预分频系数为1:16,后分频系数为1:3,PR2的值为207.即每16个指令周期TMR2加1,当TMR2从0增加到207后再加1时溢出,TMR2变为0。但前两次TMR2溢出时其中断标志位TMR2IF并不置1,只有溢出3次后TMR2IF才置1,如果允许TMR2中断则溢出3次后进入中断。*/#includepic.h__CONFIG(0x3F71);#defineLEDRB0charA;voidinterruptISR(void);voidmain(void){TRISB0=0;//RB0为输出口TMR2IE=1;//TMR2中断使能INTCON=0B11000000;//GIE,PEIE置1才能进入TMR2中断T2CON=0b00010111;//TMR2预分频系数为1:16,后分频系数为1:3,开始工作A=1;LED=1;PR2=207;//TMR2的溢出值,当TMR2为此值+1时溢出while(1);}voidinterruptISR(void){if(TMR2IF==1){TMR2IF=0;if(A==1){A=0;LED=0;}else{A=1;LED=1;}}}proteus如下图:ps:见书p126。1学习之6---看门狗定时器(WDT)//PIC.H中定义了宏#defineCLRWDT()asm(clrwdt)因此在PICC的c语言中可以直接使用CLRWDT()对WDT清0//若单片机WDT使能,在适当位置加入CLRWDT(),程序进入正常运行时,每隔一定时间均会执行CLRWDT()语句对WDT清0,芯片不会复位//如果程序陷入死循环,不会执行到CLRWDT()语句,则超出所设定的时间后,WDT溢出使芯片复位,从头(000H)开始执行,单片机恢复正常运行//PIC16F单片机,看门狗定时器的启用只能在芯片的烧写时确定,即无法用软件来开启或关闭WDT,但在PIC16f88X中可以。//PIC16单片机的WDT基本溢出时间为18MS,由RC充放电时间确定,在-40~85度之间变化时,W