CCS5.4+Proteus8的F28027实践课三、外部中断0控制LED流水灯
吃完回来了,跟老弟打了个电话,他正处于事业的迷茫期,希望他早点走出这个状态。好了,现在已经晚上八点过十分了,希望十点前能把外部中断这个主题讲完。
外部中断的概念我还是稍微说下吧,就是你映射的外部中断引脚,如果检测到相应的脉冲边沿变化,就进入外部中断处理程序,处理完后跳出中断,等待下次边沿跳变。
现在来回顾下我们外部中断的结构图:
看到这张图,大家有没有一种直接写程序的冲动,呵呵,这说明大家都前面中断那章节学习的还不错,对寄存器的操作也已经有了自己的理解。
但外部中断寄存器这部分还是需要回顾下:
寄存器这里大家也再次明白了,其实现在也差不多可以写程序了,不过还是要回顾下外部中断的PIE映射表:
我们这次要使用的是外部中断1,也就是INT1.4
来来来,开始写程序,从最简单的GPIO.c文件开始,因为我们本次课程新增了一个外部中断输入触发端口,我选择了GPIO12,因为这个端口离LED最近,好画图。。
GPIO的操作流程我再复述一遍:
1、引脚规划;
2、通过复用寄存器设置相应引脚的功能;
3、输入滤波设置;
4、数字GPIO引脚方向设置;
5、内部上拉电阻使能或禁止;
好了,直接上程序了
void InitGpio(void) { EALLOW; // Each GPIO pin can be: // a) a GPIO input/output // b) peripheral function 1 // c) peripheral function 2 // d) peripheral function 3 // By default, all are GPIO Inputs GpioCtrlRegs.GPAMUX1.all = 0x0000; // GPIO functionality GPIO0-GPIO15 GpioCtrlRegs.GPAMUX2.all = 0x0000; // GPIO functionality GPIO16-GPIO31 GpioCtrlRegs.GPBMUX1.all = 0x0000; // GPIO functionality GPIO32-GPIO34 GpioCtrlRegs.AIOMUX1.all = 0x0000; // Dig.IO funct. applies to AIO2,4,6,10,12,14 GpioCtrlRegs.GPADIR.all = 0xFFFFFFFF; // GPIO0-GPIO31 are GP outputs GpioCtrlRegs.GPBDIR.all = 0x0000; // GPIO32-GPIO34 are inputs GpioCtrlRegs.AIODIR.all = 0x0000; // AIO2,4,6,19,12,14 are digital inputs GpioCtrlRegs.GPADIR.bit.GPIO12=0; //GPIO12 is input pin // Each input can have different qualification // a) input synchronized to SYSCLKOUT // b) input qualified by a sampling window // c) input sent asynchronously (valid for peripheral inputs only) GpioCtrlRegs.GPAQSEL1.all = 0x0000; // GPIO0-GPIO15 Synch to SYSCLKOUT GpioCtrlRegs.GPAQSEL2.all = 0x0000; // GPIO16-GPIO31 Synch to SYSCLKOUT GpioCtrlRegs.GPBQSEL1.all = 0x0000; // GPIO32-GPIO34 Synch to SYSCLKOUT GpioCtrlRegs.GPAQSEL1.bit.GPIO12=2; // six samples GpioCtrlRegs.GPACTRL.bit.QUALPRD1=0x0f // 14 * SYSCLKOUT // Pull-ups can be enabled or disabled. GpioCtrlRegs.GPAPUD.all = 0x0000; // Pullup's enabled GPIO0-GPIO31 GpioCtrlRegs.GPBPUD.all = 0x0000; // Pullup's enabled GPIO32-GPIO34 //GpioCtrlRegs.GPAPUD.all = 0xFFFF; // Pullup's disabled GPIO0-GPIO31 //GpioCtrlRegs.GPBPUD.all = 0xFFFF; // Pullup's disabled GPIO32-GPIO34 GpioCtrlRegs.GPAPUD.bit.GPIO12=1; // Pullup's disabled GPIO12 GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL=12; // GPIO12 is the XINT1's source EDIS; }
写完GPIO.c文件,现在要写外部中断程序,中断函数直接去TI提供的F2802x_DefaultIsr.c文件修改就行了,修改后如下:
interrupt void XINT1_ISR(void) { // Insert ISR Code hereGpioDataRegs.GPATOGGLE.all=0x000000ff; // To receive more interrupts from this PIE group, acknowledge this interrupt PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Next two lines for debug only to halt the processor here // Remove after inserting ISR Code// asm (" ESTOP0");// for(;;);}
现在就剩最后一个主函数了,大家要记得,我们外部函数相关的开关都没开,我准备都放在主函数这里,我已经迫不及待了,马上去写出来给大家
void main(void) {// Step 1. Initialize System Control:// PLL, WatchDog, enable Peripheral Clocks// This example function is found in the DSP2802x_SysCtrl.c file. InitSysCtrl();// Step 2. Initalize GPIO:// This example function is found in the DSP2802x_Gpio.c file and// illustrates how to set the GPIO to it's default state. InitGpio();// Step 3. Clear all interrupts and initialize PIE vector table:// Disable CPU interrupts DINT;// Initialize PIE control registers to their default state.// The default state is all PIE interrupts disabled and flags// are cleared.// This function is found in the DSP2802x_PieCtrl.c file. InitPieCtrl();// Disable CPU interrupts and clear all CPU interrupt flags: IER = 0x0000; IFR = 0x0000;// Initialize the PIE vector table with pointers to the shell Interrupt// Service Routines (ISR).// This will populate the entire table, even if the interrupt// is not used in this example. This is useful for debug purposes.// The shell ISR routines are found in DSP2802x_DefaultIsr.c.// This function is found in DSP2802x_PieVect.c. InitPieVectTable();// Step 4. Initialize all the Device Peripherals:// This function is found in DSP2802x_InitPeripherals.c// InitPeripherals(); // Not required for this example// Step 5. User specific code: GpioDataRegs.GPADAT.all = 0x00000000; //GPIO0-GPIO31 initial value are 0 EALLOW; XIntruptRegs.XINT1CR.bit.POLARITY=0; XIntruptRegs.XINT1CR.bit.ENABLE=1; PieCtrlRegs.PIEIER1.bit.INTx4 = 1; PieCtrlRegs.PIECTRL.bit.ENPIE = 1; IER = 0x0001; EINT; EDIS; while(1) {// GpioDataRegs.GPATOGGLE.all=0x000000ff;// DELAY_US(1000); } }
总算把主程序调完贴出来了,效果图如下:
刚才采样时钟那里花了我一些时间,本来我取的是最大值510 * SYSCLKOUT,但是仿真一直没反应,我还以为是其他地方有问题,可其他地方检查两边都没发现明显问题,那我想肯定是采样时钟这里,毕竟我是在Protues里面仿真的,系统运行的时间看的到是以ms为单位,所以如果把采样时间设的过大,会导致采样时间内没捕捉到跳变,这个问题应该只是仿真需要注意,到时候做成品板的时候,我觉得还是要设为最大值。
好了,现在时间刚好九点半,离我们的预期时间早了半个小时,不错,先设定目标,再突破目标,是每个狼性文化的标准,那我们现在趁热打铁,去驱动12864。
菜鸟交流qq群107691092