-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.c
288 lines (251 loc) · 8.97 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
/************************************************************************************************\
TouchTapparelle v1.0 - PIC12F1840
www.ajk.altervista.com
Copyright (c) 2012, Alberto Garbui aka AjK
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
-Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
-Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
-Neither the name of the AjK Elettronica Digitale nor the names of its contributors may be
used to endorse or promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\************************************************************************************************/
#include "mTouch.h" // Required Include
//definizione connessioni
//LEDS UP/DOWN (singolo pin)
#define LED_UP(); TRISA5=0;LATA5=0;
#define LED_DOWN(); TRISA5=0;LATA5=1;
#define LED_TOGGLE(); TRISA5=0;LATA5=!LATA5;
#define LEDS_OFF(); LATA5=0;RA5=0;TRISA5=1;
//RELE' UP/DOWN
#define SWITCH_UP(); LATA0=1;
#define SWITCH_DOWN(); LATA0=0;
//RELE' MOTORE ON/OFF
#define MOTOR_ON(); LATA1=1;
#define MOTOR_OFF(); LATA1=0;
#define TOUCHDELAY 1000 //tempo permanenza touch per attivare il motore (ms)
#define TIMEOUTMOTORE 17500 //tempo attivazione motore per una corsa intera (ms)
//definizioni non modificabili
#define TOUCH_UP 0
#define TOUCH_DOWN 1
#define OFF 2
#define SWITCHDELAY 500 //intervallo tra switch ed attivazione motore (ms) (necessario!)
#define MAXDELAY 65000 //48ms * 65535 =circa 52minuti
#define INTERRUPTPERIOD 50 //ms di periodo interrupt
// CONFIGURATION SETTINGS
__CONFIG(FOSC_INTOSC & WDTE_OFF & PWRTE_OFF & MCLRE_OFF & CP_OFF & CPD_OFF & BOREN_OFF & CLKOUTEN_OFF & IESO_OFF & FCMEN_OFF);
__CONFIG(WRT_OFF & PLLEN_ON & STVREN_OFF & BORV_25 & LVP_OFF);
//variabili globali
unsigned int tempoDelay;
unsigned char statoTapparella;
unsigned char timerMotore=0; //flag avvio conteggio motore
unsigned int tempoMotore=0; //conteggio tempo motore
// PROTOTIPI
void System_Init(void);
void interrupt ISR(void);
void setLed(unsigned char touch);
void setSwitch(unsigned char touch);
void waitMTOUCH_RELEASED(unsigned char touch);
void setupTimer1(void);
void delay_ms(unsigned int ms);
void checkTouch(unsigned char touch);
unsigned char checkPresenza(unsigned char touch, unsigned int ms);
void main(void)
{
System_Init(); //init porte/oscillatore/interrupt
mTouch_Init(); //init mTouch
setupTimer1(); //avvio conteggio tempo con timer1 ed interrupts
setLed(TOUCH_UP); //accendo led up
unsigned int i,j;
for(i=500;i>50;i-=50) //animazione iniziale
{
for(j=0;j<3;j++)
{LED_TOGGLE();
delay_ms(i);}
}
for(i=0;i<20;i++)
{
LED_TOGGLE();
delay_ms(100);
}
LEDS_OFF(); //spengo i led
delay_ms(1000);
while(1) //ciclo infinito principale
{
if(mTouch_isDataReady())
{
mTouch_Service();
checkTouch(TOUCH_UP); //controllo entrambi i sensori
checkTouch(TOUCH_DOWN); //UP/DOWN
}
}//end while(1)
}//end main()
void checkTouch(unsigned char touch)
{
if((mTouch_GetButtonState(touch) == MTOUCH_PRESSED))
{
setLed(touch); //se rilevo la prensenza del touch, attivo il led corrispondente
if(checkPresenza(touch,TOUCHDELAY)) //se rilevo una pressione prolungata
{
MOTOR_OFF(); //mi assicuro che il motore sia spento
delay_ms(SWITCHDELAY); //delay per scaricare tensioni residue
setSwitch(touch); //imposto lo switch UP/DOWN
delay_ms(200);
MOTOR_ON(); //attivo il motore
tempoMotore=0; //azzero il tempo motore
timerMotore=1; //avvio il conteggio del tempo
waitMTOUCH_RELEASED(touch); //aspetto il rilascio
//ora aspetto la fine del timeoutMotore oppure una pressione per lo stop
while(1)
{
if(tempoMotore>(TIMEOUTMOTORE/INTERRUPTPERIOD)) //se supero il timeout
{
MOTOR_OFF(); //spengo il motore
timerMotore=0; //fermo il conteggio del tempo
break; //esco
}
if(mTouch_isDataReady())
{
mTouch_Service(); //se rilevo un touch qualsiasi esco
if((mTouch_GetButtonState(TOUCH_UP) == MTOUCH_PRESSED))
{
//setLed(TOUCH_UP); //accendo il led UP
MOTOR_OFF(); //spengo il motore
waitMTOUCH_RELEASED(TOUCH_UP); //aspetto il rilascio
break;
}
if((mTouch_GetButtonState(TOUCH_DOWN) == MTOUCH_PRESSED))
{
//setLed(TOUCH_DOWN); //accendo il led DOWN
MOTOR_OFF(); //spengo il motore
waitMTOUCH_RELEASED(TOUCH_DOWN); //aspetto il rilascio
break;
}
}
}
delay_ms(SWITCHDELAY); //delay per scaricare tensioni residue
setSwitch(TOUCH_DOWN); //imposto lo switch DOWN (relè a riposo)
LEDS_OFF(); //spengo i led dopo un'eventuale animazione
}else{
LEDS_OFF();
}
delay_ms(1000); //aspetto 1sec
}else{
LEDS_OFF(); //se non rilevo la presenza spengo i led
}
}
void waitMTOUCH_RELEASED(unsigned char touch)
{
//per sicurezza inserisco un timeout di 30sec
unsigned int const timeout=30000/INTERRUPTPERIOD;
tempoDelay=0; //inizio il conteggio del tempo per il timeout
while(1) //aspetto il rilascio
{
if(tempoDelay>timeout)break; //esco con timeout
if(mTouch_isDataReady())
{
mTouch_Service();
if((mTouch_GetButtonState(touch) != MTOUCH_PRESSED))break;
}
}
delay_ms(500); //delay antirimbalzo dopo il rilascio
}
void setLed(unsigned char touch)
{
switch(touch)
{
case TOUCH_UP:
LED_UP();
break;
case TOUCH_DOWN:
LED_DOWN();
break;
default:
LEDS_OFF();
break;
}
}
void setSwitch(unsigned char touch)
{
if(touch==TOUCH_UP)
{
SWITCH_UP();
}else{
SWITCH_DOWN();
}
}
unsigned char checkPresenza(unsigned char touch, unsigned int ms)
{
unsigned int timeout=ms/INTERRUPTPERIOD;
if(timeout>MAXDELAY)timeout=MAXDELAY;
tempoDelay=0;
while(tempoDelay<timeout)
{
if(mTouch_isDataReady())
{
mTouch_Service();
if((mTouch_GetButtonState(touch) != MTOUCH_PRESSED))break;
}
}
if(tempoDelay>=timeout)return 1;
else return 0;
}
void delay_ms(unsigned int ms)
{
unsigned int timeout=ms/INTERRUPTPERIOD;
if(timeout>MAXDELAY)timeout=MAXDELAY;
tempoDelay=0;
while(tempoDelay<timeout);
}
void setupTimer1() {
TMR0IE = 1;
TMR1IE = 1; // abilito interrupt overflow timer1
TMR1IF = 0; // resetto il flag di interrupt
TMR1H = 60; // set high byte
TMR1L = 176; // set low byte (overflow ogni 50ms)
T1GCON = 0; // disabilito tutte le funzioni gate sul timer1
T1CON = 0b00110001; // fosc/4, prescale=8, no LP, timer abilitato
INTCON = 0b11000000; //abilito interrupt globali e periferici
TMR1IF = 0; // resetto il flag di interrupt
}
void interrupt ISR(void)
{
SAVE_STATE(); // mTouch Framework-supplied general ISR save state macro.
// Not required, but convenient.
if(TMR1IF==1)
{
TMR1ON=0; //fermo il timer1
if(tempoDelay<MAXDELAY)tempoDelay++; //incremento il tempo se posso
if(tempoMotore<MAXDELAY && timerMotore)
tempoMotore++; //se il flag è attivo incremento il tempoMotore
setupTimer1(); //resetto il timer1 ed il flag di interrupt
}
RESTORE_STATE(); // mTouch Framework-supplied general ISR restore state macro.
}
void System_Init()
{
OSCCON = 0b11110000; // 32 MHz Fosc w/ PLLEN_ON (config bit)
// mTouch sensor pins impostati come uscite digitali
ANSELA = 0b00000000;
LATA = 0b00000000;
TRISA = 0b00000000;
WPUA = 0; //pull up disabilitate
LEDS_OFF(); //led spenti
MOTOR_OFF(); //relè motore off
SWITCH_DOWN(); //relè switch off
//la libreria Mtouch richiede l'utilizzo del timer0 ad 8bit
OPTION_REG = 0b10000000; // TMR0 Prescaler = 1:2
}