Ripulisci il repo
This commit is contained in:
parent
55ab37e758
commit
398f826bca
13 changed files with 564 additions and 0 deletions
BIN
.media/icon-128x128_round.png
Normal file
BIN
.media/icon-128x128_round.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
64
5 - Sistemi e reti/sys_data_struct_chatlog.txt
Normal file
64
5 - Sistemi e reti/sys_data_struct_chatlog.txt
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
Stefano Pigozzi, [15.04.19 19:32]
|
||||||
|
allora
|
||||||
|
|
||||||
|
Stefano Pigozzi, [15.04.19 19:33]
|
||||||
|
in python non ci sono gli array
|
||||||
|
|
||||||
|
Stefano Pigozzi, [15.04.19 19:34]
|
||||||
|
esistono però due tipi che ci assomigliano
|
||||||
|
|
||||||
|
Stefano Pigozzi, [15.04.19 19:34]
|
||||||
|
le tuple e le liste
|
||||||
|
|
||||||
|
Stefano Pigozzi, [15.04.19 19:35]
|
||||||
|
le list sono quelle che crei con le parentesi quadre
|
||||||
|
tipo
|
||||||
|
membri_ryg = ["Steffo", "Sensei", "Fedececco", ...]
|
||||||
|
|
||||||
|
Stefano Pigozzi, [15.04.19 19:36]
|
||||||
|
e si dice che sono mutabili, perchè una volta che le ho create posso modificarle
|
||||||
|
se la cate si unisce alla ryg, posso fare
|
||||||
|
membri_ryg.append("Pesca")
|
||||||
|
|
||||||
|
Stefano Pigozzi, [15.04.19 19:37]
|
||||||
|
le tuple le crei con le parentesi tonde
|
||||||
|
tipo
|
||||||
|
best_dota_players = ("Steffo", "Sensei", "Adry")
|
||||||
|
|
||||||
|
Stefano Pigozzi, [15.04.19 19:38]
|
||||||
|
e sono invece immutabili; una volta che le hai create non possono essere cambiate, solo sovrascritte
|
||||||
|
best_dota_players.append("Fedececco") # Errore
|
||||||
|
|
||||||
|
best_dota_players = ("Steffo",) # best_dota_players è stato eliminato e sovrascritto dalla nuova tupla
|
||||||
|
|
||||||
|
Stefano Pigozzi, [15.04.19 19:39]
|
||||||
|
cos'hanno di comodo le tuple?
|
||||||
|
puoi spacchettarle
|
||||||
|
(cioè, in realtà anche le liste, ma è meno usato)
|
||||||
|
|
||||||
|
Stefano Pigozzi, [15.04.19 19:40]
|
||||||
|
best_dota_players = ("Steffo", "Sensei", "Adry")
|
||||||
|
player_a, player_b, player_c = best_dota_players
|
||||||
|
print(player_a) # "Steffo"
|
||||||
|
|
||||||
|
Stefano Pigozzi, [15.04.19 19:43]
|
||||||
|
ci sono i dict, che abbinano gli oggetti
|
||||||
|
username_telegram = {"mio": "@Steffo", "max": "@MaxSensei", "balu": "@GoodBalu"}
|
||||||
|
print(username_telegram["mio"]) # @Steffo
|
||||||
|
|
||||||
|
Stefano Pigozzi, [15.04.19 19:46]
|
||||||
|
e i set, che rappresentano insiemi
|
||||||
|
giocatori_di_dota = {"Steffo", "Max", "Adry"}
|
||||||
|
giocatori_di_lol = {"Paltri", "Steffo", "Spaggia"}
|
||||||
|
|
||||||
|
giocatori_di_entrambi = giocatori_di_dota.intersect(giocatori_di_lol)
|
||||||
|
print(giocatori_di_entrambi) # Steffo
|
||||||
|
|
||||||
|
Stefano Pigozzi, [15.04.19 19:47]
|
||||||
|
giocatori = {
|
||||||
|
"dota": {"Steffo", "Max"}
|
||||||
|
"lol": {"Steffo", "Spaggia"}
|
||||||
|
}
|
||||||
|
|
||||||
|
Stefano Pigozzi, [15.04.19 19:47]
|
||||||
|
dict di set
|
39
5 - Sistemi e reti/sys_socketserver.py
Normal file
39
5 - Sistemi e reti/sys_socketserver.py
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import socket
|
||||||
|
|
||||||
|
# Crea un nuovo socket: per ora potrebbe essere sia server sia client
|
||||||
|
server = socket.socket()
|
||||||
|
|
||||||
|
# Trasforma il socket in un server:
|
||||||
|
# Crea una tupla con l'indirizzo locale a cui associare il server
|
||||||
|
# Il primo elemento è una str, e indica l'unica interfaccia da cui altri si possono connettere
|
||||||
|
# Il secondo elemento è un int, ed è la porta del server
|
||||||
|
indirizzo_locale = ('127.0.0.1', 9999)
|
||||||
|
# Associa il socket all'indirizzo
|
||||||
|
server.bind(indirizzo_locale)
|
||||||
|
# Inizia ad accettare connessioni; massimo 1 contemporaneamente,
|
||||||
|
# visto che questo il codice ne può gestire una sola alla volta
|
||||||
|
server.listen(1)
|
||||||
|
|
||||||
|
# Ciclo principale del server
|
||||||
|
while True:
|
||||||
|
# Aspetta che si connetta qualcuno;
|
||||||
|
# quando si connette, metti il suo oggetto socket corrispondente nella variabile client
|
||||||
|
# e il suo indirizzo nella variabile indirizzo_remoto (è una tupla, come indirizzo locale!)
|
||||||
|
client, indirizzo_remoto = server.accept()
|
||||||
|
print("Connection from: " + str(indirizzo_remoto))
|
||||||
|
# Aspetta che quel qualcuno ti invii dei dati;
|
||||||
|
# Quando li ricevi, mettili nella variabile data (attenzione, è del tipo bytes!)
|
||||||
|
data = client.recv(1024)
|
||||||
|
# Se ricevi una riga vuota, ignorala
|
||||||
|
if not data:
|
||||||
|
continue
|
||||||
|
# Converti in una stringa i dati che hai ricevuto
|
||||||
|
data_str = str(data, encoding="ascii")
|
||||||
|
print("Received: " + data_str)
|
||||||
|
# Invia un "addio" in risposta al messaggio
|
||||||
|
# Nota la b davanti alle prime virgolette:
|
||||||
|
# non è una stringa, sono i bytes che se convertiti in ascii scrivono "addio"
|
||||||
|
client.send(b"addio")
|
||||||
|
# Chiudi la connessione con il client; nessuno dei due sarà più in grado di mandare messaggi all'altro...
|
||||||
|
# almeno finchè non ne viene stabilita una nuova
|
||||||
|
client.close()
|
314
5 - TPS/tpsit_msp430.md
Normal file
314
5 - TPS/tpsit_msp430.md
Normal file
|
@ -0,0 +1,314 @@
|
||||||
|
# MSP430
|
||||||
|
|
||||||
|
## [Licenza CC-BY-3.0-IT](https://creativecommons.org/licenses/by/3.0/it/)
|
||||||
|
|
||||||
|
`Copyright (c) 2019 Stefano Pigozzi`
|
||||||
|
|
||||||
|
In pratica, potete riutilizzare il file dove, come e quando vi pare, ma dovete **inserire il mio nome** nei documenti in cui questo viene usato.
|
||||||
|
|
||||||
|
Capito, prof. \_\_\_\_\_\_? Non si usano appunti di altri studenti senza dargli credito!
|
||||||
|
|
||||||
|
|
||||||
|
## _Prerequisito:_ Le maschere
|
||||||
|
|
||||||
|
Prima di programmare l'MSP430 bisogna sapere cosa sono e come usare le **maschere** (bit mask) in C.
|
||||||
|
|
||||||
|
Una maschera è un'operazione che permette di modificare solo _alcuni_ bit di una variabile a più di un bit, senza cambiare gli altri.
|
||||||
|
|
||||||
|
### Esempi
|
||||||
|
|
||||||
|
```c
|
||||||
|
unsigned int variabile = 0;
|
||||||
|
|
||||||
|
//Imposta il secondo bit a 1, senza modificare gli altri 7.
|
||||||
|
variabile |= 0b0000 0010;
|
||||||
|
//Imposta il quinto bit a 1, senza modificare gli altri 7.
|
||||||
|
variabile |= 0b0001 0000;
|
||||||
|
|
||||||
|
//In questo punto del codice, variabile vale 0001 0010.
|
||||||
|
|
||||||
|
//Imposta il secondo bit a 0, senza modificare gli altri 7.
|
||||||
|
variabile &=~ 0b0000 0010;
|
||||||
|
|
||||||
|
//In questo punto del codice, variabile vale 0001 0000.
|
||||||
|
```
|
||||||
|
|
||||||
|
In particolare, se si sta modificando codice dell'MSP, è possibile usare le costanti `BITn`:
|
||||||
|
|
||||||
|
```c
|
||||||
|
unsigned int variabile = 0;
|
||||||
|
|
||||||
|
//Imposta il secondo bit a 1, senza modificare gli altri 7.
|
||||||
|
variabile |= BIT1;
|
||||||
|
//Imposta il quinto bit a 1, senza modificare gli altri 7.
|
||||||
|
variabile |= BIT4;
|
||||||
|
|
||||||
|
//In questo punto del codice, variabile vale 0001 0010.
|
||||||
|
|
||||||
|
//Imposta il secondo bit a 0, senza modificare gli altri 7.
|
||||||
|
variabile &=~ BIT1;
|
||||||
|
|
||||||
|
//In questo punto del codice, variabile vale 0001 0000.
|
||||||
|
```
|
||||||
|
|
||||||
|
Infine, puoi usare una maschera per leggere un solo bit alla volta!
|
||||||
|
```c
|
||||||
|
//Leggi solo il quinto bit.
|
||||||
|
variabile & BIT4 // --> 0001 0000
|
||||||
|
|
||||||
|
//Esegui il codice se il quinto bit è 1
|
||||||
|
if(variabile & BIT4) {
|
||||||
|
//Codice goes here
|
||||||
|
}
|
||||||
|
|
||||||
|
//Esegui il codice se il quinto bit è 0
|
||||||
|
if(!(variabile & BIT4)) {
|
||||||
|
//It'sa-me, code!
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## _Prerequisito:_ Differenze nel C dell'MSP430
|
||||||
|
|
||||||
|
Il C dell'MSP430 è simile al C normale, ma ha alcune piccole differenze.
|
||||||
|
|
||||||
|
- L'MSP430 **NON HA** i `bool`, vanno rappresentati come `int` che sono `false` se sono 0 e `true` se sono qualsiasi altro numero.
|
||||||
|
- Alcune variabili, come `P1IN`, vengono cambiate dall'esterno del codice (vedi sotto).
|
||||||
|
|
||||||
|
## Usare le porte
|
||||||
|
|
||||||
|
### Le porte
|
||||||
|
|
||||||
|
Le porte sono quei pin/buchi che vedete sull'MSP sulla sinistra e sulla destra.
|
||||||
|
|
||||||
|
Hanno un nome che va da **P1.0** a **P1.7** e da **P1.0** a **P5.0**.
|
||||||
|
|
||||||
|
Ogni porta ha cinque bit associati:
|
||||||
|
|
||||||
|
- `DIR`(ezione): specifica se una particolare porta è un **output** (1) o un **input** (0).
|
||||||
|
- `OUT`(put): se la porta è un output, decide cosa mandare fuori da quel bit, se un 0 o un 1.
|
||||||
|
- `IN`(put): ha sempre il valore dell'input dell'ingresso desiderato; non può essere modificata.
|
||||||
|
- `SEL`(ezione): visto che tutti i pin possono fare due cose diverse, seleziona quale cosa delle due devono fare: funzionano da **Input/Output** (0) oppure usano la **funzione secondaria** (1).
|
||||||
|
- `REN`: abilita / disabilita una _resistenza di pullup/down_, **assicurati che sia sempre attiva quando usi qualcosa come input** o potrebbero succedere cose inaspettate!
|
||||||
|
|
||||||
|
Per (s)comodità, nel codice C questi bit sono raggruppati in **gruppi di 8**:
|
||||||
|
tutte le porte da P1.0 a P1.7 sono raggruppate nelle variabili `P1DIR`, `P1OUT`, `P1IN`, `P1SEL` e `P1REN`; quelle da P2.0 a P2.7 in `P2DIR`, `P2OUT`, etc.
|
||||||
|
|
||||||
|
```c
|
||||||
|
//P1.5 è un input
|
||||||
|
P1DIR &=~ BIT5;
|
||||||
|
//Assicurati che P1REN sia a 1, P1OUT sia a 0 e P1SEL sia a 0 quando usi un input!
|
||||||
|
P1REN |= BIT5;
|
||||||
|
P1SEL &=~ BIT5;
|
||||||
|
P1OUT &=~ BIT5;
|
||||||
|
```
|
||||||
|
|
||||||
|
```c
|
||||||
|
//P1.5 è un output
|
||||||
|
P1DIR |= BIT5;
|
||||||
|
|
||||||
|
//Fai uscire un 1 da P1.5
|
||||||
|
P1OUT |= BIT5;
|
||||||
|
//Fai uscire uno 0 da P1.5
|
||||||
|
P1OUT &=~ BIT5;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Le funzioni
|
||||||
|
|
||||||
|
Nonostante il C dell'MSP430 sia una cosa paciugata e stranissima, per fortuna le funzioni rimangono uguali a quelle del C standard:
|
||||||
|
|
||||||
|
```c
|
||||||
|
int nomeFunzione(int parametri) {
|
||||||
|
//Codice qui...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Esempio
|
||||||
|
|
||||||
|
```c
|
||||||
|
//Scrivi una funzione di inizializzazione
|
||||||
|
void initAll() {
|
||||||
|
//Ho attaccato un led a P1.0; è quindi un I/O; per la precisione, un output.
|
||||||
|
P1SEL &=~ BIT0;
|
||||||
|
P1DIR |= BIT0;
|
||||||
|
//Ho attaccato un led a P4.7; è quindi un I/O; per la precisione, un output.
|
||||||
|
P4SEL &=~ BIT7;
|
||||||
|
P4DIR |= BIT7;
|
||||||
|
//Ho attaccato un interruttore a P1.1; è quindi un I/O; per la precisione, un input.
|
||||||
|
P1DIR &=~ BIT1;
|
||||||
|
P1REN |= BIT5;
|
||||||
|
P1SEL &=~ BIT5;
|
||||||
|
P1OUT &=~ BIT5;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Scrivi una funzione che cambi lo stato del led di P1.0
|
||||||
|
void led1(int state) {
|
||||||
|
if(state != 0) {
|
||||||
|
//Setta a 1
|
||||||
|
P1OUT |= BIT0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//Setta a 0
|
||||||
|
P1OUT &=~ BIT0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Scrivi una funzione che cambi lo stato del led di P4.7
|
||||||
|
void led2(int state) {
|
||||||
|
//Posso omettere l' != 0, perchè è implicito in tutti gli if senza altre operazioni
|
||||||
|
if(state) {
|
||||||
|
//Setta a 1
|
||||||
|
P4OUT |= BIT7;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//Setta a 0
|
||||||
|
P4OUT &=~ BIT7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Scrivi una funzione che legga il valore dello switch in P2.1
|
||||||
|
int readSwitch() {
|
||||||
|
return (P2IN & BIT1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Puoi anche usare delle variabili nel tuo codice!
|
||||||
|
//Creo una variabile globale.
|
||||||
|
int statoPrecedente;
|
||||||
|
|
||||||
|
//Scrivi una funzione che controlli se lo switch P2.1 è appena stato spinto
|
||||||
|
int debounce() {
|
||||||
|
int statoAttuale = readSwitch();
|
||||||
|
if(statoAttuale != statoPrecedente && statoAttuale) {
|
||||||
|
statoPrecedente = statoAttuale;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
statoPrecedente = statoAttuale;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Scrivi una funzione che cambi stato al led1
|
||||||
|
int toggleLed1() {
|
||||||
|
int statoAttuale = P1OUT & BIT0;
|
||||||
|
if(statoAttuale) {
|
||||||
|
led1(0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
led1(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//...c'è altro, ma non ho il testo della verifica, quindi non lo so...
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Usare il timer
|
||||||
|
|
||||||
|
> TL;DR in fondo, guarda quello se hai fretta!
|
||||||
|
|
||||||
|
Il timer è una delle funzioni dell'MSP: serve per contare il tempo con una precisione altissima.
|
||||||
|
|
||||||
|
Ha millemila impostazioni, ma al Fermi se ne è sempre usata praticamente solo una.
|
||||||
|
|
||||||
|
L'MSP ha due timer che possono funzionare contemporaneamente: si chiamano `TA0` (**TA**imer **0**... Cosa? Non si scrive così timer?) e `TA1` (Well, ci ho provato).
|
||||||
|
|
||||||
|
> Qui sotto parlerò solo di `TA1`, ma `TA0` si configura nello stesso identico modo; basta mettere lo 1 invece che l'1 nel nome della variabile!
|
||||||
|
|
||||||
|
### Velocità del timer
|
||||||
|
|
||||||
|
Il timer dell'MSP può andare a **due velocità**:
|
||||||
|
|
||||||
|
- `TASSEL__SMCLK`: 1 MHz = 1 000 000 Hz
|
||||||
|
- `TASSEL__ACLK`: 32 KHz = 32 000 Hz
|
||||||
|
|
||||||
|
> Sì, quelli sono due underscore. E' fatto così.
|
||||||
|
|
||||||
|
Inoltre, queste due velocità possono essere diminuite con l'impostazione `ID`, che divide per un certo numero la frequenza:
|
||||||
|
|
||||||
|
- `ID__1`: Mantiene la frequenza uguale. What's even the point?
|
||||||
|
- `ID__2`: Divide la frequenza **per due**.
|
||||||
|
- `ID__4`: Divide la frequenza **per quattro**. Inizi a vedere un pattern?
|
||||||
|
- `ID__8`: Divide la frequenza **PER OTTO**! WOW!
|
||||||
|
|
||||||
|
> Ricordati di non confonderti con la versione con un underscore solo, che fa una cosa diversa per qualche motivo...
|
||||||
|
|
||||||
|
Combinate, le impostazioni danno questi risultati:
|
||||||
|
|
||||||
|
| | `TASSEL__SMCLK` | `TASSEL__ACLK` |
|
||||||
|
|-|-----------------|----------------|
|
||||||
|
| `ID__1` | 1 000 000 tick/sec | 32 000 tick/sec |
|
||||||
|
| `ID__2` | 500 000 tick/sec | 16 000 tick/sec |
|
||||||
|
| `ID__4` | 250 000 tick/sec | 8 000 tick/sec |
|
||||||
|
| `ID__8` | 125 000 tick/sec | 4 000 tick/sec |
|
||||||
|
|
||||||
|
#### Configurare la durata
|
||||||
|
|
||||||
|
Per configurare il timer, bisogna mettere il numero di tick per cui si vuole che conti nella variabile `TA1CCR0`.
|
||||||
|
|
||||||
|
Come calcolare il numero di tick? Basta fare `numero_secondi * frequenza_timer`, prendendo la frequenza timer dalla tabella sopra!
|
||||||
|
|
||||||
|
#### Esempio
|
||||||
|
|
||||||
|
Voglio che il timer duri mezzo secondo.
|
||||||
|
|
||||||
|
Decido di usare `TASSEL_ACLK` e `ID__8`, perchè è il più facile da usare.
|
||||||
|
|
||||||
|
Calcolo il numero di tick: `0.5 secondi * 4000 tick/sec = 2000 tick`.
|
||||||
|
|
||||||
|
Allora, scrivo questo:
|
||||||
|
|
||||||
|
```c
|
||||||
|
TA1CCR0 = 2000;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Tante altre cose inutili
|
||||||
|
|
||||||
|
Il timer ha tante, tante, tante altre impostazioni che sono tanto, tanto, tanto inutili.
|
||||||
|
|
||||||
|
Queste vanno inserite nella variabile `TA1CTL` (**TA**imer **1** **C**on**T**ro**L**).
|
||||||
|
|
||||||
|
```c
|
||||||
|
/*
|
||||||
|
clock_scelto: metti TASSEL__ACLK o TASSEL__SMCLK in base a cosa hai scelto di usare prima
|
||||||
|
divisore_scelto: metti ID__1, ID__2, ID__4 o ID__8 in base a cosa hai scelto di usare prima
|
||||||
|
MC__UP: fai in modo che il timer vada avanti (duh)
|
||||||
|
TAIE: attiva/disattiva il timer (TAimer Interrupt Enable)
|
||||||
|
TACLR & ~TAIFG: resetta il timer
|
||||||
|
*/
|
||||||
|
TA1CTL = clock_scelto | divisore_scelto | MC__UP | TAIE | TACLR & ~TAIFG;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Funzione da chiamare quando finisce il timer
|
||||||
|
|
||||||
|
Per marcare una funzione come "quella da chiamare quando finisce il timer", bisogna aggiungere `__attribute__ (( interrupt(TIMER1_A1_VECTOR) ))` dopo `void`, ma prima del nome della funzione.
|
||||||
|
|
||||||
|
> Anche qui sì, sono due parentesi tonde.
|
||||||
|
|
||||||
|
Tutto il resto del codice verrà _interrotto_ mentre questa funzione è in esecuzione, e questa potrebbe essere chiamata mentre un'altra è a metà.
|
||||||
|
|
||||||
|
#### Esempio
|
||||||
|
|
||||||
|
```c
|
||||||
|
void __attribute__ (( interrupt(TIMER1_A1_VECTOR) )) timer1() {
|
||||||
|
//Fai cose!
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### **TL;DR**: Too long, didn't read
|
||||||
|
|
||||||
|
Per eseguire una funzione dopo X secondi, scrivi questo.
|
||||||
|
|
||||||
|
```c
|
||||||
|
void avviaTimer1(float secondi) {
|
||||||
|
TA1CCR0 = (int) (secondi * 4000)
|
||||||
|
TA1CTL = TASSEL__ACLK | ID__8 | TACLR | TAIE | MC__UP & ~TAIFG;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __attribute__ ((interrupt(TIMER1_A1_VECTOR))) timer1() {
|
||||||
|
//Codice che vuoi che venga eseguito!
|
||||||
|
}
|
||||||
|
```
|
138
5 - TPS/tpsit_msp430_verificasantinelli.c
Normal file
138
5 - TPS/tpsit_msp430_verificasantinelli.c
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
#include <msp430.h>
|
||||||
|
|
||||||
|
//Funzione inizializzazione generale
|
||||||
|
void initAll()
|
||||||
|
{
|
||||||
|
//P1.0 - LED1 - OUT -
|
||||||
|
//P4.7 - LED2 - OUT -
|
||||||
|
//P1.1 - BTN1 - IN -
|
||||||
|
//P2.1 - BTN2 - IN -
|
||||||
|
|
||||||
|
P1DIR |= BIT0;
|
||||||
|
P4DIR |= BIT7;
|
||||||
|
P1OUT &=~ BIT0;
|
||||||
|
P4OUT &=~ BIT7;
|
||||||
|
|
||||||
|
P1DIR &=~ BIT1;
|
||||||
|
P2DIR &=~ BIT1;
|
||||||
|
P1OUT &=~ BIT1;
|
||||||
|
P2OUT &=~ BIT1;
|
||||||
|
P1REN |= BIT1;
|
||||||
|
P2REN |= BIT1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Modifica stato led1
|
||||||
|
void led1(int stato){
|
||||||
|
if(stato==1) P1OUT |= BIT0;
|
||||||
|
else P1OUT &=~ BIT0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void led2(int stato){
|
||||||
|
if(stato==1) P4OUT |= BIT7;
|
||||||
|
else P4OUT &=~ BIT7;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Restituisci stato sw1
|
||||||
|
|
||||||
|
int sw1(){
|
||||||
|
return P1IN & BIT1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sw2(){
|
||||||
|
return P2IN & BIT1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//sw1 è appena stato rilasciato?
|
||||||
|
int before = 0;
|
||||||
|
|
||||||
|
int pressedSw1(){
|
||||||
|
int now=0;
|
||||||
|
now=sw1();
|
||||||
|
if(now!=before){
|
||||||
|
before = now;
|
||||||
|
return now;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int releasedSw1(){
|
||||||
|
int now=0;
|
||||||
|
now=sw1();
|
||||||
|
if(now!=before){
|
||||||
|
before = now;
|
||||||
|
return !now;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pressedSw2(){
|
||||||
|
int now=0;
|
||||||
|
now=sw2();
|
||||||
|
if(now!=before){
|
||||||
|
before = now;
|
||||||
|
return now;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int releasedSw2(){
|
||||||
|
int now=0;
|
||||||
|
now=sw2();
|
||||||
|
if(now!=before){
|
||||||
|
before = now;
|
||||||
|
return !now;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Evento di sw1
|
||||||
|
//sw1 appena rilasciato -> return 3
|
||||||
|
//sw1 appena premuto -> return 2
|
||||||
|
//sw1 è rilasciato -> return 1
|
||||||
|
//sw1 è premuto -> return 0
|
||||||
|
int eventSw1() {
|
||||||
|
if(releasedSw1()) return 3;
|
||||||
|
else if (pressedSw1()) return 2;
|
||||||
|
else if (sw1()) return 1;
|
||||||
|
else return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Evento di sw2
|
||||||
|
//sw2 appena rilasciato -> return 3
|
||||||
|
//sw2 appena premuto -> return 2
|
||||||
|
//sw2 è rilasciato -> return 1
|
||||||
|
//sw2 è premuto -> return 0
|
||||||
|
int eventSw2() {
|
||||||
|
if(releasedSw2()) return 3;
|
||||||
|
else if (pressedSw2()) return 2;
|
||||||
|
else if (sw2()) return 1;
|
||||||
|
else return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Macchina a stati finiti
|
||||||
|
int stato = 0; //Se lo stato è 1, il led dovrebbe essere acceso... Se invece è 0, il led dovrebbe essere spento.
|
||||||
|
void FSM_Led2() {
|
||||||
|
|
||||||
|
if(stato == 0 & pressedSw1()) {
|
||||||
|
led1(1);
|
||||||
|
stato=1;
|
||||||
|
}
|
||||||
|
else if (stato == 1 & pressedSw2()){
|
||||||
|
led1(0);
|
||||||
|
stato=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Actually il main
|
||||||
|
int main() {
|
||||||
|
while(1) FSM_Led2():
|
||||||
|
}
|
9
README.md
Normal file
9
README.md
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|
![](.media/icon-128x128_round.png)
|
||||||
|
|
||||||
|
# Appunti scolastici
|
||||||
|
|
||||||
|
Collezione di appunti presi durante il corso di studio in Informatica e Telecomunicazioni all'ITIS Enrico Fermi di Modena e durante il supporto allo studio ad altri studenti di informatica
|
||||||
|
|
||||||
|
</div>
|
Loading…
Reference in a new issue