第二章系统控制与中断+老师复习时专讲的中断内容1、【强记】void InitSysCtrl( )void InitSysCtrl(){ EALLOW;WDCR=0x0068; //屏蔽WatchDogPLLCR=0xA; //锁相环设为10/2=5倍频(使系统时钟30MHz*5=150MHz)//PLLCR可设0x0~0xA,其中0x0和0x1等效,均为1/2=0.5倍频for(i= 0; i< ( (131072/2)/12 ); i++) {;}HISPCP=1; // HISPCLK=SYSCLK/HISPCP*2,从而有75MHzLOSPCP=2; // LOSPCLK=SYSCLK/LOSPCP*2,从而有37.5MHzPCLKCR=0x0D0B; //写1开启部分外设,这里开启了SCIA/B,SPI,ADC,EV A/B//0000 1101 0000 1011EDIS;}2、解释WatchDog(看门狗)工作原理(记住位域名称与功能)片内振荡器时钟OSCCLK经过分频后进入8位看门狗计数器,当计数器上溢,则可输出中断或复位信号。
当看门狗使能,若系统正常运行,则需用户周期性地在看门狗计数器上溢前向复位寄存器WDKEY写入0x55+0xAA来清零计数器,若程序受干扰而跑飞,则看门狗的中断或复位信号可使系统恢复至正常状态,提高系统稳定性与可靠性。
补充——涉及寄存器:系统控制和状态寄存器SCSR:WDENINT指定看门狗输出复位信号还是中断信号;WDOVERRIDE指定是否允许用户修改控制寄存器WDCR的WDDIS位;计数寄存器WDCNTR:低8位连续加计数,可由复位寄存器WDKEY立即清零;复位寄存器WDKEY:连续写入0x55+0xAA可清零计数寄存器WDCNTR,写入其它序列则立即触发看门狗复位事件。
读该寄存器返回控制寄存器WDCR值;控制寄存器WDCR:WDFLAG为看门狗复位状态标志位,若复位事件由看门狗触发则置1,用户写1清零;WDDIS写1使能,写0屏蔽看门狗;WDCHK必须写101才能写WDCR 寄存器;WDPS为看门狗计数器时钟相对于OSCCLK/512的分频系数。
3、解释PLL(锁相环)工作原理PLL负责把片内振荡器时钟或外部时钟经过倍频转化为系统时钟SYSCLKOUT。
当引脚XF_XPLLDIS为低电平:PLL被禁止,系统时钟直接引用外部时钟源。
当引脚XF_XPLLDIS为高电平:若PLLCR为0,则PLL被旁路,片内振荡器时钟OSCCLK被二分频;若PLLCR为n(n=0x1~0xA),则PLL使能,OSCCLK被(n/2)倍频。
4、【强记】为了使CPU定时器工作在指定频率,应如何设置void InitSysCtrl();void InitCputimer(void) //定时器初始化,中断周期为1ms(1kHz){ EALLOW;TIMER0TPR=149;//CPU定时器分频寄存器,150MHz/(149+1)=1MHz的计时器时钟TIMER0TPRH=0;//CPU定时器分频寄存器的高位置0TIMER0PRD=(long)999;//设置CPU定时器周期寄存器,1MHz/(999+1)=1kHzTIMER0TCR=0xF000;//CPU定时器0的启动与清除中断标志都是这句。
EDIS;}5、解释CPU定时器工作原理系统时钟进入CPU定时器后,16位预定标计数器PSCH:PSC会连续减计数,当经过(TDDRH:TDDR+1)个SYSCLKOUT周期后下溢,预定标计数器重装TDDRH:TDDR值,并使计数寄存器TIMH:TIM减1。
当计数寄存器TIMH:TIM下溢,则重装PRDH:PRD值,并输出定时器中断信号。
补充——涉及寄存器:TPRH:TPR:高8位组合成共16位的PSCH:PSC,为预定标计数器;低8位组合成共16位的TDDRH:TDDR,为分频寄存器,储存预定标计数器的周期;TIMH:TIM:计数寄存器,下溢时输出中断信号;PRDH:PRD:周期寄存器,储存计数寄存器的周期;TCR:控制寄存器,含中断标志位、中断使能位、定时器重载控制位、定时器使能/停止位。
启动与清除中断标志都是这句:TIMER0TCR=0xF000;6、PIE工作原理PIE共有12组(m=1~12),每组控制8个中断(n=1~8),因此共控制96个外设中断。
要使外设的中断请求INTm.n被送入CPU,必先清零PIE标志位PIEIFRm(全部n=1~8都需清零),置一PIE使能位PIEIFRm.n,再向应答标志位PIEACKm写1清零。
当外设中断请求到来,相应PIE标志位和应答标志位都会置1。
当CPU转向中断服务函数,会自动清除PIE标志位PIEm.n,但还需用户软件向PIE应答标志位PIEACKm写1清零,并清零外设中断标志位。
7、CPU级中断寄存器的原理CPU级中断INTm共有14个(m=1~14),其中前12个被PIE复用。
要使中断请求INTm 被送入CPU,必先清零标志位IFR,置一使能位IFR,并使能全局中断控制位INTM(使能调用语句:asm(“EINT”);屏蔽调用语句:asm(“DINT”);)。
当中断请求到来,相应标志位IFR置一。
当CPU转向中断服务函数,会自动清除标志位IFR。
8、中断向量表工作原理当中断请求到达CPU后,CPU会保存现场,并自动清除相应的CPU中断标志位和PIE 中断标志位,再根据中断的来源按照优先级读取中断向量表的相应地址中存放的中断服务函数ISR地址,并跳转至该ISR。
ISR执行完毕后,CPU回到原现场继续执行。
对于中断向量INT_m_n(m=1~12,n=1~8),中断向量地址计算:PIE_VECT_m_n=0x0D40+2*[8*(m-1)+(n-1)](0x0D40为INT1.1即第一组第一个中断向量的地址,每个地址长度为0x0002,以此类推,INT1.2地址为0x0D42,INT1.3地址为0x0D44……)补充——老师考以下中断编程,其中断向量地址如下(但老师可能故意考上面的公式):CPU定时器0的中断:(INT_1_7) TINT0:0x0D4CEV A的通用定时器1、2的周期中断:(INT_2_4) T1PINT:0x0D56 (INT_3_1) T2PINT:0x0D60EVB的通用定时器3、4的周期中断:(INT_4_4) T3PINT:0x0D76 (INT_5_1) T4PINT:0x0D809、中断向量表的赋值写代码时严格执行这三句话:(在所有函数外)typedef interrupt void(*PINT) (void);(在所有函数外)interrupt void INT_m_n(void);(在main函数内)(*(PINT*)PIE_VECT_m_n) = & INT_m_n;其它赋值方式(写代码时不用):(在所有函数外)interrupt void INT_m_n(void);(在main函数内)InitPIE;(在main函数内)PieVectTable.TINT0=& INT_m_n;10、【强记】CPU定时器0中断程序,并使能PIE级与CPU级中断void InitSysCtrl(void){ EALLOW;WDCR=0x0068;PLLCR=0xA;//锁相环设为10/2=5倍频(使系统时钟30MHz*5=150MHz)for(i= 0; i< ( (131072/2)/12 ); i++) {;}HISPCP=1;LOSPCP=2;EDIS;}void InitCputimer0(void){ EALLOW;TIMER0TPR=149;//产生150MHz/(149+1)=1MHz的计时器时钟TIMER0TPRH=0;//CPU定时器0预定标计数器的高位部分(置0)TIMER0PRD=(long)999;//设置CPU定时器0中断周期,即1MHz/1000=1kHz TIMER0TCR=0xF000;EDIS;}void InitGpioF(void){ ……}typedef interrupt void(*PINT)(void);interrupt void INT_1_7(void);//CPU定时器0void main(void){ InitSysCtrl();InitCputimer0();//CPU定时器0初始化,它确定了中断周期为1ms(1kHz)InitGpioF();//GPIOF初始化EALLOW;PIEIFR1=0x0000;PIEIER1=0x0040;PIECTRL=0x1; //使能PIEPIEACK =0x1;(* (PINT *) 0x0D4C) = & INT_1_7;asm(" and IFR,#00H");asm(" or IER,#01H");asm(" EINT");LPMCR0=0x0; //设置低功耗模式为idle模式EDIS;for(;;){asm(" IDLE");};}interrupt void INT_1_7(void){ ……PIEACK=0x1;TIMER0TCR=0xF000;}11、【强记】T1定时器的中断程序(以T1PINT中断为例),并使能PIE级与CPU级中断void InitSysCtrl(void){ EALLOW;WDCR=0x0068;PLLCR=0xA;//锁相环设为10/2=5倍频(使系统时钟30MHz*5=150MHz)for(i= 0; i< ( (131072/2)/12 ); i++) {;}HISPCP=1;LOSPCP=2;EDIS;}void InitEV(void)//初始化EV{ EALLOW;T1CON=0x1748;//T1连续增,时钟HSPCLK被128分频,使能T1,使用内部时钟源,禁止比较操作/*如此,TICON=0001 0 111 01 00 1000,具体为:TMODE1-TMODE0=10,使T1为连续增计数模式;TPS2-TPS0=111,使外设高速时钟HSPCLK被128分频(2^7=128),使T1计时时钟频率为HSPCLK/128;TENABLE=1,使能本定时器T1;TCLKS1-TCLKS0=00,T1时钟源设为内部时钟,即HSPCLK(另外,上已设定它要被128分频才用作T1时钟);TECMPR=0,禁止本定时器的比较操作;*/T1PR=586;//T1的周期寄存器赋值586EV AIMRA=0x0080; //使能T1PINT/*如此,EVAIMRA=0000 0000 1000 0000,从而使能T1PINT*/EV AIFRA=0xFFFF;//EV A中各中断标志写1清0EDIS;}void InitIO(void){ ……}typedef interrupt void(*PINT)(void);interrupt void eva_T1PINT_isr(void);//声明了通用定时器1的周期匹配中断void main(void){ InitSysCtrl();InitIO();//初始化引脚InitEV();//初始化EVEALLOW;PIEIFR1=0x0000;PIEIER1=0x0040;PIECTRL=0x1; //使能PIEPIEACK =0x2;(* (PINT *) 0x0D56)= & INT_2_4;asm(" and IFR,#00H");asm(" or IER,#02H");//使能CPU级第2组中断通道asm(" EINT");LPMCR0=0;//低功耗模式为idleEDIS;for(;;){ asm(" IDLE");}}interrupt void eva_T1PINT_isr(void)//T1周期中断服务函数{ ……EV AIFRA=0xFFFF; //EV A中相应中断标志清零PIEACK=0x02; //PIE第2组中断通道的应答标志写1清0}关于TnPINT替换的说明:T1PINT T1CON T1PR EV AIMRA=0x0080 EV AIFRA=0xFFFF 0x0D56 INT_2_4 02H PIEIFR2=0x0000 PIEIER2=0x0008 PIEACK=0x02T2PINT T2CON T2PR EV AIMRB=0x0001 EV AIFRB=0xFFFF 0x0D60 INT_3_1 04H PIEIFR3=0x0000 PIEIER3=0x0001 PIEACK=0x04T3PINT T3CON T3PR EVBIMRA=0x0080 EVBIFRA=0xFFFF 0x0D76 INT_4_4 08H PIEIFR4=0x0000 PIEIER4=0x0008 PIEACK=0x08T4PINT T4CON T4PR EVBIMRB=0x0001 EVBIFRB=0xFFFF 0x0D80 INT_5_1 10H PIEIFR5=0x0000 PIEIER5=0x0001 PIEACK=0x10第五章SPI(串行外设接口)1、列举SPI模块的输入输出信号(有哪几根线)SPI有四个外部引脚:SPISOMI主输入从输出引脚;SPISIMO主输出从输入引脚;SPICLK串行时钟引脚,由主设备输出至从设备;SPISTE,发送使能引脚。