2015-07-23 13:44:53 +03:00

228 lines
6.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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){};
}