📄 main.c
字号:
/* code originally from phillips appnote 10254 */
/* *********************************************************
Function declarations
********************************************************* */
void DefIRQHandler(void);
void TimerHandler(void);
void feed(void);
void Initialize(void);
#define LED_R 0x01000000
#define LED_G 0x02000000
#define LED_Y 0x00800000
/**********************************************************
Header files
**********************************************************/
#include "LPC210x.h"
#include <string.h>
#define USE_PWM_TEST 1
#if USE_PWM_TEST
#include "pwm.h"
#endif
// serial port
#define RDR 0x01
#define THRE 0x20
char rx_query(void)
{
return UART0_LSR & RDR;
}
char tx_query(void)
{
return UART0_LSR & THRE;
}
void tx(char c)
{
UART0_THR = c;
}
char rx(void)
{
return UART0_RBR;
}
void tx_str(char *s) // send a string
{
while(*s)
if (tx_query())
tx(*s++);
}
/**********************************************************
MAIN
**********************************************************/
void __main (void)
{
char *x = (char *)0, *y = (char *)0x1000;
/* Initialize the system */
Initialize();
#if USE_PWM_TEST
#define POSITIONS 100
#define TEST_PWM PWM4 /* P0.8 is easier to reach with a probe */
unsigned int duty = 0;
pwm_init(POSITIONS, PWM_MSEC(2)/POSITIONS); /* 100 positions, total 2ms */
pwm_chan_init(TEST_PWM, duty); /* 0% initially (servo might want 75 e.g.)*/
#endif /* USE_PWM_TEST */
/* Start timer */
TIMER1_TCR=0x1;
// For testing library inclusion
// memcpy(x,y,100);
// test banner
tx_str("\n\rTest echo\n\r");
// echo for main loop
while(1)
{
if (rx_query() && tx_query()) // received and ready to send
{
tx(rx()); // get and send
#if USE_PWM_TEST
pwm_set(TEST_PWM,duty++);
#endif
}
}
}
/**********************************************************
Initialize
**********************************************************/
extern const char _text_start, _text_end;
extern char _data_start, _data_end;
#define PLOCK 0x400
void Initialize(void)
{
// memcpy(&_data_start, &_text_end, &_data_end - &_data_start);
// set io pins for leds red off, yellow off, green on
IODIR |= LED_Y|LED_G|LED_R; // 23-25 are outputs
IOSET = LED_G; // green led on
IOCLR = LED_R|LED_Y; // red and yellow off
/*
* Initialize PLL (Configured for a 10MHz crystal) to
* boost processor clock to 60MHz
*/
/* Setting Multiplier and divider values */
PLLCFG=0x25;
feed();
/* Enabling the PLL */
PLLCON=0x1;
feed();
/* Wait for the PLL to lock to set frequency */
while(!(PLLSTAT & PLOCK)){}
/* Connect the PLL as the clock source */
PLLCON=0x3;
feed();
/*
* Enabling MAM and setting number of clocks used for
* Flash memory fetch
*/
MAMCR=0x2;
MAMTIM=0x4;
/*
* Setting peripheral Clock (pclk) to System
* Clock (cclk)
*/
VPBDIV=0x1;
/* Initialize GPIO */
// IODIR=0xFFFF;
// IOSET=0xFFFF;
/* Initialize Timer 1 */
TIMER1_TCR=0x0; /* turn it off for now */
TIMER1_TC=0x0; /* clear so we don't miss first match */
TIMER1_PR=0x0; /* prescale of 0 -> tick rate == sysclk */
TIMER1_PC=0x0; /* clear for no particular reason */
/* End user has to fill in the match value */
TIMER1_MR0 = 60000000/2; /* 30 million cycles @ 60MHz = 0.5 sec */
/* Reset and interrupt on match */
TIMER1_MCR=0x3;
/* Initialize VIC */
VICIntSelect=0x0; /* Timer 1 selected as IRQ */
VICIntEnable= 0x20; /* Timer 1 interrupt enabled */
VICVectCntl0= 0x25;
/* Address of the ISR */
VICVectAddr0 = (unsigned long)TimerHandler;
VICDefVectAddr = (unsigned long)DefIRQHandler;
/* initialize serial port */
// initialize UART
PINSEL0 = 5; // enable UART0 in/out
UART0_FCR = 0x7; // enable and reset fifos
UART0_LCR = 0x83; // 8 bits; enable divisor latches
UART0_DLL = 0x87; // LSB divider for 60mhz to be 9600x16
UART0_DLM = 0x01; // MSB
UART0_LCR = 0x3; // disable divisor latches
}
void __attribute__((interrupt)) DefIRQHandler(void)
{
/* unexpected IRQ -- fall apart */
IOSET = LED_Y;
tx_str("Fail\r\n");
for (;;) /*EMPTY*/;
}
/**********************************************************
Timer 1 ISR
**********************************************************/
void __attribute__((interrupt)) TimerHandler(void)
{
/*
* The Interrupt Service Routine code will come here. The
* interrupt needs to be cleared in Timer1 and a write must
* be performed on the VIC Vector Address Register to
* update the VIC priority hardware. Here the user could
* blink a few LED誷 or toggle some port pins as an
* indication of being in the ISR
*/
if (IOPIN & LED_R)
IOCLR = LED_R; // red led off
else
IOSET = LED_R; // red led on
TIMER1_IR=0x1; // clear interrupt
VICVectAddr=0xff; // clear VIC
}
void feed(void)
{
PLLFEED=0xAA;
PLLFEED=0x55;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -