EmbeddedRelated.com
Forums

Introduction to Lpc2000 needed.

Started by Senkumba Edwin February 6, 2008
Hello Everyone,
I am new to the microcontroller and am trying to understand it, i was reading up on PIC ucontrollers before and the book i was reading emphasised on using Assembly language. I was recently advised to look at using the Philips lpc2148 to control an RC toy car (my first project) but i dont know much about the lpc2000 series and found out that it is programmed in C, so the information i got from the PIC book wont be of much help.
All i know about microcontrollers is that they have a couple of GPIO (that would general purpose Inout and output right?) and that these IO's are connected to the ports inside (like PORTA and PORTB for the PIC16F54 i was reading on). The ports are arranged in a file cabinet system with each cabinet being a file register. This file registers store information which is accessed (or moved aorund) using the working register.
So far thats as much as i know regarding the PIC16F5x. I need to know if what i know could help me with the lpc2148 and where i could get more information. I would aslo like to know the basic programming instructions used with the ucontroller, though am not so strong at using the C language but i am working on that right now. Any help would be much appreciated, thank you.

P.S A little more about myself, I am an Engineering Undergraduate. So all the above Information search is school based.

Edwin.
____________________________________________________________________________________
Looking for last minute shopping deals?
Find them fast with Yahoo! Search. http://tools.search.yahoo.com/newsearch/category.php?category=shopping

An Engineer's Guide to the LPC2100 Series

Edwin,

You have a bit of a mountain to climb!

This page may help to get you started:
http://tte-systems.com/beginners.php

Michael.

_____

From: l... [mailto:l...] On Behalf Of
Senkumba Edwin
Sent: 06 February 2008 05:33
To: l...
Subject: [lpc2000] Introduction to Lpc2000 needed.

Hello Everyone,
I am new to the microcontroller and am trying to understand it, i was
reading up on PIC ucontrollers before and the book i was reading emphasised
on using Assembly language. I was recently advised to look at using the
Philips lpc2148 to control an RC toy car (my first project) but i dont know
much about the lpc2000 series and found out that it is programmed in C, so
the information i got from the PIC book wont be of much help.
All i know about microcontrollers is that they have a couple of GPIO (that
would general purpose Inout and output right?) and that these IO's are
connected to the ports inside (like PORTA and PORTB for the PIC16F54 i was
reading on). The ports are arranged in a file cabinet system with each
cabinet being a file register. This file registers store information which
is accessed (or moved aorund) using the working register.
So far thats as much as i know regarding the PIC16F5x. I need to know if
what i know could help me with the lpc2148 and where i could get more
information. I would aslo like to know the basic programming instructions
used with the ucontroller, though am not so strong at using the C language
but i am working on that right now. Any help would be much appreciated,
thank you.

P.S A little more about myself, I am an Engineering Undergraduate. So all
the above Information search is school based.

Edwin.

__________________________________________________________
Looking for last minute shopping deals?
Find them fast with Yahoo! Search. http://tools.

search.yahoo.com/newsearch/category.php?category=shopping
--- In l..., Senkumba Edwin wrote:
>
> Hello Everyone,
> I am new to the microcontroller and am trying to understand it,
i > was reading up on PIC ucontrollers before and the book i was
reading >emphasised on using Assembly language. I was recently advised
to look >at using the Philips lpc2148 to control an RC toy car (my
first >project) but i dont know much about the lpc2000 series and
found out >that it is programmed in C, so the information i got from
the PIC book >wont be of much help.

Here are a couple of sources that can be pretty helpful:

This is an ARM tutorial based on commercial tools.
http://www.hitex.co.uk/arm/lpc2000book/

Just one of many sources for Jim Lynch's freeware tools tutorial.
http://www2.amontec.com/sdk4arm/ext/jlinch-tutorial-20061124-source.zip

If you really start using ARM a lot, you should also look into getting
the "ARM Architecture Reference Manual" for deeper knowledge, but the
above sources are pretty good start for a beginner.

--Dave
Hi mate,
also I'm started some months ago with a new design based on LPC2106 and
also my background was with PIC microcontrolloer
programmed ASM and C. I've found no more help on books or forum and all
I've do is just from my personal search and test, all the code
provided below is stripped from a my personal written working
application. I know that may be useful or not but this is what I've
liked
to see when I've started on working with this microcontroller and I've
not found from anyone and anywhere, this the reason why I've decided
to write this mini and not very well completed tutorial about this
stuff. I know write this is a matter of time, but I'm for free
opensource knowledge
(not for opensource production project but for sharing the knowledge
needed to build your own application :-)).
I hope that thsi can be useful is some way, anyway I can write more
detaild tutorial on solution and how to implement other stuff, also can
be
nice if other more skilled peple like to partecipate in a cook book
writing for sharing their experience, this can be viewed as a my first
starting contribute
then don't shoot to the pianist please :-).

Well as I written I can just spoke about my personal experience, I've
started with the IAR Kickstart kit for LPC2106 and code my application
in C language,
most of the code was a simple porting from Microchip (Hi-Tech compiler)
to the IAR system.

In order to start you can use the IAR example (I remember this is named
flashligth or somethings of similar), using this example you've all the
scheleton for build a
working application, you have just to write your code and make the
integration for the interrupt handling.

As used libray I've set:

#include
#include
#include
#include
#include // registry definition
#include "timer.h"
#include "lpc210x.h"
#include "io_macros.h"
#include "Flash_usage.h" // Used to manage the Flash as EEPROM, see
below to understand how to do it
#include "math.h"

....

I've written two interrupt function to manage the USART1, this ones was
called USART1_rx and
USART1_tx, here the function prototype:

void USART1_rx(unsigned char);
// USART1 (irq): callback function per RX
void USART1_tx(void);
// USART1 (irq): callback function per TX

and the code for each function:

void USART1_rx(unsigned char rxbyte)
{

asm("NOP");
asm("NOP");

SerRx = rxbyte; // read the data into the SerRx variable

// Put your rx code here and when a valid command
// is recognized set the rsFlag to 1, use this into the
// main() routine to know when we've a valid command to process,
// usually I set the process task at the end of the main cycle.

return;
}

void USART1_tx(void)
{

asm("NOP");
asm("NOP");

// Put your tx code here

return;
}

into the main() function you have to init the interrupt vector by using
this provided function:

LPC210xInitUART1Interrupt(USART1_rx, USART1_tx); // Init the callback
function for use the USART1

Of course I've implemented reading and transmitting over the serial port
with interrupt, last question is how I can send data byte over
the serial port with interrupt? Well more simple, I've just defined two
buffer used in rx and tx and other useful variable:

unsigned char SerRx; // USART1: char from rx
unsigned char RxCtr; // USART1: counter of rx chars
unsigned char TxCtr; // USART1: counter of tx chars
unsigned char TxMaxChr; // USART1: maximum allowed rx char for
preventing overflow
unsigned char SerialBufferRx[MAXSERBUF]; // USART1: rx buffer
unsigned char SerialBufferTx[MAXSERBUF]; // USART1: tx buffer
unsigned char rsFlag; // USART1: flag used to signal into the main a
valid received command

.....

The main things now is how I can transmit over serial port by using the
interrupt feature, well is more simple, here my full code for
the TX routine:

void USART1_tx(void)
{

asm("NOP");
asm("NOP");

while(U1LSR_bit.THRE == 1)
{
if (TxMaxChr > 0)
{
if ((TxCtr + 1) > TxMaxChr) // Check if I've
trasmitted all the char into the TX buffer
{
U1IER_bit.THREIE = 0; // reset the TX interrupt
TxCtr = 0; // reset the
trasmitting counter
TxMaxChr = 0; // reset the total
char counter that I've to be trasmitted
}
else
{
U1THR = SerialBufferTx[TxCtr]; // Send a char from
the TX buffer
TxCtr = TxCtr + 1; // Update the
buffer pointer for the next char that has to be sended
}
}
else
break; // end of the while
}
return;
}

and also you've to use the following code to charge the buffer and start
the TX with the interrupt (suppose to send the *OK*
chars sequence):

SerialBufferTx[0] = '*'; // First char to send
SerialBufferTx[1] = 'O'
SerialBufferTx[2] = 'K';
SerialBufferTx[3] = '*'; // Last char to send
TxMaxChr = 4; // Max number of chars to send
TxCtr = 1; // Sended chars counter, set to 1 because
the first char is sended now to activate the IRQ

U1FCR_bit.TFR = 1; // Reset the UART1 FIFO TX
swithout send any char
U1THR = SerialBufferTx[0]; // Send the first chart, the
others will be send automatically with the interrupt code
U1IER_bit.THREIE = 1; // Enable the TX interrupt

that's all, I've working hard to found this solutions and now this work
very nicely witout trouble over all the production device, of course
what you've to do
is made your personal communication protocol (code has to be written
into the USART1_rx function), and then you can write at the end of the
microcontroller main
loop into the main() function your command handler like below:

void main() void
{
// Put here your code initialization, PLL, interrupt and so on
....

// main working loop (infinite loop to keep alive the
microcontroller)
while(1)
{
// Write here your application code

....................................................................

// Serial command handler
if (rsFlag)
{
// Because the rsFlag is equal to 1 I've received a
command
// trough the serial port. Put your code here if the
command is simple or
// for better readability and coding style put all
into a
// dedicated function before the main().


....................................................................

// End of the serial code processing
rsFlag = 0;
RxCtr = 0;
for (index = 0; index < MAXSERBUF; index++) // RX
buffer cleaning for next command
SerialBufferRx[index]= '\0';
}
}
}

I think this is enough for now about the serial stuff.


-------------------
HOW TO SET THE PIN FUNCTION, DIRECTION AND STATE

------------------
Some pin exibits multiple functions then you've to select what is the
pin behaviour, this task can be achieved by using the
PINSEL0 and PINSEL1 command like below:

PINSEL0 = 0x50000; // Set the UART1 pins
PINSEL1 = 0x00; //

of course take a look on the LPC2106 datasheet in order to know what is
the settings to do for other pins, in my application I've used the
default one (0x00 for every line) and
changed just the pin function to enable the USART 1.

Into the PIC you've a bsf and bcf assembly instruction to set and clear
a bit status, into the IAR C language set and clear and direction type
was performed
by using separate command, look at the following code to see how to do
it:

#define OUTPUT_TYPE 1
#define INPUT_TYPE 0

IODIR_bit.P0_4 = OUTPUT_TYPE; // Set the PO_4 line as output

IOCLR_bit.P0_4 = 1; // Set the P0_4 value to 0 (0V)
IOSET_bit.P0_4 = 1; // Set the PO_4 value to 1 (approx 3.3 V)

Another example about set the line as input:

IODIR_bit.P0_16 = INPUT_TYPE; // Set the PO_16 line as input

to read the status of the PO_16 line configured as input write for
example:

if (IOPIN_bit.P0_16 == 0)
{
// make somethings if the PO_16 line has a low level applied
}



HOW TO USE THE FLASH MEMORY AS A INTERNAL EEPROM


This is about pin settings, another issue is about the absence of the
EEPROM memory like into the PIC one.
As a workaround you can use some flash sector (I've used the block 14)
in order to simulate the EEPROM behaviour, what I've did was
read in a buffer the entire sector, make the change into the sector,
write back the entire sector. You've to make
a copy of the sector in a buffer because writing is a sector based
operation.
To do this I've make some change to a existent code and now the read and
write operation is simple as into the PIC because
all the needed stuff was performed under the hood.

Here is the code that you've to put in a source file with name
Flash_usage.c:

// -------------- START OF THE CODE (Flash_usage.c)
#include
#include
#include // For interrupt macro
#include "Flash_usage.h"

typedef struct SLayout {
int sectors;
int size;
} Layout;

static IAP iap_entry = (IAP)kIAPentry; // MCU flash firmware
interface function.
static unsigned long sectorbuf[WRITE_SIZE/4]; // The sector buffer must
be word aligned.
// The CPU clock speed (CCLK), the default value is used if no clock
option is found.
static int clock = CCLK;

//==============================================
// 128k flash, 1'st generation
// LPC2104 (16k RAM)
// LPC2105 (32k RAM)
// LPC2106 (64k RAM)
// LPC2114 (16k RAM)
// LPC2212 (16k RAM)
// LPC2119 (16k RAM)
//==============================================
#define FLASH_SIZE 0x1E000
#include

const Layout flashLayout[] =
{
{15, 8192},
{ 0, 0}
};

const int allowedWriteSizes[] =
{
512,
1024,
4096,
8192,
0
};

//

// Returns the flash sector number for a given flash address.
// Returns -1 if the address is outside the flash.
//

int CalculateSector(unsigned long addr, int *erase_sector)
{
int i;
int j;
int sector = 0;
unsigned long current = 0;

*erase_sector = 0;
for (i = 0; flashLayout[i].sectors; i++)
{
for (j = 0; j < flashLayout[i].sectors; j++)
{
if (addr < current + flashLayout[i].size)
{
if (addr < current + WRITE_SIZE)
{
*erase_sector = 1;
}
return sector;
}
sector++;
current += flashLayout[i].size;
}
}
return -1;
}

//

// Execute a flash firmware command.
//

int ExecuteCommand(unsigned long* cmd, unsigned long* status)
{
int ret;

for (;;)
{
iap_entry(cmd, status);
ret = status[0];
if (ret != STATUS_BUSY)
{
return ret;
}
// Try again if busy.
}
}

//

// Program a sector. The device allows fractions of a sector to be
written.
// dst - the flash address to start writing at.
// src - the address of the data buffer to be written.
// size - the number of bytes in the data buffer to write.
//

unsigned char ProgramFlash(unsigned long dst, unsigned long* src, int
size)
{
int i;
int ret;
int sector;
int erase_sector;
unsigned long sum;
unsigned long cmd[6];
unsigned long status[3];

// User Flash mode
MEMMAP = 1;

// Disabilita interrupt
__disable_interrupt();

// Round up size to nearest allowable write size.
for (i = 0; allowedWriteSizes[i]; i++)
{
if (size <= allowedWriteSizes[i])
{
size = allowedWriteSizes[i];
break;
}
}

sector = CalculateSector(dst, &erase_sector);

if (dst + size > FLASH_SIZE || sector == -1)
{
return(0);
}

// Check for first part of sector 0 and that a reset vector is
present,
// note that the buffer is initialized to all 1's.
if (sector == 0 && erase_sector && src[0] != 0xffffffff)
{
// Calculate exception vector 0x14 if the sector is zero and a
reset address is present.
sum = src[0] + src[1] + src[2] + src[3] +
src[4] + src[6] + src[7];
src[5] = -sum; // Vector 0x14.
}

// Prepare sector for erase.
cmd[0] = CMD_PREPARE_SECTORS;
cmd[1] = sector;
cmd[2] = sector;
ret = ExecuteCommand(cmd, status);

if (ret != STATUS_CMD_SUCCESS)
{
return(0);
}

if (erase_sector)
{
// Erase sector.
cmd[0] = CMD_ERASE_SECTORS;
cmd[1] = sector;
cmd[2] = sector;
cmd[3] = clock;
ret = ExecuteCommand(cmd, status);
if (ret != STATUS_CMD_SUCCESS)
{
return(0);
}
}

// Prepare sector for write.
cmd[0] = CMD_PREPARE_SECTORS;
cmd[1] = sector;
cmd[2] = sector;
ret = ExecuteCommand(cmd, status);
if (ret != STATUS_CMD_SUCCESS)
{
return(0);
}

// Program sector.
cmd[0] = CMD_COPY_RAM_TO_FLASH;
cmd[1] = dst;
cmd[2] = (unsigned long)src;
cmd[3] = size;
cmd[4] = clock;
ret = ExecuteCommand(cmd, status);

if (ret != STATUS_CMD_SUCCESS)
{
return(0);
}

// Enable the interrupt
__enable_interrupt();

// All was fine
return(1);
}

//

// Write one byte to flash at addr.
// The bytes are first buffered in sectorbuf, this array is at first
// filled with the old flash data and then updated with the new one.
// The sectorbuf is written to the flash when it overflows or when
// he user call the routine with byte equal to -1.
//

void FlashWriteByte(unsigned long addr, int byte)
{
int i;
int offset; // Current offset into sector
buffer.
static int bytes = 0; // Number of bytes in the
sector buffer (including gaps).
static int base_addr; // Pysical address of the
start of the sector.
unsigned long flashaddr = 0x0001C000; // First address block 14

restart:
if (bytes == 0) // First byte of a new sector.
{
// This is the first time that we try to write some byte
// then we've to check for the total byte remainder
// before reach the maximum size, then the data storage
// buffer will be initialized.
bytes = addr % WRITE_SIZE;
base_addr = addr - bytes; // Calculate physical start address of
this sector.

// Intialize sector buffer with the pre-existent data to
// preserve all the remainder data which is stored in Flash.
// Size il WRITE_SIZE / 4 due to the fact that flashbyte is 32 bit
in length
for (i = 0; i < WRITE_SIZE/4; i++)
{
sectorbuf[i] =*((unsigned long*)flashaddr);
flashaddr += 4;
}
}

// Write sector buffer to the flash memory if a flush is requested
(byte = -1)
// or the new byte address is beyond the sector buffer.
if (byte == -1 || addr - base_addr >= WRITE_SIZE)
{
ProgramFlash(base_addr, sectorbuf, bytes);

if (byte == -1)
{
return; // This was a flush operation, all data is written.
}

// We've write the data which is pushed into the storage sectorbuf
// then we can reset the byte count for future writing
bytes = 0;

goto restart;
}

// Store byte in sector buffer.
offset = addr - base_addr;
((unsigned char*)sectorbuf)[offset] = (byte & 0x00FF);
bytes = offset + 1;

return;
}
// ---------------END OF THE CODE (Flash_usage.c)

there is also some other code to put in a header file with name
Flash_usage.h.

// -------------- START OF THE CODE (Flash_usage.h)
#define CCLK 14746

// The write size is not critical to performance.
// 512 bytes is a good size that leaves as much room to the JTAG
// read buffer as possible and is supported by all flash devices.
#define WRITE_SIZE 512

#define kIAPentry 0x7ffffff1

enum {
CMD_PREPARE_SECTORS = 50,
CMD_COPY_RAM_TO_FLASH,
CMD_ERASE_SECTORS,
CMD_BLANK_CHECK_SECTORS,
CMD_READ_PART_ID,
CMD_READ_BOOT_CODE_VERSION,
CMD_COMPARE,
};

enum {
STATUS_CMD_SUCCESS = 0,
STATUS_INVALID_COMMAND,
STATUS_SRC_ADDR_ERROR,
STATUS_DST_ADDR_ERROR,
STATUS_SRC_ADDR_NOT_MAPPED,
STATUS_DST_ADDR_NOT_MAPPED,
STATUS_COUNT_ERROR,
STATUS_INVALID_SECTOR,
STATUS_SECTOR_NOT_BLANK,
STATUS_SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION,
STATUS_COMPARE_ERROR,
STATUS_BUSY,
};

typedef void (__thumb *IAP)(void*, void*);

// --------------------------
// Function definition
// --------------------------
int ExecuteCommand(unsigned long* , unsigned long* );
unsigned char ProgramFlash(unsigned long , unsigned long* , int );
void FlashWriteByte(unsigned long , int );
// ---------------END OF THE CODE (Flash_usage.h)

>From a pratical point of view using the Flash require to set a sort of
memory map, I've do it with a set of define
statements as below:

// -----------------------
// DEFINE FLASH section data (block 14)
// -----------------------
#define ADDR_FLASH_BASEADDR 0x0001C000 // FLASH: first useful
address
#define ADDR_CODE_HYBYTE 0x0001C000 // FLASH: param1 (hi byte)
device code
#define ADDR_CODE_LOBYTE 0x0001C004 // FLASH: param1 (lo byte)
device code
#define ADDR_ADDRESS_BYTE 0x0001C008 // FLASH: param2 (one byte)
device address (0x00 to 0xFF)
#define ADDR_POWERON_HYBYTE 0x0001C00C // FLASH: param3 (hi byte)
power on counter
#define ADDR_POWERON_LOBYTE 0x0001C010 // FLASH: param3 (lo byte)
power on counter
....

and below ther is a example how you can use the Flashing routine, in
this example I simply read back the power on counter
from the flash, update the value by 1 and write back the updated value
into the Flash, I've used this code on the starting of the
main() code then every power up I can update the counter and know if the
device was powered and the number of the time.

// ---------------------------
// Read the power on register update and write back into the Flash
// ---------------------------
ulFlashAddress = (unsigned long)ADDR_POWERON_LOBYTE;
lobyte = *((int*)ulFlashAddress) & 0x000000FF;
ulFlashAddress = (unsigned long)ADDR_POWERON_HYBYTE;
hybyte = *((int*)ulFlashAddress) & 0x000000FF;
iNumberPowerOn = hybyte * 256 + lobyte;
iNumberPowerOn += 1;
lobyte = iNumberPowerOn & 0x000000FF;
hybyte = ((iNumberPowerOn & 0x0000FF00) >> 8) & 0x000000FF;

ulFlashAddress = (unsigned long)ADDR_POWERON_LOBYTE;
FlashWriteByte(ulFlashAddress, lobyte);
ulFlashAddress = (unsigned long)ADDR_POWERON_HYBYTE;
FlashWriteByte(ulFlashAddress, hybyte);

ulFlashAddress=(unsigned long)ADDR_FLASH_BASEADDR;
FlashWriteByte(ulFlashAddress, -1); // Update the Flash

....


-------
SPEED ISSUE, CORE CLOCK, PERIPHERAL CLOCK

-------

I've changed the micro from PIC to ARM into my design mainly for speed
issue, take in mind that you've a internal PLL that is usful to keep the
microcontroller core working at the maximum available speed (60 MHz for
the PLC2106).
To achieve this goal you've to work around two stuff, the peripheral
clock frequency and the internal PLL.

The output peripheral speed is a new feature respect the PIC
microncontroller, you can choose to update the output at the
external clock or the core clock, for my issue I've to use the maximum
speed the I've set the peripheral clock equal to core clock
and this one can be done by writing this statements:

VPBDIV = 0x01;

Also to reach the maximum core clock you've to set properly the internal
PLL, to do this use a external crystal of 14,7456 MHz + 30ppm
with two capacitors of 18 pF and set the internal PLL to work at the
maximum frequency with the code listed below:

// ------------------
// Set the internal PLL to work with a core clock of 60 MHz
// with a external clock of 14.745 MHz.
// M = 4, P = 2
// ------------------
PLLCFG = 0x23;
PLLCON = 0x01;
PLLFEED = 0xAA;
PLLFEED = 0x55;
while (!(PLLSTAT & 0x400)) {}
PLLCON = 0x03;
PLLFEED = 0xAA;
PLLFEED = 0x55;

Also there is another stuff to keep in mind, core clock and peripheral
clock is set at the same value and also at the maximum
available frequency (60 MHz) but you drive the output pin from the code
and this one can be executed on Flash or RAM memory.
If the code will be executed from Flash you have a limit from the Flash
access time then you can't reach the maximum output frequency,
to overcome this you've two choice, use the MAM (Memory Acceleration
Module) module or simply get the code executed from the ram.
MAM is a trick to execute code from ram but is not useful if you have
jump over the code because the fetch queue has to be updated and then
the speed is limited by Flash access, I've used the ram execution
option, only drawback is the used memory, but you reach the goal by
carefully
choosing what code or function has to be executed from ram.
To do this simply add the keyword __ramfunc before the function
declaration (no need to add it also to the function code), here is one
example
how to use it:

// Function prototipe
__ramfunc signed int ReadInterface(void);

.....

// Function definition
signed int ReadInterface(void)
{
.......
return readed_value;
}


INTERRUPT HANDLING

Also interrupt handling is simple but different than into the PIC
microcontrollers, into the ARM architecture you've a
interrupt vector that must be filled with the function address that will
be called on the interrupt event.


FINAL REMARKS

If you need more specifical infos let me know I'll be happy helping you
in starting, I know the difficult also when I've started
with this new microcontroller family I've do all by myself then now I
can share my little knowledge/experience to other...
I'm for open source knowledge :-)

Best regards
Fabio Filippa


-----Messaggio originale-----
Da: Senkumba Edwin [mailto:e...@yahoo.com]
Inviato: mercoled6 febbraio 2008 6.33
A: l...
Oggetto: [lpc2000] Introduction to Lpc2000 needed.

Hello Everyone,
I am new to the microcontroller and am trying to understand it, i was
reading up on PIC ucontrollers before and the book i was reading
emphasised on using Assembly language. I was recently advised to look at
using the Philips lpc2148 to control an RC toy car (my first project)
but i dont know much about the lpc2000 series and found out that it is
programmed in C, so the information i got from the PIC book wont be of
much help.
All i know about microcontrollers is that they have a couple of GPIO
(that would general purpose Inout and output right?) and that these IO's
are connected to the ports inside (like PORTA and PORTB for the PIC16F54
i was reading on). The ports are arranged in a file cabinet system with
each cabinet being a file register. This file registers store
information which is accessed (or moved aorund) using the working
register.
So far thats as much as i know regarding the PIC16F5x. I need to know if
what i know could help me with the lpc2148 and where i could get more
information. I would aslo like to know the basic programming
instructions used with the ucontroller, though am not so strong at using
the C language but i am working on that right now. Any help would be
much appreciated, thank you.

P.S A little more about myself, I am an Engineering Undergraduate. So
all the above Information search is school based.

Edwin.

__________________________________________________________
Looking for last minute shopping deals?
Find them fast with Yahoo! Search. http://tools.

search.yahoo.com/newsearch/category.php?category=shopping









Hi Fabio,
First of all let me thank you for your time to help me out. I am somehow able to follow some of the code you sent me but am going to have to practice a little and report my progress to you. I am about to purchase an LPC2148 evaluation board and what i want to do with it first is to try and control an RC toy car. Am going to start simple and gradually carry out more complex tasks for example using sensors to drive the RC car or even GPS. I am a Mechatronics major (well, soon i'll be) so am more into systems control.
Thank you again!

----- Original Message ----
From: Fabio Filippa
To: l...
Sent: Wednesday, February 6, 2008 6:27:12 PM
Subject: R: [lpc2000] Introduction to Lpc2000 needed.



Hi mate,

also I'm started some months ago with a new design based on LPC2106 and

also my background was with PIC microcontrolloer

programmed ASM and C. I've found no more help on books or forum and all

I've do is just from my personal search and test, all the code

provided below is stripped from a my personal written working

application. I know that may be useful or not but this is what I've

liked

to see when I've started on working with this microcontroller and I've

not found from anyone and anywhere, this the reason why I've decided

to write this mini and not very well completed tutorial about this

stuff. I know write this is a matter of time, but I'm for free

opensource knowledge

(not for opensource production project but for sharing the knowledge

needed to build your own application :-)).

I hope that thsi can be useful is some way, anyway I can write more

detaild tutorial on solution and how to implement other stuff, also can

be

nice if other more skilled peple like to partecipate in a cook book

writing for sharing their experience, this can be viewed as a my first

starting contribute

then don't shoot to the pianist please :-).



Well as I written I can just spoke about my personal experience, I've

started with the IAR Kickstart kit for LPC2106 and code my application

in C language,

most of the code was a simple porting from Microchip (Hi-Tech compiler)

to the IAR system.



In order to start you can use the IAR example (I remember this is named

flashligth or somethings of similar), using this example you've all the

scheleton for build a

working application, you have just to write your code and make the

integration for the interrupt handling.



As used libray I've set:

#include

#include

#include

#include

#include // registry definition

#include "timer.h"

#include "lpc210x.h"

#include "io_macros.h"

#include "Flash_usage. h" // Used to manage the Flash as EEPROM, see

below to understand how to do it

#include "math.h"



....



I've written two interrupt function to manage the USART1, this ones was

called USART1_rx and

USART1_tx, here the function prototype:



void USART1_rx(unsigned char);

// USART1 (irq): callback function per RX

void USART1_tx(void) ;

// USART1 (irq): callback function per TX

and the code for each function:



void USART1_rx(unsigned char rxbyte)

{



asm("NOP");

asm("NOP");



SerRx = rxbyte; // read the data into the SerRx variable



// Put your rx code here and when a valid command

// is recognized set the rsFlag to 1, use this into the

// main() routine to know when we've a valid command to process,

// usually I set the process task at the end of the main cycle.



return;

}



void USART1_tx(void)

{



asm("NOP");

asm("NOP");



// Put your tx code here



return;

}



into the main() function you have to init the interrupt vector by using

this provided function:



LPC210xInitUART1Int errupt(USART1_ rx, USART1_tx); // Init the callback

function for use the USART1



Of course I've implemented reading and transmitting over the serial port

with interrupt, last question is how I can send data byte over

the serial port with interrupt? Well more simple, I've just defined two

buffer used in rx and tx and other useful variable:



unsigned char SerRx; // USART1: char from rx

unsigned char RxCtr; // USART1: counter of rx chars

unsigned char TxCtr; // USART1: counter of tx chars

unsigned char TxMaxChr; // USART1: maximum allowed rx char for

preventing overflow

unsigned char SerialBufferRx[ MAXSERBUF] ; // USART1: rx buffer

unsigned char SerialBufferTx[ MAXSERBUF] ; // USART1: tx buffer

unsigned char rsFlag; // USART1: flag used to signal into the main a

valid received command



.....



The main things now is how I can transmit over serial port by using the

interrupt feature, well is more simple, here my full code for

the TX routine:



void USART1_tx(void)

{



asm("NOP");

asm("NOP");



while(U1LSR_ bit.THRE == 1)

{

if (TxMaxChr > 0)

{

if ((TxCtr + 1) > TxMaxChr) // Check if I've

trasmitted all the char into the TX buffer

{

U1IER_bit.THREIE = 0; // reset the TX interrupt

TxCtr = 0; // reset the

trasmitting counter

TxMaxChr = 0; // reset the total

char counter that I've to be trasmitted

}

else

{

U1THR = SerialBufferTx[ TxCtr]; // Send a char from

the TX buffer

TxCtr = TxCtr + 1; // Update the

buffer pointer for the next char that has to be sended

}

}

else

break; // end of the while

}

return;

}



and also you've to use the following code to charge the buffer and start

the TX with the interrupt (suppose to send the *OK*

chars sequence):



SerialBufferTx[ 0] = '*'; // First char to send

SerialBufferTx[ 1] = 'O'

SerialBufferTx[ 2] = 'K';

SerialBufferTx[ 3] = '*'; // Last char to send

TxMaxChr = 4; // Max number of chars to send

TxCtr = 1; // Sended chars counter, set to 1 because

the first char is sended now to activate the IRQ



U1FCR_bit.TFR = 1; // Reset the UART1 FIFO TX

swithout send any char

U1THR = SerialBufferTx[ 0]; // Send the first chart, the

others will be send automatically with the interrupt code

U1IER_bit.THREIE = 1; // Enable the TX interrupt



that's all, I've working hard to found this solutions and now this work

very nicely witout trouble over all the production device, of course

what you've to do

is made your personal communication protocol (code has to be written

into the USART1_rx function), and then you can write at the end of the

microcontroller main

loop into the main() function your command handler like below:



void main() void

{

// Put here your code initialization, PLL, interrupt and so on

....



// main working loop (infinite loop to keep alive the

microcontroller)

while(1)

{

// Write here your application code



............ ......... ......... ......... ......... ......... ......... ..



// Serial command handler

if (rsFlag)

{

// Because the rsFlag is equal to 1 I've received a

command

// trough the serial port. Put your code here if the

command is simple or

// for better readability and coding style put all

into a

// dedicated function before the main().





............ ......... ......... ......... ......... ......... ......... ..



// End of the serial code processing

rsFlag = 0;

RxCtr = 0;

for (index = 0; index < MAXSERBUF; index++) // RX

buffer cleaning for next command

SerialBufferRx[ index]= '\0';

}

}

}



I think this is enough for now about the serial stuff.



------------ --------- --------- --------- --------- --------- -

------------ -------

HOW TO SET THE PIN FUNCTION, DIRECTION AND STATE

------------ --------- --------- --------- --------- --------- -

------------ ------

Some pin exibits multiple functions then you've to select what is the

pin behaviour, this task can be achieved by using the

PINSEL0 and PINSEL1 command like below:



PINSEL0 = 0x50000; // Set the UART1 pins

PINSEL1 = 0x00; //



of course take a look on the LPC2106 datasheet in order to know what is

the settings to do for other pins, in my application I've used the

default one (0x00 for every line) and

changed just the pin function to enable the USART 1.



Into the PIC you've a bsf and bcf assembly instruction to set and clear

a bit status, into the IAR C language set and clear and direction type

was performed

by using separate command, look at the following code to see how to do

it:



#define OUTPUT_TYPE 1

#define INPUT_TYPE 0



IODIR_bit.P0_ 4 = OUTPUT_TYPE; // Set the PO_4 line as output



IOCLR_bit.P0_ 4 = 1; // Set the P0_4 value to 0 (0V)

IOSET_bit.P0_ 4 = 1; // Set the PO_4 value to 1 (approx 3.3 V)



Another example about set the line as input:



IODIR_bit.P0_ 16 = INPUT_TYPE; // Set the PO_16 line as input



to read the status of the PO_16 line configured as input write for

example:



if (IOPIN_bit.P0_ 16 == 0)

{

// make somethings if the PO_16 line has a low level applied

}



------------ --------- --------- --------- --------- --------- -

------------ --------- --------- ------

HOW TO USE THE FLASH MEMORY AS A INTERNAL EEPROM

------------ --------- --------- --------- --------- --------- -

------------ --------- --------- ------

This is about pin settings, another issue is about the absence of the

EEPROM memory like into the PIC one.

As a workaround you can use some flash sector (I've used the block 14)

in order to simulate the EEPROM behaviour, what I've did was

read in a buffer the entire sector, make the change into the sector,

write back the entire sector. You've to make

a copy of the sector in a buffer because writing is a sector based

operation.

To do this I've make some change to a existent code and now the read and

write operation is simple as into the PIC because

all the needed stuff was performed under the hood.



Here is the code that you've to put in a source file with name

Flash_usage. c:



// ------------ -- START OF THE CODE (Flash_usage. c)

#include

#include

#include // For interrupt macro

#include "Flash_usage. h"



typedef struct SLayout {

int sectors;

int size;

} Layout;



static IAP iap_entry = (IAP)kIAPentry; // MCU flash firmware

interface function.

static unsigned long sectorbuf[WRITE_ SIZE/4]; // The sector buffer must

be word aligned.

// The CPU clock speed (CCLK), the default value is used if no clock

option is found.

static int clock = CCLK;



//========== ========= ========= ========= =========

// 128k flash, 1'st generation

// LPC2104 (16k RAM)

// LPC2105 (32k RAM)

// LPC2106 (64k RAM)

// LPC2114 (16k RAM)

// LPC2212 (16k RAM)

// LPC2119 (16k RAM)

//========== ========= ========= ========= =========

#define FLASH_SIZE 0x1E000

#include



const Layout flashLayout[ ] =

{

{15, 8192},

{ 0, 0}

};



const int allowedWriteSizes[ ] =

{

512,

1024,

4096,

8192,

0

};



//

------------ --------- --------- --------- --------- --------- -

// Returns the flash sector number for a given flash address.

// Returns -1 if the address is outside the flash.

//

------------ --------- --------- --------- --------- --------- -

int CalculateSector( unsigned long addr, int *erase_sector)

{

int i;

int j;

int sector = 0;

unsigned long current = 0;



*erase_sector = 0;

for (i = 0; flashLayout[ i].sectors; i++)

{

for (j = 0; j < flashLayout[ i].sectors; j++)

{

if (addr < current + flashLayout[ i].size)

{

if (addr < current + WRITE_SIZE)

{

*erase_sector = 1;

}

return sector;

}

sector++;

current += flashLayout[ i].size;

}

}

return -1;

}



//

------------ --------- --------- --------- --------- --------- -

// Execute a flash firmware command.

//

------------ --------- --------- --------- --------- --------- -

int ExecuteCommand( unsigned long* cmd, unsigned long* status)

{

int ret;



for (;;)

{

iap_entry(cmd, status);

ret = status[0];

if (ret != STATUS_BUSY)

{

return ret;

}

// Try again if busy.

}

}



//

------------ --------- --------- --------- --------- --------- -

// Program a sector. The device allows fractions of a sector to be

written.

// dst - the flash address to start writing at.

// src - the address of the data buffer to be written.

// size - the number of bytes in the data buffer to write.

//

------------ --------- --------- --------- --------- --------- -

unsigned char ProgramFlash( unsigned long dst, unsigned long* src, int

size)

{

int i;

int ret;

int sector;

int erase_sector;

unsigned long sum;

unsigned long cmd[6];

unsigned long status[3];



// User Flash mode

MEMMAP = 1;



// Disabilita interrupt

__disable_interrupt ();



// Round up size to nearest allowable write size.

for (i = 0; allowedWriteSizes[ i]; i++)

{

if (size <= allowedWriteSizes[ i])

{

size = allowedWriteSizes[ i];

break;

}

}



sector = CalculateSector( dst, &erase_sector) ;



if (dst + size > FLASH_SIZE || sector == -1)

{

return(0);

}



// Check for first part of sector 0 and that a reset vector is

present,

// note that the buffer is initialized to all 1's.

if (sector == 0 && erase_sector && src[0] != 0xffffffff)

{

// Calculate exception vector 0x14 if the sector is zero and a

reset address is present.

sum = src[0] + src[1] + src[2] + src[3] +

src[4] + src[6] + src[7];

src[5] = -sum; // Vector 0x14.

}



// Prepare sector for erase.

cmd[0] = CMD_PREPARE_ SECTORS;

cmd[1] = sector;

cmd[2] = sector;

ret = ExecuteCommand( cmd, status);



if (ret != STATUS_CMD_SUCCESS)

{

return(0);

}



if (erase_sector)

{

// Erase sector.

cmd[0] = CMD_ERASE_SECTORS;

cmd[1] = sector;

cmd[2] = sector;

cmd[3] = clock;

ret = ExecuteCommand( cmd, status);

if (ret != STATUS_CMD_SUCCESS)

{

return(0);

}

}



// Prepare sector for write.

cmd[0] = CMD_PREPARE_ SECTORS;

cmd[1] = sector;

cmd[2] = sector;

ret = ExecuteCommand( cmd, status);

if (ret != STATUS_CMD_SUCCESS)

{

return(0);

}



// Program sector.

cmd[0] = CMD_COPY_RAM_ TO_FLASH;

cmd[1] = dst;

cmd[2] = (unsigned long)src;

cmd[3] = size;

cmd[4] = clock;

ret = ExecuteCommand( cmd, status);



if (ret != STATUS_CMD_SUCCESS)

{

return(0);

}



// Enable the interrupt

__enable_interrupt( );



// All was fine

return(1);

}



//

------------ --------- --------- --------- --------- --------- -

// Write one byte to flash at addr.

// The bytes are first buffered in sectorbuf, this array is at first

// filled with the old flash data and then updated with the new one.

// The sectorbuf is written to the flash when it overflows or when

// he user call the routine with byte equal to -1.

//

------------ --------- --------- --------- --------- --------- -

void FlashWriteByte( unsigned long addr, int byte)

{

int i;

int offset; // Current offset into sector

buffer.

static int bytes = 0; // Number of bytes in the

sector buffer (including gaps).

static int base_addr; // Pysical address of the

start of the sector.

unsigned long flashaddr = 0x0001C000; // First address block 14



restart:

if (bytes == 0) // First byte of a new sector.

{

// This is the first time that we try to write some byte

// then we've to check for the total byte remainder

// before reach the maximum size, then the data storage

// buffer will be initialized.

bytes = addr % WRITE_SIZE;

base_addr = addr - bytes; // Calculate physical start address of

this sector.



// Intialize sector buffer with the pre-existent data to

// preserve all the remainder data which is stored in Flash.

// Size il WRITE_SIZE / 4 due to the fact that flashbyte is 32 bit

in length

for (i = 0; i < WRITE_SIZE/4; i++)

{

sectorbuf[i] =*((unsigned long*)flashaddr) ;

flashaddr += 4;

}

}



// Write sector buffer to the flash memory if a flush is requested

(byte = -1)

// or the new byte address is beyond the sector buffer.

if (byte == -1 || addr - base_addr >= WRITE_SIZE)

{

ProgramFlash( base_addr, sectorbuf, bytes);



if (byte == -1)

{

return; // This was a flush operation, all data is written.

}



// We've write the data which is pushed into the storage sectorbuf

// then we can reset the byte count for future writing

bytes = 0;



goto restart;

}



// Store byte in sector buffer.

offset = addr - base_addr;

((unsigned char*)sectorbuf) [offset] = (byte & 0x00FF);

bytes = offset + 1;



return;

}

// ------------ ---END OF THE CODE (Flash_usage. c)



there is also some other code to put in a header file with name

Flash_usage. h.



// ------------ -- START OF THE CODE (Flash_usage. h)

#define CCLK 14746



// The write size is not critical to performance.

// 512 bytes is a good size that leaves as much room to the JTAG

// read buffer as possible and is supported by all flash devices.

#define WRITE_SIZE 512



#define kIAPentry 0x7ffffff1



enum {

CMD_PREPARE_ SECTORS = 50,

CMD_COPY_RAM_ TO_FLASH,

CMD_ERASE_SECTORS,

CMD_BLANK_CHECK_ SECTORS,

CMD_READ_PART_ ID,

CMD_READ_BOOT_ CODE_VERSION,

CMD_COMPARE,

};



enum {

STATUS_CMD_SUCCESS = 0,

STATUS_INVALID_ COMMAND,

STATUS_SRC_ADDR_ ERROR,

STATUS_DST_ADDR_ ERROR,

STATUS_SRC_ADDR_ NOT_MAPPED,

STATUS_DST_ADDR_ NOT_MAPPED,

STATUS_COUNT_ ERROR,

STATUS_INVALID_ SECTOR,

STATUS_SECTOR_ NOT_BLANK,

STATUS_SECTOR_ NOT_PREPARED_ FOR_WRITE_ OPERATION,

STATUS_COMPARE_ ERROR,

STATUS_BUSY,

};



typedef void (__thumb *IAP)(void*, void*);



// ------------ --------- -----

// Function definition

// ------------ --------- -----

int ExecuteCommand( unsigned long* , unsigned long* );

unsigned char ProgramFlash( unsigned long , unsigned long* , int );

void FlashWriteByte( unsigned long , int );

// ------------ ---END OF THE CODE (Flash_usage. h)



>From a pratical point of view using the Flash require to set a sort of

memory map, I've do it with a set of define

statements as below:



// ------------ --------- --------- --------- --------- --------- -

// DEFINE FLASH section data (block 14)

// ------------ --------- --------- --------- --------- --------- -

#define ADDR_FLASH_BASEADDR 0x0001C000 // FLASH: first useful

address

#define ADDR_CODE_HYBYTE 0x0001C000 // FLASH: param1 (hi byte)

device code

#define ADDR_CODE_LOBYTE 0x0001C004 // FLASH: param1 (lo byte)

device code

#define ADDR_ADDRESS_ BYTE 0x0001C008 // FLASH: param2 (one byte)

device address (0x00 to 0xFF)

#define ADDR_POWERON_ HYBYTE 0x0001C00C // FLASH: param3 (hi byte)

power on counter

#define ADDR_POWERON_ LOBYTE 0x0001C010 // FLASH: param3 (lo byte)

power on counter

....



and below ther is a example how you can use the Flashing routine, in

this example I simply read back the power on counter

from the flash, update the value by 1 and write back the updated value

into the Flash, I've used this code on the starting of the

main() code then every power up I can update the counter and know if the

device was powered and the number of the time.



// ------------ --------- --------- --------- --------- --------- -

// Read the power on register update and write back into the Flash

// ------------ --------- --------- --------- --------- --------- -

ulFlashAddress = (unsigned long)ADDR_POWERON_ LOBYTE;

lobyte = *((int*)ulFlashAddr ess) & 0x000000FF;

ulFlashAddress = (unsigned long)ADDR_POWERON_ HYBYTE;

hybyte = *((int*)ulFlashAddr ess) & 0x000000FF;

iNumberPowerOn = hybyte * 256 + lobyte;

iNumberPowerOn += 1;

lobyte = iNumberPowerOn & 0x000000FF;

hybyte = ((iNumberPowerOn & 0x0000FF00) >> 8) & 0x000000FF;



ulFlashAddress = (unsigned long)ADDR_POWERON_ LOBYTE;

FlashWriteByte( ulFlashAddress, lobyte);

ulFlashAddress = (unsigned long)ADDR_POWERON_ HYBYTE;

FlashWriteByte( ulFlashAddress, hybyte);



ulFlashAddress= (unsigned long)ADDR_FLASH_ BASEADDR;

FlashWriteByte( ulFlashAddress, -1); // Update the Flash



....



------------ --------- --------- --------- --------- --------- -

-------

SPEED ISSUE, CORE CLOCK, PERIPHERAL CLOCK

------------ --------- --------- --------- --------- --------- -

-------



I've changed the micro from PIC to ARM into my design mainly for speed

issue, take in mind that you've a internal PLL that is usful to keep the

microcontroller core working at the maximum available speed (60 MHz for

the PLC2106).

To achieve this goal you've to work around two stuff, the peripheral

clock frequency and the internal PLL.



The output peripheral speed is a new feature respect the PIC

microncontroller, you can choose to update the output at the

external clock or the core clock, for my issue I've to use the maximum

speed the I've set the peripheral clock equal to core clock

and this one can be done by writing this statements:



VPBDIV = 0x01;



Also to reach the maximum core clock you've to set properly the internal

PLL, to do this use a external crystal of 14,7456 MHz + 30ppm

with two capacitors of 18 pF and set the internal PLL to work at the

maximum frequency with the code listed below:



// ------------ --------- --------- --------- --------- ------

// Set the internal PLL to work with a core clock of 60 MHz

// with a external clock of 14.745 MHz.

// M = 4, P = 2

// ------------ --------- --------- --------- --------- ------

PLLCFG = 0x23;

PLLCON = 0x01;

PLLFEED = 0xAA;

PLLFEED = 0x55;

while (!(PLLSTAT & 0x400)) {}

PLLCON = 0x03;

PLLFEED = 0xAA;

PLLFEED = 0x55;



Also there is another stuff to keep in mind, core clock and peripheral

clock is set at the same value and also at the maximum

available frequency (60 MHz) but you drive the output pin from the code

and this one can be executed on Flash or RAM memory.

If the code will be executed from Flash you have a limit from the Flash

access time then you can't reach the maximum output frequency,

to overcome this you've two choice, use the MAM (Memory Acceleration

Module) module or simply get the code executed from the ram.

MAM is a trick to execute code from ram but is not useful if you have

jump over the code because the fetch queue has to be updated and then

the speed is limited by Flash access, I've used the ram execution

option, only drawback is the used memory, but you reach the goal by

carefully

choosing what code or function has to be executed from ram.

To do this simply add the keyword __ramfunc before the function

declaration (no need to add it also to the function code), here is one

example

how to use it:



// Function prototipe

__ramfunc signed int ReadInterface( void);



.....



// Function definition

signed int ReadInterface( void)

{

.......

return readed_value;

}



------------ --------- --------- ------

INTERRUPT HANDLING

------------ --------- --------- ------

Also interrupt handling is simple but different than into the PIC

microcontrollers, into the ARM architecture you've a

interrupt vector that must be filled with the function address that will

be called on the interrupt event.



------------ --------- --------- ------

FINAL REMARKS

------------ --------- --------- ------

If you need more specifical infos let me know I'll be happy helping you

in starting, I know the difficult also when I've started

with this new microcontroller family I've do all by myself then now I

can share my little knowledge/experienc e to other...

I'm for open source knowledge :-)



Best regards

Fabio Filippa



-----Messaggio originale--- --

Da: Senkumba Edwin [mailto:eddouble86@yahoo. com]

Inviato: mercoled6 febbraio 2008 6.33

A: lpc2000@yahoogroups .com

Oggetto: [lpc2000] Introduction to Lpc2000 needed.

Hello Everyone,

I am new to the microcontroller and am trying to understand it, i was

reading up on PIC ucontrollers before and the book i was reading

emphasised on using Assembly language. I was recently advised to look at

using the Philips lpc2148 to control an RC toy car (my first project)

but i dont know much about the lpc2000 series and found out that it is

programmed in C, so the information i got from the PIC book wont be of

much help.

All i know about microcontrollers is that they have a couple of GPIO

(that would general purpose Inout and output right?) and that these IO's

are connected to the ports inside (like PORTA and PORTB for the PIC16F54

i was reading on). The ports are arranged in a file cabinet system with

each cabinet being a file register. This file registers store

information which is accessed (or moved aorund) using the working

register.

So far thats as much as i know regarding the PIC16F5x. I need to know if

what i know could help me with the lpc2148 and where i could get more

information. I would aslo like to know the basic programming

instructions used with the ucontroller, though am not so strong at using

the C language but i am working on that right now. Any help would be

much appreciated, thank you.

P.S A little more about myself, I am an Engineering Undergraduate. So

all the above Information search is school based.

Edwin.

____________ _________ _________ _________ _________ _________ _

Looking for last minute shopping deals?

Find them fast with Yahoo! Search. http://tools.



search.yahoo. com/newsearch/ category. php?category= shopping

















____________________________________________________________________________________
Never miss a thing. Make Yahoo your home page.
http://www.yahoo.com/r/hs





Hi Fabio,
First of all let me thank you for your time to help me out. I am somehow able to follow some of the code you sent me but am going to have to practice a little and report my progress to you. I am about to purchase an LPC2148 evaluation board and what i want to do with it first is to try and control an RC toy car. Am going to start simple and gradually carry out more complex tasks for example using sensors to drive the RC car or even GPS. I am a Mechatronics major (well, soon i'll be) so am more into systems control.
Thank you again!

----- Original Message ----
From: Fabio Filippa
To: l...
Sent: Wednesday, February 6, 2008 6:27:12 PM
Subject: R: [lpc2000] Introduction to Lpc2000 needed.



Hi mate,

also I'm started some months ago with a new design based on LPC2106 and

also my background was with PIC microcontrolloer

programmed ASM and C. I've found no more help on books or forum and all

I've do is just from my personal search and test, all the code

provided below is stripped from a my personal written working

application. I know that may be useful or not but this is what I've

liked

to see when I've started on working with this microcontroller and I've

not found from anyone and anywhere, this the reason why I've decided

to write this mini and not very well completed tutorial about this

stuff. I know write this is a matter of time, but I'm for free

opensource knowledge

(not for opensource production project but for sharing the knowledge

needed to build your own application :-)).

I hope that thsi can be useful is some way, anyway I can write more

detaild tutorial on solution and how to implement other stuff, also can

be

nice if other more skilled peple like to partecipate in a cook book

writing for sharing their experience, this can be viewed as a my first

starting contribute

then don't shoot to the pianist please :-).



Well as I written I can just spoke about my personal experience, I've

started with the IAR Kickstart kit for LPC2106 and code my application

in C language,

most of the code was a simple porting from Microchip (Hi-Tech compiler)

to the IAR system.



In order to start you can use the IAR example (I remember this is named

flashligth or somethings of similar), using this example you've all the

scheleton for build a

working application, you have just to write your code and make the

integration for the interrupt handling.



As used libray I've set:

#include

#include

#include

#include

#include // registry definition

#include "timer.h"

#include "lpc210x.h"

#include "io_macros.h"

#include "Flash_usage. h" // Used to manage the Flash as EEPROM, see

below to understand how to do it

#include "math.h"



....



I've written two interrupt function to manage the USART1, this ones was

called USART1_rx and

USART1_tx, here the function prototype:



void USART1_rx(unsigned char);

// USART1 (irq): callback function per RX

void USART1_tx(void) ;

// USART1 (irq): callback function per TX

and the code for each function:



void USART1_rx(unsigned char rxbyte)

{



asm("NOP");

asm("NOP");



SerRx = rxbyte; // read the data into the SerRx variable



// Put your rx code here and when a valid command

// is recognized set the rsFlag to 1, use this into the

// main() routine to know when we've a valid command to process,

// usually I set the process task at the end of the main cycle.



return;

}



void USART1_tx(void)

{



asm("NOP");

asm("NOP");



// Put your tx code here



return;

}



into the main() function you have to init the interrupt vector by using

this provided function:



LPC210xInitUART1Int errupt(USART1_ rx, USART1_tx); // Init the callback

function for use the USART1



Of course I've implemented reading and transmitting over the serial port

with interrupt, last question is how I can send data byte over

the serial port with interrupt? Well more simple, I've just defined two

buffer used in rx and tx and other useful variable:



unsigned char SerRx; // USART1: char from rx

unsigned char RxCtr; // USART1: counter of rx chars

unsigned char TxCtr; // USART1: counter of tx chars

unsigned char TxMaxChr; // USART1: maximum allowed rx char for

preventing overflow

unsigned char SerialBufferRx[ MAXSERBUF] ; // USART1: rx buffer

unsigned char SerialBufferTx[ MAXSERBUF] ; // USART1: tx buffer

unsigned char rsFlag; // USART1: flag used to signal into the main a

valid received command



.....



The main things now is how I can transmit over serial port by using the

interrupt feature, well is more simple, here my full code for

the TX routine:



void USART1_tx(void)

{



asm("NOP");

asm("NOP");



while(U1LSR_ bit.THRE == 1)

{

if (TxMaxChr > 0)

{

if ((TxCtr + 1) > TxMaxChr) // Check if I've

trasmitted all the char into the TX buffer

{

U1IER_bit.THREIE = 0; // reset the TX interrupt

TxCtr = 0; // reset the

trasmitting counter

TxMaxChr = 0; // reset the total

char counter that I've to be trasmitted

}

else

{

U1THR = SerialBufferTx[ TxCtr]; // Send a char from

the TX buffer

TxCtr = TxCtr + 1; // Update the

buffer pointer for the next char that has to be sended

}

}

else

break; // end of the while

}

return;

}



and also you've to use the following code to charge the buffer and start

the TX with the interrupt (suppose to send the *OK*

chars sequence):



SerialBufferTx[ 0] = '*'; // First char to send

SerialBufferTx[ 1] = 'O'

SerialBufferTx[ 2] = 'K';

SerialBufferTx[ 3] = '*'; // Last char to send

TxMaxChr = 4; // Max number of chars to send

TxCtr = 1; // Sended chars counter, set to 1 because

the first char is sended now to activate the IRQ



U1FCR_bit.TFR = 1; // Reset the UART1 FIFO TX

swithout send any char

U1THR = SerialBufferTx[ 0]; // Send the first chart, the

others will be send automatically with the interrupt code

U1IER_bit.THREIE = 1; // Enable the TX interrupt



that's all, I've working hard to found this solutions and now this work

very nicely witout trouble over all the production device, of course

what you've to do

is made your personal communication protocol (code has to be written

into the USART1_rx function), and then you can write at the end of the

microcontroller main

loop into the main() function your command handler like below:



void main() void

{

// Put here your code initialization, PLL, interrupt and so on

....



// main working loop (infinite loop to keep alive the

microcontroller)

while(1)

{

// Write here your application code



............ ......... ......... ......... ......... ......... ......... ..



// Serial command handler

if (rsFlag)

{

// Because the rsFlag is equal to 1 I've received a

command

// trough the serial port. Put your code here if the

command is simple or

// for better readability and coding style put all

into a

// dedicated function before the main().





............ ......... ......... ......... ......... ......... ......... ..



// End of the serial code processing

rsFlag = 0;

RxCtr = 0;

for (index = 0; index < MAXSERBUF; index++) // RX

buffer cleaning for next command

SerialBufferRx[ index]= '\0';

}

}

}



I think this is enough for now about the serial stuff.



------------ --------- --------- --------- --------- --------- -

------------ -------

HOW TO SET THE PIN FUNCTION, DIRECTION AND STATE

------------ --------- --------- --------- --------- --------- -

------------ ------

Some pin exibits multiple functions then you've to select what is the

pin behaviour, this task can be achieved by using the

PINSEL0 and PINSEL1 command like below:



PINSEL0 = 0x50000; // Set the UART1 pins

PINSEL1 = 0x00; //



of course take a look on the LPC2106 datasheet in order to know what is

the settings to do for other pins, in my application I've used the

default one (0x00 for every line) and

changed just the pin function to enable the USART 1.



Into the PIC you've a bsf and bcf assembly instruction to set and clear

a bit status, into the IAR C language set and clear and direction type

was performed

by using separate command, look at the following code to see how to do

it:



#define OUTPUT_TYPE 1

#define INPUT_TYPE 0



IODIR_bit.P0_ 4 = OUTPUT_TYPE; // Set the PO_4 line as output



IOCLR_bit.P0_ 4 = 1; // Set the P0_4 value to 0 (0V)

IOSET_bit.P0_ 4 = 1; // Set the PO_4 value to 1 (approx 3.3 V)



Another example about set the line as input:



IODIR_bit.P0_ 16 = INPUT_TYPE; // Set the PO_16 line as input



to read the status of the PO_16 line configured as input write for

example:



if (IOPIN_bit.P0_ 16 == 0)

{

// make somethings if the PO_16 line has a low level applied

}



------------ --------- --------- --------- --------- --------- -

------------ --------- --------- ------

HOW TO USE THE FLASH MEMORY AS A INTERNAL EEPROM

------------ --------- --------- --------- --------- --------- -

------------ --------- --------- ------

This is about pin settings, another issue is about the absence of the

EEPROM memory like into the PIC one.

As a workaround you can use some flash sector (I've used the block 14)

in order to simulate the EEPROM behaviour, what I've did was

read in a buffer the entire sector, make the change into the sector,

write back the entire sector. You've to make

a copy of the sector in a buffer because writing is a sector based

operation.

To do this I've make some change to a existent code and now the read and

write operation is simple as into the PIC because

all the needed stuff was performed under the hood.



Here is the code that you've to put in a source file with name

Flash_usage. c:



// ------------ -- START OF THE CODE (Flash_usage. c)

#include

#include

#include // For interrupt macro

#include "Flash_usage. h"



typedef struct SLayout {

int sectors;

int size;

} Layout;



static IAP iap_entry = (IAP)kIAPentry; // MCU flash firmware

interface function.

static unsigned long sectorbuf[WRITE_ SIZE/4]; // The sector buffer must

be word aligned.

// The CPU clock speed (CCLK), the default value is used if no clock

option is found.

static int clock = CCLK;



//========== ========= ========= ========= =========

// 128k flash, 1'st generation

// LPC2104 (16k RAM)

// LPC2105 (32k RAM)

// LPC2106 (64k RAM)

// LPC2114 (16k RAM)

// LPC2212 (16k RAM)

// LPC2119 (16k RAM)

//========== ========= ========= ========= =========

#define FLASH_SIZE 0x1E000

#include



const Layout flashLayout[ ] =

{

{15, 8192},

{ 0, 0}

};



const int allowedWriteSizes[ ] =

{

512,

1024,

4096,

8192,

0

};



//

------------ --------- --------- --------- --------- --------- -

// Returns the flash sector number for a given flash address.

// Returns -1 if the address is outside the flash.

//

------------ --------- --------- --------- --------- --------- -

int CalculateSector( unsigned long addr, int *erase_sector)

{

int i;

int j;

int sector = 0;

unsigned long current = 0;



*erase_sector = 0;

for (i = 0; flashLayout[ i].sectors; i++)

{

for (j = 0; j < flashLayout[ i].sectors; j++)

{

if (addr < current + flashLayout[ i].size)

{

if (addr < current + WRITE_SIZE)

{

*erase_sector = 1;

}

return sector;

}

sector++;

current += flashLayout[ i].size;

}

}

return -1;

}



//

------------ --------- --------- --------- --------- --------- -

// Execute a flash firmware command.

//

------------ --------- --------- --------- --------- --------- -

int ExecuteCommand( unsigned long* cmd, unsigned long* status)

{

int ret;



for (;;)

{

iap_entry(cmd, status);

ret = status[0];

if (ret != STATUS_BUSY)

{

return ret;

}

// Try again if busy.

}

}



//

------------ --------- --------- --------- --------- --------- -

// Program a sector. The device allows fractions of a sector to be

written.

// dst - the flash address to start writing at.

// src - the address of the data buffer to be written.

// size - the number of bytes in the data buffer to write.

//

------------ --------- --------- --------- --------- --------- -

unsigned char ProgramFlash( unsigned long dst, unsigned long* src, int

size)

{

int i;

int ret;

int sector;

int erase_sector;

unsigned long sum;

unsigned long cmd[6];

unsigned long status[3];



// User Flash mode

MEMMAP = 1;



// Disabilita interrupt

__disable_interrupt ();



// Round up size to nearest allowable write size.

for (i = 0; allowedWriteSizes[ i]; i++)

{

if (size <= allowedWriteSizes[ i])

{

size = allowedWriteSizes[ i];

break;

}

}



sector = CalculateSector( dst, &erase_sector) ;



if (dst + size > FLASH_SIZE || sector == -1)

{

return(0);

}



// Check for first part of sector 0 and that a reset vector is

present,

// note that the buffer is initialized to all 1's.

if (sector == 0 && erase_sector && src[0] != 0xffffffff)

{

// Calculate exception vector 0x14 if the sector is zero and a

reset address is present.

sum = src[0] + src[1] + src[2] + src[3] +

src[4] + src[6] + src[7];

src[5] = -sum; // Vector 0x14.

}



// Prepare sector for erase.

cmd[0] = CMD_PREPARE_ SECTORS;

cmd[1] = sector;

cmd[2] = sector;

ret = ExecuteCommand( cmd, status);



if (ret != STATUS_CMD_SUCCESS)

{

return(0);

}



if (erase_sector)

{

// Erase sector.

cmd[0] = CMD_ERASE_SECTORS;

cmd[1] = sector;

cmd[2] = sector;

cmd[3] = clock;

ret = ExecuteCommand( cmd, status);

if (ret != STATUS_CMD_SUCCESS)

{

return(0);

}

}



// Prepare sector for write.

cmd[0] = CMD_PREPARE_ SECTORS;

cmd[1] = sector;

cmd[2] = sector;

ret = ExecuteCommand( cmd, status);

if (ret != STATUS_CMD_SUCCESS)

{

return(0);

}



// Program sector.

cmd[0] = CMD_COPY_RAM_ TO_FLASH;

cmd[1] = dst;

cmd[2] = (unsigned long)src;

cmd[3] = size;

cmd[4] = clock;

ret = ExecuteCommand( cmd, status);



if (ret != STATUS_CMD_SUCCESS)

{

return(0);

}



// Enable the interrupt

__enable_interrupt( );



// All was fine

return(1);

}



//

------------ --------- --------- --------- --------- --------- -

// Write one byte to flash at addr.

// The bytes are first buffered in sectorbuf, this array is at first

// filled with the old flash data and then updated with the new one.

// The sectorbuf is written to the flash when it overflows or when

// he user call the routine with byte equal to -1.

//

------------ --------- --------- --------- --------- --------- -

void FlashWriteByte( unsigned long addr, int byte)

{

int i;

int offset; // Current offset into sector

buffer.

static int bytes = 0; // Number of bytes in the

sector buffer (including gaps).

static int base_addr; // Pysical address of the

start of the sector.

unsigned long flashaddr = 0x0001C000; // First address block 14



restart:

if (bytes == 0) // First byte of a new sector.

{

// This is the first time that we try to write some byte

// then we've to check for the total byte remainder

// before reach the maximum size, then the data storage

// buffer will be initialized.

bytes = addr % WRITE_SIZE;

base_addr = addr - bytes; // Calculate physical start address of

this sector.



// Intialize sector buffer with the pre-existent data to

// preserve all the remainder data which is stored in Flash.

// Size il WRITE_SIZE / 4 due to the fact that flashbyte is 32 bit

in length

for (i = 0; i < WRITE_SIZE/4; i++)

{

sectorbuf[i] =*((unsigned long*)flashaddr) ;

flashaddr += 4;

}

}



// Write sector buffer to the flash memory if a flush is requested

(byte = -1)

// or the new byte address is beyond the sector buffer.

if (byte == -1 || addr - base_addr >= WRITE_SIZE)

{

ProgramFlash( base_addr, sectorbuf, bytes);



if (byte == -1)

{

return; // This was a flush operation, all data is written.

}



// We've write the data which is pushed into the storage sectorbuf

// then we can reset the byte count for future writing

bytes = 0;



goto restart;

}



// Store byte in sector buffer.

offset = addr - base_addr;

((unsigned char*)sectorbuf) [offset] = (byte & 0x00FF);

bytes = offset + 1;



return;

}

// ------------ ---END OF THE CODE (Flash_usage. c)



there is also some other code to put in a header file with name

Flash_usage. h.



// ------------ -- START OF THE CODE (Flash_usage. h)

#define CCLK 14746



// The write size is not critical to performance.

// 512 bytes is a good size that leaves as much room to the JTAG

// read buffer as possible and is supported by all flash devices.

#define WRITE_SIZE 512



#define kIAPentry 0x7ffffff1



enum {

CMD_PREPARE_ SECTORS = 50,

CMD_COPY_RAM_ TO_FLASH,

CMD_ERASE_SECTORS,

CMD_BLANK_CHECK_ SECTORS,

CMD_READ_PART_ ID,

CMD_READ_BOOT_ CODE_VERSION,

CMD_COMPARE,

};



enum {

STATUS_CMD_SUCCESS = 0,

STATUS_INVALID_ COMMAND,

STATUS_SRC_ADDR_ ERROR,

STATUS_DST_ADDR_ ERROR,

STATUS_SRC_ADDR_ NOT_MAPPED,

STATUS_DST_ADDR_ NOT_MAPPED,

STATUS_COUNT_ ERROR,

STATUS_INVALID_ SECTOR,

STATUS_SECTOR_ NOT_BLANK,

STATUS_SECTOR_ NOT_PREPARED_ FOR_WRITE_ OPERATION,

STATUS_COMPARE_ ERROR,

STATUS_BUSY,

};



typedef void (__thumb *IAP)(void*, void*);



// ------------ --------- -----

// Function definition

// ------------ --------- -----

int ExecuteCommand( unsigned long* , unsigned long* );

unsigned char ProgramFlash( unsigned long , unsigned long* , int );

void FlashWriteByte( unsigned long , int );

// ------------ ---END OF THE CODE (Flash_usage. h)



>From a pratical point of view using the Flash require to set a sort of

memory map, I've do it with a set of define

statements as below:



// ------------ --------- --------- --------- --------- --------- -

// DEFINE FLASH section data (block 14)

// ------------ --------- --------- --------- --------- --------- -

#define ADDR_FLASH_BASEADDR 0x0001C000 // FLASH: first useful

address

#define ADDR_CODE_HYBYTE 0x0001C000 // FLASH: param1 (hi byte)

device code

#define ADDR_CODE_LOBYTE 0x0001C004 // FLASH: param1 (lo byte)

device code

#define ADDR_ADDRESS_ BYTE 0x0001C008 // FLASH: param2 (one byte)

device address (0x00 to 0xFF)

#define ADDR_POWERON_ HYBYTE 0x0001C00C // FLASH: param3 (hi byte)

power on counter

#define ADDR_POWERON_ LOBYTE 0x0001C010 // FLASH: param3 (lo byte)

power on counter

....



and below ther is a example how you can use the Flashing routine, in

this example I simply read back the power on counter

from the flash, update the value by 1 and write back the updated value

into the Flash, I've used this code on the starting of the

main() code then every power up I can update the counter and know if the

device was powered and the number of the time.



// ------------ --------- --------- --------- --------- --------- -

// Read the power on register update and write back into the Flash

// ------------ --------- --------- --------- --------- --------- -

ulFlashAddress = (unsigned long)ADDR_POWERON_ LOBYTE;

lobyte = *((int*)ulFlashAddr ess) & 0x000000FF;

ulFlashAddress = (unsigned long)ADDR_POWERON_ HYBYTE;

hybyte = *((int*)ulFlashAddr ess) & 0x000000FF;

iNumberPowerOn = hybyte * 256 + lobyte;

iNumberPowerOn += 1;

lobyte = iNumberPowerOn & 0x000000FF;

hybyte = ((iNumberPowerOn & 0x0000FF00) >> 8) & 0x000000FF;



ulFlashAddress = (unsigned long)ADDR_POWERON_ LOBYTE;

FlashWriteByte( ulFlashAddress, lobyte);

ulFlashAddress = (unsigned long)ADDR_POWERON_ HYBYTE;

FlashWriteByte( ulFlashAddress, hybyte);



ulFlashAddress= (unsigned long)ADDR_FLASH_ BASEADDR;

FlashWriteByte( ulFlashAddress, -1); // Update the Flash



....



------------ --------- --------- --------- --------- --------- -

-------

SPEED ISSUE, CORE CLOCK, PERIPHERAL CLOCK

------------ --------- --------- --------- --------- --------- -

-------



I've changed the micro from PIC to ARM into my design mainly for speed

issue, take in mind that you've a internal PLL that is usful to keep the

microcontroller core working at the maximum available speed (60 MHz for

the PLC2106).

To achieve this goal you've to work around two stuff, the peripheral

clock frequency and the internal PLL.



The output peripheral speed is a new feature respect the PIC

microncontroller, you can choose to update the output at the

external clock or the core clock, for my issue I've to use the maximum

speed the I've set the peripheral clock equal to core clock

and this one can be done by writing this statements:



VPBDIV = 0x01;



Also to reach the maximum core clock you've to set properly the internal

PLL, to do this use a external crystal of 14,7456 MHz + 30ppm

with two capacitors of 18 pF and set the internal PLL to work at the

maximum frequency with the code listed below:



// ------------ --------- --------- --------- --------- ------

// Set the internal PLL to work with a core clock of 60 MHz

// with a external clock of 14.745 MHz.

// M = 4, P = 2

// ------------ --------- --------- --------- --------- ------

PLLCFG = 0x23;

PLLCON = 0x01;

PLLFEED = 0xAA;

PLLFEED = 0x55;

while (!(PLLSTAT & 0x400)) {}

PLLCON = 0x03;

PLLFEED = 0xAA;

PLLFEED = 0x55;



Also there is another stuff to keep in mind, core clock and peripheral

clock is set at the same value and also at the maximum

available frequency (60 MHz) but you drive the output pin from the code

and this one can be executed on Flash or RAM memory.

If the code will be executed from Flash you have a limit from the Flash

access time then you can't reach the maximum output frequency,

to overcome this you've two choice, use the MAM (Memory Acceleration

Module) module or simply get the code executed from the ram.

MAM is a trick to execute code from ram but is not useful if you have

jump over the code because the fetch queue has to be updated and then

the speed is limited by Flash access, I've used the ram execution

option, only drawback is the used memory, but you reach the goal by

carefully

choosing what code or function has to be executed from ram.

To do this simply add the keyword __ramfunc before the function

declaration (no need to add it also to the function code), here is one

example

how to use it:



// Function prototipe

__ramfunc signed int ReadInterface( void);



.....



// Function definition

signed int ReadInterface( void)

{

.......

return readed_value;

}



------------ --------- --------- ------

INTERRUPT HANDLING

------------ --------- --------- ------

Also interrupt handling is simple but different than into the PIC

microcontrollers, into the ARM architecture you've a

interrupt vector that must be filled with the function address that will

be called on the interrupt event.



------------ --------- --------- ------

FINAL REMARKS

------------ --------- --------- ------

If you need more specifical infos let me know I'll be happy helping you

in starting, I know the difficult also when I've started

with this new microcontroller family I've do all by myself then now I

can share my little knowledge/experienc e to other...

I'm for open source knowledge :-)



Best regards

Fabio Filippa



-----Messaggio originale--- --

Da: Senkumba Edwin [mailto:eddouble86@yahoo. com]

Inviato: mercoled6 febbraio 2008 6.33

A: lpc2000@yahoogroups .com

Oggetto: [lpc2000] Introduction to Lpc2000 needed.

Hello Everyone,

I am new to the microcontroller and am trying to understand it, i was

reading up on PIC ucontrollers before and the book i was reading

emphasised on using Assembly language. I was recently advised to look at

using the Philips lpc2148 to control an RC toy car (my first project)

but i dont know much about the lpc2000 series and found out that it is

programmed in C, so the information i got from the PIC book wont be of

much help.

All i know about microcontrollers is that they have a couple of GPIO

(that would general purpose Inout and output right?) and that these IO's

are connected to the ports inside (like PORTA and PORTB for the PIC16F54

i was reading on). The ports are arranged in a file cabinet system with

each cabinet being a file register. This file registers store

information which is accessed (or moved aorund) using the working

register.

So far thats as much as i know regarding the PIC16F5x. I need to know if

what i know could help me with the lpc2148 and where i could get more

information. I would aslo like to know the basic programming

instructions used with the ucontroller, though am not so strong at using

the C language but i am working on that right now. Any help would be

much appreciated, thank you.

P.S A little more about myself, I am an Engineering Undergraduate. So

all the above Information search is school based.

Edwin.

____________ _________ _________ _________ _________ _________ _

Looking for last minute shopping deals?

Find them fast with Yahoo! Search. http://tools.



search.yahoo. com/newsearch/ category. php?category= shopping

















____________________________________________________________________________________
Looking for last minute shopping deals?
Find them fast with Yahoo! Search. http://tools.search.yahoo.com/newsearch/category.php?category=shopping





--- In l..., Senkumba Edwin wrote:

> All i know about microcontrollers is that they have a couple of
GPIO (that would general purpose Inout and output right?)

right

>and that these IO's are connected to the ports inside (like PORTA and
PORTB for the PIC16F54 i was reading on).

yes

>The ports are arranged in a file cabinet system with each cabinet
being a file register. This file registers store information which is
accessed (or moved aorund) using the working register.

I'm not sure what you are saying here. A port is just a collection of
pins and each one is controlled from a bit in a register. This is not
called a working register. This is just an I/O control register.
Working registers generally hold intermediate results during
calculations. The PIC is more limiting and you really need to
understand the register model in depth. Many Arm users don't directly
interact with working registers on a routine basis (the C language
lets us ignore them most of the time). C can also be used on a PIC but
the PIC is very small and it's hard to use C on such a small device.

I think the first question for you is whether you understand binary
and hex? This is pretty important stuff for Microcontrollers. The idea
of AND and OR and NOT, and storing bits inside bytes, and storing
bytes inside words are important.

> So far thats as much as i know regarding the PIC16F5x. I need to
know if what i know could help me with the lpc2148 and where i could
get more information. I would aslo like to know the basic programming
instructions used with the ucontroller, though am not so strong at
using the C language but i am working on that right now. Any help
would be much appreciated, thank you.

The Arm devices are far stronger than a PIC, and I recommend that you
learn C first and use that to program the devices. People tend to hate
assembler programming of a complex chip like an Arm! C is actually
easier, and it makes debugging easier, also.

Eric


>
> The Arm devices are far stronger than a PIC, and I recommend that you
> learn C first and use that to program the devices. People tend to hate
> assembler programming of a complex chip like an Arm! C is actually
> easier, and it makes debugging easier, also.
>
> Eric

HEATHEN! Your license to program is hereby revoked!

Kids these days... Why, I remember when we had to program in 1's and
0's, and we were lucky, lucky! I say to have the 0's!

--jc
> So far thats as much as i know regarding the PIC16F5x. I need to
know if what i know could help me with the lpc2148 and where i could
get more information. I would aslo like to know the basic programming
instructions used with the ucontroller, though am not so strong at
using the C language but i am working on that right now. Any help
would be much appreciated, thank you.
>
> P.S A little more about myself, I am an Engineering Undergraduate.
So all the above Information search is school based.
>
> Edwin.

In my view, starting from the beginning and using a chip like the ARM
presents a learning curve that is just too steep. In really gross
terms, I mentally rank the complexity (and capability) of the chips as
PIC, AVR and ARM. I am not ignoring all the other chips, I just want
to set a scale of, say, 1 to 100 with the AVR (ATmega128 for my
'scale') somewhere in the middle.

Yes, the ARM probably is 100 times more complex than the PIC (16F...).

Do yourself a favor: get a PIC16F877 with a built in bootloader
(http://www.junun.org/MarkIII/Info.jsp?item $8) or get a complete
controller as a kit ((http://www.junun.org/MarkIII/Info.jsp?item=3
$30) and start out simple with C (use the demo version of cc5x) and
get started. It will take a while to sort out analog inputs, digital
IO, PWM, UARTs, Timers, interrupts, C and all the other things that
are taken for granted in this group. And the chip uses a 40 pin DIP
package that is a lot easier to use than the LPC2148.

Heck, buy the entire 'bot kit
(http://www.junun.org/MarkIII/Info.jsp?item=1 $92). It is the
cheapest learning platform you will ever buy. It has real IO, does
real things, has the expansion capabilities to implement things like
the I2C protocol and a raft of things that you would eventually want
to do with the LPC2148.

If you just buy the controller kit, it will be more than adequate for
your toy car project.

The LPC2148 will still be here when you have moved up the curve.

If you absolutely have to use the LPC2148 (and it is a fun device!),
Sparkfun has a nice development board (currently out of stock but
it'll be back!)
http://www.sparkfun.com/commerce/product_info.php?products_idT5

You will need to install YAGARTO (asuming Windows) for the IDE and GNU
toolchain. There is a tutorial on setting up your own system "ARM
Cross Development with Eclipse Version 3" by James Lynch; the most
important document ever written for starting with the ARM. Google for
it, it's hard to find. If you can't find it, send my email off line
and I'll send it to you.

Richard
--- In l..., "J.C. Wren" wrote:
>
> >
> > The Arm devices are far stronger than a PIC, and I recommend that you
> > learn C first and use that to program the devices. People tend to
hate
> > assembler programming of a complex chip like an Arm! C is actually
> > easier, and it makes debugging easier, also.
> >
> > Eric
>
> HEATHEN! Your license to program is hereby revoked!
>
> Kids these days... Why, I remember when we had to program in 1's and
> 0's, and we were lucky, lucky! I say to have the 0's!
Gee, I thought the 1's were already provided for you when you erased
the flash ! DoH !!

boB

>
> --jc
>