Diferencia entre revisiones de «Código Acelerómetro para Codewarrior 10.6»
De Wikitronica
(→Descripción de funciones) |
(→Enviar caracteres) |
||
Línea 78: | Línea 78: | ||
===Funciones para la transmisión y recepción de datos=== | ===Funciones para la transmisión y recepción de datos=== | ||
− | ==== | + | ====Recibir caracteres==== |
<syntaxhighlight lang="c"> | <syntaxhighlight lang="c"> | ||
char RecChar(void) { | char RecChar(void) { | ||
Línea 84: | Línea 84: | ||
if (SCI1S1_RDRF) | if (SCI1S1_RDRF) | ||
− | rec_char = SCI1D; | + | |
− | SCI1C2_RE = 1; | + | <font color="#3f7f5f">/ Si el buffer de transmisión esta lleno</font> |
− | while(!SCI1S1_RDRF){ }; | + | |
− | rec_char = SCI1D; | + | rec_char = SCI1D; <font color="#3f7f5f">/ Limpio el buffer</font> |
− | SendChar((char) rec_char); | + | SCI1C2_RE = 1; <font color="#3f7f5f">/Habilito la transmisión</font> |
+ | while(!SCI1S1_RDRF){ };<font color="#3f7f5f">/ Espero hasta que el buffer no esté vacío</font> | ||
+ | rec_char = SCI1D; <font color="#3f7f5f">/ Obtengo el caracter enviado</font> | ||
+ | SendChar((char) rec_char); <font color="#3f7f5f">/ Reenvío el caracter</font> | ||
return (char) SCI1D; | return (char) SCI1D; | ||
} | } |
Revisión del 18:06 22 jun 2016
Descripción general
Descripción de funciones
Inicialización de periféricos
ICS
El módulo ICS (Internal Clock Source) maneja las diferentes opciones para la fuente de reloj. Tiene siete modos de operación: FEI, FEE, FBI, FBILP, FBE, FBELP, y stop. En este caso se trabajará con el modo por defecto FEI.
Para inicilizar el ICS deben modificarse tres de sus registros:
ICSC1: ICS Control Register 1
ICSC2: ICS Control Register 2
ICSSC: ICS Status and Control
Rutina de inicialización
#define ICSC1_FEI 0x04
#define ICSC2_FEI 0x06
#define ICSSC_FEI 0x80
void ICS_FEI(void) {
: if (NVICSTRM != 0xFF)
:: ICSTRM = NVICSTRM;
:else
::ICSTRM = 0xAD;
::ICSC1 = ICSC1_FEI;
::ICSC2 = ICSC2_FEI;
::ICSSC = ICSSC_FEI;
:while (ICSC1_CLKS != ICSSC_CLKST) {}
}
KBI
void InitKBI(void) {
// Enable KBI1P[3:2] as interrupt
KBI1PE = KBI_SW;
KBI1SC = 0b00000110;
/* ||||
|||+---- KBIMOD = KBI detection mode: 0=edge only
||+----- KBIE = KBI int enable: 1=enabled
|+------ KBACK = KBI int acknowledge: 1=clr IRQF
+------- KBF = KBI flag
*/
}
SCI
void InitSCI(word baud) {
SCI1BD = baud; // set baud
}
ICC
void IIC_configuration (void) {
IIC2F = 0x90;
IIC2C1 = 0xC0;
}
Funciones para la transmisión y recepción de datos
Recibir caracteres
char RecChar(void) {
byte rec_char;
if (SCI1S1_RDRF)
<font color="#3f7f5f">/ Si el buffer de transmisión esta lleno</font>
rec_char = SCI1D; <font color="#3f7f5f">/ Limpio el buffer</font>
SCI1C2_RE = 1; <font color="#3f7f5f">/Habilito la transmisión</font>
while(!SCI1S1_RDRF){ };<font color="#3f7f5f">/ Espero hasta que el buffer no esté vacío</font>
rec_char = SCI1D; <font color="#3f7f5f">/ Obtengo el caracter enviado</font>
SendChar((char) rec_char); <font color="#3f7f5f">/ Reenvío el caracter</font>
return (char) SCI1D;
}
Recibir caracter
void SendChar(char s_char) {
SCI1C2 = 0x08; // enable Tx
while(!SCI1S1_TDRE){ }
SCI1D = (byte) s_char; // 2nd half of TDRE clear procedure
} //end SendChar
}
Enviar mensaje
void SendMsg(char msg[]) {
byte i=0;
char nxt_char;
SCI1C2 = 0x08; // enable Tx
nxt_char = msg[i++];
while(nxt_char != 0x00) {
while(!SCI1S1_TDRE){}
SCI1D = (byte) nxt_char; // 2nd half of TDRE clear procedure
nxt_char = msg[i++];
} //end while((SCI1D
} //end SendMsg
Conversión de datos
word hex2bcd(word hex){
byte dec[4],i;
word bcd;
for (i=0;i<4;i++){
dec[i] = (byte) (hex%10);
hex = (word) (hex/10);
}
if (hex>0){
bcd=0xffff;
}else{
bcd=(word)((word)(dec[3]<<12) + (word)(dec[2]<<8) + (dec[1]<<4) + dec[0]);
}
return bcd;
} //end hex2bcd
byte asc2byte(char n_asc) {
byte n;
n = (byte)(n_asc - 0x30); //convert from ascii to int
if(n > 0x09) // if num is $a or larger...
n -= 0x07; // ...sub $7 to correct
if(n > 0x0f) // if lower case was used...
n -= 0x20; // ...sub $20 to correct
if(n > 0x0f) // if non-numeric character...
n = 0x00; // ...default to '0'
return n;
} //end asc2num
word asc2word(byte n_asc[2]) {
word n,n2;
// assumes n_asc[0] is MSB, n_asc[1] is LSB
n = (word)(n_asc[0] - 0x30); //convert from ascii to int
if(n > 0x09) // if num is $a or larger...
n -= 0x07; // ...sub $7 to correct
if(n > 0x0f) // if lower case was used...
n -= 0x20; // ...sub $20 to correct
if(n > 0x0f) // if non-numeric character...
n = 0x00; // ...default to '0'
n = (word)(n<<8); // shift into high byte
n2 = (word)(n_asc[1] - 0x30); //convert from ascii to int
if(n2 > 0x09) // if num is $a or larger...
n2 -= 0x07; // ...sub $7 to correct
if(n2 > 0x0f) // if lower case was used...
n2 -= 0x20; // ...sub $20 to correct
if(n2 > 0x0f) // if non-numeric character...
n2 = 0x00; // ...default to '0'
n += n2; //
return n;
} //end asc2word
char * byte2asc(byte num, byte base) {
byte n;
if (base){
n=(byte)(hex2bcd(num));
}else{
n=num;
} //end if (base)
n_str[0] = (byte)((n>>0x04)+0x30); // convert MSN to ascii
if(n_str[0]>0x39) // if MSN is $a or larger...
n_str[0]+=0x07; // ...add $7 to correct
n_str[1] = (byte)((n&0x0f)+0x30); // convert LSN to ascii
if(n_str[1]>0x39) // if LSN is $a or larger...
n_str[1]+=0x07; // ...add $7 to correct
n_str[2] = 0x00; // add line feed
return (char *) n_str;
} //end byte2asc
char * word2asc(word num, byte base) {
word n;
if (base){
n=hex2bcd(num);
}else{
n=num;
} //end if (base)
n_str[0] = (byte)((n>>12)+0x30); // convert MSN to ascii
if(n_str[0]>0x39) // if MSN is $a or larger...
n_str[0]+=0x07; // ...add $7 to correct
n_str[1] = (byte)(((n>>8)&0x0f)+0x30); // convert 2nd MSN to ascii
if(n_str[1]>0x39) // if LSN is $a or larger...
n_str[1]+=0x07; // ...add $7 to correct
n_str[2] = (byte)(((n>>4)&0x0f)+0x30); // convert 2nd MSN to ascii
if(n_str[2]>0x39) // if LSN is $a or larger...
n_str[2]+=0x07; // ...add $7 to correct
n_str[3] = (byte)((n&0x0f)+0x30); // convert 2nd MSN to ascii
if(n_str[3]>0x39) // if LSN is $a or larger...
n_str[3]+=0x07; // ...add $7 to correct
n_str[4] = 0x00; // add line feed
return (char *) n_str;
} //end word2asc
Aceleración
void ReadAcceleration(void){
byte i;
signed int temp;
for(i=0;i<3;i++){
temp = IIC_Rec_Data[i] & 0x3F;
if(IIC_Rec_Data[i] & 0x20){
temp |= 0xFFC0;
temp += 32;
IIC_Converted_Data[i] = temp;
}else{
IIC_Converted_Data[i] = temp + 32;
}
}
}
void ShowAcceleration (void)
{
word SampleCNT;
byte j,k;
ReadAcceleration();
ADCSC1 = 0x01;
x.reading[samp] = (dword)( IIC_Converted_Data[0] <<8);
ADCSC1 = 0x08;
y.reading[samp] = (dword)( IIC_Converted_Data[1] <<8);
ADCSC1 = 0x09;
z.reading[samp] = (dword)( IIC_Converted_Data[2] <<8);
StartTPM(0); //0 = TPM prescaler = /2
if(samp>0){
switch (mode){
case filter: filter_data(); break;
case avg : avg_data(); break;
default : copy_data();
}
} else {
copy_data();
}
SampleCNT = StopTPM();
if (SampleCNT<0x0100) {
for(j=0xff;j>0;j--){
for(k=0x10;k>0;k--){}
}
}
// Display Acceleration
SendMsg("\r\n");
SendMsg(word2asc((word)x.result[samp],dis_base));
SendMsg(",");
SendMsg(word2asc((word)y.result[samp],dis_base));
SendMsg(",");
SendMsg(word2asc((word)z.result[samp],dis_base));
SendMsg(",");
SendMsg(word2asc(SampleCNT,dis_base));
// Shift array of results if we hit max
if (samp >= max-1) {
for (j=0;j<max-1;j++){
x.result[j] = x.result[j+1];
x.reading[j] = x.reading[j+1];
y.result[j] = y.result[j+1];
y.reading[j] = y.reading[j+1];
z.result[j] = z.result[j+1];
z.reading[j] = z.reading[j+1];
}
samp = max-1;
} else {
samp++;
} //end if (i => max)
}
Funciones del Maestro
void Master_Read_and_Store(void) {
IIC_Rec_Data[rec_count++] = IIC2D;
}
void Master_Write_MMA7660_register(byte transbytes) {
last_byte = 0; // Initialize variables to 0
count = 0;
bytes_to_trans = transbytes;
if (transbytes == 0) return;
IIC2C1_TX = 1; // Set TX bit for Address cycle
IIC2C1_MST = 1; // Set Master Bit to generate a Start
IIC2D = mma7660[count++]; // Send first byte (should be 7-bit address + R/W bit)
}
void Master_Read_MMA7660_register(byte transbytes, byte recbytes) {
rec_count = 0; // Initialize variables to 0
last_byte = 0;
count = 0;
repeat_start_sent = 0;
bytes_to_trans = transbytes;
num_to_rec = recbytes;
if (transbytes == 0) return;
IIC2C1_TXAK = 0;
IIC2C1_TX = 1; // Set TX bit for Address cycle
IIC2C1_MST = 1; // Set Master Bit to generate a Start
reading_mma7660_reg = 1;
IIC2D = mma7660[count++]; // Send first byte (should be 7-bit address + R/W bit)
}