Roteiro 4 EA870 2S2009

De DCA-Wiki

Contents

Roteiro 4 – Transmissão serial assíncrona

Agradecimento

O desenvolvimento deste roteiro teve a grata contribuição de Yuri Hayashi Isayama (yurihayama@yahoo.com.br), Igor Kovacs Biscaia - (igor.biscaia@gmail.com), Guilherme A.Zalewski - mailto:buzzag@gmail.com , Pedro Augusto (okaitt@gmail.com) e Marcos Medeiros Raimundo - mailto:marcosmrai@gmail.com .

Avisos

  • 08/09/2009 - Caros,

É preciso um cuidado especial quando se usar as instruções de move quando esta envolver a leitura e escrita nos registradores de Entrada/Saída. A razão é a seguinte. Como os registradores de dados (D0 a D7) possuem 4 bytes, se a entrada e saída for BYTE e estiver associada a um endereço, por exemplob BASE. Fazer move D0, BASE fará com que a parte mais significativa do D0 (bits 31 a 24) sejam escritas no registrador BASE, e fará com que os restantes 3 bytes de D0 (bits 23 a 0) sejam escritas nos endereços BASE+1, BASE+2 e BASE+3, o que é conceitualmente errado, pois pode ser que nestes endereços existam outros registradores de E/S que não devem ser alterados.

              Assim, o correto é       move.b D0, BASE. 

Qualquer dúvida estou à disposição. Profs. e Tutores

Introdução

O Objetivo desta experiência é observar e trabalhar (configurar registradores e respectivos bits) a porta serial de 9 pinos - RS232 - da placa MCF52. A programação consiste em enviar e receber dados através dos bit/9.pinos dessa porta e, para tanto, fazendo uso do programa Hiperterminal. Para iniciar seções pelo Hiperterminal, siga os seguintes passos:

  • 1. (OBS.: Alertamos que o Hiperterminal NÃO É DISPONÍVEL NO WINDOWS-VISTA. O programa executável - *.exe - e os auxiliares devem ser importados do XP ou 2000)

No Microsoft Windows XP, 2mil, clique em Iniciar > Programas > Assessórios > Comunicações > Hiperterminal.

  • 2. O software pede um nome, forneça-o de sua escolha, por exemplo HP100, clique em OK. Na sequência, o software exibe a tela: conectar-se.
  • 3. Na caixa Conectar-se usando-se, selecione COM1 ou COM2 na lista pull-down. Em seguida, o software exibe uma tela de configurações:
  • 4. Selecione as seguintes configurações:
    • Bits por segundo - bps - 9600
    • Bits de dados: 8
    • Paridade: Nenhuma
    • Bits de parada (stop bits): 1
    • Controle de fluxo: Nenhum
  • 5. Clique em OK.

Na sequência, a sessão do Hiperterminal é executada, como se pode observar no "timer" exibido no canto inferior, à esquerda da tela. Use a seção para se comunicar com o Storage Processor - SP. (Mais uma vez avisamos: Cuidado, para facilidade e aqui no LE30, chamaremos a MCF52221DEMO de apenas [[MCF52]]). Recomenda-se para o maior entendimento do roteiro e do exemplo dado a leitura do capítulo 12 do manual /3/, pois ele esclarece cada passagem de ativação da porta serial e também de sua configuração, além do conhecimento do código ASCII (a tabela será utilizada também http://pt.wikipedia.org/wiki/ASCII/).

Questões de estudo

  1. O que é UART (Veja Cap. 23/24 na Ref. 1/3 respectiv.)? Faça seu diagrama de blocos e explique como funciona cada?
  2. Qual é a frequência padrão do relógio da placa? (Veja Reg/UBG1n/UBG2b)
  3. Explique como é feito o cálculo interno do Baud Rates (Seção 23.4.1.2.1)
  4. Explique a diferença e mostre quando e como se usa as instruções assembly: move e movea.
  5. Em assembly, qual a diferença entre os comandos “move”, “move.b”, “move.w” ou “move.l”? Quando utilizá-los?
  6. Para que serve o programa Hyperterminal?
  7. Qual é o tipo de codificação que o programa Hyperterminal utiliza para interpretar os dados recebidos?
  8. O que vem a ser o código ASCII? (Veja "site" na Seção de Introdução)
  9. O quê sinifica e qual a diferença de bitrate e baudrate?
  10. Qual o nome do registrador utilizado para configurar a taxa de transferência.
  11. Compare a transmissão paralela com a transmissão serial e explique as diferenças.
  12. Qual a utilidade do stopbit, startbit? Quais os valores que os configura? Qual o valor padrão?
  13. Faça um diagrama que mostra antes, no envio de dados e, depois da transmissão, como fica o sinal de envio de dados.

Registros da Interface de comunicação tipo serial - UARTs -

Nesta seção, como exemplo, define-se um dos módulos de registradores da UARTn, para n = 0,1 e 2. Neste presente roteiro usa-se a UART0. A designação n que aparece em toda seção refere-se aos registradores ou sinais associados a um dos três módulos UARTs idênticos: UART0, UART1 e UART2. Veja definição completa no Cap 23 de /1/. Na sequência, para facilidade, mostra-se um esboço de Esquema de Comunicação Serial. Mais uma vez, chama-se a atenção ao fato que a UART é uma INTEFACE de comunicação serial, pois consiste de uma série de registradores que necessitam ser configurados. Enquanto Porta, como a dos LEDS, configurou-se os bits da porta NQ - rot2 e rot3. A seguir mostra-se os registradores da interface UART0 que devem ser configurados:

  • UMR10 - Registro de Modo: configura erros, Paridade.
  • USR0 - Status Register - receiver ready - recebedor.
  • UCSR0 - Control Source Transmiter Ready - transmissor - controla fonte de Clock para transmissão e recepção.
  • UCR0 - Command Register, Reset device and error.
  • URB0 - RX Receive Buffer
  • UTB0 - TX Transmit Buffer

Esquema de Comunicação Serial (onde n=1 ou 2, refere à COM1/COM2; i=1,2,...)

              Teclado:1 ---->             ---->2  UARTi RX  ---->3  
                               COMn                                UCP
              Display:6 <----             <----5  UARTi TX  <----4
                            
              Hiperterminal                                     ColdFire
  • 1 - Caratere é digitado no teclado via Hiperterminal e enviado via COMn;
  • 2 - O caratere é transmitido serialmente p/UARTi-2;
  • 3 - O Core-UCP-3 lê o char da URBi e o armazena na memória;
  • 4 - O Core-UCP-4 o transfere da memória p/UTBn;
  • 5 - A COMn-5 recebe serialmente cada bit do char;
  • 6 - O Hiperterminal o exibe: display char.

Roteiro de aula

Nesta experiência, iremos executar o programa SERIAL/main.c que está codificado em assembly language do ColdFire MCF52. Este é um exemplo de configuração da UART0 e deve ser igual em qualquer aplicação utilizando a UART0 com o mesmo baud-rate. Estude a UART, seu funcionamento e como configurar seus registradores nos respectivos cap23 ou cap24 das ref 1 e 3. Não esqueçam da pseudo-instrução #define que tem funcionalidade idêntica ao EQU in assembly language.

- Programa SERIAL/main.c

Atenção, este programa foi modificado. A última versão (correta e validada) é de 8set09, 9h00. A modificação foi feita principalmente no acesso de 8 bits (move.b) para leitura e escrita nas portas da UART. Esta é a razão do aviso no topo do roteiro.

A versão atual deve funcionar, caso contrário, favor avisar.

#include "support_common.h" /* include peripheral declarations and more */
#include "stdio.h"
#include "uart_support.h"

#define UCR0  	0x40000208
#define UMR10   0x40000200
#define UBG20	0x4000021C
#define UBG10	0x40000218
#define UISR0	0x40000214	
#define UCSR0   0x40000204
#define UTB0    0x4000020C
#define URB0    0x4000020C

 int main(void)
 {
 asm
 {	
	
    /*Configuração da porta serial UART0*/
          move.b  #0x30, D0     //Reset transmissor, veja table 23-7, ref /1/
          move.b  D0, UCR0
          move.b  #0x20, D0     //Reset receptor
          move.b  D0, UCR0
          move.b  #0x10, D0	//Reset Mode Register point
          move.b  D0, UCR0
          move.b  #0x13, D0	//Sem paridade e com dados de 8 bits
          move.b  D0, UMR10     // veja table 23-3, ref /1/
          move.b  #0x07, D0	//Configurado 1 stop bit e sem eco ou loop back
          move.b  D0, UMR10
          move.b  #0xDD, D0	//Configura o clock do receptor/transmissor
          move.b  D0, UCSR0
          move.b  #0x0, D0	//Desabilita interrupção
          move.b  D0, UISR0
          move.b  #0x1, D0	//Gera Baud-rate
          move.b  D0, UBG10	//Clock de 80MHz
          move.b  #0x04, D0	//Segundo registrador p/ Baud-rate
          move.b  D0, UBG20
          move.b  #0x05, D0		//Habilita transmissor e receptor
          move.b  D0, UCR0
    /*Fim da configuração da UART0*/

 ECO:     JSR	  LEITURA               // Faz leitura da porta serial e coloco em D0
          JSR	  ESCRITA	        // Escreve D0 na porta serial
          bra	  ECO 		        // Volta
 
 ESCRITA: move.b  UCSR0, D1     //Lê a situação da porta serial
          andi	  #0x4, D1      //Verifica se o canal de transmissão está pronto
          beq	  ESCRITA       //Se não, volta e tenta de novo (laço de espera)
          move.b  D0, UTB0	//Estando pronto para tx, envia o dado para a porta serial
          rts

 LEITURA: move.b  UCSR0, D0     //Lê a situação da porta serial
          andi	  #0x1, D0      //Verifica se existe caractere a ser lido
          beq	  LEITURA       //Se não, verifica novamente (laço de espera)
          move.b  URB0, D0	//Do contrário, lê caractere e coloca em D0 (byte)
          rts                   // Retorna o valor lido em D0
          }
 }

- Programa SR/main.c

O Objetivo deste programa é possibilitar o uso do registrador SR para somas e subtrações de 4 bits. Neste programa é entrado o valor 0x0f (0000 1111) em d0, e 0x02 (0000 0010) em d1. Estes dois registradores são deslocados em 18 posições para que os 4 bits menos significativos se tornem os mais significativos.

Ex: Estado inicial: 0x0000000f Após o deslocamento: 0xf0000000.

Esse deslocamento faz com que as operações com os 4 bits possam ser "vistas" pelo registador SR. Para o exemplo acima, no estado inicial o bit que indica negativo no SR está resetado, e após o delocamento está setado. Assim como a soma entre 0x00000002 e 0x0000000f não setará a flag de overflow. Enquanto, a soma entre 0xf0000000 e 0x20000000 setará.


#include "support_common.h"
#include <stdio.h>


int main(void)
{
	asm
	{
        INI:
        move.b #0x0f, d0 //insersão de um valor a ser tratado
        lsl #0x08, d0 // deslocamentos para deixar o valor tratado no byte mais significativo
        lsl #0x08, d0 // para assim observar a mudanca do registrador SR
        lsl #0x08, d0
        lsl #0x04, d0 // ponto 1
        move.b #0x02, d1 // insersão de um valor a ser tratado
        lsl #0x08, d1 // deslocamentos para deixar o valor tratado no byte mais significativo
        lsl #0x08, d1 // para assim observar a mudanca do registrador SR
        lsl #0x08, d1
        lsl #0x04, d1 // ponto 2
        add d1, d0 // ponto 3
        bra INI: 
	}
}


Relatório

Entregar as questões abaixo em forma de relatório:

  • 1.1. Faça um diagrama de blocos do programa SERIAL/main.c, procurando entendê-lo.
  • 1.2. Rode o programa SR/main.c passo a passo, procurando entendê-lo, observando as mudanças do registrador SR, e explicando as mudanças ocorridas nos 5 bits menos significativos entre após os pontos 1, 2 e 3.
  • 2. Implemente um programa, em assembly language, que receba dois números binários de 4 bits em complemento de 2 (isto é, os numeros estarão no intervalo de -8 a 7). O usuáro digitará apenas 0 e 1 no programa hyperterminal, sem espaçamento entre os números, implicando que o bit mais significativo será enviado primeiro. Mostre o resultado da subtração dos dois através dos LEDS. É necessário também que se envie os números recebidos (estilo "eco") e o resultado da operação para o programa Hyperterminal.
    • DICA: Cada número recebido terá codificação ASCII (30 para o número 0 e 31 para o número 1 e .... assim por diante). Um método eficaz é comparar o valor recebido com 30 ou 31, montando assim o número binário de 4 bits.
    • DICA: Utilize de um contador para receber o primeiro número de quatro bits, assim como o segundo.
    • DICA: Para se obter o número binário, pode-se usar a instrução de deslocamento a cada bit recebido.
  • 3. Faça um fluxograma do programa acima.
  • 4. Funcionado o programa acima, altere o programa para que se tenha uma apresentação inicial no HYPERTERMINAL desta forma:
#### FEEC - CALCULADORA SIMPLES ####
Digite a operacao:
Digite o primeiro operando:
Digite o segundo operando:
Resultado em binario:
Resultado em decimal:
Houve Overflow?:

Após a requisição da operação, aguarde a entrada da operação "+" ou "-" seguida de um <ENTER>. Transmita a frase seguinte e aguarde a entrada dos operandos, recebendo-os seguidos de <ENTER> para a confirmação. Deverá ser apresentado o resultado em binário, em decimal, sendo que este deverá ter sinal, e por fim uma flag dizendo se houve overflow. Da mesma forma como foi feito no primeiro programa, exiba o resultado nos leds.

    • DICA: Pequise os caracteres "+" e "-" em ASCII e compare-os para saber se eles já ocorreram.
    • DICA: Para fazer a mudança de linha corretamente deve-se usar o "line-feed"(0x0A) seguido do retorno de carro "carriage return"(0x0D) (ou seja, enviando os dois comandos seguidos, uma linha é pulada).
    • DICA: O <ENTER> recebido serialmente possui código hexadecimal "0x0D".
    • DICA: Para facilitar o envio das mensagens via porta serial, declare as strings em C, e crie uma rotina em assembly para imprimir uam string, que receba o endereço da string declarada e envie a mensagem via hiperterminal.
  • 5. Faça um fluxograma do programa modificado.

- Referências

Ferramentas pessoais