📄 lpc221x.c
字号:
/*
* $Revision: 1.8 $
*/
#include <inarm.h>
#include <iolpc2114.h>
#include "lpc221x.h"
#define BAUDRATE 9600
#define BAUDRATEDIVISOR (PCLKFREQ/(BAUDRATE*16))
#define VIC_TIMER0_bit (1 << VIC_TIMER0)
#define VIC_EINT0_bit (1 << VIC_EINT0)
#define VIC_EINT1_bit (1 << VIC_EINT1)
#define VIC_EINT2_bit (1 << VIC_EINT2)
#define VIC_UART1_bit (1 << VIC_UART1)
#define FIRST_PLL_FEED 0xAA
#define SECOND_PLL_FEED 0x55
// Pointers to interrupt callback functions.
static void (*timer_function)();
static void (*eint0_function)();
static void (*eint1_function)();
static void (*eint2_function)();
static void (*uart1rx_function)(unsigned char);
static void (*uart1tx_function)();
//
// Interrupt handlers.
//
//Dummy interrupt handler, called as default in irqHandler() if no other
//vectored interrupt is called.
static void DefDummyInterrupt()
{}
// Timer interrupt handler
static void TimerInterrupt()
{
(*timer_function)(); // Call timer callback function.
T0IR = 0xff; // Clear timer 0 interrupt line.
}
// The external interrupt handlers should call their callback functions
// only once for every button press. If the button is pressed the
// corresponding flag will not be reset when it is written to.
static void ExternalInterrupt0()
{
EXTINT_bit.EINT0 = 1; // Try to reset external interrupt flag.
if(!EXTINT_bit.EINT0) // Check if flag was reset (button not pressed).
(*eint0_function)(); // Call external interrupt callback function.
}
static void ExternalInterrupt1()
{
EXTINT_bit.EINT1 = 1; // Try to reset external interrupt flag.
if(!EXTINT_bit.EINT1) // Check if flag was reset (button not pressed).
(*eint1_function)(); // Call external interrupt callback function.
}
static void ExternalInterrupt2()
{
EXTINT_bit.EINT2 = 1; // Try to reset external interrupt flag.
if(!EXTINT_bit.EINT2) // Check if flag was reset (button not pressed).
(*eint2_function)(); // Call external interrupt callback function.
}
//UART1 interrupt handler
static void UART1Interrupt()
{
switch(U1IIR_bit.IID)
{
case 0x1: //THRE interrupt
(*uart1tx_function)(); //Call tx buffer empty callback function
break;
case 0x2: //Receive data available
(*uart1rx_function)(U1RBR); //Call received byte callback function
break;
case 0x0: //Modem interrupt
case 0x3: //Receive line status interrupt (RDA)
case 0x6: //Character time out indicator interrupt (CTI)
default:
break;
}
}
// IRQ exception handler. Calls the interrupt handlers.
__irq __arm void irq_handler(void)
{
void (*interrupt_function)();
unsigned int vector;
vector = VICVectAddr; // Get interrupt vector.
interrupt_function = (void(*)())vector;
(*interrupt_function)(); // Call vectored interrupt function.
VICVectAddr = 0; // Clear interrupt in VIC.
}
//
// System initialization.
//
void LPC210xSystemInit()
{
// Set PLL 58.96 M = 4; P = 2
PLLCFG_bit.MSEL = 3;
PLLCFG_bit.PSEL = 1;
// Connect and enable PLL
PLLCON_bit.PLLE = PLLCON_bit.PLLC = 1;
// Write FEED
// First disable interrupts.
__disable_interrupt();
PLLFEED_bit.FEED = FIRST_PLL_FEED;
PLLFEED_bit.FEED = SECOND_PLL_FEED;
// Wait to PLL lock frequency
while(!PLLSTAT_bit.PLOCK);
// VPB Initialization
// Not implement in header file
// VPBDIV_bit.VPBDIV = 1; // pclk = cclk
// VPBDIV_bit.XCLKDIV = 1; // xclk = cclk
VPBDIV = 0x11;
// Initialization of MAM
// Initialization of EMC
// FLASH 16bit; IDCY = F; WST1 = 4; RBLE = 1; WST2 = 6
BCFG0=0x1000348F;
// SRAM 32bit; IDCY = F; WST1 = 0; RBLE = 1; WST2 = 0
BCFG1=0x2000040F;
#ifdef JTAG_DEBUG
// Map lowest 64 bytes of the address space to bottom of internal RAM.
// This will move the exception vectors in place.
MEMMAP = 2;
#endif
MAMCR_bit.MODECTRL = 0;
MAMTIM_bit.CYCLES = 4;
MAMCR_bit.MODECTRL = 1;
}
//
// Interrupt controller initalization.
//
void LPC210xInitVIC()
{
// Setup interrupt controller.
VICProtection = 0;
// Disable all interrupts but the one used for the ROM monitor
VICIntEnClear = 0xffffffbf;
VICDefVectAddr = (unsigned int)&DefDummyInterrupt;
}
void LPC210xInitTimerInterrupt(void(*timer_func)())
{
// Setup timer callback function.
timer_function = timer_func;
VICIntSelect &= ~VIC_TIMER0_bit; // IRQ on timer 0 line.
VICVectAddr1 = (unsigned int)&TimerInterrupt;
VICVectCntl1 = 0x20 | VIC_TIMER0; // Enable vector interrupt for timer 0.
VICIntEnable = VIC_TIMER0_bit; // Enable timer 0 interrupt.
}
void LPC210xInitExternalInterrupt0(void(*eint0_func)())
{
// Setup eint0 callback function.
eint0_function = eint0_func;
VICIntSelect &= ~VIC_EINT0_bit; // IRQ on external int 0.
VICVectAddr2 = (unsigned int)&ExternalInterrupt0;
VICVectCntl2 = 0x20 | VIC_EINT0; // Enable vector interrupt for EINT 0.
VICIntEnable = VIC_EINT0_bit; // Enable EINT 0 interrupt.
}
void LPC210xInitExternalInterrupt1(void(*eint1_func)())
{
// Setup eint1 callback function.
eint1_function = eint1_func;
VICIntSelect &= ~VIC_EINT1_bit; // IRQ on external int 1.
VICVectAddr3 = (unsigned int)&ExternalInterrupt1;
VICVectCntl3 = 0x20 | VIC_EINT1; // Enable vector interrupt for EINT1.
VICIntEnable = VIC_EINT1_bit; // Enable EINT 1 interrupt.
}
void LPC210xInitExternalInterrupt2(void(*eint2_func)())
{
// Setup eint2 callback function.
eint2_function = eint2_func;
VICIntSelect &= ~VIC_EINT2_bit; // IRQ on external int 2.
VICVectAddr4 = (unsigned int)&ExternalInterrupt2;
VICVectCntl4 = 0x20 | VIC_EINT2; // Enable vector interrupt for EINT2.
VICIntEnable = VIC_EINT2_bit; // Enable EINT 2 interrupt.
}
void LPC210xInitUART0Interrupt(void(*uart1rx_func)(unsigned char),
void(*uart1tx_func)())
{
// Setup uart1 callback functions.
uart1rx_function = uart1rx_func;
uart1tx_function = uart1tx_func;
VICIntSelect &= ~VIC_UART1_bit; // IRQ on UART1.
VICVectAddr5 = (unsigned int)&UART1Interrupt;
VICVectCntl5 = 0x20 | VIC_UART1; // Enable vector interrupt for UART1.
VICIntEnable = VIC_UART1_bit; // Enable UART 1 interrupt.
}
//
// Timer functions.
//
void LPC210xInitTimer()
{
T0TCR = 2; // Disable timer 0. and rese
T0PC = 0; // Prescaler is set to no division.
T0MR0 = PCLKFREQ/1000; // Count up to this value. Generate 1000 Hz interrupt.
T0MCR = 3; // Reset and interrupt on MR0 (match register 0).
T0CCR = 0; // Capture is disabled.
T0EMR = 0; // No external match output.
}
void LPC210xStartTimer()
{
T0TCR = 1; // Enable timer 0.
}
//
// External interrupt functions
//
void LPC210xInitEINT0()
{
PINSEL0_bit.P0_1=0x11; // Set pin function to EINT0
}
void LPC210xInitEINT1()
{
PINSEL0_bit.P0_14=0x2; // Set pin function to EINT1
}
void LPC210xInitEINT2()
{
PINSEL0_bit.P0_15=0x2; // Set pin function to EINT2
}
unsigned char EINT0PinIsLow()
{
return !IO0PIN_bit.P0_1;
}
unsigned char EINT1PinIsLow()
{
return !IO0PIN_bit.P0_14;
}
unsigned char EINT2PinIsLow()
{
return !IO0PIN_bit.P0_15;
}
//
// Parallel I/O functions.
//
void LPC210xInitPIO()
{
// Uses GPIO pins P0.0-P0.30 pins P1.0 - P1.31
PINSEL0 = 0;
PINSEL1 = 0;
// P1.26 : P1.31 - JTAG
// P2.0 : P2.31 - Data bus
// P3.1 : P3.22 - Address bus
// P1.0 - CS0 (Flash)
// P3.26 - CS1 (RAM)
// P3.31 - BLS0
// P3.30 - BLS1
// P3.29 - BLS2
// P3.28 - BLS3
// P3.26 - WE
// P1.1 - OE
PINSEL2 = 0x0F000924; //0000 1111 0000 0000 0000 1001 0010 0100
// IO0DIR = 0xFFFFBFFF;
IO0DIR = 0x60000001; //0110 0000 0000 0000 0000 0000 0000 0001 - LED,TXD0,PULL_PIN0
// All pins are output
// IO1DIR=0xFFFFFFFF;
IO1DIR = 0x02000003; //0000 0010 0000 0000 0000 0000 0000 0011 - PULL_PIN_P1, CS0, OE
}
//
// LED output drivers.
//
void LPC210xLedSet(unsigned short led_state)
{
// Set LED
if (led_state)
{
IO0CLR_bit.P0_30 = 1;
}
else
{
IO0SET_bit.P0_30 = 1;
}
}
//
// UART functions
//
void LPC210xInitUART0()
{
//Set pins for use with UART
PINSEL0_bit.P0_0=0x1; // Set pin function to TxD (UART1)
PINSEL0_bit.P0_1=0x1; // Set pin function to RxD (UART1)
//Set the FIFO enable bit in the FCR register. This bit must be set for
//proper UART operation.
U0FCR_bit.FCRFE = 1;
//Set baudrate
U0LCR_bit.DLAB = 1;
U0DLL = BAUDRATEDIVISOR & 0x00ff;
U0DLM = (BAUDRATEDIVISOR >> 8) & 0x00ff;
U0LCR_bit.DLAB = 0;
//Set mode
U0LCR_bit.WLS = 0x3; //8 bit word length
U0LCR_bit.SBS = 0x0; //1 stop bit
U0LCR_bit.PE = 0x0; //No parity
//Enable UART1 interrupts
U0IER_bit.RDAIE = 1; //Enable byte received interrupt
U0IER_bit.THREIE = 1; //Enable tx buf empty interrupt
}
//Transmits one byte via UART1
//Note: The UART1 THRE register must be empty before the call to this
// function. Otherwise data can be lost.
void LPC210xUART0TxByte(unsigned char byte)
{
U0THR = byte;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -