Blackfin 535 Blinklicht – via Delay und ISR
In meiner Diplomarbeit suchte ich nach einem Beispiel in C für die Timerkontrolle. Damit man sieht, das der Code funktioniert, wird die LED getoggelt. Als erstes das normale Delay C-Beispiel, das 100% CPU Auslastung hat:
#include <sys\exception.h> // necessary for ISR
#include <signal.h>
#include <cdefbf535.h> // pointer on BF535 register
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <limits.h>
EX_INTERRUPT_HANDLER(Timer0_ISR);
int i;
/* global variables */
volatile unsigned short * fio_dir_reg;
volatile unsigned short * fio_set_reg;
volatile unsigned short * fio_clr_reg;
void main(void)
{
/* setup the general purpose register first */
fio_dir_reg = (unsigned short *)FIO_DIR;
fio_set_reg = (unsigned short *)FIO_FLAG_S;
fio_clr_reg = (unsigned short *)FIO_FLAG_C;
// set PF0 - PF3 as output
*fio_dir_reg = (unsigned short)0x000F;
while(1)
{
for(i = 0; i < 0xFFFFF; i++)
{
asm("nop;");
}
if(*fio_clr_reg & 0x0001 == 0x0001)
{
*fio_clr_reg = 0x0001;
}
else
{
*fio_set_reg = 0x0001;
}
}
}
Danach probierte ich das Beipiel aus der Engineer To Engineer Note EE-192. Allerdings funktionierte das bei meinem Blackfin BF535 und dem VDSP++ 4.5 nicht. Der Grund liegt anscheinend darin, dass der Timer erst nach der Initialisierung der ISR aktiviert werden darf. Die Auslastung ist dabei sehr niedrig. Folgender Code funktioniert bei mir:
#include <signal.h>
#include <cdefbf535.h> // pointer on BF535 register
#include <sys\exception.h> // necessary for ISR
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <limits.h>
EX_INTERRUPT_HANDLER(Timer0_ISR);
int count,i;
// global variables
volatile unsigned short * fio_dir_reg;
volatile unsigned short * fio_set_reg;
volatile unsigned short * fio_clr_reg;
void main(void)
{
/* setup the general purpose register first */
fio_dir_reg = (unsigned short *)FIO_DIR;
fio_set_reg = (unsigned short *)FIO_FLAG_S;
fio_clr_reg = (unsigned short *)FIO_FLAG_C;
// set PF0 - PF3 as output
*fio_dir_reg = (unsigned short)0x000F;
count = 0;
*pTIMER0_CONFIG = 0x0019; // Configure Timer
*pTIMER0_PERIOD_HI = 0x0200; // Configure Timer Period
*pTIMER0_PERIOD_LO = 0x0000; // Configure Timer Period
*pTIMER0_WIDTH_HI = 0x0180; // Configure Timer Width
*pTIMER0_WIDTH_LO = 0x0000; // Configure Timer Width
*pSIC_IMASK = 0x00004000;
register_handler(ik_ivg11, Timer0_ISR);
*pIMASK = 0x0800;
*pTIMER0_STATUS = 0x0100; // Enable Timer
while(1)
{
//wait for Timer
}
}
EX_INTERRUPT_HANDLER(Timer0_ISR)
{
*pTIMER0_PERIOD_HI = 0x0200; // Configure Timer Period
*pTIMER0_PERIOD_LO = 0x0000; // Configure Timer Period
*pTIMER0_WIDTH_HI = 0x0180; // Configure Timer Width
*pTIMER0_WIDTH_LO = 0x0000; // Configure Timer Width
*pTIMER0_STATUS = 0x0001;
if(*fio_clr_reg & 0x0001 == 0x0001)
{
*fio_clr_reg = 0x0001;
}
else
{
*fio_set_reg = 0x0001;
}
count++;
if(count == 20)
{
*pTIMER0_STATUS |= 0x0200; // timer disable
}
}