-
Notifications
You must be signed in to change notification settings - Fork 2
/
main.c
227 lines (214 loc) · 6.78 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
#include <pic16f873a.h>
#include "signals.h"
#define BUFSIZE 95
//#define CLRWDT _asm clrwdt _endasm;
typedef unsigned int word;
word at 0x2007 CONFIG = 0x3F72; // ÄÌÑ WDT: 0x3F76
unsigned char
cmd, // ÐÏÌÕÞÅÎÎÁÑ ËÏÍÁÎÄÁ
d_H, d_L, // ÓÔÁÒÛÉÊ É ÍÌÁÄÛÉÊ ÂÁÊÔÙ Ä×ÕÈÂÁÊÔÎÏÊ ÐÏÓÙÌËÉ
T1H, T1L, // ÚÎÁÞÅÎÉÑ ÒÅÇÉÓÔÒÏ× ÓÞÅÔÞÉËÁ ÔÁÊÍÅÒÁ 1
mC_addr, // ÆÉÚ. ÁÄÒÅÓ ËÏÎÔÒÏÌÌÅÒÁ (ËÏÎÓÔÁÎÔÁ, ÕÓÔÁÎÁ×ÌÉ×ÁÅÔÓÑ ÆÕÎËÃÉÅÊ init)
tmr_on; // ==1 - ÔÁÊÍÅÒ ×ËÌÀÞÅÎ
unsigned char write_SPI(unsigned char);
void hands(){
unsigned char i;
write_SPI(10); // ÉÎÉÃÉÁÌÉÚÁÃÉÑ
write_SPI(0);
/* write_SPI(128);
for(i=0; i<20; i++)
write_SPI(0);*/
write_SPI(94); // ÒÕËÉ
for(i=0; i<5; i++)
write_SPI(0);
T1CON = 0;
}
void focus(){
unsigned char i;
write_SPI(194);
TX9D = 0;
for(i=0; i<5; i++){
TXEN = 1;
TXREG = write_SPI(0);
while(!TRMT);
}
}
void send9bit(unsigned char something){
unsigned char tmp;
something &= 0x1F; // ÓÂÒÏÓ ÓÔÁÒÛÉÈ ÔÒÅÈ ÂÉÔ (ÔÁÍ ÂÕÄÅÔ ÁÄÒÅÓ)
tmp = mC_addr | something;
TXEN = 1; // ÇÏÔÏ× Ë ÐÅÒÅÄÁÞÅ
TX9D = 0; // 0 - ÐÅÒÅÄÁÅÔ ËÏÎÔÒÏÌÌÅÒ
TXREG = tmp; // ÐÏÓÌÁÔØ ËÏÍÁÎÄÕ
}
unsigned char get9bit(){
unsigned char err1, err2, flag9bit, tmp;
while(!RCIF);
flag9bit = RX9D;
err1 = FERR; err2 = OERR; // ÓÞÉÔÁÔØ 9-Ê ÂÉÔ É ÏÛÉÂËÉ
cmd = RCREG; // ÏÞÉÓÔÉÔØ ÂÕÆÅÒ ÄÁÎÎÙÈ
RX9D = 0;
if(err1 == 1){
return NO_STOP_BIT;
}
if(err2 == 1){
CREN = 0; CREN = 1; // ÓÂÒÏÓÉÔØ ÆÌÁÇ ÏÛÉÂËÉ
return STACK_OVERFLOW;
}
if(flag9bit) return TWOBYTE; // ÄÁÎÎÙÅ - ÞÁÓÔØ Ä×ÕÈÂÁÊÔÎÏÊ ÐÏÓÙÌËÉ (ÎÅÉÚ×ÅÓÔÎÏ ÅÝÅ ÞØÅÊ :) )
tmp = cmd & 0xE0; // ×ÙÄÅÌÅÎÉÅ ÁÄÒÅÓÁ ÉÚ ËÏÍÁÎÄÙ
cmd &= 0x1F; // ÏÂÎÕÌÅÎÉÅ ÁÄÒÅÓÎÙÈ ÂÉÔÏ×
if(tmp != mC_addr) return ERR_CMD; // ÅÓÌÉ ÁÄÒÅÓÏ×ÁÎ ÞÕÖÏÍÕ
send9bit(cmd); // üÈÏ ÐÒÉÎÑÔÏÊ ËÏÍÁÎÄÙ
return OK;
}
void sendword(unsigned char data_H, unsigned char data_L){
RCIE = 0; // disable USART in interrupt
TMR1IF = 0;
TMR1IE = 0;
TXEN = 1;
TX9D = 1;
TXREG = data_H;
while(!TRMT);
TXEN = 1;
TX9D = 1;
TXREG = data_L;
RCIE = 1;
if(tmr_on) TMR1IE = 1;
}
unsigned char getword(){
unsigned char ret = 0;
RCIE = 0; // disable USART in interrupt
TMR1IF = 0;
TMR1IE = 0;
if(ten_times_read()){
d_H = cmd;
if(ten_times_read()){
d_L = cmd;
ret = 1;}} // ÅÓÌÉ ÏÂÁ ÂÁÊÔÁ ÓÞÉÔÁÌÉ ÐÒÁ×ÉÌØÎÏ
if(tmr_on) TMR1IE = 1;
RCIE = 1; // enable USART in interrupt
return ret;
}
unsigned char ten_times_read(){ // 10 ÐÏÐÙÔÏË ÞÔÅÎÉÑ ÄÌÑ Ä×ÕÈÂÁÊÔÎÏÇÏ ÐÒÉÅÍÁ
unsigned char i=0;
do i++;
while(get9bit() != TWOBYTE && i < 10);
if(i > 9){send9bit(ERR_CMD); return 0;}
send9bit(OK);
return 1;
}
void init(){ // ÉÎÉÃÉÁÌÉÚÁÃÉÑ
// îÁÓÔÒÏÊËÁ USART'a
// TXSTA: | CSRC | TX9 | TXEN | SYNC | N/A | BRGH | TRMT | TX9D |
TXSTA = 0x66; // (11000110): master, 9-ÔÉ ÂÉÔÎÙÊ ××ÏÄ/×Ù×ÏÄ, async, hi-speed, ready
// SPBRG - ÓËÏÒÏÓÔØ ÐÅÒÅÄÁÞÉ
SPBRG = 25; // 9.6 ËÂ/Ó
// RCSTA: | SPEN | RX9 | SREN | CREN | ADDEN | FERR | OERR | RX9D |
RCSTA = 0xD0; // ( 11010000): enable, 9bit, continuous mode
// ÎÁÓÔÒÏÊËÁ ÐÏÒÔÏ×:
PORTA = 0; // 6-ÔÉ ÂÉÔÎÙÊ ÁÎÁÌÏÇÏ×Ï/ÃÉÆÒÏ×ÏÊ ÐÏÒÔ (0..5 ÂÉÔÙ)
// ADCON1: | ADFM | N/A | N/A | N/A | PCFG3 | PCFG2 | PCFG1 | PCFG0 |
ADCON1 = 0x06; // áÎÁÌÏÇÏ×Ï/ÃÉÆÒÏ×ÏÊ ÐÏÒÔ ÒÁÂÏÔÁÅÔ × ÐÏÌÎÏÓÔØÀ ÃÉÆÒÏ×ÏÍ ÒÅÖÉÍÅ
TRISA = 0; // ÎÁÐÒÁ×ÌÅÎÉÅ ÐÏÒÔ á (1-×ÈÏÄ, 0-×ÙÈÏÄ)
TRISB = 0xff; // --/ B /--
// OPTION_REG: | !RBPU | INTEDG | TOCS | TOSE | PSA | PS2 | PS1 | PS0 |
OPTION_REG = 0x7f; /* (01111111) 0 - ÐÏÄËÌÀÞÅÎÉÅ ÐÏÄÔÑÖÅË ÎÁ ÐÏÒÔ B (ÕÓÔ. ÌÏÇ. 1),
ÐÒÅÒÙ×ÁÎÉÅ ÐÏ ÎÁÒÁÓÔÁÀÝÅÍÕ ÆÒÏÎÔÕ RB0,
ÔÁÊÍÅÒ 0 ÒÁÂÏÔÁÅÔ ÐÏ ÓÉÇÎÁÌÕ Ó RA4
ÔÁÊÍÅÒ 0 Õ×ÅÌÉÞÉ×ÁÅÔÓÑ ÐÒÉ ÓÐÁÄÅ ÓÉÇÎÁÌÁ ÎÁ RA4
ÐÒÅÄÄÅÌÉÔÅÌØ ÐÏÄËÌÀÞÅÎ Ë ÓÔÏÒÏÖÅ×ÏÍÕ ÔÁÊÍÅÒÕ
ÒÅÖÉÍ prescaler: 1:128 */
TRISC = 0xC0; // (11000000) - 0..5 ÂÉÔÙ ËÁË ×ÙÈÏÄÙ
INTCON = 0; // ÏÔËÌÀÞÉÔØ ×ÓÅ ÐÒÅÒÙ×ÁÎÉÑ
T1CON = 0;
// PIE1: | PSPIE | ADIE | RCIE | TXIE | SSPIE | CCP1IE | TMR2IE | TMR1IE |
PIE1 = 0x20; // (00100000): enable USART(in)
// PIE2: ×ÓÅ N/A, ËÒÏÍÅ EEIE (PIE2.4)
PIE2 = 0; // & disable other int.s
PORTB = 0;
// INTCON: | GIE | PEIE | T0IE | INTE | RBIE | T0IF | INTF | RBIF |
INTCON = 0xC0; // (1100000) - ×ËÌÀÞÉÔØ ÇÌÏÂÁÌØÎÙÅ ÐÒÅÒÙ×ÁÎÉÑ, ÐÒÅÒÙ×ÁÎÉÑ ÐÏ ÐÅÒÉÆÅÒÉÉ
PORTC = 0; // ÂÅÚ ÎÁÐÒÑÖÅÎÉÑ
PORTA = 0xF; // (00001111)
// ÐÏÌÕÞÅÎÉÅ ÁÄÒÅÓÁ
mC_addr = PORTB; // ÆÉÚÉÞÅÓËÉÊ ÁÄÒÅÓ ÕÓÔÒÏÊÓÔ×Á
mC_addr &= 0xE0; // ×ÙÄÅÌÅÎÉÅ ÆÉÚÉÞÅÓËÏÇÏ ÁÄÒÅÓÁ
// SSPCON: | WCOL | SSPOV | SSPEN | CKP | SSPM3 | SSPM2 | SSPM1 | SSPM0 |
SSPCON = 0x32; // (00110010) - ×ËÌÀÞÉÔØ SPI, ×ÙÓÏËÉÊ ÕÒÏ×ÅÎØ CLK (CKP=1), ÞÁÓÔÏÔÁ Fosc/64
// SSPSTAT: | SMP | CKE | - | - | - | - | - | BF |
SSPSTAT = 0; // ÒÅÖÉÍ ÒÁÂÏÔÙ SPI: SMP=0 - ÏÐÒÏÓ ×ÈÏÄÁ × ÓÅÒÅÄÉÎÅ ÐÅÒÉÏÄÁ
// CKE=0 - ÄÁÎÎÙÅ ÐÅÒÅÄÁÀÔÓÑ ÐÏ ÚÁÄÎÅÍÕ ÆÒÏÎÔÕ
TRISC = 0xD0; SSPIE = 1;
tmr_on = 0;
hands();
}
void timer1set(){ // ÕÓÔÁÎÏ×ËÁ ÔÁÊÍÅÒÁ
// unsigned int tmp = 0xffff - usec/8;
T1CON = 0; // ×ÙËÌÀÞÉÔØ ÔÁÊÍÅÒ
TMR1IF = 0; // ÓÂÒÏÓÉÔØ ÆÌÁÇ ÐÒÅÒÙ×ÁÎÉÑ
TMR1IE = 1; // ÒÁÚÒ/ÚÁÐÒ ÐÒÅÒÙ×ÁÎÉÅ
TMR1H = T1H = d_H; //(tmp >> 8) & 0xff;
TMR1L = T1L = d_L; //tmp & 0xff; // ÕÓÔÁÎÏ×ÉÔØ ÓÞÅÔÞÉËÉ
// T1CON: | - | - | T1CPS1 | T1CPS0 | T1OSCEN | T1SYNC | TMR1CS | TMR1ON |
T1CON = 0x31; // (00110001) - ×ËÌÀÞÉÔØ ÔÁÊÍÅÒ 1, ÐÒÅÄÄÅÌÉÔÅÌØ ÎÁ 1/8 (250 ËçÃ)
tmr_on = 1;
}
unsigned char write_SPI(unsigned char byte){
unsigned char ans;
TMR1IF = 0;
if(tmr_on){
T1CON = 0; // ÏÔËÌÀÞÁÅÍ ÔÁÊÍÅÒ
TMR1IE = 0;
}
SSPBUF = byte;
while(!SSPIF); // ÖÄÅÍ ÏËÏÎÞÁÎÉÑ ÐÅÒÅÄÁÞÉ
ans = SSPBUF; // ÒÅÇÉÓÔÒÉÒÕÅÍ ÐÏÌÕÞÅÎÎÙÊ ÂÁÊÔ
SSPIF = 0;
SSPIE = 1;
if(tmr_on){
TMR1H = T1H; TMR1L = T1L;
T1CON = 0x31; // ÚÁÐÕÓËÁÅÍ ÔÁÊÍÅÒ
TMR1IE = 1;
}
return ans;
}
void on_interrupt() __interrupt 0{ // ÏÂÒÁÂÏÔËÁ ÐÒÅÒÙ×ÁÎÉÊ
if(RCIF == 1){ // ÐÏÓÔÕÐÉÌÏ ÐÒÅÒÙ×ÁÎÉÅ ÏÔ USART
if(get9bit() != OK) return;
switch(cmd){
case INIT: init(); break;
case SET_TIMER: if(getword()) timer1set();
else send9bit(ERR_CMD);
break;
case TMR_SETTINGS: sendword(T1H, T1L); break;
case SPI_send_one: while(!RCIF);
TX9D = 0; TXEN = 1; TXREG = write_SPI(RCREG); break;
case SPI_ON: SSPEN = 1; SSPIE = 1; break;
case SPI_OFF: SSPEN = 0; SSPIE = 0; break;
case MID_DATA: SMP = 0; break;
case END_DATA: SMP = 1; break;
case MID_SPD: SPBRG = 12; break; // 19200
case LOW_SPD: SPBRG = 25; break; // 9600
case SPEED1: d_H = 0x6D; d_L = 0x84; timer1set(); break; // 0.3Ó
case SPEED2: d_H = 0xE7; d_L = 0x96; timer1set(); break; // 0.05Ó
case SPEED3: d_H = 0xFB; d_L = 0x1E; timer1set(); break; // 0.01Ó
case FORW: write_SPI(5); break;
case BACK: write_SPI(6); break;
case INFTY: write_SPI(37); break;
case ZERO: write_SPI(22); break;
case HANDS: hands(); break;
case TMR_OFF: tmr_on = 0; T1CON = 0; TMR1IE = 0; break;
case TMR_ON: tmr_on = 1; T1CON = 0x31; TMR1IE = 1; break;
case FOCUS: focus(); break;
}
}
if(TMR1IF == 1 && tmr_on){ // ÐÏÓÔÕÐÉÌÏ ÐÒÅÒÙ×ÁÎÉÅ ÏÔ ÔÁÊÍÅÒÁ
write_SPI(4); // ÐÏÓÙÌÁÅÍ ÓÉÇÎÁÌ ÓÔÏÐ É ÐÅÒÅÚÁÐÕÓËÁÅÍ ÔÁÊÍÅÒ
write_SPI(0);
}
}
void main(){ // ÏÓÎÏ×ÎÏÊ ÃÉËÌ
init();
while(1){};
}