Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

Как да го направя с CCS !?!
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=542
Страница 1 от 1

Автор:  forest_gump [ Пет Апр 01, 2005 8:51 pm ]
Заглавие:  Как да го направя с CCS !?!

Въпросът е към корифеите на CSS, започнах проект със pic16f873@16Mhz, и компилатор CSS /версията от линка на Тони, благодарско за което/, хем да понауча т'ва Ц и аз де,... та имам поредица от 28 такта с честота 1Khz появяваща се през 30Hz, всеки заден фронт указва кога да се прочете друг сигнал по друга жица, пика трябва да прочете 28-те бита и да ги групира по 4 и ги покаже като 7 ASCII символа през rs-232 .. и т.н., аз го направих със прекъсване INT-RB0 към тактовия сигнал и в прекъсването сложих ...
авеее ето кода :
Код:
#use fixed_io(a_outputs=PIN_A4)
#use fixed_io(b_outputs=PIN_B2)
#use standard_io(C)
#define  pwr_led  PIN_A4      // blinking power led
#define  in       PIN_C0      // PIN_C0 is an input
#define  step_out PIN_B2      // PIN_B2 is an output for control
//*** variables ***
static int16 line_num;
int1  pin_stat;
byte  lambda [9];
#locate  lambda=0x50
static int16 counter, delay_count;
#locate  counter = 0x70
#locate  delay_count = 0x73
static int  bptr, bptrdiv;
#locate  bptrdiv=0x7c
#locate  bptr=0x7d
int save_status;
#locate save_status=0x7e
int save_w;
#locate save_w=0x7f
#byte status=3
#bit zero_flag = status.2
#bit t0if = 0xb.2
#bit  intf   = 0x00b.1  //intcon register . intf R=0
#bit  intedg = 0x081.6  //option register . intedg 1=rising 0=faliing R=1

//#INT_GLOBAL
#INT_EXT noclear
void isr()  {
   #asm
   //store current state of processor
   MOVWF save_w
   SWAPF status,W
   BCF   status,5
   BCF   status,6
   MOVWF save_status
   // Save anything else your code may change
   // You need to do something with PCLATH if you have GOTOs

   // remember to check to see what interrupt fired if using more than one!!

   // code for isr
   CLRF  delay_count
   INCF  counter,F
   BTFSC zero_flag
   INCF  (&counter+1),F
   #endasm
   
   if(bptrdiv == 4){
      bptr++;
      if(bptr == 3) bptr++;    //avoiding overwrite '.' sign
      bptrdiv=0;
   }
   delay_us(50);
   if (bptr <= 8)shift_left(&lambda[bptr],1,input(in));
   bptrdiv++;

   #asm
   BCF   intf  //reenable intr
   // restore processor and return from interrupt
   SWAPF save_status,W
   MOVWF status
   SWAPF save_w,F
   SWAPF save_w,W
   #endasm
}

void cpl_pwr_led(){

   if ( pin_stat == 1 ){
      output_bit(pwr_led,0);
      pin_stat=0;
    }
   else{
      output_bit(pwr_led,1);
      pin_stat=1;
    }
}

void main(){
int i,j,k;
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);

   printf("Let's play rock and roll !\r");
   counter = 0;
   bptr = 0;
   bptrdiv =0;

   for (i=0; i<9; i++)
     if (i == 3 ) lambda[i]='.';
     else lambda[i]=0;

   intedg = false;  //int0 to falling edge
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);

   while (TRUE) {
      while( delay_count != 0 );  // waith for first counter clear
      while( delay_count != 6 ){  // waith for intrs pause >= 18ms
         delay_ms(3);
         delay_count++;
      }

      cpl_pwr_led();

      printf("%5lu ",line_num);
      printf("bits: %5lu LAMBDA : ",counter);
      printf("%U",lambda[0]);
      printf("%C",' ');
      printf("%U",lambda[1]);
      printf("%C",' ');
      printf("%U",lambda[2]);
      printf("%C",' ');
      printf("%C", lambda[3]); //this is a '.' sign
      printf("%C",' ');
      printf("%U",lambda[4]);
      printf("%C",' ');
      printf("%U",lambda[5]);
      printf("%C",' ');
      printf("%U",lambda[6]);
      printf("%C",' ');
      printf("%U",lambda[7]);
      putc(13);
      putc(10);
      line_num++;
      counter = 0;
      bptr = 0;
      bptrdiv = 0;
      for (i=0; i<9; i++)
        if (i == 3 ) lambda[i]='.';
        else lambda[i]=0;
   }
}

това нещо работи дава си някакви данни, там е работата че незнам дали данните са верни , и няма как да ги проверя или сравня , на пръв поглед са логични ...но Хмм!!!!, въпросът е - има ли друг начин да се направи това със CCS-а ,
Код:
int1 asciibuffer[28]; // нее възможно нали?

Автор:  ToHu [ Пет Апр 01, 2005 10:18 pm ]
Заглавие: 

Хм .. не съм пробвал масив от int1 ..... може и да го приеме компилатора .....
но не схванах какво точно искаш да направиш .....

Автор:  Predator_MF [ Съб Апр 02, 2005 10:00 am ]
Заглавие: 

Aбе има няколко неща дето са ти в излишък...
Код:
   #asm
   //store current state of processor
   MOVWF save_w
   SWAPF status,W
   BCF   status,5
   BCF   status,6
   MOVWF save_status
   // Save anything else your code may change
...
   #asm
   BCF   intf  //reenable intr
   // restore processor and return from interrupt
   SWAPF save_status,W
   MOVWF status
   SWAPF save_w,F
   SWAPF save_w,W
   #endasm

Тия редове въобще не са ти нужни, компилатора си ги дроби сам. Превключване на банки също не е нужно да правиш. Определено не можеш да направиш масив от битове, ще трябва да се мъчиш с цели байтове...

Автор:  forest_gump [ Съб Апр 02, 2005 10:20 am ]
Заглавие: 

Хищник, това със "#asm" в прекъсването го копнах от хелпа на CCS-а без да разсъждавам щото прочетох че, така било по правилата за ISR-функция, изглеждаше ми логично да се пази statusa в стек.
ТоНи, искам да прочета поредица от 28 бита тактувани от тактов сигнал нещо като SPI само че само в една посока аз съм slave в случая, после тези 28 бита да ги групирам по четири и да ги покажа като ASCII през RS-а на пика!

Автор:  Predator_MF [ Съб Апр 02, 2005 10:34 am ]
Заглавие: 

Ами доста ме озадачаваш с това "копнах го от хелпа". Досега съм написал доста работещи неща на CCS, без да имам такива редове в прекъсванията, та ми е трудно да си обясня как въобще работят щом не пазя "жизнено важните" регистри....
Иначе ето тук ми се вижда малко оплескано:
Код:
shift_left(&lambda[bptr],1,input(in));


В хелпа на CCS също пише за shift_left/right:
Цитат:
address is a pointer to memory, bytes is a count of the number of bytes to work with, value is a 0 to 1 to be shifted in.

Значи ако ще shift-ваш нещо в променлива, пишеш:
Код:
shift_left(&променливата,колко байта ще се мести, 1 или 0);


В твоя случай lambda[bptr] ти е "pointer to memory", затова ти предлагам да го напишеш:
Код:
shift_left(lambda[bptr],1,input(in));
.
Цялата ти задачка се свежда до един масив Lambda[4] (4*8 = 32 бита, 4 от тях няма да ползваш). Прав ли съм? :D

Автор:  forest_gump [ Съб Апр 02, 2005 12:54 pm ]
Заглавие: 

Predator_MF написа:

Значи ако ще shift-ваш нещо в променлива, пишеш:
Код:
shift_left(&променливата,колко байта ще се мести, 1 или 0);


В твоя случай lambda[bptr] ти е "pointer to memory", затова ти предлагам да го напишеш:
Код:
shift_left(lambda[bptr],1,input(in));
.

това го пробвах и не работи, затова го проверих и стана ясно че трябва да е
Код:
shift_left(&lambda[bptr], 1, input(in));

ето листинга на CCS-a
Код:
//lambda[0] е със адрес 0x50 и стойност 0
....................       shift_left(&lambda[0],1,input(in));//lambda[0]=0
008A:  BSF    2E.0
008B:  MOVF   2E,W
008C:  BSF    03.5   ;status.5=1   bank #1
008D:  MOVWF  07   ;W -> TRIS C (PIN_C0 = input)
008E:  BCF    03.5   ;status.5=0   bank #0
008F:  BTFSC  07.0   ;if PIN_C0==1 goto 093
0090:  GOTO   093   ;goto 093
0091:  BCF    03.0   ;status.0=0   C=0
0092:  GOTO   094   ;goto 094
0093:  BSF    03.0   ;status.0=1   C=1
0094:  RLF    50,F   ;RAM addr(0x50) = RAM addr(0x50) << C

//lambda[0] е със адрес 0x50 и стойност 0
....................       shift_left(lambda[0],1,input(in));//lambda[0]=0
008A:  BSF    2E.0
008B:  MOVF   2E,W
008C:  BSF    03.5   ;status.5=1   bank #1
008D:  MOVWF  07   ;W -> TRIS C (PIN_C0 = input)
008E:  BCF    03.5   ;status.5=0   bank #0
008F:  BTFSC  07.0   ;if PIN_C0==1 goto 093
0090:  GOTO   093   ;goto 093
0091:  BCF    03.0   ;status.0=0   C=0
0092:  GOTO   094   ;goto 094
0093:  BSF    03.0   ;status.0=1   C=1
0094:  MOVF   50,W   ;W=lambda[0]
0095:  MOVWF  04   ;FSR=lambda[0]
0096:  RLF    00,F   ;RAM addr(0x00) = { RAM addr(0x00) } << C

значи във първия ротацията е в lambda[0] а във втория случай прави ротация във INDF интересно защо не заби пика но нищо не излезе през RS-a, или аз греша нещо ....Хммм.?!?

Автор:  ToHu [ Съб Апр 02, 2005 2:13 pm ]
Заглавие: 

Ами ... ето това ти е в прекъсването
#INT_RB
B0_IRS()
{
shift_right(&data,4,input(in));
}

като data ти е масив или struct :
struct {
byte byte_0;
byte byte_1;
byte byte_2;
byte byte_3;
} data;

естествено вече трябва да си предвидиш кога си нулираш данните, това е само шифтването на данните в масива или структурата.

Автор:  [ Съб Апр 02, 2005 6:44 pm ]
Заглавие: 

Вектора на прекъсване при CCS по е по-тромав отколкото ако използвате стандартната конструкция на МикроЧип, а все пак прекъсванията трябва да заемат минимално процесорно време, затова от години използвам следната конструкция:
[code]
#RESERVE 0x7C,0x7D,0x7E,0x7F
#RESERVE 0xFC,0xFD,0xFE,0xFF
#BYTE Wtemp=0x7C
#BYTE STATUStemp=0x7D
#BYTE PCLATHtemp=0x7E
#BYTE FSRtemp=0x7F

#INLINE
void PushOntoStack(void)
{
#asm
movwf Wtemp
swapf STATUS,W
clrf STATUS
movwf STATUStemp
movf PCLATH,W
movwf PCLATHtemp
clrf PCLATH
movf FSR,W
movwf FSRtemp
#endasm
}

#INLINE
void PopFromStack(void)
{
#asm
clrf STATUS
movf FSRtemp,W
movwf FSR
movf PCLATHtemp,W
movwf PCLATH
swapf STATUStemp,W

movwf STATUS
swapf Wtemp,F
swapf Wtemp,W
// retfie тази инструкция е излишна, CCS си слага негова
#endasm
}

void Tmr0Service(void);

#INT_GLOBAL
void InterruptHandler(void)
{
GIE = 0;
PushOntoStack();
if( T0IF )
Tmr0Service();
PopFromStack();
}

void Tmr0Service(void)
{
// някакъв код ....
}
[/code]

Автор:  Predator_MF [ Нед Апр 03, 2005 1:37 pm ]
Заглавие: 

forest_gump написа:
значи във първия ротацията е в lambda[0] а във втория случай прави ротация във INDF интересно защо не заби пика но нищо не излезе през RS-a, или аз греша нещо ....Хммм.?!?


При мен е точно обратното, твоя вариант не работи (затова имах доста ядове върху тоя ред). В моя случай наистина върти INDF (след като променливата се помести там де) , но при мен само така тръгва...

Автор:  forest_gump [ Пон Апр 04, 2005 6:02 pm ]
Заглавие: 

Днес си поиграх доста и го проверих на практика, направих едно пикче да подава поредица от 28 бита последователно и тактов сигнал , пуснах на изхода му стринга "1234567", оказа се че правилно чете само когато е
Код:
shift_left(&lambda[bptr],1,input(in));

без '&' дава някакви маймуни, щом работи не пипам повече, ама ми е много чудно тоя компилатор CCS-a или хелпа му е объркан или аз него разбирам правилно.

Автор:  Predator_MF [ Пон Апр 04, 2005 6:04 pm ]
Заглавие: 

Абе съмнителна работа, няма да споря щом работи :) Иначе съм готов да си пейстна целия код за 18F452 да видиш как съм го написал (на поне 20 места имам shift_) и работи 8)

Автор:  forest_gump [ Пон Апр 04, 2005 8:09 pm ]
Заглавие: 

ToHu написа:
Ами ... ето това ти е в прекъсването
#INT_RB
B0_IRS()
{
shift_right(&data,4,input(in));
}

като data ти е масив или struct :
struct {
byte byte_0;
byte byte_1;
byte byte_2;
byte byte_3;
} data;

естествено вече трябва да си предвидиш кога си нулираш данните, това е само шифтването на данните в масива или структурата.

ТоНи, това работи също, само съм добавил проверка за извикване на shift_left не повече от 28 пъти преди да прочета данните , става и със масив вместо struct:
Код:
byte data[4];
#locate data =0x50;
;

Автор:  ToHu [ Пон Апр 04, 2005 9:41 pm ]
Заглавие: 

Да това рабти със сигурност, така чета 1-Wire на далас, интересно като даваш по горе само един байт да ротейтва как работи, акто сложиш 4 то ги върти последователн ои така става истинското шифтване, а като пишеш 1, върти само първия .....а иначе да , работи и с масив

Автор:  forest_gump [ Вто Апр 05, 2005 9:34 pm ]
Заглавие: 

ТоНи, със 4-ри байта за шифтване е същото като
Код:
shift_left(&byte_3, 1, shift_left(&byte_2, 1, shift_left(&byte_1, 1, shift_left(&byte_0, 1, input(in)))));

Хмм ,.... голяма манджа стана :-)

Страница 1 от 1 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/