Roteiro 11 EA870 2S2009

De DCA-Wiki

Contents

Roteiro 11 - Transmissão Serial Síncrona (SPI/QSPI) e Conversor Digital/Analógico

  • Continuação com a transmissão SPI/QSPI
  • Uso do Conversor Digital/Analógico (DAC)

Agradecimentos

O desenvolvimento deste roteiro teve a grata contribuição de-

Guilherme A. Zalewski (buzzag@gmail.com) e Pedro Augusto (okaitt@gmail.com).

Introdução ao Experimento de Hoje

  • Neste experimento iremos continuar a utilizar da transmissão serial síncrona (SPI) do MCF para utilizarmos do conversor digital/analógico presente na placa auxiliar (CI DAC577). Mais uma vez teremos o código exemplo para o envio de bits para o DAC e a sua ativação.

Roteiro de Estudos

  • 1. O que é um conversor Digital/Analógico?
  • 2. Qual a faixa de conversão do DAC577 /5/?
  • 3. O que é resolução de conversão? Qual é a resolução do DAC577 /5/?
  • 4. Como se representaria uma tensão X em binário /5/?
  • 5. Qual a função do periférico QSPI no conversor DAC ?
  • 6. Quais são os passos para ativar o conversor DAC /5/?

Roteiro da Aula

O programa exemplo:

- Programa DAC/main.c

#include "support_common.h" /* include peripheral declarations and more */
#include "uart_support.h"
#include <stdio.h>
//Define os endereços necessário às portas
#define DDRAS	0x40100023
#define PORTAS	0x4010000B
#define PASPAR	0x4010006B
#define CLRAS	0x40100053
#define SETAS	0x4010003B

//FUNÇÃO DE TRANSMISSÃO QSPI
void envia_spi(uint8 sinal)
{
MCF_QSPI_QAR = 0x0000;		//Registrador de endereço aponta para área de transmissão
MCF_QSPI_QDR = sinal;		//É armazenado o dado a ser transmitido
MCF_QSPI_QDLYR |= 0x8000;	//Dá início à transmissão
}


//FUNÇÃO PRINCIPAL - CONVERSOR DIGITAL/ANALOGICO
int main(void)
{

uint8 sinal=0;
//Cria apontadres para os endereços de portas
uint8 *ddras = (uint8 *)DDRAS;
uint8 *portas = (uint8 *)PORTAS;
uint8 *paspar = (uint8 *)PASPAR;
uint8 *clras = (uint8 *)CLRAS;

//CONFIGURAÇÃO DO PERIFERICO QSPI

MCF_GPIO_PQSPAR |= 0x1555;               //A porta porta QS exerce função QSPI
					//Configuração do registrador "Mode"
MCF_QSPI_QMR &= ~(MCF_QSPI_QMR_CPHA);	//Dados mudam na borda de subida do clk
MCF_QSPI_QMR |= MCF_QSPI_QMR_MSTR;	//Modo MASTER (Obrigatorio)
MCF_QSPI_QMR |= MCF_QSPI_QMR_BITS(0x8);	//8bits por transmissão
MCF_QSPI_QMR |= MCF_QSPI_QMR_BAUD(0x2);	//Baud Rate 10Mhz

MCF_QSPI_QDLYR = 0x0000;		//Delay register = 0 Delays são todos zero
MCF_QSPI_QWR = 0x1000;			//Abaixa nível de CS0 e informa transmisão única
					//Lembrando-se que o HLT pára transmissão
//O nível de CS0 deve ser baixo para ser possível selecionar o conversor D/A porteriormente
MCF_QSPI_QIR |= MCF_QSPI_QIR_SPIF;	//Garante que o "finish flag" é alto nível

//Programa a transmissão
MCF_QSPI_QAR = 0x0020;			//Registrador de endereço aponta para área de comandos 
MCF_QSPI_QDR = 0x7E00;			//Programa a transmissão (nº de bits...)

//FIM DA CONFIGURACAO DO QSPI

//Configura as portas
*paspar = 0x00;		//PortAS tem sua função de porta
*ddras = 0x02;		//Pino AS1 é definido como saída

*clras = 0x00;		//Abaixa a porta PAS1 para que se selecione o conversor D/A
envia_spi(sinal);	//Transmite o "sinal" para o conversor D/A

}
  • Crie um novo projeto no CodeWarrior e utilize o código acima como código principal (main).
  • Procure entender exatamente o que o código faz.


Agora, para a confecção do relatório, é preciso a função varre_teclado() utilizada no Roteiro 7. Basta incluir os "DEFINES" no programa DAC/main.c e incluir a função no seu código. Lembrando que é necessário um vetor de tamanho 12 de entrada para a função, que retorna os botões pressionados. Abaixo a função:

Função varre_teclado()

#define PORTTC  0x4010000F
#define DDRTC   0x40100027
#define PORTUBP 0x40100042
#define DDRUB   0x4010002A
#define PUBPAR  0x40100072

void varre_teclado(int situacao[])
{
	int i,j, mask;
	int aterra[4] = {0x0E000000,0x0D000000,0x0B000000,0x07000000}; /*Sequencia de saidas para as portas*/
	int io[4] = {0x01000000,0x02000000,0x04000000,0x08000000}; /*Sequencia de configuracao de porta*/
	int *end_aterra = (int *)aterra;  /*Recebe o endereco do vetor de dados*/ 
	int *end_io  = (int *)io; /*Recebe o endereco do vetor de dados*/ 
	int *end_key = (int *)situacao; /*Recebe o endereco do vetor de status do teclado*/ 
	int *porttc  = (int *)PORTTC;
	int *ddrtc   = (int *)DDRTC;
	int *portubp = (int *)PORTUBP;
	int *ddrub   = (int *)DDRUB;
	int *pubpar  = (int *)PUBPAR;

	*pubpar = 0xFF; /*Configura porta UB para trabalhar como porta comum*/
	*ddrub = 0xFF;	/*Configura UB como ENTRADA*/

	/*Rotina para varrer teclado. Previne contra curto quando mais teclas estao apertadas ao mesmo tempo*/
	for (i=0; i<4; i++){  

	/*Faz a leitura da linha i*/
	*ddrtc = *end_io; /*Configura TCi como saida e o restante como entrada*/
	*porttc = *end_aterra; /*Seta ZERO no bit TCi*/

	end_aterra++;  /*Pega o dado seguinte, aterra ou nao*/
	end_io++; /*Pega a configuracao seguinte, Entrada ou Saida*/
	mask = 0x01000000; /*Configura mascara para detectar botao apertado ou nao*/

		for (j=0;j<3;j++){
		
		/*Caso o botao esteja apertado, o bit i do registrador PORTUBP estara em ZERO*/
		if(!(mask & *portubp)) *end_key = 1;
		else *end_key = 0;
        
        mask = mask <<1; /*Verifica bit seguido (colula j)*/
    	end_key++; /*Passa para proximo digito no vetor TECLADO*/
		}
	}
}

Podemos também utilizar as funções de envio e recebimento da UART0 em C visto no relatório de PWM. Abaixo estão as funções:

#include "uart_support.h"  //Nao se esqueça de colocar este include
...
int main(){
...
uart_init(0,80000,9600);  //Apenas inicialize uma vez o periférico
...
uart_putchar(0,'A');  //Envia um char
...
algum_char = uart_getchar(0);  //Pega um char digitado
...
}

Relatório

(Veja na página da disciplina, na opção calendário a data referente à entrega de cada relatório).

  • 1. Faça o fluxograma para o programa exemplo.
  • 2. Utilizando como base o exemplo, construa um programa que:
    • Ao pressionar o SWA, entre na função varre_teclado(). Deve-se receber UM dígito e aguardar o SWA ser pressionado novamente. Apos detectar o SWA pressionado pela segunda vez, deve-se receber mais UM dígito e esperar o SWA ser pressionado novamente. Na terceira vez em que o SWA for pressionado, deve-se receber UM último dígito e formar com os três digitos coletados um número de 000 a 255 (não se preocupe com o usuário digitar um valor maior que 255 ou digitar menos de três digitos), sendo que o primeiro dígito recebido representa a centena, o segundo a dezena e o terceiro a unidade.
      • DICA: Após receber o vetor da função varre_teclado, verifique se algum dígito foi recebido, e, se isso for verdade, passe para o próximo dígito.
      • DICA: Para obter o valor real, multiplique o primeiro dígito por 100 somado ao segundo dígito multiplicado por 10 e somado ao último dígito multiplicado por 1.
    • Receba este valor e envie-o para o conversor DAC.
    • Agora, verifique com um multímetro a saída analógica.
  • 3. Funcionando o programa anterior, altere-o para que após receber os três dígitos pelo teclado:
    • Ele espere o SWB ser pressionado para que envie o valor convertido em binario para o DAC.
    • Após o SWB ser pressionado, o valor em decimal, binário e a voltagem correspondente (dada pela fórmula em /5/) apareçam no display LCD separados por espaço.
  • 4. Faça um fluxograma do seu programa, feito no item 3.

- Referências

Ferramentas pessoais