Отговори на тема  [ 14 мнения ] 
Как да го направя с CCS !?! 
Автор Съобщение
Ранг: Професионалист
Ранг: Професионалист
Аватар

Регистриран на: Сря Окт 13, 2004 11:24 pm
Мнения: 500
Местоположение: Стара Загора
Мнение Как да го направя с 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]; // нее възможно нали?


Пет Апр 01, 2005 8:51 pm
Профил YIM
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 9:21 pm
Мнения: 30684
Местоположение: София
Мнение 
Хм .. не съм пробвал масив от int1 ..... може и да го приеме компилатора .....
но не схванах какво точно искаш да направиш .....


Пет Апр 01, 2005 10:18 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Окт 07, 2004 1:22 pm
Мнения: 1949
Местоположение: София
Мнение 
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

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


Съб Апр 02, 2005 10:00 am
Профил
Ранг: Професионалист
Ранг: Професионалист
Аватар

Регистриран на: Сря Окт 13, 2004 11:24 pm
Мнения: 500
Местоположение: Стара Загора
Мнение 
Хищник, това със "#asm" в прекъсването го копнах от хелпа на CCS-а без да разсъждавам щото прочетох че, така било по правилата за ISR-функция, изглеждаше ми логично да се пази statusa в стек.
ТоНи, искам да прочета поредица от 28 бита тактувани от тактов сигнал нещо като SPI само че само в една посока аз съм slave в случая, после тези 28 бита да ги групирам по четири и да ги покажа като ASCII през RS-а на пика!


Съб Апр 02, 2005 10:20 am
Профил YIM
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Окт 07, 2004 1:22 pm
Мнения: 1949
Местоположение: София
Мнение 
Ами доста ме озадачаваш с това "копнах го от хелпа". Досега съм написал доста работещи неща на 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


Съб Апр 02, 2005 10:34 am
Профил
Ранг: Професионалист
Ранг: Професионалист
Аватар

Регистриран на: Сря Окт 13, 2004 11:24 pm
Мнения: 500
Местоположение: Стара Загора
Мнение 
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, или аз греша нещо ....Хммм.?!?


Съб Апр 02, 2005 12:54 pm
Профил YIM
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 9:21 pm
Мнения: 30684
Местоположение: София
Мнение 
Ами ... ето това ти е в прекъсването
#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 2:13 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Фев 25, 2005 1:58 pm
Мнения: 4585
Местоположение: US
Мнение 
Вектора на прекъсване при 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]


Последна промяна на Съб Яну 28, 2012 11:32 am, променена общо 2 пъти



Съб Апр 02, 2005 6:44 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Окт 07, 2004 1:22 pm
Мнения: 1949
Местоположение: София
Мнение 
forest_gump написа:
значи във първия ротацията е в lambda[0] а във втория случай прави ротация във INDF интересно защо не заби пика но нищо не излезе през RS-a, или аз греша нещо ....Хммм.?!?


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


Нед Апр 03, 2005 1:37 pm
Профил
Ранг: Професионалист
Ранг: Професионалист
Аватар

Регистриран на: Сря Окт 13, 2004 11:24 pm
Мнения: 500
Местоположение: Стара Загора
Мнение 
Днес си поиграх доста и го проверих на практика, направих едно пикче да подава поредица от 28 бита последователно и тактов сигнал , пуснах на изхода му стринга "1234567", оказа се че правилно чете само когато е
Код:
shift_left(&lambda[bptr],1,input(in));

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


Пон Апр 04, 2005 6:02 pm
Профил YIM
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Окт 07, 2004 1:22 pm
Мнения: 1949
Местоположение: София
Мнение 
Абе съмнителна работа, няма да споря щом работи :) Иначе съм готов да си пейстна целия код за 18F452 да видиш как съм го написал (на поне 20 места имам shift_) и работи 8)


Пон Апр 04, 2005 6:04 pm
Профил
Ранг: Професионалист
Ранг: Професионалист
Аватар

Регистриран на: Сря Окт 13, 2004 11:24 pm
Мнения: 500
Местоположение: Стара Загора
Мнение 
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;
;


Пон Апр 04, 2005 8:09 pm
Профил YIM
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 9:21 pm
Мнения: 30684
Местоположение: София
Мнение 
Да това рабти със сигурност, така чета 1-Wire на далас, интересно като даваш по горе само един байт да ротейтва как работи, акто сложиш 4 то ги върти последователн ои така става истинското шифтване, а като пишеш 1, върти само първия .....а иначе да , работи и с масив


Пон Апр 04, 2005 9:41 pm
Профил
Ранг: Професионалист
Ранг: Професионалист
Аватар

Регистриран на: Сря Окт 13, 2004 11:24 pm
Мнения: 500
Местоположение: Стара Загора
Мнение 
ТоНи, със 4-ри байта за шифтване е същото като
Код:
shift_left(&byte_3, 1, shift_left(&byte_2, 1, shift_left(&byte_1, 1, shift_left(&byte_0, 1, input(in)))));

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


Вто Апр 05, 2005 9:34 pm
Профил YIM
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 14 мнения ] 

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 2 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни