Página 1 de 2

Interrupção

MensagemEnviado: 13 Dez 2016 11:20
por febupe
Bom dia,

Trabalho com o ARM7,LPC2138.
Amigos, estou com um problema.. vou tentar detalhar a vocês o que pretendo fazer.
Possuo um sensor em uma das entradas analógicas, gostaria de fazer uma interrupção para uma entrada analogica do meu lpc 2138.
Seria possivel isso? Por onde devo começar a pesquisar?
Ps: sou iniciante, comecei a mexer agora com o o microcontorladores ARM.

Obrigado,

Thiago Brandão.

Re: Interrupção

MensagemEnviado: 14 Dez 2016 07:38
por tcpipchip

Re: Interrupção

MensagemEnviado: 14 Dez 2016 07:53
por EDSONCAN
Você quer gerar um interrupção a cada vez que a conversão esteja pronta ou gerar uma interrupção quando estiver acima ou abaixo de determinado valor?

Não mexo muito com os da NXP, mas com os da ST prefiro fazer um DMA e direto em um buffer, sobrecarrega menos o Hardware, mas é questão de gosto....

Re: Interrupção

MensagemEnviado: 14 Dez 2016 10:56
por febupe


Obrigado

Re: Interrupção

MensagemEnviado: 14 Dez 2016 10:59
por febupe
EDSONCAN escreveu:Você quer gerar um interrupção a cada vez que a conversão esteja pronta ou gerar uma interrupção quando estiver acima ou abaixo de determinado valor?

Não mexo muito com os da NXP, mas com os da ST prefiro fazer um DMA e direto em um buffer, sobrecarrega menos o Hardware, mas é questão de gosto....


Edson, o meu objetivo é para gerar uma interrupção tanto pra cima quanto pra baixo. Tipo assim, se meu sensor estiver acima de 511bits(metade de 1023) ele vai ter uma função e quando estiver abaixo desse valor outra função de acordo com o tempo que ficar entendeu? E quando o valor estiver em 511 ele sai da interrupção, mais ou menos isso que é o que preciso fazer.

Obrigado.

Re: Interrupção

MensagemEnviado: 14 Dez 2016 13:43
por EDSONCAN
6.8 10-bit ADC
The LPC2131/32 contain one and the LPC2134/36/38 contain two ADCs. Thesevconverters are single 10-bit successive approximation ADCs with eight multiplexed channels.
6.8.1 Features
• Measurement range of 0 V to 3.3 V.
• Each converter capable of performing more than 400000 10-bit samples per second.
• Burst conversion mode for single or multiple inputs.
• Optional conversion on transition on input pin or Timer Match signal.
• Global Start command for both converters (LPC2134/36/38 only).
6.8.2 ADC features available in LPC213x/01 only
• Every analog input has a dedicated result register to reduce interrupt overhead.
• Every analog input can generate an interrupt once the conversion is completed.


Não conheço muito a linha da NXP. mas onde você viu que era possível gerar um interrupção por valor de resultado do AD?

Re: Interrupção

MensagemEnviado: 14 Dez 2016 14:32
por febupe
Eu não vi em lugar nenhum não, eu tive pesquisando e vi que para o PIC é possivel.. vi em uns videos do youtube.
Dai queria ver como fazia no lpc2138 e se era possivel.
Caso não tenha como fazer essa interrupção o que você me aconselha a fazer para resolver este problema?

Re: Interrupção

MensagemEnviado: 14 Dez 2016 16:46
por EDSONCAN
Se fixar o canal do AD a conversão é rápida nos ARM, converte e compara o valor por software....

Re: Interrupção

MensagemEnviado: 15 Dez 2016 06:48
por febupe
EDSONCAN escreveu:Se fixar o canal do AD a conversão é rápida nos ARM, converte e compara o valor por software....


Não entendi direito Edson, você esta me sugerindo gravar um programa no meu ARM para fazer isso? Mas isso eu ja estou fazendo, só que se eu preciso fazer uma interrupção porque quando esse meu sensor variar do valor de Vref (1,65v) ele é obrigado a fazer alterações no meu programa

Re: Interrupção

MensagemEnviado: 15 Dez 2016 07:04
por EDSONCAN
Então não sei como resolver seu problema, me parece que voce precisa de um comparador e não de um AD....

Re: Interrupção

MensagemEnviado: 15 Dez 2016 09:28
por pbernardi
febupe escreveu:
EDSONCAN escreveu:Você quer gerar um interrupção a cada vez que a conversão esteja pronta ou gerar uma interrupção quando estiver acima ou abaixo de determinado valor?

Não mexo muito com os da NXP, mas com os da ST prefiro fazer um DMA e direto em um buffer, sobrecarrega menos o Hardware, mas é questão de gosto....


Edson, o meu objetivo é para gerar uma interrupção tanto pra cima quanto pra baixo. Tipo assim, se meu sensor estiver acima de 511bits(metade de 1023) ele vai ter uma função e quando estiver abaixo desse valor outra função de acordo com o tempo que ficar entendeu? E quando o valor estiver em 511 ele sai da interrupção, mais ou menos isso que é o que preciso fazer.

Obrigado.


Pra fazer exatamente isso que você quer, acho que não é possível. Mas acho que o seguinte algorítimo deve te atender:

1 - Interrupção para vez que a leitura de AD estiver pronta.
2 - Le o valor do AD.
3a - Se for igual a 511, sai da interrupção.
3b - Se o valor for acima de 511, executa "função acima".
3c - Senão, executa a "função abaixo"

Lembrando que funções dentro de interrupções não são muito recomendáveis, melhor seria fazer uma função inline, e bem rápida. Alternativamente, você poderia apenas setar um flag acima/abaixo e fazer o tratamento das funções fora da interrupção.

Re: Interrupção

MensagemEnviado: 15 Dez 2016 11:20
por febupe
Bom dia pbernardi, obrigado pela atenção.
Seguinte meu codigo ta ficando mais ou menos assim, vou escrever a parte que importa só.. esse while esta dentro do main

cpp code
while(1){
Nivel_sinal=Ler_ADC(2)
}

unsigned short Ler_ADC(unsigned char canal)
{

unsigned short resultado;
signed char ret_code;
unsigned int canal_hex;

switch(canal)
{
case 2:
canal_hex=0x4;
break;
case 3:
canal_hex=0x8;
break;
case 4:
canal_hex=0x10;
break;
case 5:
canal_hex=0x20;
break;
}

// INICIA CONVERSÃO
MA_Start_ADC(MA_AD_CONVERTER_1,MA_AD_SOFTWARE_MODE,AD1CR_START_START_NOW,canal_hex);
ret_code=MA_EMPTY;
// LER O RESULTADO DA CONVERSÃO
while(ret_code==MA_EMPTY) ret_code = MA_Read_ADC(MA_AD_CONVERTER_1,&canal,&resultado);
if (ret_code != MA_OK) resultado=0;
// PARAR CONVERSAO
MA_Stop_ADC(MA_AD_CONVERTER_1);

return resultado;
}


Bom, ai esta mais ou menos o que eu tenho para ler o ADC..
Dai o que pensei depois para fazer foi isso só que não esta dando certo:

cpp code
if(Nivel_sinal > 511)
{
Posicao=Posicao + (((Nivel_sinal - 511)/511)*90);
}
if(Nivel_sinal < 511)
{
Posicao=Posicao + (((Nivel_sinal - 511)/511)*90);
}

Re: Interrupção

MensagemEnviado: 15 Dez 2016 13:02
por EDSONCAN
Para que fazer esse if se os dois fazem a mesma coisa?

cpp code
if(Nivel_sinal > 511)
{
Posicao=Posicao + (((Nivel_sinal - 511)/511)*90);
}
if(Nivel_sinal < 511)
{
Posicao=Posicao + (((Nivel_sinal - 511)/511)*90);
}

Re: Interrupção

MensagemEnviado: 16 Dez 2016 06:40
por febupe
Na hora em que copiei aqui que veio errado..
Mas mesmo assim, não esta funcionando dessa maneira isso. O que eu estou fazendo de errado será?

Re: Interrupção

MensagemEnviado: 16 Dez 2016 07:48
por andre_luis
Estava pensando: Qual seria o propósito dessa interrupção, se o que estaria contido nela teria de ser executada necessariamente na sequencia após o cálculo ? A menos que fosse algo que precisasse ser executado impreterivelmente sem correr o risco de ser atropelado por uma outra interrupção; mas se não estou enganado tem o vetor VICSoftInt que aparentemente cumpre essa tarefa.

Mas novamente, ainda que tenha de fazer uns calculos de divisão na função acima, isso ainda poderia ser melhorado em termos de velocidade, já que a ALU do core possui instrução de multiplicação, mas não de divisão. Repare que voce está utilizando 511 que é muito proximo de 2^9 ( 512-511 → erro de +0,2% ), e em outras palavras, se a precisão exigida para o resultado não for muito alta, poderia fazer a operação matemática x/512 com uma operação lógica x>>9 dando o mesmo resultado.