SCI – ejemplos de clase

por | 2017.10.21

Este ejemplo envía T18.7C (+ un salto de línea) cada 1s
La configuración de UART es 9600 8N1

/*
  Envía T18.7C por SCI (UART) 9600 8N1 cada 1s
*/

#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */

unsigned int conteo = 0;
unsigned int mandar = 0;

// vector donde se coloca lo que se va a enviar
unsigned char resp[] = "T00.0C\n";
unsigned char i = 0;

void main(void) {
	SOPT1 &= 0x3F;    // deshabilito COP

	// este bloque "calibra" el oscilador interno a +/- 2% de error aprox.
	// es necesario para usar SCI
	asm {
		LDA $FFAF;-- inicializa osc. interno
		STA ICSTRM
	}
	while (!ICSSC_IREFST); /* espera ck interno estable */

	// se habilitan interrupciones 
	EnableInterrupts;

	// se configura timer 1 - overflow int @ 1ms
	TPM1SC = 0b01001011;
	TPM1MOD = 999;

	// se configura SCI - 9600 8N1
	SCIBD = 52; // divisor = 52 baudrate = 8MHz / 52 / 16 = 9615,38 → 9600
	SCIC1 = 0b00000000; // sin paridad
	SCIC2 = 0b00001100; // tx & rx encendidos
	SCIC3 = 0;
	
	// loop
	for (;;) {
		// se colocan los codigos ASCII de los valores a transmitir
		resp[1] = '1'; 
		resp[2] = 8 + 0x30;  // 8 + 0x30 = código ASCII de '8'
		resp[4] = '7';

                // si pasó 1s... ("aviso" de la interrupción)
		if (mandar == 1) {		
			// si  está lbre el registro de transmisión...				
			if (SCIS1_TDRE == 1) {
				// mando los 8 bits en posición i del vector resp
				SCID = resp[i];

				// incremento i (apunta al siguiente grupo de 8 bits)
				i++;

				// si es 7 terminó de mandar todo resp[] 
				if (i == 7) {
					// i vuelve a "apuntar" al primer elemento de resp
					i = 0;
					// se inhabilita transmisión hasta que pase 1s
					mandar = 0;
				}
			}
		}
	} 
}

// servicio de interrupción Timer 1 Overflow 
__interrupt VectorNumber_Vtpm1ovf void toto() {
	TPM1SC_TOF = 0; // se limpia TOF
	conteo++;       // incrementa conteo 
	if (conteo == 1000) {  
		// si coneo es 1000 pasó 1s =>
        // - vuelvo conteo a 0
		conteo = 0;
        // - con mandar = 1 "aviso" al que pasó 1s
		mandar = 1;
	}
}

Un ejemplo de programa en C (para Win32) que recibe lo que envía este firmware se puede encontrar acá

Otro ejemplo, más sencillo pero que habría que evitar ya que cada

while (SCIS1_TDRE == 0)

bloquea el programa por un 1ms aproximadamente.

/*
  Envía T13 por SCI (UART) 9600 8N1 cada 1s
*/

#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */

unsigned int conteo = 0;
unsigned int mandar = 0;

void main(void) {
	SOPT1 &= 0x3F;

	asm {
		LDA $FFAF;-- inicializa osc. interno
		STA ICSTRM
	}
	while (!ICSSC_IREFST); /* espera ck interno estable */

	EnableInterrupts;

	TPM1SC = 0b01001011;
	TPM1MOD = 999;

	SCIBD = 52; // divisor = 52 baud = 8MHz / 52 / 16 = 9615,38 → 9600
	SCIC1 = 0b00000000; // sin paridad
	SCIC2 = 0b00001100; // habilita int por RX, tx & rx encendidos
	SCIC3 = 0;

	for (;;) {
		if (mandar == 1) {
			SCID = 'T';
			while (SCIS1_TDRE == 0);
			SCID = '1';
			while (SCIS1_TDRE == 0);
			SCID = '3';
			while (SCIS1_TDRE == 0);
			SCID = '\n';
			while (SCIS1_TDRE == 0);

			mandar = 0;
		}
	} 
}

__interrupt VectorNumber_Vtpm1ovf void toto() {
	TPM1SC_TOF = 0;
	conteo++;
	if (conteo == 1000) {
		conteo = 0;
		mandar = 1;
	}
}

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *