Página 1 de 1

serial no LPC2xxx

MensagemEnviado: 31 Jan 2008 11:45
por j.silvestre
senhores

não estou conseguindo simular no keil um programa que ecoa os dados pela serial... é um código pronto.. da hitex... nem no simulador do keil funciona... o caracter escrito na serial é armazenado no registrador no registrador U0THR ?? isto não está acontecendo... simula normal... mas não escreve nada no registrador.... onde terei errado ??





-----------------------------------------------------------------------------------------
#define CR 0x0D
#include <LPC214x.H>

void init_serial (void);
int putchar (char ch);
int getchar (void);


unsigned char test;

int main(void)
{
VPBDIV = 0x02; //Divide Pclk by two
init_serial();

while(1)
{


putchar('a');

}
}

void init_serial (void) /* Initialize Serial Interface */
{
PINSEL0 = 0x00050000; /* Enable RxD0 and TxD0 */
U0LCR = 0x00000083; /* 8 bits, no Parity, 1 Stop bit */
U0DLL = 0x000000C2; /* 9600 Baud Rate @ 30MHz VPB Clock */
U0LCR = 0x00000003; /* DLAB = 0 */



}


int putchar (char ch) /* Write character to Serial Port */
{
U0THR = ch;//
if (ch == '\n') {
while (!(U0LSR & 0x20));
U0THR = CR; /* output CR */
}
while (!(U0LSR & 0x20));
return( U0THR = ch);
}


int getchar (void) /* Read character from Serial Port */
{

while (!(U0LSR & 0x01));

return (U0RBR);
}



j.silvestre

MensagemEnviado: 31 Jan 2008 12:44
por j.silvestre
Problema resolvido....


a tal da curva de aprendizagem... faz parte da lei de murphy.... hehehe...




sds

j.silvestre

Silvestre, desculpe entrar no seu post, mas ponha a resposta ao problema ok ? Edite o post do código e deixe grafado em negrito. Os newbies agradecem.

tambem nao consegui !!!

MensagemEnviado: 06 Mar 2008 23:18
por mauricio_lula
usei alguma coisa parecida e tambem nao funcionou !!

MensagemEnviado: 07 Mar 2008 08:32
por j.silvestre
olá..

estou postando o código da serial + I2C for lpc2148. só falta por um buffer para receber os dados na rotina de interrupção. A rotina da serial funciona redonda, mas por algum motivo não simula no keil.

I2C preparada para ler e escrever eeprom 24LC512.
sds

j.silvestre

-----------------------------------------------------------------------------------------
/********************************************************************************************/
/* INCLUDES */
/********************************************************************************************/
#include <LPC214x.H>

/*********************************************************************************************/
/* PROTOTYPE FUNCTIONS */
/*********************************************************************************************/
void I2CISR (void) __irq ; //I2C interrupt routine
void UART_1_INTVectoredIRQ (void)__irq;
int sendchar (char *dat);
void init_PLL_VPB(void);
void config_Uart1_9k(void);
void initI2C0(void);
void write_eeprom(unsigned char write,unsigned short MemAddr, unsigned char Counter);
void read_eeprom(unsigned char read,unsigned short MemAddr, unsigned char Counter);
/*********************************************************************************************/
/* GLOBAL VARIAVEIS */
/*********************************************************************************************/
unsigned char dado[13] ;// dados s serem gravados na eeprom //
char dado_in[10] ={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x42}; // buffer que vai guardar
// valores lidos //
unsigned char mybtnum,
I2Counter, //quantidade de bytes a ser gravado/lido //
I2CAddress,// endereço da eeprom 0xA0 -> write 0xa1 -> read
MemAddress_high,// endereço da memoria parte alta
MemAddress_low, //endereço da memoria parte baixa
// endereço para 24LC512 tem um range de 0x00 -> 0xFFFF//
lock; // flga que trava até o final da interrupção I2c

struct eeprom // endereço da eprom 00000 -> 65536
{
unsigned char low_byte :8;
unsigned char high_byte :8;
};
union
{
struct eeprom addr; //address.addr_full = 0xaabb
unsigned short addr_full; //address.addr.low_byte = 0xbb
}address; //address.addr.high_byte = 0xaa


/*********************************************************************************************/
/* MAIN */
/********************************************************************************************/
int main(void)
{
//unsigned char n;
mybtnum =0;
lock = 0;
init_PLL_VPB();
config_Uart1_9k();
initI2C0();

// I2CAddress/address eeprom / numero de bytes //
write_eeprom(0xa0,0xAA00,12); //sempre 2 bytes a mais que o read eeprom que é addrhigh e addrlow.
sendchar(" wait...wait...wait..."); // delay para chamar read eeprom .. its necessáry//
read_eeprom(0xa1,0xAA00,10);
sendchar(dado_in); // buffer que armazena os dados lidos da eeprom //

while(1){} // loop infinito //
}
/********************************************************************************************/
/* write_eeprom */
/* "write" comando para escrever na eeprom */
/* "MemAddr" endereço da memória 24LC512 composto de 16 bits */
/* "Counter" quantidade de caracteres que ira ser escrito na eeprom. (Counter -2) igual */
/* quantidade de caracteres a ser escriro, pois a posição dado[0] e dado[1] contem os */
/* os endereços msb e lsb da eeprom 24LC512. */
/********************************************************************************************/

void write_eeprom(unsigned char write,unsigned short MemAddr, unsigned char Counter)

{

lock = 0; // flag de controle do fim da interrupção//
mybtnum = 0x00; // index do buffer de escrita e leitura //
I2CAddress = write; // endereço da eeprom + R/W
address.addr_full = MemAddr;// endereço da memoria de 16 bits //
I2Counter = Counter; // controla a quantidade de bytes a ser escritos ou lidos
dado [0] = address.addr.high_byte; // enderço high da eeprom
dado [1] = address.addr.low_byte; // endereço low da eeprom
dado [2] = 'A';
dado [3] = 'B'; // buffer dos dados a serem escritos //
dado [4] = 'C';
dado [5] = 'D';
dado [6] = 'E';
dado [7] = '$';
dado [8] = 'G';
dado [9] = 'H';
dado [10] = '*';
dado [11] = 'J';
//dado [12] = '*';
I2C0CONSET = 0x20; // //Start bit
while(!lock); // aguarda fim da interrupção SI //


}

/*********************************************************************************************/
/* */
/*********************************************************************************************/
void read_eeprom(unsigned char read,unsigned short MemAddr, unsigned char Counter)
{

lock = 0;
I2CAddress = 0xa0; // escrever na eeprom
address.addr_full = MemAddr;
I2Counter =2 ;
dado [0] = address.addr.high_byte; // escreve os endereços high e low na eeprom
dado [1] = address.addr.low_byte;
mybtnum = 0x00; // controla a quantidade de bytes escritos ou lidos //
I2C0CONSET = 0x20; // //Start bit
while(!lock); // aguarda o fim da interrupção SI //
I2CAddress = 0xa1; // ler a eeprom
I2Counter =Counter ; //quantidade de bytes a ser escritos ou lidos //
mybtnum = 0;
lock = 0; // flag que controla o fim da interrupção.
I2C0CONSET = 0x20; // //Start bit

while(!lock); // aguarda fim da interrupção//

}




/*******************************************************************************************/
/* */
/* */
/*******************************************************************************************/
void I2CISR (void) __irq //I2C interrupt routine
{

switch (I2C0STAT) //Read result code and switch to next action
{
// Start and Send byte conditions

case ( 0x08): // Start bit ok //
sendchar ("CASE 08 "); //*for debug*//
I2C0CONCLR = 0x20; //Clear start bit
I2C0DAT = I2CAddress; //Send address and write bit
break;

case (0x18): //Slave address + W Ok.
sendchar ("CASE 18 "); //*for debug*//
I2C0DAT = dado[mybtnum]; // primeiro byte do buffer a ser escrito na eeprom

mybtnum ++; // posição do byte no buffer // neste caso endereço a eprom parte high
I2Counter--; // quantidade de bytes a ser enviadas
break;

case (0x20): //Slave address +W, Not ACK
sendchar ("CASE 20 "); //*for debug*//
I2C0CONSET = 0x14; // send stop (error)
break;

case (0x28):
sendchar ("CASE 28 "); //*for debug*//
if(I2Counter > 0) //Data sent, Ack
{
lock = 0;
I2C0DAT = dado[mybtnum]; //Write data to tx register
mybtnum ++;
I2Counter--;
}
else
{
lock = 1;
I2C0CONSET = 0x14; //*** //Stop condition
sendchar ("stop condition "); //*for debug*//
}
break;

case (0x30) :
sendchar ("CASE 30 "); //Data sent, NOT Ack
I2C0CONSET = 0x10; //Stop condition
break;


//Receive byte conditions

case (0x40) : //Slave Address +R, ACK
sendchar ("CASE 40 "); //*for debug*//
I2C0CONSET = 0x04; //Enable ACK for data byte
break;

case (0x48) : //Slave Address +R, Not Ack
sendchar ("CASE 48 "); //*for debug*//
I2C0CONSET = 0x14; //send stop
break;

case (0x50) : //Data Received, ACK
sendchar ("CASE 50 "); //*for debug*//
if(I2Counter > 0)
{
dado_in[mybtnum] = I2C0DAT;
mybtnum ++;
I2Counter--;
}
else
{
I2C0CONSET = 0x10;
lock = 1; //Stop condition
sendchar ("stop ok "); //*for debug*//
}
break;

case (0x58):
sendchar ("CASE 58 "); //Data Received, Not Ack
I2C0CONSET = 0x10; // Send Stop
sendchar ("stop error "); //*for debug*//
break;

default :
break;

}

I2C0CONCLR = 0x08; //Clear I2C interrupt flag
VICVectAddr = 0x00000000; //Clear interrupt in

}
/********************************************************************************************/
/* config_Uart1(void) 9k */
/********************************************************************************************/
void config_Uart1_9k(void)
{
PINSEL0 = 0x00050000; /* Enable RxD1 and TxD1 */
U1LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
U1DLL = 0xC3; /* 9600 Baud Rate @ 30MHz VPB Clock */
//U1DLL = 0X61; /*19200 Baud Rate @ 30MHz VPB Clock */
//U1DLL = 0X20; /*57600 Baud Rate @ 30MHz VPB Clock */
U1LCR = 0x03; /* DLAB = 0 */
U1IER = 0x02; // habilita uart receiver/;/
VICVectAddr2 = (unsigned) UART_1_INTVectoredIRQ; //pass the address of the IRQ into the VIC slot
VICVectCntl2 = 0X00000027;
VICIntEnable = 0X00000080; // habilita interrupção UART1 //
}

/********************************************************************************************/
/* UART_1_INTVectoredIRQ (void)__irq */
/* Recebe um Byte e armazena em um buffer */
/* Funciona da seguinte maneira: enche o primeiro buffer, transfere para serial, e começa a */
/* encher o segundo, qdo cheio envia para a serial, depois o terceiro buffer e envia para a */
/* serial , então volta ao primeiro buffer. */
/********************************************************************************************/

void UART_1_INTVectoredIRQ (void)__irq // for debug I2c
{


while (!(U1LSR & 0x01));

VICVectAddr = 0;//0x0000; // limpa interrupção //
}

/*********************************************************************************************/
/* sendchar Write character to Serial Port */
/*********************************************************************************************/

int sendchar (char *dat) // for debug I2C

{ /* Write character to Serial Port */
int j=0;

// if( dat ==0x00) return;
while(dat[j]) // send string
{

// start sending one byte
while (!(U1LSR & 0x20));
U1THR=dat[j];
j++;

if( j == 10) // tamanho do buffer a ser lido //
return (U1THR );
}


return (U1THR );
}
/*********************************************************************************************/
/* void init_PLL_VPB(void) */
/* */
/********************************************************************************************/

void init_PLL_VPB(void)
{

PLL0CFG = 0x00000024; // configura o multiplicador e o divisor para 60MHZ ->cristal de 12MHZ
PLL0CON = 0x00000001; // habilita o PLL //
PLL0FEED = 0x000000AA; // atualiza os registradores
PLL0FEED = 0x00000055; // atualiza os registradores
while(!(PLL0STAT & 0x00000400)); // testa PCLOCK
PLL0CON = 0x00000003; // conecta ao PLL //
PLL0FEED = 0x000000AA; // atualiza os registradores
PLL0FEED = 0x00000055; // atualiza os registradores
VPBDIV = 0x00000002; // configura o divisor VPB para 30MHZ.
// CCLK /2
}
void initI2C0(void)
{
VICVectCntl1 = 0x00000029; //select a priority slot for a given interrupt
VICVectAddr1 = (unsigned)I2CISR; //pass the address of the IRQ into the VIC slot
VICIntEnable = 0x00000200; //enable interrupt

PINSEL0 |= 0x50; //Switch GPIO to I2C pins

I2C0SCLH = 0x96; // for 100khz
I2C0SCLL = 0x96;
I2C0CONSET = 0x40;
}

--------------------------------------------------------------------------------------
sds

j.silvestre

duvida no codigo postado ???

MensagemEnviado: 08 Mar 2008 18:09
por mauricio_lula
quantos bytes vc recebe na serial ,antes de gerar a interrupção,aonde esta o codigo da interrupção serial ??,o que gostaria de implementar é igual ao 8051 a cada byte recebido faz o tratamento e etc...

void UART_1_INTVectoredIRQ (void)__irq
{

while (!(U1LSR & 0x01));


** poderia escrever o codigo aqui ??[/b]


VICVectAddr = 0;//0x0000; // limpa interrupção //
}

Valeu !!!

MensagemEnviado: 09 Mar 2008 10:33
por j.silvestre
Mauricio
é o seguinte:


// variaveis globais //
char buffer_in[10];
unsigned char conta_buffer;
.
.
substitua na função config_Uart1_9k a linha :
U1IER = 0x02; // habilita uart receiver/;/
por
U1IER = 0x01; // habilita uart receiver/;/

Agora esta igual a rotina de interrupção do bom e velho 8051 cada byte re
cebido ele guarda no buffer_In, o tmanho do buffer_in esta setado para 10 caracter
mas vc pode aumentar o tamanho do buffer.
------------------------------------------------------------------------



void UART_1_INTVectoredIRQ (void)__irq
{

while (!(U1LSR & 0x01));

if(conta_buffer = 10
{
buffer_in[conta_buffer]=U1RBR; // copy input bufffer to buffer[n]//
conta_buffer = 0
VICVectAddr = 0;//0x0000; // limpa interrupção //
return;
}

conta_buffer ++;
VICVectAddr = 0;//0x0000; // limpa interrupção //
}



-----------------------------------------------------------------------------------
j.silvestre

MensagemEnviado: 09 Mar 2008 10:37
por j.silvestre
humm... teve um errinho de logica... a rotina certa é esta aqui..

void UART_1_INTVectoredIRQ (void)__irq
{

while (!(U1LSR & 0x01));

if(conta_buffer <= 10
{
buffer_in[conta_buffer]=U1RBR; // copy input bufffer to buffer[n]//
conta_buffer = ++
VICVectAddr = 0;//0x0000; // limpa interrupção //
return;
}

conta_buffer 0;
VICVectAddr = 0;//0x0000; // limpa interrupção //
}



j.silvestre

MensagemEnviado: 10 Mar 2008 20:34
por mauricio_lula
Valeu !!! ainda não funcionou !! tá dando uns erros de compilação ,acho que deve ser ao IAR ,vou migrar para o KEIL !!!

mauricio

Ainda nao funcionou !!!

MensagemEnviado: 21 Mar 2008 10:59
por mauricio_lula
consigo transmitir apenas ,mas nao consigo fazer a rotina de interrupcao serial funcionar .....abaixo esta o codigo ....a rotina e bem simples se receber 'A' ele deveria setar um flag(que no iar nao consigo declarar bit) e no programa principal escrever no lcd.

#include <iolpc2138.h>

#define botao_1 IO0PIN_bit.P0_16
#define botao_2 IO0PIN_bit.P0_17

#define cursor_fino 0x0e // Faz o cursor sublinhado.
#define cursor_cheio 0x0d // Faz o cursor completo.
#define cursor_apaga 0x0c // apaga o cursor.

unsigned long data;
unsigned char flag_serial;

void delay (unsigned long);
void pisca_led_1 (void);
void led_desliga_1 (void);
void led_liga_1 (void);
void pisca_led_2 (void);
void led_desliga_2 (void);
void led_liga_2 (void);
void enable (void);
void inicializa_lcd (void);
void cmlcd (unsigned char);
void wrlcd (unsigned char);
void write (char *);
void INTERRUPCAO_UART1 (void);

void delay (unsigned long a)
{
while (--a!=0);
}

void inicializa_pll(void)
{

PLLCFG = 0x00000022; // configura o multiplicador e o divisor para 60MHZ ->cristal de 12MHZ
PLLCON = 0x00000001; // habilita o PLL
PLLFEED = 0x000000AA; // atualiza os registradores
PLLFEED = 0x00000055; // atualiza os registradores
while((PLLSTAT & 0x00000400)==0); // testa PCLOCK
PLLCON = 0x00000003; // conecta ao PLL
PLLFEED = 0x000000AA; // atualiza os registradores
PLLFEED = 0x00000055; // atualiza os registradores
VPBDIV = 0x00000002; // configura o divisor VPB para 30MHZ CCLK /2
}

void inicializa_serial()
{
PINSEL0 = 0x00050000; //seleciona os pinos como tx1 e rx1

U1LCR = 0x00000083; // habilita acesso a latch do baudrate,configura 8,N,1
U1DLL = 0x000000C3; // byte mais significativo baud rate
U1DLM = 0x00; // byte menos significativo baud rate
U1LCR = 0x03; // desabilita acesso aos latch baud rate
U1IER = 0x01; //habilita interrupçao serial rx
// VICIntSelect = 0x00000080; // seleciona interrupção UART1 como VIC como FIQ
VICVectCntl0 = 0x00000027; // seleciona canal 7( uart1) + habilita Slot
VICVectAddr0 = (unsigned) INTERRUPCAO_UART1; // passa o endereco da interrupcao UART1
VICIntEnable = 0x00000080; // habilita interrupção UART1;
// U1FCR = 0x07; //habilita Fifo e configura com 1 byte, 1 byte
}

void inicializa_lcd()
{
unsigned char i;
unsigned char dadoslcd [7] = {0x33,0X33,0X32,0X14,0X01,0x0C,0x0C};

for (i=0 ; i<7 ; i++)
{
cmlcd(dadoslcd[i]);
delay(200);
}

delay(5000);
}

void INTERRUPCAO_UART1(void)
{
unsigned char data;

while(U1LSR_bit.DR==0);

// U1IIR |= 0x01; //limpa a interrupcao

data=U1RBR;

if(data == 'A')
flag_serial=1;

VICVectAddr0 =0;

}

void txd(unsigned char c)
{
while (U1LSR_bit.THRE == 0);
U1THR = c;
}

void enable()
{
IO1SET_bit.P0_18 = 1; //set E to high
delay(100);
IO1CLR_bit.P0_18 = 1; //set E to low
}

void cmlcd(unsigned char dado)
{
unsigned char data;

IO1CLR_bit.P0_19 = 1;

data = ((dado >> 4)& 0x0F);
IO1CLR |= 0x00F00000;
IO1SET |= (data << 20);

enable();

data = ((dado & 0x0F));
IO1CLR |= 0x00F00000;
IO1SET |= (data << 20);

enable();

delay(500);
}

void wrlcd(unsigned char dado)
{
unsigned char data;

IO1SET_bit.P0_19 = 1;

data = ((dado >> 4)& 0x0F);
IO1CLR |= 0x00F00000;
IO1SET |= (data << 20);

enable();

data = ((dado & 0x0F));
IO1CLR |= 0x00F00000;
IO1SET |= (data << 20);

enable();

delay(500);
}

void write(char *c)
{
for(;*c!=0;c++)
wrlcd(*c);
}

void setcursor(char tipo)
{
cmlcd(tipo);
}

void gotoxy(char x, char y)
{
switch (y)
{
case 1:
cmlcd(0x80 + (x-1)); //128
break;
case 2:
cmlcd(0xc0 + (x-1)); //192
break;
}
}

void pisca_led_1(void)
{
IO0SET_bit.P0_12 = 1;
delay(500000);
IO0CLR_bit.P0_12 = 1;
delay(500000);
}

void led_desliga_1(void)
{
IO0CLR_bit.P0_12 = 1;
}

void led_liga_1(void)
{
IO0SET_bit.P0_12 = 1;
}

void pisca_led_2(void)
{
IO0SET_bit.P0_13 = 1;
delay(500000);
IO0CLR_bit.P0_13 = 1;
delay(500000);
}

void led_desliga_2(void)
{
IO0CLR_bit.P0_13 = 1;
}

void led_liga_2(void)
{
IO0SET_bit.P0_13 = 1;
}

int main()
{
// inicializa oscilador PLL
inicializa_pll();

// configura portas para entrada
IO0DIR_bit.P0_16 = 0;
IO0DIR_bit.P0_17 = 0;

// configura portas para saida
IO0DIR_bit.P0_12 = 1;
IO0DIR_bit.P0_13 = 1;
IO1DIR_bit.P0_20 = 1;
IO1DIR_bit.P0_21 = 1;
IO1DIR_bit.P0_22 = 1;
IO1DIR_bit.P0_23 = 1;
IO1DIR_bit.P0_19 = 1;
IO1DIR_bit.P0_18 = 1;

inicializa_lcd();

setcursor (cursor_apaga);

inicializa_serial();

// desliga_leds
IO0CLR_bit.P0_12 = 1;
IO0CLR_bit.P0_13 = 1;

flag_serial=0;

gotoxy(1,1);
// 1234567890123456
write(" TESTE DO MICRO ");
gotoxy(1,2);
// 1234567890123456
write(" ARM - LPC 2138 ");


while(1)
{
// pisca_led_1();

if(flag_serial==1)
{
flag_serial=0;
gotoxy(1,2);
// 1234567890123456
write(" FUNFOU !! ");
led_liga_1();
led_liga_2();
while(1);
}


if(botao_1 == 0)
{
led_liga_1();
txd('T');
txd('E');
txd('S');
txd('T');
txd('E');
txd(' ');
txd('D');
txd('O');
txd(' ');
txd('A');
txd('R');
txd('M');
txd('!');
}
else
led_desliga_1();

pisca_led_2();

if(botao_2==0)
led_liga_2();
else
led_desliga_2();

}

}

MensagemEnviado: 10 Dez 2008 15:05
por lasfclestat
Prezados

Estou querendo utilizar a recepção serial pela interrupção.
Porém não esta funcionando.
Eu consigo enviar normal pela serial, porém não consigo receber nada.
Abaixo esta o código da interrupção.

Código: Selecionar todos
//..
VICVectAddr6  = (unsigned long)UART_IRQHandler;       
VICVectCntl6  = 13;                       
VICIntEnable  = (1  << 6);                 
//..

//..
__irq void UART_IRQHandler(void)
{
   
  while (!(U0LSR & 0x01));
  leu = U0RBR;

  VICVectAddr = 0;                     
}
//..

//..
printf ("recebeu= ",leu);    // leu é tipo char
//..



Como poderia fazer funcionar???
Estou usando o LPC2368.

Obrigado

[]s