Página 1 de 1

.....

MensagemEnviado: 20 Ago 2009 16:21
por fabim
[code]#include <math.h>
#include <LPC210X.h>


#define u16 unsigned int
#define u08 unsigned char

unsigned int const radiano = 360;
unsigned int const numero_pontos = 180;
unsigned int const grau_ponto = radiano/numero_pontos;
unsigned int const resolucao = 32767;
unsigned int const ponto_0 = resolucao / 2;
unsigned int const volume = 500; // minimo 10* (sum_p/4)

u16 raw_sample[180];

void aloca_valores(u16 *pontos){
u08 angulo;

for(angulo = 0; angulo < (numero_pontos/2); angulo++){
*pontos++ = (u16)ponto_0 + (sin((angulo*grau_ponto)*0.017453)*volume);
}

for(angulo = 0; angulo < (numero_pontos/2); angulo++){
*pontos++ = (u16)ponto_0 - (sin((angulo*grau_ponto)*0.017453)*volume);
}

}

////////////////////////////////////////////////////////////////////////////////
int main(void){
aloca_valores(&raw_sample[0]);
for(;;);
}[/code]

mimimi !! mimi...

miiiiiiiii!

MensagemEnviado: 20 Ago 2009 16:27
por tcpipchip
Gyroscope ?

MensagemEnviado: 20 Ago 2009 16:34
por fabim
[quote="tcpipchip"]Gyroscope ?[/quote]


mimi!!
Gerar senoide para DAC ou pwm..
Com amplitude controlavel...

Se precisar de uma amplitude menor, precisa de diminuir o numero de samples.

Um amigo nosso duvidou que eu dava conta, me chamou de mula véia e de zé mané.

o LPC2103 em 60mhz, demora 168mS pra gerar os calculos.

MIMI !!!

MensagemEnviado: 20 Ago 2009 17:01
por Jorge_Francisco
Gerador senoidal com defasagem de 90º. Muito legal, e aí fabim o que está achando dos ARM's? Valem à pena no seu escopo? Está aprendendo por aprender ou acha que tem grande uso nos seus projetos?

Abraço.

MensagemEnviado: 20 Ago 2009 17:04
por Jorge_Francisco
Reduz 2 for's para 1 só pow!!!

MensagemEnviado: 20 Ago 2009 17:13
por proex
Fabin disse: Se precisar de uma amplitude menor, precisa de diminuir o numero de samples.

Proex disse: Isso não pode acontecer. O Sampling Rate tem que ficar fixo.

Faça assim com áudio digital e verá a porcaria que vai ficar seu controle de volume.

Controle de amplitude (ou volume) é uma função logaritmica, e deve atuar somente na amplitude da forma de onda e nada mais.

Estuda mais um pouquinho que vc consegue.

mi mi mi mi mi !!!!

MensagemEnviado: 20 Ago 2009 17:13
por fabim
olha velho, vou ser sincero.
A unica coisa que encomoda é que não tem arm de 28 pinos e DIP.

Soldar isso é um parto, e esse monte de pino sobrando é druris.

No mais, ser sincero.

Estamos acostumado com pic, para projetos simples de alarmes, controladores simples, automação simples etc.
Logicamente, que existem aqueles que fazem um pic virar um jato e controlar tanta coisa que da até medo.
Não é correto menosprezar a linha uxip, mais no meu ver AGORA.
Levando em consideração numero de pinos, perifericos, consumo, velocidade, arquitetura bem flexivel e fazendo uma comparação com uxip tem sim a possibilidade de substituir um 18f4550 por um LPC1766, que são de mesmo custo mais com capacidades incomparaveis.
Tanto como um 16f877/18f452 por um LPC2103 por exemplo.

Unica coisa que me deixou muito animado, é que não preciso mais me preocupar com tempo de execução.
Por exemplo o DTS5000 que estou desenvolvendo.
18F4550 a 12 mips, fazendo 5860 amostras de um DAC externo por segundo, multiplexado. Entre amostras elevar ao quadrado as duas variaveis e depois de 1S/40 tirar o RMS, e sem parar de fazer amostragem. Meo precisei ficar um tempão debugando, enxugando e batenco a cabeça.
Ja no arm, hum..

Abraços

E sim, ARM7=> sim compensa substituir. Logico que não vai colocar um ARM7 pra piscar led, ou fazer um alarme ou central de portão, baita despercidio.

Abraços2


Fabim

MensagemEnviado: 20 Ago 2009 17:18
por fabim
[quote="proex"]Fabin disse: Se precisar de uma amplitude menor, precisa de diminuir o numero de samples.

Proex disse: Isso não pode acontecer. O Sampling Rate tem que ficar fixo.

Faça assim com áudio digital e verá a porcaria que vai ficar seu controle de volume.

Controle de amplitude (ou volume) é uma função logaritmica, e deve atuar somente na amplitude da forma de onda e nada mais.

Estuda mais um pouquinho que vc consegue.

mi mi mi mi mi !!!![/quote]

Mula véia.
De 0 a 90° = 45 amostras.

estamos workando com valores inteiros.

coloca 45 por exemplo no calculo, ou coloca 25...veja a resultante.

mimii !!! eu ja sabia!! mimimi!! estou falando de calculo de seno pra gerar os valores para senoide, o calculo que eu fiz!!! mimimi

Abraços

mimi!!!

MensagemEnviado: 20 Ago 2009 21:40
por B-EAGLE
esses dias modulei a amplitude de um sinal de 60hz em 12-45hz num ADuC7026 (arm7)...

tenho o código aqui ainda... ficou legal a parada, por interrupción! :D

ah! os semiciclos positivos em DAC0 e os negativos em DAC2...

Código: Selecionar todos
#include <ADuC7026.h>               // ADuC7026 definitions
#include <stdio.h>
#include <math.h>

//**************Protótipos das funções***************
void inicializa(void);
void configura_ad(void);
void configura_da(void);
unsigned short le_ad(unsigned char);
void configura_timer1(void);
void IRQ_Handler(void) __irq;
void portadora(double);
//***************************************************

//****************Variáveis globais******************
unsigned short res_ad;
unsigned int x, i;
float temp, t;
unsigned short valores_dac0[360];
unsigned short valores_dac1[360];
//***************************************************


void main(void){
   inicializa();
   configura_ad();
   configura_da();
   portadora(35);
   while(1);
}

void portadora(double freq){
   double periodo_port;
   for(t = 0; t < 360; t++){
      temp = sin(t*0.0174532925)*3276;            //fórmula seno
      if (t <= 180){                           //valores para senóide DAC0
         valores_dac0[t] = ((unsigned short)temp);
         valores_dac1[t] = 3276;
      }
      else{                                 //valores para senóide DAC2
         valores_dac0[t] = 0;
         valores_dac1[t] = ((unsigned short)temp);
      }         
   }
   //cálculo e configuração timer1 para interrupção e atualização da senóide
   periodo_port = 1/freq;                     //calcula período da portadora
   periodo_port /= 360;                     //divide pela qtd de pontos totais da senóide = periodo de interrupção
   T1LD = periodo_port/0.0000000239348970799426;   //divide periodo de interrupção   pelo período do clock do core (41.78MHz)
   T1LD -= 3;   
   T1CON = 0xC0;                           // Enabled,Periodic,Binary and CLK/16
   IRQEN = GP_TIMER_BIT;                     // Enable XIRQ0 and Timer1 IRQ
   i = 0;                                 //contador de ponto da senóide = 0
   return;
}
 
void inicializa(void){
   PLLKEY1 = 0xAA;      //sequência para habilitar escrita em PLLCON
   PLLCON = 0x21;      //registrador de seleção de fonte de clock
   PLLKEY2 = 0x55;      //PLLCON = 0x21 -> Internal 32KHz clock source

   POWKEY1 = 0x01;      //sequência para habilitar escrita em POWCON
   POWCON = 0x00;      //registrador de divisor do clock.
   POWKEY2 = 0xF4;      // POWCON = 0 -> CD = 0 / clock divider = 0 -> 41.78MHz;

   CMPCON = 0x400;      //comparador desabilitado

   GP4CON = 0x0000;   //todos pinos de P4 são GPIO
   GP4DAT = 0x04000000;

   return;
}

void configura_ad(void){
   unsigned int time_wakeup;
   time_wakeup = 50000;
   ADCCON = 0x20;                     //ADC on;
   while (time_wakeup > 0) time_wakeup--;   //wake-up time para o ADC   
   ADCCON = 0x0223;                  // fADC/1 - 8 clocks - single-ended mode - single sw conv //0000 0010 0010 0011   
   REFCON = 0x01;                     //referência interna de 2.5V conectada ao Vref
   return;
}

unsigned short le_ad(unsigned char canal){
    ADCCP = canal;               //seleciona canal
   ADCCON |= 0x083;            //inicia conversão   
   while(!ADCSTA);               //espera conversão finalizar
   return (ADCDAT >> 16) & 0x0FFF;   //retorna resultado em 12 bits
}
      
void configura_da(void){
   DAC0CON = 0x12;      //core-clock dac update - referência interna de 2.5V   
   DAC2CON = 0x12;      //core-clock dac update - referência interna de 2.5V   
   return;
}   

void IRQ_Handler() __irq {                  // example with two IRQ
   if ((IRQSTA & GP_TIMER_BIT) != 0){
      T1CLRI = 0;                        // Clear Timer IRQ
      DAC0DAT = valores_dac0[i] << 16;
      DAC2DAT = valores_dac1[i] << 16;
      i++;
      if (i == 360) i = 0;
   }             
   return ;
}            

MensagemEnviado: 21 Ago 2009 08:16
por fabim
poisé.
nada impede de usar um potenciometro digital de 255 niveis.

saindo do PWM, a cada 2* Sample/4, e controlando a amplitude novamente no potenciometro digital.

com essa rotina, tu faz a roda cortada em qualquer frequencia que o pwm e o core permita.
Por exemplo de 0,5hz a trocentos hz.

ia me esquecendo.

*pontos++ = (u16)ponto_0 + (sin((angulo*grau_ponto)*0.017453)*volume);
/***********************************************************
Ponto_0 = ponto de onde vai partir o 0 da senoide, o seu valor deve ser tal que a soma de volume não ultrapasse o ranger do PWM ou DAC.
/************************************************************
Volume = peso no qual o calculo vai gerar a senoide.
/************************************************************
sin((angulo*grau_ponto)*0.017453)*

sin() = calculo seno do keil, ele trabalha em radianos.

angulo*grau_ponto = angulo é o sample do momento que vai de 0 a 180.
grau_ponto = 360°/numero samples180 = 2°.
0.017453 =radianos, como estou calculando para 180°.. sendo 0 - 90 - 180, o radiano = PI/180.

EX.:
sin((45*2°)*0.017453)*5000 = 5000

para por exemplo o ponto_0 = 15000.
o VP+ em 90° = 15000 + 5000,

Para gerar o semi ciclo de 180 a 270, é so fazer o ponto_0 - as mesmas resultantes ou fazer direto.

Abraços

MensagemEnviado: 21 Ago 2009 09:56
por tcpipchip
Por falar em PERFORMANCE...faz um teste ai...

Mude o tipo de dado de "angulo" para 32 bits sem sinal...assim...o compilador nao vai passar trabalho em gerar os ROL da vida para alinhamento (32 bits)

Enfim, evite usar tipos de dado u8

Testa ai Fabim...

TCPIPCHIP

MensagemEnviado: 21 Ago 2009 12:31
por fabim
[quote="tcpipchip"]Por falar em PERFORMANCE...faz um teste ai...talvez para pequenos loops nao faça diferença....

Mude o tipo de dado de "angulo" para 32 bits sem sinal...assim...o compilador nao vai passar trabalho em gerar os ROL da vida para alinhamento (32 bits)

Enfim, evite usar tipos de dado u8

Testa ai Fabim...

TCPIPCHIP[/quote]

CARACA...!!!!!!!!!!
De 165mS para preencher o raw.
Coloquei tudo como unsigned long.
caiu para "6.37352mS"
casetada. 6mS!!

MensagemEnviado: 21 Ago 2009 16:48
por tcpipchip
Legal né Fabim !!!!

Fico feliz que baixou para 6ms...

Depois que se estuda o assembly do ARM, a gente vê alguns pontos fracos de alguns dos compiladores na geração de código do código assembly.

Que tal baixarmos para 3 ms ?

TCPIPCHIP

MensagemEnviado: 25 Ago 2009 12:51
por fabim
[quote="tcpipchip"]Legal né Fabim !!!!

Fico feliz que baixou para 6ms...

Depois que se estuda o assembly do ARM, a gente vê alguns pontos fracos de alguns dos compiladores na geração de código do código assembly.

Que tal baixarmos para 3 ms ?

TCPIPCHIP[/quote]

TCP, desisto.
Fiz algumas modificações e mesmo assim, cheguei no minimo de 5.383mS.

Abraços

Fabim