单片机开发 F28335中断系统
- 格式:pptx
- 大小:2.01 MB
- 文档页数:64
TMS320F28335开发过程中常见问题总结1.SPI驱动TLE7241E出现返回值不对的问题。
主要是由于时序的不对,导致TLE7241E输入采样时数据还没有建立,所以TLE7241E 收到的命令不正确,所以返回值不正确。
2.SPI驱动EEPROM时,如果用金属物触到clock pin时,能正确运行,否则不能正确运行。
出现次问题也是由于时序的问题,金属物触到clock导致clock出现微小幅度的偏移,导致正好和eeprom 的时序对上,而不用金属物触碰时时序不正常,当使dsp MOSIpin数据发送提前半个周期后,eeprom工作正常。
3.示波器有时会导致显示的波形被消尖,所以用示波器测量时周期不能太大。
TMS320F28335笔记-I2C1.响应和非响应的区别是什么?关于i2c的响应问题:对于每一个接收设备(从设备,slaver),当它被寻址后,都要求在接收到每一个字节后产生一个响应。
因此,the master device 必须产生一个额外的时钟脉冲(第九个脉冲)用以和这个响应位相关联。
在这个脉冲期间,发出响应的从设备必须将SDA拉低并在时钟脉冲的高电平期间保持住。
这表示该设备给出了一个ACK。
如果它不拉低SDA线,就表示不响应(NACK)。
另外,在从机(发送方)发送完最后一个字节后主设备(接收方)必须产生一个不响应位,用以通知从机(发送方)不要再发送信息了,这样从机就知道该将SDA释放了,而后,主机发出一个停止位给slaver。
总结下,i2c通讯中,SDA 和 SCL 都是有主机控制的,从设备只是能够将SDA线拉低而已。
对于SCL线,从机是没有任何能力去控制的。
从机只能被动跟随SCL再说的清楚些:主机发送数据到从机的状态下:主机控制SCL信号线和SDA信号线,从机只是在SCL线为高的时候去被动读取SDA线。
主机读取从机的数据:主机来发出时钟信号,从机只是保证在时钟信号为高电平的时候的SDA的状态而已。
基于F28335的通过定时器中断控制LED#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File #include "DSP2833x_Examples.h" // DSP2833x Examples Include File// Prototype statements for functions found within this file.interrupt void cpu_timer0_isr(void); //中断函数//interrupt void cpu_timer1_isr(void);//interrupt void cpu_timer2_isr(void);//#define mem (*(unsigned short int *)0x200000)#define LED (*(unsigned short int *)0x180000)#define startCpuTimer0() CpuTimer0Regs.TCR.bit.TSS=0 //停止定时器int i=0,ncount;unsigned int uLBD;void main(void){// Step 1. Initialize System Control:// PLL, WatchDog, enable Peripheral Clocks// This example function is found in the DSP2833x_SysCtrl.c file.InitSysCtrl();// Step 2. Initalize GPIO:// This example function is found in the DSP2833x_Gpio.c file and// illustrates how to set the GPIO to it's default state.// InitGpio(); // Skipped for this exampleInitXintf16Gpio(); //zq// Step 3. Clear all interrupts and initialize PIE vector table: // Disable CPU interruptsDINT; //Disable Interrupt 禁止中断// Initialize the 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 DSP2833x_PieCtrl.c file.InitPieCtrl(); //初始化PIE模块// 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 DSP2833x_DefaultIsr.c.// This function is found in DSP2833x_PieVect.c.InitPieVectTable();// Interrupts that are used in this example are re-mapped to // ISR functions found within this file.EALLOW; // This is needed to write to EALLOW protected registersPieVectTable.TINT0 = &cpu_timer0_isr;//PieVectTable.XINT13 = &cpu_timer1_isr;//PieVectTable.TINT2 = &cpu_timer2_isr;EDIS; // This is needed to disable write to EALLOW protected registers// Step 4. Initialize the Device Peripheral. This function can be // found in DSP2833x_CpuTimers.cInitCpuTimers(); // For this example, only initialize the Cpu Timers#if (CPU_FRQ_150MHZ)// Configure CPU-Timer 0, 1, and 2 to interrupt every second: // 150MHz CPU Freq, 1 second Period (in uSeconds)ConfigCpuTimer(&CpuTimer0, 150, 1000000);//ConfigCpuTimer(&CpuTimer1, 150, 1000000);//ConfigCpuTimer(&CpuTimer2, 150, 1000000);#endif#if (CPU_FRQ_100MHZ)// Configure CPU-Timer 0, 1, and 2 to interrupt every second: // 100MHz CPU Freq, 1 second Period (in uSeconds)ConfigCpuTimer(&CpuTimer0, 100, 1000000);//ConfigCpuTimer(&CpuTimer1, 100, 1000000);//ConfigCpuTimer(&CpuTimer2, 100, 1000000);#endif// To ensure precise timing, use write-only instructions to write to the entire register. Therefore, if any// of the configuration bits are changed in ConfigCpuTimer and InitCpuTimers (in DSP2833x_CpuTimers.h), the// below settings must also be updated.//CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0//CpuTimer1Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0//CpuTimer2Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0// Step 5. User specific code, enable interrupts:CpuTimer0Regs.PRD.all=0xffff;CpuTimer0Regs.TPR.all=0;CpuTimer0Regs.TIM.all=0;CpuTimer0Regs.TPRH.all=0;CpuTimer0Regs.TCR.bit.TSS=1;CpuTimer0Regs.TCR.bit.SOFT=1;CpuTimer0Regs.TCR.bit.FREE=1;CpuTimer0Regs.TCR.bit.TRB=1;CpuTimer0Regs.TCR.bit.TIE=1;CpuTimer0.InterruptCount=0;startCpuTimer0();// Enable CPU int1 which is connected to CPU-Timer 0, CPU int13// which is connected to CPU-Timer 1, and CPU int 14, which is connected// to CPU-Timer 2:IER |= M_INT1; //开CPU中断1//IER |= M_INT13;//IER |= M_INT14;// Enable TINT0 in the PIE: Group 1 interrupt 7PieCtrlRegs.PIEIER1.bit.INTx7 = 1; //使能PIE模块中的CPU定时器0的中断// Enable global Interrupts and higher priority real-time debug events: EINT; // Enable Global interrupt INTMERTM; // Enable Global realtime interrupt DBGM// Step 6. IDLE loop. Just sit and loop forever (optional):for(;;){}}interrupt void cpu_timer0_isr(void){CpuTimer0.InterruptCount++;// Acknowledge this interrupt to receive more interruptsfrom group 1PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;CpuTimer0Regs.TCR.bit.TIF=1;CpuTimer0Regs.TCR.bit.TRB=1;if(ncount==0){ LED=uLBD;uLBD++;uLBD%=16;}ncount++;ncount%=194; }。
通过TI源码对TMS320f28335中断机制的进⼀步理解因为TI官⽅给出的28335的例⼦中,对中断向量表的定义为// Define Vector Table:struct PIE_VECT_TABLE {// Reset is never fetched from this table.// It will always be fetched from 0x3FFFC0 in// boot ROMPINT PIE1_RESERVED;PINT PIE2_RESERVED;PINT PIE3_RESERVED;PINT PIE4_RESERVED;PINT PIE5_RESERVED;PINT PIE6_RESERVED;PINT PIE7_RESERVED;PINT PIE8_RESERVED;PINT PIE9_RESERVED;PINT PIE10_RESERVED;PINT PIE11_RESERVED;PINT PIE12_RESERVED;PINT PIE13_RESERVED;// Non-Peripheral Interrupts:PINT XINT13; // XINT13 / CPU-Timer1PINT TINT2; // CPU-Timer2PINT DATALOG; // Datalogging interruptPINT RTOSINT; // RTOS interruptPINT EMUINT; // Emulation interruptPINT XNMI; // Non-maskable interruptPINT ILLEGAL; // Illegal operation TRAPPINT USER1; // User Defined trap 1PINT USER2; // User Defined trap 2PINT USER3; // User Defined trap 3PINT USER4; // User Defined trap 4PINT USER5; // User Defined trap 5PINT USER6; // User Defined trap 6PINT USER7; // User Defined trap 7PINT USER8; // User Defined trap 8PINT USER9; // User Defined trap 9PINT USER10; // User Defined trap 10PINT USER11; // User Defined trap 11PINT USER12; // User Defined trap 12// Group 1 PIE Peripheral Vectors:PINT SEQ1INT;PINT SEQ2INT;PINT rsvd1_3;PINT XINT1;PINT XINT2;PINT ADCINT; // ADCPINT TINT0; // Timer 0PINT WAKEINT; // WD...}(只列出到了group1,到这⾥就够了)因为TI的官⽅⼿册中《TMS320x2833x, 2823x System Control and Interrupts Reference Guide》给出的中断向量排布是就在这个地⽅需要注意的是Reset和INT1~INT12⼀共13个向量是没有使⽤的,这⾥只是作为⼀个32位⽆符号整数占据地址位置,⽽在代码中程序员没有这么写,直接是PIE1_RESERVED~PIE13_RESERVED,这让我⼀开始看代码的时候产⽣了很⼤困惑,因为⽂档中说Reset向量复位的时候是不从这个表中取的,是从boot ROM中取的,所以Reset向量这⾥就没写,但是CMD⽂件中PIE_VECT : origin = 0x000D00, length = 0x000100,中断向量表的起始地址是 0x000D00,如果不定义Reset向量,那所有后⾯的向量不就向前⾯移动了两个地址,后来我为了地址对应就在向量表定义中加⼊了⼀⾏ PINTReset_RESERVED,结果编译报错,好像是CMD中分配的地址重叠了,因为多加了⼀项,我就把向量表中的最后⼀项注释掉了(group12的最后⼀项),编译过了,但是发现进不了指定中断(我这⾥⽤的是TI例程中看门狗中断的例⼦),只能进⼊中断向量表初始化时指定的默认中断(就是⼀个NOP空操作,这⾥多说⼀句,为什么⼀定要初始化中断向量表,因为⼀旦有中断发⽣,没有初始化中断向量表,中断向量表中的地址值是随机的,这样程序就跳转到⼀个随机地址,程序就跑飞了,所以开始给所有中断向量赋⼀个指定的地址值,⼀旦发⽣中断,程序就跳到那个地址去执⾏,这⾥TI给的代码中,这个初始化地址就是⼀个只包含⼀个NOP指令的函数不对程序产⽣影响),继续说我们的调试,我发现CPU是从0x0D4E这个地址中取出的中断函数(看PIECTRL Register的1~15位就知道了,第0位是PIE使能位),⽽⼿册上说WAKEINT这个中断也确实是在0x0D4E 这个地址上,⽽我们指定的中断服务函数PieVectTable.WAKEINT = &wakeint_isr却在下⼀个地址0x0D50的位置上(中断向量表每条中断向量都是32位的)。
DSP实验四TMS320F28335 定时器中断 IO中断控制LED亮灭dsp实验四、tms320f28335定时器中断io中断控制led亮灭继续我的第四个实验;实现定时器中断功能处理ld4翻转,按键IO中断控制ld3翻转;学习目的:中断寄存器的设置,io中断、定时器中断的使用,F28335有三个定时器:定时器0、定时器1和定时器2(定时器2也可用于DSP/BIOS);功能描述:开机时Ld3和ld4默认关闭;初始化完成后,ld4以1hz(1s)频率做状态翻转;ld3接受按键控制,每触发一次按键,状态翻转一次。
电路连接说明:Ld4和ld3设置为通用GPIO上拉输出。
初始化后,输出LED默认熄灭;Ld4和ld3控制LED灯的负极,如下图所示;本次实验选用定时器0,程序时刻读取计数器的值,当值为0时,产生定时器0中断,ld4状态翻转;IO键SW12中断控制ld3状态反转。
定时器0中断程序设计说明:第一步。
定时器0的预设寄存器和计数器设置:定时器输入时钟为sysclkout(=135mhz),1、如果定时1s(即1hz)中断一次(即计数结束),1hz=135mhz/1350/100000预分频器寄存器(即分频器)设置为1350,计数器设置为100000;2、如果定时1ms(即1000hz)中断一次,计算公式为:1000hz=135mhz/1350/100预设寄存器也设置为1350,计数器设置为100;转让声明如下://定时器0设为1hz=135mhz/(1350*100000)cputimer0regs。
珠三角。
全部=100000;//计数周期寄存器。
10万次循环后,计数器降至0putimer0regs tpr。
一点tddr=1350&0xff;//0x546预分频器寄存器(预分频器)cputimer0regs.tprh.bit.tddrh=(1350>>8)&0x00ff;//0x546预定标寄存器(预分频器)第二步a)设置定时器0相关中断寄存器使能定时器0中断,即cputimer0regs.tcr.bit.tie=1;//启用计时器0中断b)设置饼图级别相关中断寄存器,以启用计时器0中断所在的饼图组,即pieierx寄存器设置C)设置CPU级别中断相关寄存器,CPU级别启用与上述饼图对应的通道,即ier寄存器设置步骤3中断向量入口映射位置设置,如下:eallow;//thisisneededtowritetoeallowprotectedregisters皮埃维克塔。
TMS320F28335项目开发记录9_28335之中断系统1.中断系统在这里我们要十分清楚DSP的中断系统。
C28XX一共有16个中断源,其中有2个不可屏蔽的中断RESET和NMI、定时器1和定时器2分别使用中断13和14。
这样还有12个中断都直接连接到外设中断扩展模块PIE上。
说的简单一点就是PIE通过12根线与28335核的12个中断线相连。
而PIE的另外一侧有12*8根线分别连接到外设,如AD、SPI、EXINT等等。
PIE共管理12*8=96个外部中断。
这12组大中断由28335核的中断寄存器IER来控制,即IER确定每个中断到底属于哪一组大中断(如IER |= M_INT12; 说明我们要用第12组的中断,但是第12组里面的什么中断CPU并不知道需要再由PIEIER确定)。
接下来再由PIE模块中的寄存器PIEIER中的低8确定该中断是这一组的第几个中断,这些配置都要告诉CPU (我们不难想象到PIEIER共有12总即从PIEIER1-PIEIER12)。
另外,PIE模块还有中断标志寄存器PIEIFR,同样它的低8位是来自外部中断的8个标志位,同样CPU的IFR寄存器是中断组的标志寄存器。
由此看来,CPU的所有中断寄存器控制12组的中断,PIE的所有中断寄存器控制每组内8个的中断。
除此之外,我们用到哪一个外部中断,相应的还有外部中断的寄存器,需要注意的就是外部中断的标志要自己通过软件来清零。
而PIE和CPU的中断标志寄存器由硬件来清零。
1. EALLOW; // This is needed to write to EALLOW protected registers2. PieVectTable.XINT2 = &ISRExint; //告诉中断入口地址3. EDIS; // This is needed to disable write to EALLOW protected registers4. PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block使能PIE5. PieCtrlRegs.PIEIER1.bit.INTx5= 1; //使能第一组中的中断56. IER |= M_INT1; // Enable CPU 第一组中断7. EINT; // Enable Global interrupt INTM8. ERTM; // Enable Global realtime interrupt DBGM也就是说,12组中的每个中断都要完成上面的相同配置,剩下的才是去配置自己的中断。
DSPF28335---中断系统28335的中断系统中断概述通过硬件或软件驱动的信号,使CPU将当前的程序挂起,执行另一个称为中断服务子程序称为中断。
28335内部有16根中断线,其中有两个不可屏蔽中断(RESET、NMI)与16个可屏蔽中断(INT1-14、RTOSINT、DLOGINT),这里主要说明INT1-14。
在28335中,CPU定时器1、2一般预留给实时操作系统使用,中断线单独分配给INT13、INT14。
其余12个可屏蔽中断直接连接在外设中断扩展模块PIE上,供外部中断和处理器内部单元使用。
这就有一个问题,28335内部有很多个外设模块,这些外设都有自己的中断而且有很多个,那么剩余12个中断怎么够用。
为了解决这个问题所有引入PIE模块。
PIE通过12根线与28335核的12个中断线相连。
而PIE的另外一侧有12*8=96根线分别连接到外设,如AD、SPI、EXINT等等。
说明:PIE和CPU的中断标志寄存器由硬件来清零;但外部中断的标志位要通过软件来清零。
一.三级中断1.外设级中断如果有外设产生中断事件,则寄存器中相应的中断标志位被置一,如果相应的中断使能为(IE)被置位,那么外设就像PIE发出一个中断请求。
如果外设使能位没有被置位,那么中断标志(IF)位将保持为1直到软件清除。
2.PIE中断对于复用的中断源,PIE模块有相应的标志寄存器[PIEIFR(x,y) x=1-12,y=1-8]和中断使能寄存器PIEIER(x,y) ;对于每一个PIE中断组来说还有一个中断应答寄存器PIEACKx。
当有中断请求进入PIE模块的时候,如果相应的PIE中断标志位PIEIFR(x.y)和中断使能寄存器PIEIER(x,y)置1;这是PIE控制器就会检查PIEACKx标志位看CPU 是否已经准备好接收这个PIE中断组的中断。
说明:如果PIEACKZx被清零,PIE会把这个中断请求送到CPU 级的INTx。