Skip to content

Instantly share code, notes, and snippets.

@carlosdelfino
Created May 7, 2020 15:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save carlosdelfino/999f54d5567ff115935ee64c7e62816f to your computer and use it in GitHub Desktop.
Save carlosdelfino/999f54d5567ff115935ee64c7e62816f to your computer and use it in GitHub Desktop.
/*********************************************************************
* ALGORITMOS DSP FORUM CdH *
* *
* Arquivo: Average_Filter.C *
* Descrição: Arquivo contendo funções de filtro média móvel *
*********************************************************************/
/********************************************************************
* Autor: Felipe Neves *
* *
* Historico: primeira revisão *
* *
* Funcoes: - Average_UpdateBuffer() *
* - Average_Filter() *
* *
********************************************************************/
/*******************************************************************
--INCLUDES
*******************************************************************/
#include Average_Filter.h //arquivo header
/*****************************************************************
--VARIAVEIS GLOBAIS
*****************************************************************/
st_AveragerBuffers stFilterBuffer; //buffer de filtros
/****************************************************************
--FUNCOES
****************************************************************/
/*********************************************************************
* FUNCAO: Average_UpdateBuffer() *
* DESC: Atualiza posição do buffer apontado *
* *
* Entrada : pwBuffer, wNewSample *
* Saida : Nenhuma *
*********************************************************************/
void Average_UpdateBuffer( int *pwBuffer, int wNewSample)
{
int by;
int wBufferTemporario[MAXAVGFILTER]; //buffer temporario para reordenacao
int *pwTemporário
*pwTemporario = (int *) &pwBuffer; //guarda o endereço do buffer de entrada
for ( by = 0; by < MAXAVGFILTER; by++)
{
wBufferTemporario[by] = (int)*pwBuffer++; //preenche buffer temporario
}
//reordena todo mundo, de modo que todos os elementos sejam deslocados
//para aesquerda e a posição 0 do buffer fique livre
for (by = MAXAVGFILTER; by > 0; by--)
{
wBufferTemporario[by] = wBufferTemporario[by - 1];
}
//Coloca nova amostra no buffer
wBufferTemporario[0] = wNewSample;
//atualiza buffer que passamos como parametro via ponteiro
for (by = 0; by < MAXAVGFILTER; by ++)
{
*pwTemporario++ = wBufferTemporario[by];
}
}
/*********************************************************************
* FUNCAO: Average_Filter() *
* DESC: Filtra amostras utilizando o algoritmo "average moving" *
* *
* Entrada : st_AverageBuffers stBuffer *
* Saida : Nenhuma *
*********************************************************************/
void Average_Filter (st_AverageBuffers stBuffer)
{
long int dwAccumulador = 0 ; //para usuários do CCS mudar aqui para int32
int by; //variavel de controle
int NewSample; //nova amostra
for(by = 0; by < MAXAVGFILTER; by++)
{
dwAccumulador += stBuffer.wIn[by]; //acumula valor
}
wNewSample = dwAccumulador >> NUMSHIFTS; //divide por 8
Average_UpdateBuffer(&stBUffer->Out, wNewSample); //atualiza buffer de saida
}
/**********************************************************************
FIM DO ARQUIVO Average_Filter.C
**********************************************************************/
/*********************************************************************
* ALGORITMOS DSP FORUM CdH *
* *
* Arquivo: Average_Filter.h *
* Descrição: Arquivo header de Average_Filter.C *
*********************************************************************/
/********************************************************************
--Conteúdo:
-- Externs
-- Defines
-- Structs
-- Prototipos
**********************************************************************/
#ifndef __AVERAGE_FILTER_H
#define __AVERAGE_FILTER_H 1
/*********************************************************************
--DEFINES
*********************************************************************/
#define MAXAVGFILTER 0x08 //tamanho da média do filtro
#define NUMSHIFTS 0x03 //Numero de shitfs correspondente
// a uma divisão po MAXAVGFILTER
//usem potencias de 2
/**********************************************************************
-- STRUCTS
**********************************************************************/
typedef struct
{
wIn[MAXAVGFILTER]; //buffer de entrada de dados, salvem as leituras
//do A/D aqui
wOut[MAXAVGFILTER]; //buffer de saida de dados, salvem aqui os dados
// que vão para o D/A ou PWM
}st_AverageBuffers; //tipo da estrutura
/***********************************************************************
-- EXTERNS
***********************************************************************/
extern st_AverageBuffers stFilterBuffer; //ja criei uma pra vocês usarem
/**********************************************************************
-- PROTOTIPOS
**********************************************************************/
void Average_UpdateBuffer( int *pwBuffer, int wNewSample); //atualiza buffers
void Average_Filter (st_AverageBuffers stBuffer); //filtra
/**********************************************************************
-- ENDIF
**********************************************************************/
#endif
/*********************************************************************
FIM DO ARQUIVO Average_Filter.h
*********************************************************************/
/************************************************************************
Algoritmo básico Cordic para geração de Seno e Cosseno
Autor: Felipe Neves
REV: 00
************************************************************************/
/************************************************************************
Arquivo: Cordic.c
Funções:
- doCordicSine()
************************************************************************/
/************************************************************************
--INCLUDES:
************************************************************************/
#include "Cordic.h" //arquivo com as definições e constantes
/************************************************************************
--Variaveis globais
************************************************************************/
extern Cpx FFT_Array; //matriz de dados para FFT
/************************************************************************
--FUNCOES
************************************************************************/
/************************************************************************
FUNCAO: doCordic ()
DESCRICAO: Executa algoritmo Cordic em 360 e salva em uma tabela
ENTRADA: wAngle
SAIDA: Nenhuma
*************************************************************************/
int doCordicSine (signed int wAngle)
{
//signed int wAngle = 0; //Angulo de partida
long dwdx, dwdy, dwda; //Vetores de rotacionamento
int wAtan[RESOLUTION] = {0x648,0x3B5,0x1F5,0xFE,0x7F,0x3F,0x1F,0x0F,0x07,
0x03,0x01,0}; //Steps do angulo Theta para multiplicação
int wSin = 0, wCos = KCOS;
int by; //loop count
for (by = 0; by < RESOLUTION ; by++)
{
dwdx = wCos >> by; //rotaciona vetor
dwdy = wSin >> by;
dwda = wAtan [by]; //recupera angulo
if(wAngle >= 0)
{
wCos = wCos - dwdy;
wSin = wSin + dwdx; //rotaciona vetores no sentido horario
wAngle = wAngle - dwda; //p´roximo angulo
}
else
{
wCos = wCos + dwdy;
wSin = wSin - dwdx; //rotaciona vetores no sentido anti -horario
wAngle = wAngle + dwda; //p´roximo angulo
}
}
return (wSin); //retorna o seno da funcao
}
/************************************************************************
FUNCAO: doCordic Cosine()
DESCRICAO: Executa algoritmo Cordic em 360 e salva em uma tabela
ENTRADA: wAngle
SAIDA: Nenhuma
*************************************************************************/
int doCordicCosine (signed int wAngle)
{
//signed int wAngle = 0; //Angulo de partida
long dwdx, dwdy, dwda; //Vetores de rotacionamento
int wAtan[RESOLUTION] = {0x648,0x3B5,0x1F5,0xFE,0x7F,0x3F,0x1F,0x0F,0x07,
0x03,0x01,0}; //Steps do angulo Theta para multiplicação
int wSin = 0, wCos = KCOS;
int by; //loop count
for (by = 0; by < RESOLUTION ; by++)
{
dwdx = wCos >> by; //rotaciona vetor
dwdy = wSin >> by;
dwda = wAtan [by]; //recupera angulo
if(wAngle >= 0)
{
wCos = wCos - dwdy;
wSin = wSin + dwdx; //rotaciona vetores no sentido horario
wAngle = wAngle - dwda; //p´roximo angulo
}
else
{
wCos = wCos + dwdy;
wSin = wSin - dwdx; //rotaciona vetores no sentido anti -horario
wAngle = wAngle + dwda; //p´roximo angulo
}
}
return (wCos); //retorna o seno da funcao
}
/****************************************************************************
Fim do arquivo Cordic.c
****************************************************************************/
/************************************************************************
Algoritmo Cordic básico
Autor: Felipe Neves
REV 00
************************************************************************/
#ifndef __CORDIC_H
#define __CORDIC_H 1
/************************************************************************
--INCLUDES
************************************************************************/
/************************************************************************
--DEFINES
************************************************************************/
#define RESOLUTION 12 //resolução de 12bits
#define MAXANGLE 0xC90 //+PI/2
#define MINIANGLE (~(0xC90) +1) //-PI/2
#define KCOS 1243 //Constante cosseno theta
/************************************************************************
--STRUCTS
************************************************************************/
typedef struct
{
int Real[2000];
int Imag[2000];
}Cpx;
/************************************************************************
--PROTOTIPOS
************************************************************************/
int doCordicSine (signed int wAngle); //executa função cordic
int doCordicCosine (signed int wAngle);
#endif
/************************************************************************
* CordiCMSP430
*
* Arquivo: timer.c
* Desc: Arquivo principal do firmware que acessa os outros
************************************************************************/
/************************************************************************
* Conteudo:
* --Includes
* --Globais
* --Funcoes
************************************************************************/
/************************************************************************
* Historico:
* -Versao: Inicial
* -Motivo: Criacao
* -Autor: FSN
* -Data:
************************************************************************/
/************************************************************************
* --INCLUDES
************************************************************************/
#include <msp430.h>
#include <ti/mcu/msp430/csl/CSL.h>
#include "Cordic.h"
#include "timer.h"
/************************************************************************
* --VARIAVEIS GLOBAIS
************************************************************************/
U8 byTickFlag = 0; //flag de tempo de ponto decorrido
U16 byTicks = 0;
/************************************************************************
* --FUNCOES
************************************************************************/
/************************************************************************
* FUNCAO: OCR0_Handler()
* DESC: Tratamento da interrupcao do timer
*
* ENT: N/A
* SAI: N/A
* RET: N/A
************************************************************************/
void OCR0_Handler (void)
{
//static U16 byTicks = 0; //variavel tick counter
byTicks++; //incrementa variavel de controle
if(byTicks == SINEPOINT) //passado o tempo de ponto da senoide
{
byTicks = 0; //resseta timer
byTickFlag = 1;
}
}
/************************************************************************
* FUNCAO: SetPWM()
* DESC: Seta PWM com dutycicle correspondente
*
* ENT: wInput
* SAI: N/A
* RET: N/A
************************************************************************/
void SetPWM(U16 wInput)
{
CCR1 = (wInput >> 5)+ 60; //faz downscale e passa valor ao PWM
}
/************************************************************************
* FUNCAO: SetPWMN()
* DESC: Seta PWM com dutycicle correspondente
*
* ENT: wInput
* SAI: N/A
* RET: N/A
************************************************************************/
void SetPWMN(U16 wInput)
{
CCR1 = (wInput >> 5); //faz downscale e passa valor ao PWM
}
/************************************************************************
* FUNCAO: main()
* DESC: Funcao principal responsavel por executar outras rotinas
*
* ENT: N/A
* SAI: N/A
* RET: N/A
************************************************************************/
void main(void)
{
//U8 byPoint = 0; //ponto atual da senoide
I16 wAngle = 0; //fase da senoide
U8 byQuadrant = 1; //quadrante da senoide
CSL_init(); // Activate Grace-generated configuration
while (1)
{
switch(byQuadrant)
{
case 1 :
if(byTickFlag)
{
wAngle += OFFSET; //incrementa angulo da senoide
if(wAngle >= MAXANGLE)
{
byQuadrant++;// fez um full, então vamos ao proximo
//wAngle = MAXANGLE;
}
else //senao calcula seno
{
SetPWM(doCordic(wAngle)); //atualiza PWM
}
byTickFlag = 0; //zera flag
}
break;
case 2 :
if(byTickFlag)
{
wAngle -= OFFSET; //incrementa angulo da senoide
if(wAngle <= 0)
{
byQuadrant ++;// fez um full, então vamos ao proximo
//wAngle = 0; //faz complemento de 0
}
else //senao calcula seno
{
SetPWM(doCordic(wAngle)); //atualiza PWM
}
byTickFlag = 0; //zera flag
}
break;
case 3 :
if(byTickFlag)
{
wAngle -= OFFSET; //incrementa angulo da senoide
if(wAngle <= MINIANGLE)
{
byQuadrant ++;// fez um full, então vamos ao proximo
//wAngle = MINIANGLE; //
}
else //senao calcula seno
{
SetPWMN( 2048 - (~(doCordic(wAngle)))); //atualiza PWM
}
byTickFlag = 0; //zera flag
}
break;
case 4 :
if(byTickFlag)
{
wAngle += OFFSET; //incrementa angulo da senoide
if(wAngle >= 0)
{
byQuadrant = 1;// fez um full, então vamos ao proximo
//wAngle = 0;
}
else //senao calcula seno
{
SetPWMN( 2048 - (~(doCordic(wAngle)))); //atualiza PWM
}
byTickFlag = 0; //zera flag
}
break;
}
}
}
/************************************************************************
* CordiCMSP430
*
* Arquivo: timer.h
* Desc: Header de timer.c
************************************************************************/
/************************************************************************
* Conteudo:
* --Defines
* --Externs
* --Structs
* --Prototipos
************************************************************************/
#ifndef __TIMER_H
#define __TIMER_H 1
/*************************************************************************
* --DEFINES
*************************************************************************/
#define OFFSET (MAXANGLE / 16) //incremento de angulo da senoide
#define SINEPOINT 1 //numero de ticks por ponto
typedef unsigned char U8; //define tipo para U8
typedef unsigned int U16; //define tipo para U16
typedef signed int I16; //define tipo sinalizado para U16
typedef unsigned long int U32; //define tipo para U32
/*************************************************************************
* --PROTOTIPOS
*************************************************************************/
void OCR0_Handler (void); //interrupcao de captura
void SetPWM(U16 wInput); //faz feed do PWM
void SetPWMN(U16 wInput);//feed PWM negativo
void main(void); //funcao principal do programa
/*************************************************************************
* --ENDIF
*************************************************************************/
#endif /**/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment