main.c
4.19 KB
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
#include <avr/io.h> // for the input/output register
#include <util/delay.h>
// For the serial port
#define CPU_FREQ 16000000L // Assume a CPU frequency of 16Mhz
#define tempo 25
#define debit 9600 //débit liaison série en bauds
#define debut_serial_tx 0x40 //pour détecter la transmission d'une trame pour le 16u2
void init_serial(int speed)
{
/* Set baud rate */
UBRR0 = CPU_FREQ/(((unsigned long int)speed)<<4)-1;
/* Enable transmitter & receiver */
UCSR0B = (1<<TXEN0 | 1<<RXEN0);
/* Set 8 bits character and 1 stop bit */
UCSR0C = (1<<UCSZ01 | 1<<UCSZ00);
/* Set off UART baud doubler */
UCSR0A &= ~(1 << U2X0);
}
void send_serial(unsigned char c)
{
loop_until_bit_is_set(UCSR0A, UDRE0);
UDR0 = c;
}
unsigned char get_serial(void) {
loop_until_bit_is_set(UCSR0A, RXC0);
return UDR0;
}
// For the AD converter
void ad_init(unsigned char channel)
{
ADCSRA|=(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
ADMUX|=(1<<REFS0)|(1<<ADLAR);
ADMUX=(ADMUX&0xf0)|channel;
ADCSRA|=(1<<ADEN);
}
//récupère la valeur de l'ADCH
unsigned int ad_sample(void){
ADCSRA|=(1<<ADSC);
while(bit_is_set(ADCSRA, ADSC));
return ADCH;
}
// For the I/O
void output_init(void){
DDRB |= 0b00111111; // PIN 8-13 as output (LED)
}
/*
void output_set(unsigned char value){
if(value==0) PORTB &= 0xfe; else PORTB |= 0x01;
}
*/
void input_init(void){
DDRD &= 0b10000011; // PIN 2-6 as input (Bouton Joystick + boutons)
PORTD |= 0x7C; // Pull up de 0 à 1
}
/*
unsigned char input_get(void){
return ((PIND&0x04)!=0)?1:0;
}
*/
/* Commande des LED */
void commande_leds(){
unsigned char temp_serial, leds;
temp_serial = UDR0;
if (temp_serial !=0){
leds = temp_serial;
// Allumer LED de 'A' à 'F'
if (leds == 'A') PORTB = PORTB | 0x01;
if (leds == 'B') PORTB = PORTB | 0x02;
if (leds == 'C') PORTB = PORTB | 0x04;
if (leds == 'D') PORTB = PORTB | 0x08;
if (leds == 'E') PORTB = PORTB | 0x10;
if (leds == 'F') PORTB = PORTB | 0x20;
// Eteindre LED de 'a' à 'f'
if (leds == 'a') PORTB = PORTB & 0xfe;
if (leds == 'b') PORTB = PORTB & 0xfd;
if (leds == 'c') PORTB = PORTB & 0xfb;
if (leds == 'd') PORTB = PORTB & 0xf7;
if (leds == 'e') PORTB = PORTB & 0xef;
if (leds == 'f') PORTB = PORTB & 0xdf;
}
}
/* Récupération de la valeur des boutons et mise en forme */
unsigned char get_buttons(void){
unsigned char boutons = PIND;
boutons = boutons >>2;
boutons = boutons & 0b00111111;
boutons = boutons | 0b00100000;
return boutons;
}
/* Met en forme l'octet de l'axe pos du joystick */
unsigned char shape_joy(unsigned char pos){
pos = pos >>3; //On récupère les 5 bits de poids forts de l'ADCH (diminuer sensibilité)
pos = pos & 0b00111111;
pos = pos | 0b00100000;
return pos;
}
/* Récupération de la valeur de l'axe du joystick sur la chaîne channel du CAN */
unsigned char get_joystick(int channel){
unsigned char axis;
ad_init(channel);
axis = ad_sample();
axis = shape_joy(axis);
return axis;
}
/* Dummy main */
int main(void){
//INITIALISATIONS
unsigned char boutons, boutons_anc;
unsigned char joystick_x=0x10, joystick_x_anc=0x10;
unsigned char joystick_y=0x10, joystick_y_anc=0x10;
init_serial(debit);
output_init();
input_init();
//Récupération des valeurs des boutons et joystick, et mise en forme
boutons = get_buttons();
joystick_x = get_joystick(0);
joystick_y = get_joystick(1);
while(1){
boutons_anc = boutons;
joystick_x_anc = joystick_x;
joystick_y_anc = joystick_y;
//Récupération des valeurs des boutons et joystick, et mise en forme
boutons = get_buttons();
joystick_x = get_joystick(0);
_delay_ms(tempo);
joystick_y = get_joystick(1);
//Port série libre
if ((UCSR0A & (1<<RXC0)) == 0){
// Si une des grandeurs a changé
if ((boutons_anc != boutons) || (joystick_x_anc != joystick_x) || (joystick_y_anc != joystick_y)){
/* On envoie la trame des grandeurs */
send_serial(debut_serial_tx); //début de trame
send_serial(boutons); //état global des grandeurs
send_serial(joystick_x);
send_serial(joystick_y);
//retour chariot
send_serial(0x0a);
send_serial(0x0d);
}
}
//Port série occupé
else{
commande_leds(); //On gère la commande des leds
}
}
return 0;
}