• Non ci sono risultati.

Appendice B Firmware

N/A
N/A
Protected

Academic year: 2021

Condividi "Appendice B Firmware"

Copied!
26
0
0

Testo completo

(1)

Appendice B Firmware

Appendice B: Firmware

// v@@@@@@@@@@@@@@@@@@@@@@@@@@ main.c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

//#include "stdafx.h"

#include "config.h"

#include "init.h"

#include "task.h"

#include "driver.h"

// --- DEFINIZIONE INTERFACCIA BOOTLOADER --- ---

/*

Uchar data api_command _at_ 0x1C;

Uchar data api_value _at_ 0x1D;

Uchar data api_dpl _at_ 0x1F;

Uchar __api_rd_generic (Uchar command, Uchar dpl) {

api_command = command;

api_dpl = dpl;

MAP_BOOT;

__API_FLASH_ENTRY_POINT();

UNMAP_BOOT;

return(api_value);

}

*/

// --- DEFINIZIONE VARIABILI GLOBALI --- ---

// variabili di controllo

volatile Uchar task_in_progress; // attivazione ciclo lento type_stato_nodo stato_nodo, nuovo_stato_nodo;

Int8 livello_precarico, nuovo_livello_precarico;

Int32 corsa_media;

bdata Uchar stato_L, stato_H;

Sbit( done, stato_H, 7 );

Sbit( vel_inrange, stato_H, 6);

Sbit( set, stato_H, 5);

Sbit( setting, stato_H, 4);

Sbit( stato_algoritmo_3, stato_H, 3 );

Sbit( stato_algoritmo_2, stato_H, 2 );

Sbit( stato_algoritmo_1, stato_H, 1 );

Sbit( stato_algoritmo_0, stato_H, 0 );

Sbit( errore, stato_L, 7 );

Sbit( setta, stato_L, 6 );

Sbit( leggi, stato_L, 5 );

Sbit( fine_corsa, stato_L, 4 );

Sbit( cav, stato_L, 3 );

(2)

Appendice B Firmware

Sbit( dir_m, stato_L, 2 );

Sbit( stato_m, stato_L, 1 );

Sbit( cmd_m, stato_L, 0 );

//variabili per il controllo della corrente assorbita DA

SETTARE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

bdata Uchar corrente_motore;

Sbit(s_m , corrente_motore, 0);

Sbit(misura_in_corso , corrente_motore, 1);

Sbit(prima_misura , corrente_motore, 2);

//Uint8 s_m=0;

//Uint8 misura_in_corso=1;

bdata Uchar controllo;

Sbit( enable_log, controllo, 7 );

Sbit( controllo_remoto, controllo, 6 );

Sbit( leggi_precarico, controllo, 5 );

Sbit( azzera_precarico, controllo, 4 );

Sbit( m_up_down, controllo, 3 );

Sbit( setta_precarico, controllo, 2 );

Sbit( setta_corsa, controllo, 1 );

Sbit( attiva_m, controllo, 0 );

Uchar cicli_dopo_off;

// variabili d'ingresso remote Uchar chiave;

// variabili d'ingresso locali bdata Uchar in_on_off_A;

Sbit( in_on_off_A_7, in_on_off_A, 7 );

Sbit( in_on_off_A_6, in_on_off_A, 6 );

Sbit( cav_lat, in_on_off_A, 5 );

Sbit( in_on_off_A_4, in_on_off_A, 4 );

Sbit( in_on_off_BtConnected, in_on_off_A, 3 );

Sbit( in_on_off_A_2, in_on_off_A, 2 );

Sbit( in_on_off_A_1, in_on_off_A, 1 );

Sbit( in_on_off_A_0, in_on_off_A, 0 );

// misura velocità Uint16 delta_tempo;

Uchar num_cicli_contati;

// misura corrente

volatile Uint16 corrente_media;

volatile Uint16 corrente_media_sal;

volatile Uint16 corrente_media_disc;

volatile Uint16 corrente_media_assorbita;

volatile Uint16 num_sample_corrente;

volatile Uchar nuova_misura_vel;

volatile Uint16 sospensione, pressione, precarico;

volatile Uint16 corrente;

(3)

Appendice B Firmware

Uchar velocita, temperatura;

// variabili ricevute su seriale bdata Uchar controllo_rx;

Sbit( enable_log_rx, controllo_rx, 7 );

Sbit( controllo_remoto_rx, controllo_rx, 6 );

Sbit( leggi_precarico_rx, controllo_rx, 5 );

Sbit( azzera_precarico_rx, controllo_rx, 4 );

Sbit( m_up_down_rx, controllo_rx, 3 );

Sbit( setta_precarico_rx, controllo_rx, 2 );

Sbit( setta_corsa_rx, controllo_rx, 1 );

Sbit( attiva_m_rx, controllo_rx, 0 );

Uchar livello_precarico_rx;

// variabili di uscita locali // variabili per il debug

Uchar pacchetto_log[NUM_BYTE_PACCHETTO_LOG];

// --- main()

{

/* tutte le variabili sono a 0 (il compilatore inserisce la porzione di codice

che azzera la memoria, mentre le porte di I/O (dopo reset hardware) sono a 1

*/

// disabilitazione generale delle interruzioni EA = 0;

// stato RESET

stato_nodo = STATO_RESET;

// 6 cicli x istruzione CKCON = CKCON | 0x01;

// lettura identificazione nodo

// cris = __api_rd_CRIS(); // id nodo

// id_nodo = __api_rd_NNB(); // indentificatore base msg flip // inizializzazione periferiche uC

init_uart();

init_timer1();

init_pca();

init_ADC();

// inizializzazione misura frequenza reset_mis_freq();

// inizializzazione variabili globali enable_log = FALSE;

(4)

Appendice B Firmware

// inizializzazione ciclo lento task_in_progress = 1;

// inizializzazione variabili globali sospensione = 0;

precarico = 0;

/// stato = 0;

// batteria = 0;

chiave = TRUE;

dir_m = 1;

controllo = 0;

controllo_rx = 0;

//abilito generale delle interruzioni EA = 1;

// --- CICLO LENTO --- while(1)

{

if (task_in_progress) {

task_in_progress = 0;

// esecuzione task

lettura_ingressi_locali();

calcola_nuovo_stato_nodo();

esegui_controllo();

scrivi_uscite_locali();

logging();

// fine task }

// attesa di un nuovo tick idle();

} }

// --- DEFINIZIONE VETTORI DI INTERRUPT --- // driver che gestisce l'interrupt generata dal TIMER 1

Interrupt(driver__tick_sistema(void), 3) {

static conta_tempo = 0;

static conta_tempo_ADC = 0;

// riazzera flag interrupt TF1 = 0;

// sampling ADC

if (conta_tempo_ADC == CONTA_CICLI_ADC)

{ adc_start_conv_interrupt(SOSPENSIONE_ADC_CH, 2);

conta_tempo_ADC = 0;

}

else conta_tempo_ADC ++;

(5)

Appendice B Firmware

// tick di sistema

if (conta_tempo == CONTA_CICLI_TIMER1) { task_in_progress = 1;

conta_tempo = 0;

}

else conta_tempo ++;

}

// driver che gestisce l'interrupt generata da uart Interrupt(driver_uart(void), 4)

{

if (TI) tx_carattere();

else rx_carattere();

}

// driver che gestisce l'interrupt generata dal PCA Interrupt(it_6(void), 6)

{

mis_freq_driver();

}

// driver che gestisce l'interrupt generata dall'ADC Interrupt(it_8(void), 8)

{

adc_driver();

}

// --- //

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

// @@@@@@@@@@@@@@@@@@@@@@@@@@@ task.c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

#include "config.h"

#include "task.h"

#include "driver.h"

// --- DEFINIZIONE VARIABILI LOCALI --- Uchar modo_prog; // attivazione stato programmazione

Uchar cycles; // conta i cicli

//---DICHIARAZIONE VARIBILI ESTERNE --- extern Uchar _num_adc_conv, _adc_channel; //driver.c

// --- DEFINIZIONE TASK --- // --- lettura_ingressi_locali --- void lettura_ingressi_locali()

{

(6)

Appendice B Firmware

static Uchar star_0_A = 0;

static Uchar star_1_A = 0;

Uchar nuovo_star_0;

Uchar sample_in_on_off_A;

//campionamento ingressi

sample_in_on_off_A = PORTA_IN_on_off_A;

//RC che produce il nuovo stato

nuovo_star_0 = ( star_0_A & ~star_1_A ) |

( star_0_A & ~sample_in_on_off_A ) | ( star_1_A & ~sample_in_on_off_A );

star_1_A = ( ~star_0_A & ~star_1_A & ~sample_in_on_off_A) | ( star_0_A & ~star_1_A & sample_in_on_off_A);

star_0_A = nuovo_star_0;

//l'uscita della rete seq. coincide con star_0 in_on_off_A = star_0_A;

}

// --- calcola_nuovo_stato_nodo --- void calcola_nuovo_stato_nodo()

{

// conto i cicli dello scheduler in un certo stato cycles ++;

switch(stato_nodo) {

case STATO_RESET:

if (cycles == CYCLES_RESET) nuovo_stato_nodo = STATO_SLEEP;

break;

case STATO_SLEEP:

if (chiave) nuovo_stato_nodo = STATO_ON;

break;

case STATO_ON:

if (!chiave) nuovo_stato_nodo = STATO_SLEEP;

else if (modo_prog == 1) nuovo_stato_nodo = STATO_PROG;

break;

default:

nuovo_stato_nodo = STATO_SLEEP;

break;

}

if ( (nuovo_stato_nodo ^ stato_nodo) ) {

stato_nodo = nuovo_stato_nodo;

cycles = 0;

switch (stato_nodo)

(7)

Appendice B Firmware

{

case STATO_RESET:

break;

case STATO_SLEEP:

break;

case STATO_ON:

break;

case STATO_PROG:

EA = 0;

TH2 = 0;

TL2 = 0;

RCAP2L = 0;

RCAP2H = 0;

MAP_BOOT;

__API_JMP_BOOTLOADER();

//reset break;

} }

}

// --- esecuzione controllo --- enum {START=0, READY=1, MEASURE=2, REMOTE=3, ERROR=4, WAIT = 5, PRELOAD_SET=6, PRELOAD_SETTING=7} stato_algoritmo=START, stato_algoritmo_saved;

void esegui_controllo() {

static enum {IDLE_CTRL, RESET_CTRL, LEGGI_CTRL, SETTA_CTRL}

stato_controllo = IDLE_CTRL;

static Uchar segno_precarico = 0;

static Uint16 nuovo_precarico, conta_cicli;

static Uint16 cicli_misura = 0, cicli_nuova_misura, cicli_vel_zero, cicli_inrange_prima_misura;

static Uint32 vel_prec=0;

Uint32 vel, acc;

// Int8 segno_correzione_precarico;

// macchina a stati che implementa algoritmo di controllo switch(stato_nodo) {

case STATO_ON:

switch(stato_algoritmo) { case START:

misura_in_corso=1;// massimo prima_misura=1;// massimo

controllo = 0;

enable_log = 1;

// azzero precarico done = 0;

azzera_precarico = 1;

livello_precarico = 0;

stato_algoritmo_saved = READY;

stato_algoritmo = WAIT;

break;

case READY:

set = FALSE;

(8)

Appendice B Firmware

if(!cav_lat) stato_algoritmo = MEASURE;

else if(controllo_remoto_rx) { enable_log_rx = 1;

attiva_m_rx = 0;

setta_precarico_rx = 0;

stato_algoritmo = REMOTE;

} break;

case MEASURE:

#define VEL_MAX 5243 // 40 km/h

#define VEL_MIN 2621 // 20 km/h

#define ACC_MAX 285 // 0.5 m/s^2

/* #define DURATA_MISURA 500 // x10 ms = 5 s

*/

#define DURATA_MISURA 350 // x10 ms = 3.5 s

#define CORRENTE_MEDIA1 42,623

#define CORRENTE_MEDIA2 50,819 leggi = TRUE;

// calcolo velocità e accelerazione if(nuova_misura_vel) {

nuova_misura_vel = 0;

if(delta_tempo==0) vel = 0;

else {

vel = num_cicli_contati;

vel = vel << 24;

vel = vel/delta_tempo;

}

if(vel>vel_prec) acc = vel - vel_prec; else acc = vel_prec - vel;

// vel in range acc in modulo minore val max vel_prec = vel;

}

//CONTROLLO VELOCITA E ACCELERAZIONE //verifica se velocita' e accelerazione if((vel < VEL_MAX) && (vel > VEL_MIN) && (acc <

ACC_MAX)) {

vel_inrange = TRUE;

//eseguo la misura della corrente if(misura_in_corso){// definita in main //stabilisco il livello di precarico

if (prima_misura){

prima_misura=0;

if(livello_precarico==0){nuovo_livello_precarico=3, s_m = MOTORE_UP;}

else{if(livello_precarico==4){nuovo_livello_precarico=7, s_m = MOTORE_UP;}

else{nuovo_livello_precarico=4, s_m = MOTORE_DOWN;}}

corrente_media_sal = 0;

stato_controllo = LEGGI_CTRL;

(9)

Appendice B Firmware

}else{prima_misura=1;

if(livello_precarico==3){nuovo_livello_precarico=0, s_m = MOTORE_DOWN;}

else{if(livello_precarico==7){nuovo_livello_precarico=4, s_m = MOTORE_DOWN;}

else{nuovo_livello_precarico=7, s_m = MOTORE_UP;} }

corrente_media_disc = 0;

stato_controllo = LEGGI_CTRL;

misura_in_corso = 0;

} }

else{ //se non c'è misura in corso corrente_media_assorbita =

corrente_media_sal/NUM_CAMPIONI_PRELEVATI_SAL-

corrente_media_disc/NUM_CAMPIONI_PRELEVATI_DISC;

}

//la misura della corrente è finita e calcolo il carico

if(corrente_media_assorbita <

CORRENTE_MEDIA1){

nuovo_livello_precarico = 0; //carico = CONDUCENTE;

}else{

if(corrente_media_assorbita <

CORRENTE_MEDIA2)

nuovo_livello_precarico = 4; //carico = CONDUCENTE_BAGAGLI;

else nuovo_livello_precarico = 7;

//carico = CONDUCENTE_PASSEGGERO;

// conosco il carico e devo impostare il nuovo_livello_precarico

stato_algoritmo = PRELOAD_SETTING;

cicli_nuova_misura = CICLI_NUOVA_MISURA;

cicli_vel_zero = CICLI_VEL_ZERO;

leggi = FALSE;

}

}else{

//velocita' e accelerazione NON sono nel range

vel_inrange = FALSE;

cicli_misura = 0;

corrente_media = 0;

cicli_inrange_prima_misura = 0;

}

if(cav_lat) {

stato_algoritmo = START;

leggi = FALSE;

} break;

case REMOTE:

(10)

Appendice B Firmware

if (!controllo_remoto_rx) stato_algoritmo = READY;

else {

azzera_precarico = azzera_precarico_rx;

azzera_precarico_rx = 0;

attiva_m = attiva_m_rx;

attiva_m_rx = 0;

m_up_down = m_up_down_rx;

setta_precarico = setta_precarico_rx;

setta_precarico_rx = 0;

nuovo_livello_precarico = livello_precarico_rx;

} break;

case WAIT:

if(done) stato_algoritmo = stato_algoritmo_saved;

else if(errore) stato_algoritmo = ERROR;

break;

case ERROR:

if(controllo_remoto_rx) { enable_log_rx = 1;

attiva_m_rx = 0;

setta_precarico_rx = 0;

stato_algoritmo = REMOTE;

} break;

case PRELOAD_SETTING:

if((nuovo_livello_precarico - livello_precarico!=0) && !set) {

stato_algoritmo_saved = PRELOAD_SET;

done = FALSE;

setta_precarico = TRUE;

stato_algoritmo = WAIT;

setting = TRUE;

}

else stato_algoritmo = PRELOAD_SET;

break;

case PRELOAD_SET:

cicli_nuova_misura--;

setting = FALSE;

set = TRUE;

if (num_cicli_contati==0) cicli_vel_zero--;

else cicli_vel_zero = CICLI_VEL_ZERO;

if(cav_lat) stato_algoritmo = START;

else if((cicli_nuova_misura==0) ||

(cicli_vel_zero==0)) stato_algoritmo = MEASURE;

break;

default:;

} break;

default:stato_algoritmo = START;

}

// macchina a stati che controlla il motore;

conta_cicli++;

switch (stato_controllo) { case IDLE_CTRL:

(11)

Appendice B Firmware

conta_cicli = 0;

if(azzera_precarico) { fine_corsa = 0;

stato_controllo = RESET_CTRL;

}

else if (attiva_m) { attiva_m = 0;

cmd_m = 1;

dir_m = m_up_down;

stato_controllo = IDLE_CTRL;

done = 1;

}

else if (leggi_precarico) { num_sample_corrente = 0;

stato_controllo = LEGGI_CTRL;

corrente_media = 0;

leggi_precarico = 0;

leggi = 1;

}

else if(setta_precarico) {

#define OFFSET_PRECARICO 50

#define DELTA_PRECARICO 53 setta = 1;

setta_precarico = FALSE;

nuovo_precarico =

OFFSET_PRECARICO+nuovo_livello_precarico*DELTA_PRECARICO;

stato_controllo = SETTA_CTRL;

if(nuovo_precarico > precarico) segno_precarico=1;

else segno_precarico = 0;

if(segno_precarico) dir_m = MOTORE_UP;

else dir_m = MOTORE_DOWN;

} break;

case RESET_CTRL:

if(fine_corsa) { precarico = 0;

stato_controllo = IDLE_CTRL;

azzera_precarico = 0;

errore = 0;

done = 1;

}

else if(conta_cicli<RESET_CTRL_TIMEOUT) { cmd_m = 1;

dir_m = MOTORE_DOWN;

}

else {

errore = 1;

azzera_precarico = 0;

stato_controllo = IDLE_CTRL;

} break;

case LEGGI_CTRL:

if( num_sample_corrente<NUM_SAMPLE_CORRENTE) { stato_m = 1;// accendo il motore

dir_m =s_m;

(12)

Appendice B Firmware

_adc_channel=CORRENTE_ADC_CH;// campiono la corrente

adc_driver();

}

else {

stato_controllo = IDLE_CTRL;

leggi = 0;

done = 1;

stato_m=0;

} break;

case SETTA_CTRL:

if ((nuovo_precarico>precarico)^segno_precarico) { stato_controllo = IDLE_CTRL;

setta = 0;

done = 1;

livello_precarico = nuovo_livello_precarico;

}

else {

cmd_m = 1;

} break;

default:

stato_controllo = IDLE_CTRL;

} }

// --- scrittura uscite locali--- void scrivi_uscite_locali()

{

// aggiungere watchdog sul tempo max di attivazione motore stato_m = cmd_m;

cmd_m = 0;

// DIR_MOTORE(dir_m);

// MOTORE(stato_m);

MOTOR_CTRL(stato_m, dir_m);

}

// --- logging --- void logging()

{

static periodo = 0;

if (enable_log && (stato_nodo == STATO_ON)) { periodo++;

if (periodo == PERIODO_LOG) { periodo = 0;

// preparo il pacchetto EA = 0;

cav = cav_lat;

stato_H &= 0xF0;

stato_H |= (stato_algoritmo & 0x0F);

(13)

Appendice B Firmware

pacchetto_log[0] = stato_L;

pacchetto_log[1] = BYTE1(sospensione);

pacchetto_log[2] = BYTE1(precarico);

pacchetto_log[3] = BYTE0(precarico);

pacchetto_log[4] = BYTE1(corrente);

pacchetto_log[5] = BYTE1(corrente);// batteria----corrente pacchetto_log[6] = BYTE1(delta_tempo);

pacchetto_log[7] = BYTE0(delta_tempo);

pacchetto_log[8] = num_cicli_contati;

pacchetto_log[9] = temperatura;

pacchetto_log[10] = stato_H;

pacchetto_log[11] = BYTE0(corrente);

pacchetto_log[12] = livello_precarico;

pacchetto_log[13] = nuovo_livello_precarico;

EA = 1;

// abilito la trasmissione TI = 1;

} }

else periodo = 0;

}

// --- Attesa di un nuovo tick di sistema --- void idle()

{

EA = 1;

PCON = PCON | 0x01; // idle }

//

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ driver.c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

#include "config.h"

#include "driver.h"

//--- // struttura dati per la misura della frequenza

Uchar misura;

Uchar msk_capture;

Uchar start_time_L;

Uchar start_time_H;

Uchar stop_time_L;

Uchar stop_time_H;

Uchar num_eventi;

(14)

Appendice B Firmware

Uchar evento_catturato;

//--- MISURA FREQUENZA --- /*

alterno NUM_MISURE_FREQ misure:

misura_0 -> velocità misura_1 ->

misura_2 ->

misura_3 ->

precarico (deve essere gestito autonomamente; vanno contati gli impulsi con segno dato da dir motore)

*/

void reset_mis_freq() {

Uint16 start_time, stop_time;

TCON = TCON & 0xCF; // disbilito timer0;

// converto la misura su 16 bit e la scrivo start_time = start_time_H;

start_time = start_time << 8;

start_time = start_time + start_time_L;

stop_time = stop_time_H;

stop_time = stop_time << 8;

stop_time = stop_time + stop_time_L;

EA = 0;

delta_tempo = stop_time - start_time;

num_cicli_contati = num_eventi;

nuova_misura_vel = 1;

EA = 1;

// imposto il nuovo tempo di misura e seleziono il modulo del PCA TL0 = TH0_MISURA_VELOCITA;

TH0 = TH0_MISURA_VELOCITA;

//abilito capture mode(positive) e interrupt quando cattura un evento CCAPM_MISURA_PRECARICO = 0x21;

CCAPM_MISURA_VELOCITA = 0x21;

msk_capture = MSK_CAPTURE_MISURA_VELOCITA;

TCON = TCON | 0x10; // abilito il timer0 // azzero le variabili della misura

num_eventi = 0;

evento_catturato = 0;

start_time_L = 0;

start_time_H = 0;

stop_time_L = 0;

(15)

Appendice B Firmware

stop_time_H = 0;

// azzero il contatore del PCA CL = 0;

CH = 0;

CCON = CCON & MSK_CAPTURE_MISURA_PRECARICO; // disabilito il contatore del PCA e resetto tutti i flag ad eccezione del precarico

CCON |= 0x40; //abilito il contatore del PCA // abilito le interruzioni provenienti dal PCA EC = 1;

}

void mis_freq_driver() {

Uchar aux, ramo_ov;

Uchar ccapl, ccaph;

EC = 0; //disabilito le interruzioni provenienti dal PCA

// guardo chi ha generato l'interrupt: capture e/o overflow o precarico //precarico

#define CICLI_DOPO_OFF 4

if (CCON & MSK_CAPTURE_MISURA_PRECARICO) {

CCON = CCON & ~MSK_CAPTURE_MISURA_PRECARICO;

if(dir_m==MOTORE_UP) {

if (cicli_dopo_off<CICLI_DOPO_OFF) { if(precarico < 0xFFFF) precarico++;}

else if (precarico >0) precarico--;

}

// motore down

else if (cicli_dopo_off<CICLI_DOPO_OFF) {if (precarico >0) precarico--;}

else if (precarico < 0xFFFF) precarico++;

}

else {

// velocità

aux = CCON; //leggo registro di controllo

// leggo i registri di cattura del modulo coinvolto nella misura corrente

ccapl = CCAPL_MISURA_VELOCITA;

ccaph = CCAPH_MISURA_VELOCITA;

ramo_ov = 0;

//controllo se CF = 1 e CCF0 = 1 e in quel caso decido //quale delle due è arrivata prima

if ((aux & msk_capture) && (aux & MSK_OVERFLOW) && (ccaph==0)) ramo_ov = 1;

if((aux & msk_capture) && !ramo_ov) // ramo capture {

//resetto flag CCF0 CCON = CCON & ~msk_capture;

(16)

Appendice B Firmware

if(!evento_catturato) //primo evento {

evento_catturato = 1;

start_time_H = ccaph;

start_time_L = ccapl;

start_time_H = ccaph;

start_time_L = ccapl;

} else {

stop_time_H = ccaph;

stop_time_L = ccapl;

stop_time_H = ccaph;

stop_time_L = ccapl;

num_eventi++;

} }

else //ramo overflow: la misura corrente è terminata {

// scrivo il risultato della misura e configuro la misura succesiva

reset_mis_freq();

} }

// riabilito interruzioni provenienti dal PCA EC = 1;

}

//--- COMUNICAZIONE SERIALE CON LO HOST --- Uchar bin_to_ascii (Uchar to_convert)

{

Uchar convert;

if ((to_convert >= 0) && (to_convert <= 9)) convert = to_convert + 0x30;

else convert = to_convert + 0x37;

return (convert);

}

Uchar ascii_to_bin (Uchar to_convert) { Uchar convert;

if ((to_convert >= '0') && (to_convert <= '9')) convert = to_convert - '0';

else if ((to_convert >= 'A') && (to_convert <= 'F')) convert = 10 + to_convert - 'A';

else convert = 255; //errore return (convert);

}

(17)

Appendice B Firmware

#define TRAILER_RX 13 void rx_carattere() {

static type_stato_rx stato_rx;

Uchar carattere_rx;

carattere_rx = SBUF;

switch(stato_rx) { case WAIT_RX:

switch (carattere_rx) {

case 'A': // Azzera precarico azzera_precarico_rx = TRUE;

stato_rx = WAIT_TRAILER_RX;

break;

case 'C': // disabilita logging enable_log_rx = FALSE;

stato_rx = WAIT_TRAILER_RX;

break;

case 'I':

controllo_remoto_rx = FALSE;

stato_rx = WAIT_TRAILER_RX;

break;

case 'L':

leggi_precarico_rx = 1;

stato_rx = WAIT_TRAILER_RX;

break;

case 'M':

stato_rx = MOTORE_RX;

break;

case 'O': // abilita logging enable_log_rx = TRUE;

stato_rx = WAIT_TRAILER_RX;

break;

case 'R':

controllo_remoto_rx = TRUE;

stato_rx = WAIT_TRAILER_RX;

break;

case 'S':

stato_rx = SETTA_RX;

break;

default:

stato_rx = WAIT_TRAILER_RX;

} break;

case SETTA_RX:

livello_precarico_rx = ascii_to_bin(carattere_rx);

setta_precarico_rx = 1;

stato_rx = WAIT_TRAILER_RX;

break;

case MOTORE_RX:

switch (carattere_rx) { case '+':

attiva_m_rx = 1;

m_up_down_rx = 1;

(18)

Appendice B Firmware

stato_rx = WAIT_TRAILER_RX;

break;

case '-':

attiva_m_rx = 1;

m_up_down_rx = 0;

stato_rx = WAIT_TRAILER_RX;

break;

default:

stato_rx = WAIT_TRAILER_RX;

} break;

case WAIT_TRAILER_RX:

if (carattere_rx == TRAILER_RX) stato_rx = WAIT_RX;

break;

default:

stato_rx = WAIT_TRAILER_RX;

}

// acknowledgemnt interrupt RI = 0;

}

// driver che gestisce l'invio di un pacchetto di byte

#define HEADER 'A'

#define TRAILER_1 13

#define TRAILER_2 10

void tx_carattere() {

static num_byte_tx = 0;

static lsb = 0;

static num_byte_servizio = 0;

// acknowledgement interrupt TI = 0;

// per ogni byte trasmetto prima i 4 msb

if ( (num_byte_tx == 0) && (num_byte_servizio == 0)) {

SBUF = HEADER;

num_byte_servizio = 1;

}

else if ( num_byte_tx < NUM_BYTE_PACCHETTO_LOG) {

if ( !lsb ) SBUF = (bin_to_ascii((pacchetto_log[num_byte_tx] & 0xF0)

>> 4));

else SBUF = (bin_to_ascii(pacchetto_log[num_byte_tx] & 0x0F));

num_byte_tx += lsb;

lsb = lsb ^ 1;

}

else if ( num_byte_servizio == 1 ) {

SBUF = TRAILER_1;

num_byte_servizio = 2;

}

else if ( num_byte_servizio == 2 )

(19)

Appendice B Firmware

{

SBUF = TRAILER_2;

num_byte_servizio = 3;

} else {

num_byte_servizio = 0;

num_byte_tx = 0;

} }

Uchar _num_adc_conv, _adc_channel;

void adc_start_conv_interrupt(Uchar channel, Uchar num_adc_conv) {

//we assume that the ADC interrupt is already enable //as well as the general intterpt

if(num_adc_conv) {

_num_adc_conv = num_adc_conv;

_adc_channel = channel;

//select channel

ADCON &= ~MSK_ADCON_SCH;

ADCON |= channel;

//start the conversion ADCON |= MSK_ADCON_ADSST;

} }

void adc_driver() {

static Uchar cicli_attesa=0;

Int16 appoggio;

//clear flag end of concersion ADCON &= ~MSK_ADCON_ADEOC;

switch(_adc_channel) {

case SOSPENSIONE_ADC_CH:

appoggio = ADDH - BYTE1(sospensione);

sospensione += appoggio;

_adc_channel = CORRENTE_ADC_CH;

break;

case CORRENTE_ADC_CH:

//corrente istantanea

appoggio = ADDH - BYTE1(corrente);

corrente += appoggio;

//corrente media

#define CICLI_ATTESA_SAL 150 // 1 ciclo ogni 10 msec finito transistorio corrente di spunto motore salita

#define CICLI_ATTESA_DISC 80 //finito transistorio corrente di spunto motore discesa

if(stato_m){ //motore attivo if(s_m){

if(cicli_attesa < CICLI_ATTESA_SAL) cicli_attesa++;

(20)

Appendice B Firmware

else {

num_sample_corrente ++ ; if (num_sample_corrente <

NUM_CAMPIONI_PRELEVATI_SAL)

corrente_media_sal += ADDH;

if (ADDH >= MAX_CORRENTE) { fine_corsa = 1;

stato_m = OFF;

MOTOR_CTRL(stato_m, MOTORE_UP);

//disattivazione motore

}

else fine_corsa = 0;

}}

else {

if(cicli_attesa < CICLI_ATTESA_DISC) cicli_attesa++;

else {

num_sample_corrente ++;

if (num_sample_corrente <=

NUM_CAMPIONI_PRELEVATI_DISC)

corrente_media_disc += ADDH;

if (ADDH >= MAX_CORRENTE) { fine_corsa = 1;

stato_m = OFF;

MOTOR_CTRL(stato_m, MOTORE_UP);//disattivazione motore

}

else fine_corsa = 0;

} }

}

else cicli_attesa = 0;

_adc_channel = SOSPENSIONE_ADC_CH;

break;

default:

_num_adc_conv = 1;

}

_num_adc_conv--;

adc_start_conv_interrupt(_adc_channel, _num_adc_conv);

}

// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ init.c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

#include "config.h"

#include "init.h"

// INIZIALIZZAZIONE DEL TIMER 1 A GENERARE UN INTERRUPT OGNI 0.19 ms void init_timer1()

{

CKCON = CKCON | 0x04; // dimezzo il clock del timer 1 TMOD = TMOD & 0x0F;

TMOD = TMOD | 0x20; // 8-bit e auto-reload mode TH0 = RELOAD_TIMER1;

(21)

Appendice B Firmware

TL0 = RELOAD_TIMER1;

TCON = TCON | 0x40;

ET1 = 1;

}

// INIZIALIZZAZIONE UART A 19200 SOLO IN TRASMISSIONE void init_uart (void)

{

PCON = PCON & 0X3F; // selezione SMO in SCON SCON = 0x50; // seleziono mode 1 e non mulitiprocessor communication

// abilito la ricezione // utilizzo overflow del timer2 per generare clock uart

T2CON = 0;

TH2 = 65527;

TL2 = 65527;

// RCAP2L = LOW(65536-52); // baud_rate = 19200 // RCAP2H = HIGH(65536-52);

RCAP2L = LOW(65536-26); // baud_rate = 38400 RCAP2H = HIGH(65536-26);

TCLK = 1;

RCLK = 1;

TR2 = 1; // attiva il timer

TI = 0; // azzero flag interrupt relativo

a tx ok

RI = 0; // azzero flag interrupt relativo

a rx ok

ES = 1; // abilito uart a generare interrupt }

// INIZIALIZZAZIONE PCA void init_pca()

{

//configurazione PCA

CMOD = 0x05; //scelgo come il clock timer0 ov e abilito interrupt quando c'è overflow

//configurazione del timer0

TMOD = TMOD & 0xF0; //selezione il modo 2 TMOD = TMOD | 0x02;

TCON = TCON & 0xCF; // disabilito timer0 e resetto flag relativo }

void init_ADC() {

ADCF = 0x81; // configuro P1.0 (corsa), P1.7(corrente) come ingresso ADC

ADCLK = 12; // Clock ADC = 16000/2/ADCLK kHx (max 700 kHz) ADCON = 0x20; // ADEN

EADC = 1;

}

(22)

Appendice B Firmware

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

// ************************************* NODO 1

*****************************************

/* CONFIGURAZIONE PERIFERICHE uC

FOSC = 16 MHz e 6 cicli x istruzione (X2 = 2) TIMER 0 -> clock PCA

TIMER 1 -> orologio di sistema TIMER 2 -> clock uart

PCA moduli 1, 2, 3, 4 -> CAPTURE MODE

*/

// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ config.h @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

#ifndef _CONFIG_H_

#define _CONFIG_H_

#define KEIL // è utilizzata in compiler.h

//---INCLUDO FILE REGISTRI E INTESTAZIONE LIBRERIE ---

#include "AT89C51CC03/include/compiler.h"

#include "AT89C51CC03/include/at89c51cc03.h"

#include "AT89C51CC03/include/can_lib.h"

#include "AT89C51CC03/include/interfacciamento_power.h"

//--- PARAMETRI DI CONFIGURAZIONE SOFTWARE --- // OROLOGIO (UN TICK OGNI 10 ms)

#define RELOAD_TIMER1 0 // genera un interrupt ogni // 1/(Fosc/12/(256-

RELOAD_TIMER1)) = 0.192ms

#define CONTA_CICLI_TIMER1 51 // conta CONTA_CICLI_TIMER1+1 interrupt // prima di avere un nuovo tick

#define CONTA_CICLI_ADC 4 // conta CONTA_CICLI_ADC+1 interrupt // prima di avere un nuovo

campionamento ADC

// TEMPORIZZAZIONE STATI

#define CYCLES_RESET 5

#define CYCLES_SLEEP 100

#define CYCLES_MONIT 1

//--- DEFINIZIONE NOMI SIMBOLICI ALLE PORTE uC ---

#define PORTA_IN_on_off_A P2

(23)

Appendice B Firmware

#define CAVALLETTO 5 // (P2.5)

#define SOSPENSIONE_ADC_CH 0 //P

#define CORRENTE_ADC_CH 7

#define CICLI_ATTIVAZIONE_MOTORE 10

#define CICLI_ATTIVAZIONE_MOTORE_OFF 9

#define NUM_SAMPLE_CORRENTE 250 //Tsample = 1ms

#define SALTA_LETTURE 2

#define RESET_CTRL_TIMEOUT 1500

#define MAX_CORRENTE 125

#define CICLI_NUOVA_MISURA 6000 //2 min tempo dopo il quale ripete la misura

#define CICLI_VEL_ZERO 2000 //20s t

#define NUM_CAMPIONI_PRELEVATI_SAL 1500 // 1,5 sec campiono a 1kHz

#define NUM_CAMPIONI_PRELEVATI_DISC 1000 // 1 sec campiono a 1kHzempo a vel nulla dopo il quale ripete la misura

#define CICLI_INRANGE_PRIMA_MISURA 250

//#define MOTORE(x) {P1_3 = !x;} //inversione sulla scheda //#define DIR_MOTORE(x) {P2_1 = x;}

#define MOTORE_DOWN 0

#define MOTORE_UP 1

#define INA_DRIVER P2_0

#define INB_DRIVER P2_1

#define MOTOR_CTRL(stato_m, dir_m) { INA_DRIVER = !dir_m; \ INB_DRIVER = (stato_m&&dir_m) || (!stato_m&&!dir_m); }

/* esempi di utilizzo MOTORE = MOTORE_ON;

MOTORE = UP; MOTORE = DOWN;

*/

//--- INTERFACCIA BOOTLOADER ---

#define __API_JMP_BOOTLOADER (*((const void(code*)(void)) 0xFBF1 ))

#define __API_FLASH_ENTRY_POINT (*((const void(code*)(void)) 0xFFC0 ))

#define __api_rd_NNB() __api_rd_generic(_COMMAND_RD_XAF, 0x1F)

#define __api_rd_CRIS() __api_rd_generic(_COMMAND_RD_XAF, 0x20)

#define MAP_BOOT AUXR1 |= MSK_AUXR1_ENBOOT;

#define UNMAP_BOOT AUXR1 &= ~MSK_AUXR1_ENBOOT;

#define _COMMAND_RD_XAF 5

Uchar __api_rd_generic (Uchar command, Uchar dpl);

(24)

Appendice B Firmware

//--- DICHIARAZIONE MACRO ---

#define BYTE0(U32) ((Uchar) (U32))

#define BYTE1(U32) ((Uchar) (U32 >> 8))

#define BYTE2(U32) ((Uchar) (U32 >> 16))

#define BYTE3(U32) ((Uchar) (U32 >> 24))

//--- DICHIARAZIONE TIPI --- typedef enum { STATO_RESET = 0,

STATO_SLEEP = 1, STATO_ON = 2, STATO_PROG = 3 } type_stato_nodo;

//--- DICHIARAZIONE VARIABILI GLOBALI --- // variabili di controllo

extern Uchar cris; // identificatore base msg FLIP extern Uchar id_nodo;

extern Uchar modo_prog;

extern Uchar task_in_progress; // attivazione ciclo lento extern type_stato_nodo stato_nodo, nuovo_stato_nodo;

extern Uchar cicli_dopo_off;

extern Uchar stato_L, stato_H;

extern bit dir_m, cmd_m, stato_m, leggi, setta, errore, cav, fine_corsa, done, vel_inrange, set, setting;

extern bdata Uchar controllo;

extern bit enable_log, leggi_precarico, azzera_precarico, setta_precarico, setta_corsa, controllo_remoto, attiva_m, m_up_down;

extern Uchar velocita, corsa_impostata, temperatura;

extern Int8 livello_precarico, nuovo_livello_precarico;

extern Int32 corsa_media;

//variabili per il controllo della corrrente assorbita //extern Uint8 s_m, misura_in_corso;

extern bit s_m, misura_in_corso, prima_misura;

// variabili d'ingresso locali extern bdata Uchar in_on_off_A;

extern bit cav_lat;

extern volatile Uint16 sospensione, pressione, precarico, corrente_media, corrente, corrente_media_sal, corrente_media_disc, corrente_media_assorbita;

extern volatile Uint16 corrente_media;

extern volatile Uint16 num_sample_corrente;

extern volatile Uchar nuova_misura_vel;

extern volatile Uint16 delta_tempo;

extern volatile Uchar num_cicli_contati;

//variabili d'ingresso remote extern Uchar chiave;

// variabili d'ingresso remote rx extern bdata Uchar controllo_rx;

(25)

Appendice B Firmware

extern bit enable_log_rx, leggi_precarico_rx, azzera_precarico_rx, setta_precarico_rx, setta_corsa_rx, controllo_remoto_rx, attiva_m_rx, m_up_down_rx;

extern Uchar livello_precarico_rx;

// variabili d'uscita locali // variabili per il logging

#define PERIODO_LOG 10 // periodicità di invio del pacchetto in multipli di 10 ms

#define NUM_BYTE_PACCHETTO_LOG 14 // numero byte pacchetto extern Uchar pacchetto_log[NUM_BYTE_PACCHETTO_LOG];

#endif //

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

(26)

This document was created with Win2PDF available at http://www.win2pdf.com.

The unregistered version of Win2PDF is for evaluation or non-commercial use only.

This page will not be added after purchasing Win2PDF.

Riferimenti

Documenti correlati

This view of the commonwealth and justice underpins Vitoria’s theory of public war and his view that soldiers are obligated to obey commands to serve in war and are not obligated

- Che cosa significa immaginare?.. - Differenza tra pensare ed immaginare- l’immaginazione come strumento per studiare la realtà. - La filosofia come scoperta: Talete

From an institutional perspective the European Community may be coherently interpreted both as an institution that has been established by the member states within the

Given the different propensity of women and men to guess, and given that closed ended items are more likely to incite guessing than open ended items (Luskin and Bullock 2011),

4 Date indéterminée elle aussi, mais qui remonte au moins au années 1760 comme nous 1 avons dit; Mazzoni fait venir de Gênes au premiers temps de la fabrication des

Le forze di polizia, incaricate di far rispettare la legge, incontrarono forti resistenze da parte delle comunità – come nel caso della rivolta di Pirano avvenuta nel 1814, durante

The die has nonetheless been cast: under these reservations, the stringency of which has been questioned in the literature,63 the Federal Tribunal has recognized EU legal materials

According to the Association Agreements between the Community and individual Baltic States, a free trade area will be established in transitional periods lasting