сделай пожалуста изменение в прошивке чтоби PD4(вив6) управлял завоцкой китайской сервой (а PD5 будет про запас)
С остальним всем согласен,теске MASIK Привет БУДЕМ ПОВТОРЯТЬ
Эта схема для MASIK, заточена под самодельную серву. Если делать по нормальному, то надо перекинуть модуль nRF24L01+ и сделать нормальную ШИМ (можно с двуми сервами).. А вообще есть и другие варианты))sashamelja писал(а):чтоби PD4(вив6) управлял завоцкой китайской сервой
Я на одном аппаратном модуле ССР (Capture/Compare/PWM) делаю 6 въхода PPM. Так что - возможно. Код (C) вълагал здесь - правда на PIC-e.roman.com писал(а): к ATmega8 можно подключить только две сервы... жаль... Какие есть варианты? Целая куча...)))
Такие комментарии нам очень помогают... )))botchin писал(а):Я на одном аппаратном модуле ССР (Capture/Compare/PWM) делаю 6 въхода PPM. Так что - возможно. Код (C) вълагал здесь - правда на PIC-e.
Не понял... ты насхеме нарисовал 4 сервы... теперь одна? Ты определись... от этого зависит схема ипрограмма...sashamelja писал(а):нада одна серва
Дрожание критично. Может перегреваться серва и самое с главное - повышенный разряд аккумулятора... Оно тебе надо? ))sashamelja писал(а):дрожание не критично,главное чтоби связь не терялась а управление мотором такое как в Маsika
Третий вариант - это для 4 сервы (и больше)... программный ШИМ. Для одной сервы - идеально аппаратный ШИМ.sashamelja писал(а):я за третий вариант,если ти согласен написать програму я все соберу и протестирую на практеке у меня все есть в наличие
Так ты определись что ты хочешь... А то я сейчас всё повыкидываю... Потом тебе не понравится))sashamelja писал(а):Что ненужно виброси что надо добавь,что хочеш поменяй
Твой катер? Для начала нормальненько))sashamelja писал(а):Вот начем я буду тестить https://www.youtube.com/watch?v=WeZfOw78zCw
Как всегда!!!!?roman.com писал(а):Такие комментарии нам очень помогают... ))) опять... ни схемы, ни алгоритма, ни описания...
Код: Выделить всё
#include <pic.h>
__CONFIG(
FCMEN_OFF & // Монитор генератора бесперебойной работы - отключен
IESO_OFF & // Функция переключателя Internal/External генератор - отключена
// Internal/External Switchover mode is disabled
CLKOUTEN_OFF & // Фунцйия CLKOUT выхода тактовой частоты на вывод генератора - отключена
// CLKOUT function is enabled. I/O or oscillator function on the CLKOUT pin
BOREN_OFF & // Сброс по понижению питания отключен
// Brown-out Reset disabled
CPD_OFF & // Защитата на паметта (EPPROM) - изключена
CP_OFF & // Защитата на програмата - изключена
MCLRE_OFF & // вывод MCLR/VPP функция RA3
PWRTE_ON & // Таймер задержки включения питания
// PWRT disabled
WDTE_OFF & // Сторожевой таймер включен в рабочем режиме, выключен в режиме сна
// WDT изключен
FOSC_INTOSC // внутрений генератор, выводы генератора используются как порты ввода вывода
//вътрешен ген. Изводите като вх/изх
);
// Fail-Safe Clock Monitor is disabled
__CONFIG(
LVP_OFF & // Низковольтное программирование отключено
BORV_25 & // Уровень сброса по понижению питания установлен на 2.5V
STVREN_OFF & // сброс по переполнению стека отключен
PLLEN_OFF & // Внутренний умножитель 4x PLL - изключен
WRT_ALL // Память программ - защищена от записи
);
//_XTAL_FREQ=16000000; //for __delay_ms();
// Register: CCPR1 ----- must be in pic16f1829.h
volatile unsigned int CCPR1 @ 0x291;
// Register: CCPR2 ----- must be in pic16f1829.h
volatile unsigned int CCPR2 @ 0x298;
#define test_
#define MASK_SI 0x58 //маска налагана върху входния сигнал за определяне дали е СИ
#define MASK_23 0xF0 //маска налагана на аналоговите данни за отхвърляне на големите разлики
//с 0xF0 две стойности с разлика до 16 ще се приемат за равни - 16uS
//unsigned char Mode;
struct {
volatile unsigned char _SiLoad:1; //получен е СИ
unsigned char _PWM4_On_PPM:1; //
unsigned char _PWM5_On_PPM:1; //
volatile unsigned char _start_2of3:1; //
volatile unsigned char _valid_data:2; //брой сгрешени СИ
volatile unsigned char free:2; //
} Mode;
#define SiLoad (Mode._SiLoad)
#define ready_in (Mode._ready_in)
#define PWM4_On_PPM (Mode._PWM4_On_PPM) //какво да се извежда PPM или PWM
#define PWM5_On_PPM (Mode._PWM5_On_PPM)
#define St2of3 (Mode._start_2of3)
#define ValidData (Mode._valid_data)
typedef struct {
unsigned char a[6]; //6 аналогови (0 - 255) команди.
unsigned char d:6; //+ 6 дискретни (цифрови)
unsigned char rx:1; //дали пакета е получен. Използва се за установяване на St2of3
unsigned char err:1; //дали пакета е маркиран като грешен
} _buff_in;
_buff_in Buff2Of3[4] @0x20; //масив от последните две приети стойности за логика 2от3
_buff_in *ToOut, // след 2of3 тук ще се укажат от къде ще се извеждат данните
*BuffIn; //указател къде ще се въвежда инфо от CCP1
_buff_in *buffarr[] = {&Buff2Of3[0],&Buff2Of3[1],&Buff2Of3[2],&Buff2Of3[3]};
volatile unsigned char BuffWork; //
volatile unsigned char cnt @0x70; //брояч за приетите
volatile unsigned char iNextPPM @0x71; //номер на текущо стартираната PPM машинка
volatile unsigned char cNextPPM @0x72; //маска на текущо стартираната PPM машинка
unsigned char Tmp;
unsigned int iTmp;
// //////////////////////////////////////////////////////////////////////
unsigned char rrrr; //използва се в ASM за прехвърляне на буферите
unsigned int rrrrr; //хептем временна променлива за тест
//unsigned char eecnt; //тестови брояч за записа в EEPROM
//unsigned char ee_old;
//unsigned int _buff_TMR1[14] @0xA0; // буфер за стойностите от CCPR1H:CCPR1L при захват
unsigned int TI ; //изчислена ширина на импулса
unsigned int PrevCCP; //предишно сработване на CCP1 - за изчисляванена TI
unsigned char dMask; //маска за дискретните команди при приемане - бягаща единица
unsigned char CheckSt2of3(void);
void toDOut(void);
//void TestStart(unsigned int);
unsigned char asm_1; // използват се
unsigned char asm_2; // в
unsigned char asm_3; // асемблерните модули
unsigned char asm_1i; // използват се в асемблерните модули
unsigned char asm_2i; // interrupt
// //////////////////////
unsigned char eecnt;
//unsigned char __tmp;
//unsigned int rcrc;
// //////////////////////
//_buff_in *BuffNext(_buff_in *); //връща следващия буфер където ще се записва
_buff_in *BuffNext(void); //връща следващия буфер където ще се записва
_buff_in *NextOut23(void); //връща следващия буфер от където ще се извежда
unsigned char check23(unsigned char ,unsigned char );
void Init(void)
{
OSCCON = 0b01111010; //16MHz
CM1CON0 = 0; //изключване на компаратор 1
CM2CON0 = 0; //изключване на компаратор 2
LATA=LATB=LATC = 0;
TRISA = 0xCB; /* 0 - вход за управление на RC6, 1 - аналог вход - цифров изход
2 - изход PPM/PWM (PWM3), 3 - вход за управление на RA2
4,5 кварц, 6 и 7 - не са реализирини в желязото */
TRISB = 0x0f; /* 4 изхода за PPM команди (4,5,6,7), 0,1,2,3 - не са реализирини в желязото*/
#ifdef test
TRISC = 0x00; /* Изходи за дискретни команди- (0,1,2,3,4,7), изход PPM/PWM - (6) Вход - (5)*/
#else
TRISC = 0x20; /* Изходи за дискретни команди- (0,1,2,3,4,7), изход PPM/PWM - (6) Вход - (5)*/
#endif
ANSELB = 0x00; //no analog input
ANSELC = 0x00; //no analog input
nWPUEN = 0; //GLOBAL enable WPU
WPUB = 0x00; //pull up
WPUC = 0x00; //pull up
/*
ANSELA = 0x02; //RA1 as analog input
ADCON1 = 0b00010000; //ляво подравнено, Fosc/8, Vref = Vdd
ADCON0 = 0b00001001; //ADC chanel 1, ADC ON
// ???? pull_up
ADGO = 1;
while (ADGO)NOP(); //вземаме инфо от AN1 (RA1)
// ще анализираме ADC_RA1 за да определим как ще се управлява PWM1/2
ADC_RA1 = ADRESH;
*/
ADCON0 = 0; //ADC OFF
TRISA = 0xC9; // RA1 става цифров изход
ANSELA = 0x00; // RA1 as digital out
WPUA = 0x09; //pull up RA0, RA3
//TMR0 - предделител 64, Fosc/4 - 4.096mS
OPTION_REG = 0b00000101;
// 16MHz --------------TMR1------------------------
T1CON = 0b00100000; // Fosc/4, прескалер 4
// 4MHz PR2 = 118;
// ще стартираме следващата PPM машинка през интервал от 3,3mS
// 4MHz T2CON = 0x31; //postscaler 7; prevscaler 4 -> 4*7*(118+1)mS = 3.3mS
// 16MHz -----------------TMR2-------------------
PR2 = 51;
T2CON = 0x7a; //postscaler 16; prevscaler 16 -> 16*16*(51 + 1)/Fosc*4 = 3.3mS
iNextPPM = 0;
cNextPPM = 0x01; //ще се стартира първата машинка
////////////
// как да се обработват PPM4/PWM0 и PPM5/PWM1
if (RA3)
PWM4_On_PPM=1;
else
PWM4_On_PPM=0;
// PWM4_On_PPM = RA3; //ако е 1 - PPM, ако е 0 - PWM
if (RA0)
PWM5_On_PPM=1;
else
PWM5_On_PPM=0;
// PWM5_On_PPM = RA0; //ако е 1 - PPM, ако е 0 - PWM
// PWM4_On_PPM = 1; //ако е 1 - PPM, ако е 0 - PWM
// PWM5_On_PPM = 1; //ако е 1 - PPM, ако е 0 - PWM
rrrrr=0;
eecnt = 0;
ValidData = 0; //нямаме сгрешени СИ
BuffWork = 3;
BuffIn = BuffNext();
// BuffIn = &Buff2Of3[3];
BuffIn ->d = 0;
BuffIn ->rx = 0;
Buff2Of3[0].rx=Buff2Of3[1].rx=Buff2Of3[2].rx= 0;
//засега мажоритарната логика няма да работи. След проемането на третия пакет се включва
St2of3 = 0;
PEIE =1;
CCP1IE = 1; //разрешаваме прекъсване при получаване на импулс на входа
TMR0IE = 1; //разрешаваме прекъсване при загуба на сигнала
CCP1CON = 0x04;
ei ();
cnt = 0;
TMR1ON = 1;
TMR1GE = 0; //старт TMR1
// test start
}
void interrupt bbb(void)
{
if (CCP1IF && CCP1IE)
{
TMR0 = 0; //допълнителна задръжка за удължаване на (евентуално) пропускания импулс (шум)
NOP(); //
NOP(); //
NOP(); //
NOP(); // 1uS
NOP(); //
NOP(); //
NOP(); //
NOP(); // 1uS
NOP(); //
NOP(); //
NOP(); //
NOP(); // 1uS
Tmp = PORTC; //вземаме текущата стойност на PORTC
asm("swapf _Tmp,f");
asm("rrf _Tmp,f"); // в младшия бит стойността на RC5
Tmp &= 0x01;
CCP1IF=0;
if (Tmp == (CCP1CON & 0x01))
{ // входа е с валидна стойност - не е шум
CCP1CON ^=1; //сменяме фронта на захвата
// _buff_TMR1[cnt] = CCPR1-PrevCCP;
TI = CCPR1-PrevCCP;
if(!SiLoad || cnt == 13)
{ //не сме приели SI или сме приели и чакаме втори SI
Tmp = TI >> 4;
Tmp = Tmp & 0x00f8 ; //Привеждане на приетото в един байт 0x05C0 => 0x5C
/*237: if ((Tmp ^ MASK_SI) == 0 ) //Приели сме СИ
0039 0840 MOVF 0x40, W
003A 3A58 XORLW 0x58
003B 1D03 BTFSS 0x3, 0x2
003C 283F GOTO 0x3f
*/
if (Tmp ^ MASK_SI )
{ //Не сме приели СИ
if(cnt == 13)
ValidData ++;
cnt = 0;
SiLoad = 0;
}
else
{ //Приели сме СИ
SiLoad = 1;
if (cnt == 13)
{ //SI след вече приет SI => приели сме пакет
ValidData = 0; ;//нямаме сгрешен СИ
cnt = 1; // после ще има cnt++;
BuffIn->rx = 1; //маркираме буфера като приет
BuffIn->d ^= 0x3f; //инвертираме дискретните. 1 при натиснат бутон
BuffIn = BuffNext();
BuffIn->rx = 0; //веднага си маркираме буфера като невалиден
BuffIn->d = 0; //и изчистваме дискретните команди
St2of3 = CheckSt2of3(); //установяваме St2of3 ako са приети 3 пакета
if (St2of3) //приети са три пакета
{
ToOut = NextOut23(); //засега
if (ToOut) // Имаме валидни данни (минали 2of3)
// какво да правим ако нямаме . Как да спреме PPM?????
{
TMR2IE= 1;
CCP2IE = 1;
TMR2ON = 1; //и пускаме PPM-а и PWM-a
ValidData = 0; //нямаме сгрешени СИ
}
else //нямаме валидна информация
{
// TMR2IE= 0;
// CCP2IE = 0;
if (ValidData ==2)
TMR2ON = 0; //и спираме PPM-а и PWM-a
}
}
}
cnt = 1; // ще следва аналогова
}
dMask = 0x01; //маска за дискретните команди
}
else
{ //имаме SI и се намираме някъде в "приемане на пакет"
if (cnt & 0x01) //нечетно - аналогов
{
// BuffIn->a[cnt /2] = (TI < 0x200)?0x00:(TI > 0x3ff)?0xFF:(TI-0x200)/2;
TI -= 0x200;
TI >>= 1;
if(TI >= 0x0100)
asm_1i = 0xff;
else if (TI & 0x8000)
asm_1i = 0x00;
else
{
asm("movf _TI,w");
asm("movwf _asm_1i");
}
BuffIn->a[cnt /2] = asm_1i;
/*
// BuffIn->a[cnt /2] = (TI < 0x200)?0x00:(TI > 0x3ff)?0xFF:(TI-0x200)/2;
#asm
movlb 0
decfsz _TI+1,f // _TI - 0x100
goto analog_cont //< 0x1ff
movlw 0
goto end_aa
analog_cont movlw 0xff
decf _TI+1,f
decfsz _TI+1,f //TI - 0x100
goto end_aa // > 0x3ff
incf _TI+1,f
lsrf _TI+1,f
rrf _TI,w //TI / 2
end_aa movwf _asm_1i
#endasm
BuffIn->a[cnt /2] = asm_1i;
*/
}
else //дискретни команди
{
// BuffIn->d |= ((_buff_TMR1[cnt] /512 ) & 0x01) << cnt /2 -1;
#asm
movlb 0
lsrf _TI+1,f //старшата част /2
movf _dMask,w
btfss _TI+1,0 //имаме ли 1
movlw 0
movwf _asm_1i
lslf _dMask,f
#endasm
BuffIn->d |= asm_1i;
/*
#asm
movlb 0
lsrf _TI+1,w //старшата част /2
andlw 0x01 // в W:0 дискретната команда
btfss WREG,Z
movwf _asm_1i //същото в _asm_1
lsrf _cnt,w
movwf _asm_2i // колко пъти трябва да го умножим
loop_ss
lslf _asm_1i,f
decfsz _asm_2i,f
goto loop_ss
lsrf _asm_1i,f //едно назад
#endasm
BuffIn->d |= asm_1i; //предварително да е нулирано
*/
}
cnt++;
}
/*
// Tmp &= 0xF8; //маскираме младшите три бита
if ((Tmp ^ MASK_SI) == 0 && cnt == 0) //Приели сме СИ
{
SiLoad = 1;
//if (_buff_TMR1[cnt] > 0x05c0) //приели сме по-широк СИ
// OSCTUNE--;
//if (_buff_TMR1[cnt] < 0x05c0) //приели сме по-тесен СИ
// OSCTUNE++;
}
if (SiLoad) //ако сме получили валиден СИ
{
if((cnt > 0) && (cnt < 0x0d))
if (cnt & 0x01) //нечетно - аналогов
{
// BuffIn->a[cnt /2] = min((_buff_TMR1[cnt] - 0x200) /2,0xff);
#asm
movlb 0
movlw __buff_TMR1
movwf fsr0l
clrf fsr0h
lslf _cnt,w //cnt*2
addwf fsr0l,f
incf fsr0l,f //на старшата част на аналогова
decf indf0,f
decf indf0,f //-0x200
lsrf indf0,f
decf fsr0l,f
rrf indf0,f //аналоговата команда /2
moviw ++fsr0 //на старшата част
btfss status,2 //zero
movlw 0xff
decf fsr0l,f
iorwf indf0,w //аналоговата команда
movwf _asm_1i
#endasm
BuffIn->a[cnt /2] = asm_1i;
}
else //дискретни команди
{
// BuffIn->d |= ((_buff_TMR1[cnt] /512 ) & 0x01) << cnt /2 -1;
#asm
movlb 0
movlw __buff_TMR1
movwf fsr0l
clrf fsr0h
lslf _cnt,w
addwf fsr0l,f
incf fsr0l,f
lsrf indf0,w
andlw 0x01 // в W:0 дискретната команда
movwf _asm_1i //същото в _asm_1
lsrf _cnt,w
movwf _asm_2i // колко пъти трябва да го умножим
loop_ss
lslf _asm_1i,f
decfsz _asm_2i,f
goto loop_ss
lsrf _asm_1i,f //едно назад
// movlw 0x3f
// xorwf _asm_1i,f //инвертираме
#endasm
BuffIn->d |= asm_1i; //предварително да е нулирано
}
cnt++;
}
if(cnt == 14) //време е пак да получим СИ
if(Tmp & MASK_SI )
{ //получили сме СИ
BuffIn->rx = 1; //маркираме буфера като приет
BuffIn->d ^= 0x3f; //инвертираме дискретните. 1 при натиснат бутон
BuffIn = BuffNext(BuffIn);
BuffIn->rx = 0; //веднага си маркираме буфера като невалиден
BuffIn->d = 0; //и изчистваме дискретните команди
St2of3 = CheckSt2of3(); //установяваме St2of3 ako са приети 3 пакета
if (St2of3) //приети са три пакета
{
ToOut = NextOut23(BuffIn); //засега
// указателя към валидната инфо е в ToOut
if (ToOut) // Имаме валидни данни (минали 2of3)
// какво да правим ако нямаме . Как да спреме PPM?????
{
TMR2IE= 1;
CCP2IE = 1;
TMR2ON = 1; //и пускаме PPM-а и PWM-a
ValidData = 0; //нямаме сгрешени СИ
}
else //нямаме валидна информация
{
// TMR2IE= 0;
// CCP2IE = 0;
if (ValidData ==2)
TMR2ON = 0; //и спираме PPM-а и PWM-a
}
}
cnt = 1; // следващия ще е 1-ви аналогов
// ready_in = 1; //заявка за прехвърляне на информацията
}
else //СИ не се е оказал на място
{
cnt = 0; //започваме от търсене на СИ
SiLoad = 0; //
ValidData++; //увеличаваме брояча на сгрешените СИ
// ready_in = 0; //
if (ValidData ==3)
{
ToOut = 0;
TMR2ON = 0; //и спираме PPM-а и PWM-a
}
}
*/
PrevCCP = CCPR1;
// if (CCP1IF) cnt = 0; //???????????????
}
}
if (CCP2IE && CCP2IF)
//ако е свършила работата на машинката стоп
{
CCP2IF = 0;
CCP2CON =0;
PORTB = 0; //спиране на всички машинки на PORTB
if (PWM4_On_PPM)RC6=0;
if (PWM5_On_PPM)RA2=0;
if(iNextPPM & 0x01)
toDOut(); //извеждаме дискретните
}
if(TMR2IE && TMR2IF)
//прекъсване на всеки 3,3mS и запуск на следващата машинка. Спирането чрез CCP2
{
TMR2IF = 0;
iTmp = TMR1 + 735;
// iTmp = TMR1 + 1000; //
// всички до 4 - се пускат; 4 и 5 се пускат само ако са PPM.
// if((iNextPPM<4) || (iNextPPM == 4 && PWM4_On_PPM) || (iNextPPM == 5 && PWM5_On_PPM))
// {
if(ToOut) //имаме валидни данни за извеждане
{
CCPR2 = iTmp; //минималния сигнал 1mS после ще добавим и останалото
CCP2CON = 0x0A; //пускане на CCP2
#asm
movlb 0
swapf _cNextPPM,w
movwf _PORTB //четирите младши бита отиват на RB7 - RB4
#endasm
if(PWM4_On_PPM && (iNextPPM ==4))RC6=1;
if(PWM5_On_PPM && (iNextPPM ==5))RA2=1;
//изчисляваме къде трябва да спре PPM-а.
//end = in*4 + in*2 + in/4 + TMR1
//би трябвало обхвата на PPM да е от .7 до 2.3mS
// iTmp = ToOut->a[iNextPPM] *6 +ToOut->a[iNextPPM] /4;
// iTmp = ToOut->a[iNextPPM] *6;
// iTmp = ToOut->a[iNextPPM] *5;
// iTmp = ToOut->a[iNextPPM] *4; //1.0 mS + ???
// if (RC0)
// CCPR2 += 6*0+ 0/4;
// else if (RC1)
// CCPR2 += 6*128+ 128/4;
// else if (RC2)
// CCPR2 += 6*255+ 252/4;
// else
iTmp =ToOut->a[iNextPPM] *6; // + ToOut->a[iNextPPM] /4;
CCPR2 += iTmp;
}
// }
iNextPPM++;
cNextPPM <<= 1;
// if (NextPPM == 4 && PWM4_On_PPM==0) NextPPM++; //ако обработката на PPM4 ще е на PWM0
// if (NextPPM == 5 && PWM5_On_PPM==0) NextPPM++; //ако обработката на PPM5 ще е на PWM1
if(iNextPPM > 5) {iNextPPM = 0;cNextPPM = 0x01;}
//NextPPM=0;
}
if(TMR0IE && TMR0IF)
{ //TMR0 е настроен да сработва на всеки 2mS.
//Ако сработи значи за това време не е постъпвал входен сигнал.
//най вероятна причина - загуба на сигнала
TMR0IF = 0;
// ToOut = 0;
//аналоговите (PPM) ще спрат всяка по свое време
//аналоговите (PWM) ????
toDOut(); //нулираме дискретните
}
}
//връща следващия буфер който ще се използва за въвеждане от CCP
//_buff_in *BuffNext(_buff_in *ex)
_buff_in *BuffNext(void)
{
BuffWork ++;
BuffWork &= 0x03;
return (buffarr[BuffWork]);
/*
if(ex == &Buff2Of3[3])
return(&Buff2Of3[0]);
else
return(ex+1);
*/
}
unsigned char CheckSt2of3(void)
//проверяваме дали и трите пакета в Buff2Of3 са приети.
//Ако да - вдигаме си флага St2Of3 с което разрешаваме работата на мажоритарната логика
{
// unsigned char ret;
asm_2 = sizeof(_buff_in);
// asm_1 = Buff2Of3[0].rx + Buff2Of3[1].rx + Buff2Of3[2].rx + Buff2Of3[3].rx;
#asm
movlw _Buff2Of3
addlw 6 //отстъп до .rx
movwf fsr0l // в fsr0 (indf0) Buff2Of3
movlw _asm_1
movwf fsr1l // в fsr1 (indf1) asm_1
clrf indf1,f //
btfsc indf0,6
incf indf1,f //if (Buff2Of3[0].rx == 1) asm_1++;
movf _asm_2,w //sizeof(_buff_in)
addwf fsr0l,f
btfsc indf0,6
incf indf1,f //if (Buff2Of3[1].rx == 1) asm_1++;
movf _asm_2,w //sizeof(_buff_in)
addwf fsr0l,f
btfsc indf0,6
incf indf1,f //if (Buff2Of3[2].rx == 1) asm_1++;
movf _asm_2,w //sizeof(_buff_in)
addwf fsr0l,f
btfsc indf0,6
incf indf1,f //if (Buff2Of3[3].rx == 1) asm_1++;
movf indf1,w
movwf _asm_1
#endasm
return (asm_1>2);
}
//извеждане на информацията на изходите на МК
void toDOut(void)
{
// дискретни
if (ToOut)
rrrr = ToOut->d;
else
rrrr = 0; //загуба на връзка, лоши пакети и др.
// задачата е да преместим бит 5 на позиция 7 - 0b001xxxxx да стане 0b100xxxxx
#asm
movlb 0
movlw 0x80
btfss _rrrr,5
movlw 0x00
iorwf _rrrr,f
movlw 0xdf;
andwf _rrrr,w
movwf _PORTC ,f
#endasm
//PPM се извежда в прекъсването TMR2 CCP2
return;
}
//връща 0 - при неравенство на структурите и 1 - при равенство
//за равни се приемат структури с равенство на дискретните части и
//равенство на старшите части на аналоговата част.
//Аналоговата част се "маскира" с маска MASK_23
//Чрез нея стойностите 0x57 и 0x5a ще са равни
//(0x57 & 0xf0) ^ (0x5a & 0xf0) = 0x00
//допустимата разлика е до 16 uS +/- 8uS
unsigned char check23(unsigned char s1,unsigned char s2)
{ // 137 машинни инструкции ASM
// 215 машинни инструкции C
// asm_1 = (unsigned char)&(Buff2Of3[s1].a[0]);
// asm_2 = (unsigned char)&(Buff2Of3[s2].a[0]);
asm_1 = (unsigned char)(buffarr[s1]->a[0]);
asm_2 = (unsigned char)(buffarr[s2]->a[0]);
asm_3 = MASK_23;
#asm
movf _asm_1,w
movwf fsr0l //*n
clrf fsr0h
movf _asm_2,w
movwf fsr1l //*n
clrf fsr1h
movlw 6
addwf fsr0l
addwf fsr1l //на ->d - дискретните
// i = (*(n+6) & 0x3f) ^ (*(v+6) & 0x3f); //цифровата част - десните 6 бита
movf indf0,w
andlw 0x3f
movwf _asm_1 // (n+6) & 0x3f
movf indf1,w
andlw 0x3f // W = (v+6) & 0x3f
xorwf _asm_1,f // (n+6) & 0x3f ^ (v+6) & 0x3f
btfss status,2 //zero ?
goto check23_exit
//дискретните са равни => продължаваме
// for(a1=0;asm_1==0 && a1<6;a1++)
movlw 6
subwf fsr0l
subwf fsr1l //връщаме се в началото на масивите
movwf _asm_2 //ще въртиме за 6 променливи
// asm_1 = (*n++ & MASK_23) ^ (*v++ & MASK_23);
check23_loop
moviw fsr0++
andwf _asm_3,w //MASK_23
movwf _asm_1 // (n+x) & 0xf0
moviw fsr1++
andwf _asm_3,w //MASK_23
xorwf _asm_1,f // (n+6) & 0x3f ^ (v+6) & 0x3f
btfss status,2 //zero ?
goto check23_exit
decfsz _asm_2
goto check23_loop
check23_exit
#endasm
return(!asm_1);
/*
// горното на С
unsigned char a1,*n,*v;
unsigned char i;
n = &(Buff2Of3[s1].a[0]);
v = &(Buff2Of3[s2].a[0]);
i = (*(n+6) & 0x3f) ^ (*(v+6) & 0x3f); //цифровата част - десните 6 бита
for(a1=0;i==0 && a1<6;a1++)
i += (*n++ & MASK_23) ^ (*v++ & MASK_23);
return(!i);
*/
}
//връща указател към структура от където ще се извежда информацията
//изключва се ex структурата - обикновенно там се въвежда инфо от CCP
//останалите структури се подлагат на мажоритарно решение от къде ще се извежда инфото
_buff_in *NextOut23()
{ //231 машинни цикъла
unsigned char a1,a2;
for(a1=0;a1<3;a1++)
{
if(BuffWork == a1)
continue;
for(a2=a1+1;a2<4;a2++)
{
if( BuffWork == a2)
continue;
if(check23(a1,a2))
return(buffarr[a2]);
}
}
return(0); //да се проверява при използване
/*
for(a1=0;a1<3;a1++)
{
if(ex == buffarr[a1])
continue;
for(a2=a1+1;a2<4;a2++)
{
if(ex == buffarr[a2])
continue;
if(check23(a1,a2))
return(buffarr[a2]);
}
}
return(0); //да се проверява при използване
*/
}
void TestStart(unsigned int delay)
{
#ifdef test
TMR1 = delay + CCPR1;
RC5 = !((CCP1CON ^ 0x01) & 0x01); //педизвиква CCP1IF =1;
#else
asm("nop");
#endif
return;
}
void main(void)
{
// Register: CCPR1 ----- must be in pic16f1829.h
// volatile unsigned int CCPR1 @ 0x291;
#asm
movlb 0 //bank 0
movlw high (_CCPR1) // in bank 5
movwf fsr0h
movlw low(_CCPR1) // in bank 5
movwf fsr0l
moviw fsr0++
// store movwi fsr1++ // must be set
//store movwf ____
moviw fsr0++
// store movwi fsr1++
#endasm
Init();
// test(); //external .as file
/*
Buff2Of3[0].a[0] = 0xef;
Buff2Of3[0].a[1] = 0xee;
Buff2Of3[0].a[2] = 0xed;
Buff2Of3[0].a[3] = 0xec;
Buff2Of3[0].a[4] = 0xeb;
Buff2Of3[0].a[5] = 0xea;
Buff2Of3[0].d = 0x39; //d
Buff2Of3[0].rx = 1; //rx
Buff2Of3[1].a[0] = 0xef;
Buff2Of3[1].a[1] = 0xee; // normal
//Buff2Of3[1].a[1] = 0xe8; //?? min err
//Buff2Of3[1].a[1] = 0xce; //big err
Buff2Of3[1].a[2] = 0xed;
Buff2Of3[1].a[3] = 0xec;
Buff2Of3[1].a[4] = 0xeb;
Buff2Of3[1].a[5] = 0xea;
Buff2Of3[1].d = 0x39; //d
Buff2Of3[1].rx = 1; //rx
Buff2Of3[2].a[0] = 0xef;
Buff2Of3[2].a[1] = 0xee;
//Buff2Of3[2].a[1] = 0xfe; //big err
Buff2Of3[2].a[2] = 0xed;
Buff2Of3[2].a[3] = 0xec;
Buff2Of3[2].a[4] = 0xeb;
Buff2Of3[2].a[5] = 0xea;
Buff2Of3[2].d = 0x39; //d
Buff2Of3[2].rx = 1; //rx
Buff2Of3[3].a[0] = 0xef;
Buff2Of3[3].a[1] = 0xee;
//Buff2Of3[3].a[1] = 0xfe; //big err
Buff2Of3[3].a[2] = 0xed;
Buff2Of3[3].a[3] = 0xec;
Buff2Of3[3].a[4] = 0xeb;
Buff2Of3[3].a[5] = 0xea;
Buff2Of3[3].d = 0x39; //d
Buff2Of3[3].rx = 1; //rx
*/
/*
//RC2=BuffNew->d & 0x04?1:0;
_buff_TMR1[1] = 0x0200;
_buff_TMR1[2] = 0x0300; //d 1
_buff_TMR1[3] = 0x0200;
_buff_TMR1[4] = 0x0180; //d 0
_buff_TMR1[5] = 0x0300;
_buff_TMR1[6] = 0x0180; //d 0
_buff_TMR1[7] = 0x0280;
_buff_TMR1[8] = 0x0180; //d 0
_buff_TMR1[9] = 0x02c0;
_buff_TMR1[10] = 0x0300; //d 1
_buff_TMR1[11] = 0x0300;
_buff_TMR1[12] = 0x0300; //d 1
//_buff_TMR1[1] >>=1;
/*
ToOut = &Buff2Of3[1];
Buff2Of3[0].d=Buff2Of3[1].d=Buff2Of3[2].d=0;
BuffIn = &Buff2Of3[3];
ToOut =NextOut23(BuffIn);
*/
#ifdef test
RC5 =1;
TMR1 = CCPR1 = 0;
TestStart(0x0180);
TestStart(0x05C0); //SI
#endif
do{
#ifdef test
TestStart(0x02A1); //A0 0x51
TestStart(0x02D2); //d0 1
TestStart(0x03A3); //A1 0xd2
TestStart(0x02D4); //d1 1
TestStart(0x03A5); //A2 0xd3
TestStart(0x0300); //d2 1
TestStart(0x03A7); //A3 0xd4
TestStart(0x0188); //d3 0
TestStart(0x02A9); //A4 0x55
TestStart(0x018a); //d4 0
TestStart(0x03Ab); //A5 0xd6
TestStart(0x02fc); //d5 1 = 0x27 => !0x27 = 0x18
TestStart(0x05C0); //SI
#endif
NOP();
NOP();
}while(1);
}
Видали... дальше что? Ну если всё настролько просто, то взял бы и сделал ... Накидай по быстрому программку под мегу и данный модуль. Какие проблемы? )) Ты лучше ответь.. ты делать будешь или опять пришёл от нечего делать просто языком почесать?))botchin писал(а):На предъдущей странице есть файл Algol.png. Да и сама идея настолько простая, что мне стъдно обсуждать ее.
Ну тогда не понятно что мы тут вообще тогда обсуждаем... в теме "Радиоуправлениe на модулях nRF24L01+"...botchin писал(а):botchin читает и делать не будеть. Причин две:
1. Использование nRF24L01+ и
2. Использование Мега8
Вот тут чувак (кстате с этого сайта, радиокот) предложил свою идею)) Даже видео снял))sashamelja писал(а):я все соберу и протестирую на практеке у меня все есть в наличие
Так сделай.roman.com писал(а):дальше что? Ну если всё настролько просто, то взял бы и сделал
Код: Выделить всё
list p=PIC16F873A
#include P16F873A.inc ; ; 16.000 MHz
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON& _HS_OSC &_LVP_OFF &_CPD_OFF
errorlevel -302
#define sin_ok Modes,0 ;ако сме определили синхро импулс
#define sin_fal Modes,1 ;ако е инало синхрониация и е пропаднала
#define ready_in Modes,2 ;ако е минал цял цикъл приемане и
; е запазена и синхронизацията => прехвърля buf_in в buf_r
#define stmacro_
st macro v
#ifdef stmacro
CBLOCK 0x79
mtot:2 ;за stmacro
endc
movlw v & H'FF' ;Mask to get LSB
addwf mtot+1,f
btfsc STATUS,C
incf mtot,f
movlw v >>D'08' & H'FF'
addwf mtot,f
call delay_200iS
movf mtot,w
movwf TMR1H
movwf CCPR1H
movf mtot+1,w
movwf TMR1L
movwf CCPR1L
bsf PIR1,CCP1IF
#else
nop
nop
#endif
endm
; --------------------------------------------------
CBLOCK 0x7B
W_TEMP ;storage for WREG during interrupt
STATUS_TEMP ;storage for STATUS during interrupt
PCLATH_TEMP ;storage for PCLATH during interrupt
FSR_TEMP ;storage for FSR during interrupt
Modes
endc ;0x7F
CBLOCK 0x20
CCP1_Mode ;съхраняваме режима на работа на CCP1
DigVal ;цифрови изходи
buf_r:.30 ;СИ + СП + 6 аналогови + 6 цифрови + СИ
CCP1_buf:.2 ;буфер за съхранение на CCP1
CCP1_prev:2 ;буфер за съхранение на предишната стойнист на TMR1(CCP1)
CCP1_Ti:2 ;буфер за изчислената продължителност на импулса
in_pass ;брояч на миналите приемания на информацията
CCP1_Tmp ;временна променлива за работа в CCP1
buf_CCP2:12 ;тук ще се съхранява информацията за стойностите за машинките
Calc_CCP2:2 ;изчисленото CCP2 - къде трябва да спре машинката
CCP2_pass ;за цикъла за обработка на стойностите
CCP2_tmp:2 ;временна променлива
dig_tmp ;временна промелива за цифровите сигнали
pass_ix ;брояч за указване коя машинка пускаме
PPM_ix ;указател за пуснатата машинка
TMR1HH ;натрупване на сработването на препълването на TMR1
eed ;променлива за работа с EEPROM
d1 ;ЗА ЗАКЪСНЕНИЕТО
d2
endc
org 0x0000
start
nop
goto main
nop
nop
org 0x0004
goto interrupt
main
bsf STATUS, RP0 ;bank 1
movlw b'00000111'
movwf CMCON ; компараторите - изключени
movlw 0x06
movwf ADCON1
movlw b'11000000' ;6 изхода за дискретни команди
movwf TRISA
movlw b'11000000' ;6 изхода за аналогови команди
movwf TRISB
movlw b'11111111' ;всички входове
movwf TRISC
bsf PIE1,CCP1IE ;enable interrupt CCP1
bsf PIE2,CCP2IE ;enable interrupt CCP2
;ще се пусне за първи път след приемане на пълен пакет данни
bcf PIE2,EEIE ;disable interrupt EEPROM
bcf PIE1,TMR1IE ;disable interrupt TMR1
bsf PIE1,TMR2IE ;enable interrupt TMR2
;ще се пусне за първи път след приемане на пълен пакет данни
movlw .118
movwf PR2 ; Fosc/(4*16*(118+1)*7) = 0.0033 S
movlw b'01000111' ; вкл притягащите резистори,
movwf OPTION_REG ; TMR0 с предделител 256
bcf STATUS, RP0 ;bank 0
bcf INTCON,TMR0IE ;disable interrupt TMR0
movlw b'00110001'
movwf T1CON ; TMR1 - Fosc/4, prescale 8,TMR1 включено
movlw b'00110010'
movwf T2CON ; TMR2 - Fosc/4, prescale 16*(118+1)*7,TMR2 изключено
;очаква се да предизвиква прекъсване на 3.3 mS
clrf ADCON0 ;ADC изключено
movlw b'00000100' ;
movwf CCP1_Mode ;запазваме си режима на работа на CCP1
clrf CCP1CON ;спираме CCP1
clrf CCP2CON ;спираме CCP2
bsf INTCON,PEIE ;enable interrupt's
bsf INTCON,GIE ;enable interrupt's
clrf PORTA
clrf PORTB
clrf TMR1HH
; goto end_test_start
test_start
end_test_start
movlw 1
movwf PPM_ix ;подготвяме за пускане първата машинка
bcf sin_ok ;
clrf DigVal
clrf in_pass
clrf Modes
clrf pass_ix
movf CCP1_Mode,w ;запазваме си режима на работа на CCP1
movwf CCP1CON ; Capture mode, every rising
; clrf TMR1L
; clrf TMR1H
main_loop
st 0x0a03 ;1
nop
st 0x0b03 ;1
nop
st 0x0a03 ;1
nop
st 0xab03 ;1
nop
main_2loop
st 0x09c0 ;2
nop
st 0x07c0 ;3
nop
st 0x0581 ;4
nop
st 0x0300 ;5
nop
st 0x0382 ;6
nop
st 0x0180 ;7
nop
st 0x0683 ;8
nop
st 0x0180 ;9
nop
st 0x0584 ;10
nop
st 0x0180 ;11
nop
st 0x0485 ;12
nop
st 0x0180 ;13
nop
st 0x06a6 ;14
nop
st 0x0300 ;15
nop
nop
nop
nop
nop
nop
nop
nop
goto main_2loop
interrupt
bcf INTCON, PEIE ; turn off interupts
movwf W_TEMP
swapf STATUS,w
movwf STATUS_TEMP
clrf STATUS
movf PCLATH,w ;save PCLath
movwf PCLATH_TEMP
clrf PCLATH ;assume that this ISR is in page 0
movf FSR,w
movwf FSR_TEMP
interrupt_TMR1
btfss PIR1,TMR1IF
goto interrupt_CCP2
; goto interrupt_TMR2 ; не е от TMR1
bcf PIR1,TMR1IF
incf TMR1HH,f
btfsc TMR1HH,2 ;дали имаме 4 препълвания 0.13s*4 = 0.52s
goto Stop_PPM
goto interrupt_done
Stop_PPM
bcf T2CON,TMR2ON ;TMR2 OFF - с което си спиране и машинките
bcf ready_in ;данните са невалидни
goto interrupt_done
interrupt_CCP2
btfss PIR2,CCP2IF
goto interrupt_TMR2
bcf PIR2,CCP2IF
clrf PORTB ;свършило е времето за работа на машинката
clrf CCP2CON ;и спираме CCP2
; incf eed,f
goto interrupt_done
interrupt_TMR2
btfss PIR1,TMR2IF
goto interrupt_CCP1 ; не е от TMR2
bcf PIR1,TMR2IF
; btfss T2CON,TMR2ON ;имаме ли разрешение за работа на машинките
; goto interrupt_done
movlw buf_CCP2+1
movwf FSR
bcf STATUS,C
rlf pass_ix,w
addwf FSR,f
incf FSR,f
movf INDF,w
addwf TMR1L,w
movwf CCPR2L
decf FSR,f
movf INDF,w
btfsc STATUS,C
incf INDF,w
addwf TMR1H,w
movwf CCPR2H
clrf CCP2CON
nop
nop
; incf eed,f
movlw 0x0A
movwf CCP2CON ; пускаме CCP2
;следващ индекс
incf pass_ix,f
movf pass_ix,w
sublw 6
btfsc STATUS,Z
clrf pass_ix
movf PPM_ix,w
movwf PORTB
bcf STATUS,C
rlf PPM_ix,f
movlw 0x41
btfsc PPM_ix,6
xorwf PPM_ix,f ;нулираме старшия бит и установяваме младшия
goto interrupt_done
interrupt_CCP1 ;приемане на информацията и предварителна обработка
btfss PIR1,CCP1IF
goto interrupt_done
bcf PIR1,CCP1IF
clrf CCP1CON ;изключваме CCP1
;обръщаме фронта на сработване на CCP1
movlw 1
xorwf CCP1_Mode,w
movwf CCP1_Mode
; movwf CCP1CON
;запазваме сработилото CCP1
movf CCPR1H,w ;запазваме CCPR1H:L във временна променлива CCP1_prev
movwf CCP1_buf
; btfsc STATUS,Z ;ако е 0 имаме лъжливо сработване
; goto get_tmr1
movf CCPR1L,w
movwf CCP1_buf+1
; goto CCP1_valid_data
;get_tmr1
; movf TMR1L,w
; movwf CCP1_buf+1
; movf TMR1H,w
; movwf CCP1_buf
CCP1_valid_data
movf in_pass,w
btfss STATUS,Z ;ако in_pass <> 0
goto CCP1_next
in_pass_add
goto pass_inc ; in_pass == 0
;продължаваме с обработката - in_pass е по голямо или равно на 1
CCP1_next
;да си определим продължителността на импулса
movf CCP1_prev+1,w
subwf CCP1_buf+1,w
movwf CCP1_Ti+1 ;младша част
btfss STATUS,C
decf CCP1_buf,f
movf CCP1_prev,w
subwf CCP1_buf,w
movwf CCP1_Ti ;старша част
; определили сме продължителността на импулса в Ti
; сега ще си го обработим
;1 дали е по малко от 0x100
movf CCP1_Ti,w
btfsc STATUS,Z
goto pass_0 ; ще отидем да нулираме in_pass
movlw 0x0A
subwf CCP1_Ti,w
btfsc STATUS,C
goto pass_0 ; ще отидем да нулираме in_pass
;импулса е над 0x100 и под 0xA00
;записваме го
movlw buf_r-2
movwf FSR
bcf STATUS,C
rlf in_pass,w
addwf FSR,f
incf FSR,f
movf CCP1_Ti+1,w
movwf INDF ;младша част
decf FSR,f
movf CCP1_Ti,w
movwf INDF ;старша част
;дали in_pass ==1
movlw .1
subwf in_pass,w
btfsc STATUS,Z
goto check_SI
movlw .15
subwf in_pass,w
btfss STATUS,Z
goto pass_inc
check_SI ;ако in_pass==1 или in_pass==15 ще проверяваме за СИ
;ще определяме дали е равно на СИ 0x9C0
; decf FSR,F ;вече сме го изчислили и знаем къде е
movlw 0x09
subwf INDF,w
btfss STATUS,Z
goto do_not_si
incf FSR,f
movf INDF,w
andlw 0x80
xorlw 0x80
btfss STATUS,Z ;младшата част на приетото 0x80 ли е?
goto do_not_si
;определили сме СИ
; movlw 0
; btfsc sin_ok ;дали сме имали предишен СИ
; movlw 0x0a
; movwf CCP2CON ;ако сме имали предишен СИ пускаме CCP2
movf in_pass,w
btfsc sin_ok ;дали сме имали предишен СИ
movlw 1
movwf in_pass ;ако сме имали СИ и пак го получаваме in_pass==1
movlw 0
btfss sin_ok ;ако сме имали предишен СИ
goto set_si
movf INDF,w
movwf buf_r+1
decf FSR,f
movf INDF,w
movwf buf_r
;тук ще обработим информацията за предаване на изходите
movlw 6
movwf CCP2_pass ;имаме 6 машинки
CCP2_Calc_Loop
;вземаме информацията от buf_r + CCP2_pass*4
movlw buf_r
movwf FSR
movf CCP2_pass,w
movwf CCP2_tmp
bcf STATUS,C
rlf CCP2_tmp,f
rlf CCP2_tmp,w
addwf FSR,f
decf INDF,w ;изваждаме 0х100
movwf CCP2_tmp ;съхраняваме в междинна променлива
incf FSR,f
movf INDF,w
movwf CCP2_tmp+1
; подготвяме buf_CCP2+CCP2_pass*2
movlw buf_CCP2
movwf FSR
bcf STATUS,C
rlf CCP2_pass,w
addwf FSR,f
movf CCP2_tmp+1,w
movwf INDF ;и записваме
decf FSR,f
movf CCP2_tmp,w
movwf INDF ;и записваме
decfsz CCP2_pass,f
goto CCP2_Calc_Loop
; и цифровите команди
movlw 6
movwf CCP2_pass ;имаме 6 машинки
clrf dig_tmp
movlw buf_r+8
movwf FSR
movf CCP2_pass,w
movwf CCP2_tmp
bcf STATUS,C
rlf CCP2_tmp,f
rlf CCP2_tmp,w
addwf FSR,f
decf FSR,f
decf FSR,f
dig_Calc_Loop
movlw 4
subwf FSR,f
decf INDF,w
bcf STATUS,C
btfss STATUS,Z
bsf STATUS,C
rlf dig_tmp,f
decfsz CCP2_pass,f
goto dig_Calc_Loop
movf dig_tmp,w
movwf DigVal ;прехвърляме стойността в реалния буфер
movwf PORTA ;и на PORTA
bsf STATUS, RP0 ;bank 1
bsf PIE1,TMR1IE ;enable interrupt TMR1
bcf STATUS, RP0 ;bank 0
clrf TMR1HH ;изчистване на променливата за натрупване на прекъсванията
btfsc ready_in
goto set_si ;избягваме повторно предизвикване на прекъсване
bsf ready_in ;минал е цял цикъл приемане и е запазена синхронизацията
bsf T2CON,TMR2ON ;TMR2 On
; bsf PIR1,TMR2IF ;и предизвикваме прекъсване по TMR
; call WriteEE
set_si
bsf sin_ok
goto pass_inc
do_not_si
pass_0
; clrf CCP2CON ;спираме CCP2
clrf in_pass
bcf sin_ok ;нямаме минал СИ
bcf ready_in ;нямаме валидна информация
pass_inc
incf in_pass,f
movf CCPR1H,w ;запазваме CCPR1H:L във временна променлива CCP1_prev
movwf CCP1_prev
movf CCPR1L,w
movwf CCP1_prev+1
movf CCP1_Mode,w
movwf CCP1CON
; goto interrupt_done
interrupt_done
movf FSR_TEMP,w
movwf FSR
movf PCLATH_TEMP,w
movwf PCLATH
swapf STATUS_TEMP,w
movwf STATUS
swapf W_TEMP,f
swapf W_TEMP,w
bsf INTCON,PEIE ;enable interrupt's
retfie
#ifdef stmacro ;само ако се използва st
delay_200iS
;798 cycles
movlw 0x9F
movwf d1
movlw 0x01
movwf d2
Delay_0
decfsz d1, f
goto $+2
decfsz d2, f
goto Delay_0
;2 cycles
goto $+1
return
#endif
Delay_19k ;19968 cycles
;19968 cycles
movlw 0x99
movwf d1
movlw 0x10
movwf d2
Delay_19k_loop
decfsz d1, f
goto $+2
decfsz d2, f
goto Delay_19k_loop
return
WriteEE ;зациклено е
; bsf PORTA,0
movlw .51
movlw 0x33
movwf eed
btfsc Modes,3
goto Write_exit
movlw 0x20
; movlw wcb
movwf FSR ;source
bsf STATUS,RP1 ;bank 2
movlw 0x00 ;0x2100
movwf EEADR
bsf STATUS,RP0 ;bank 3
bcf EECON1, EEPGD ; ще записваме в EEPROM
bcf INTCON,GIE ;малко да спрем прекъсванията
bsf EECON1,WREN ;разрешаваме записа
bcf STATUS,RP0 ;bank 2
write_loop
movf INDF,w
movwf EEDATA
bsf STATUS,RP0 ;bank 3
; btfsc EECON1,WR
; goto $-1
;задължителния код
movlw 0x55
movwf EECON2
movlw 0xAA
movwf EECON2
bsf EECON1,WR ;write
;край задължителния код
btfsc EECON1,WR
goto $-1
nop
; bcf EECON1,WREN ;разрешаваме записа
bcf STATUS,RP0 ;bank 2
incf FSR,f
incf EEADR,f
decfsz eed,f
goto write_loop
bsf STATUS,RP0 ;bank 3
bcf EECON1,WREN ;разрешаваме записа
bcf STATUS,RP0 ;bank 0
bcf STATUS,RP1 ;bank 0
bcf PIR2,EEIF
bsf INTCON,GIE ;малко да пуснем прекъсванията
bsf Modes,3
bcf INTCON,PEIE ;disable interrupt's
nop
nop
goto $-2
Write_exit
return
;EEPROM данни
ORG 0X2100
AN_Cor de 0x00,0x01,0x02,0x03
end
/*
Примите под внимание наличе макроса stmacro. Он сделан для подстройки программъ в тестовом режиме.
Имейте в виду, что с WriteEE въхода нет. Она замкнута на себе. Тоже для тестовъх режимов - просмотр изменение длинъ даннъх при реальнъх работ.
Давни делал. Ета версия кажется с 2013г.
*/
По етой методике у меня 3 или 4 варианта. Включая и последнего (с пред. поста) которъй еще не работал в "жизни" - да и вряд ли заработает. Так, я-то делал и если все будет хорошо и буду делать, а вот тебе кроме линейнъх алгоритмов видно ничего другое не подвластно.roman.com писал(а):ты делать будешь
Дополни имя темъ и только про меги. С императивнъм тоном. Можно "и только про roman.com".roman.com писал(а):"Радиоуправлениe на модулях nRF24L01+"...
ясно)) Тогда рисуем схему... Бедем тестить)) А паять на чём и как ?sashamelja писал(а): 1 ATmega8 TQFP
2 стабильная рабора радио связи(без потери соединения)
3 одна серва на руль,
3.1 управление мотором как у масика шим+реверс,
4 четыри кнопки (виезд лотка,заезд лотка,свет,ехолот)
5 индикацыя проблем(потоп,перегрев,уровень сьвязі,батарея корабля+пульта)
можно... Только показания индикатора будет не точными.. Хотя можно сделать разную частоту мигания диодов))sashamelja писал(а):переделай индикацыю,я незнаю как это зделать по пинам лутше