Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вопрос по Си...
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему
wasp
Прошу прощения за глупый вопрос.
Пытаюсь разобраться с программой для РIС(пример передачи пакета данных для RF-модуля FSK-передатчика http://www.hoperf.com/pdf/RF02B.pdf ).
Сама программка находится здесь: http://www.hoperf.com/pdf/RF02_code.pdf стр. 11-16.
И там на стр. 15 вот такой фрагмент кода:


Не подскажите зачем там эти две строчки:
........
while (!nIRQ);
while (nIRQ);
.........

что бы это значило? 05.gif
rezident
Видимо автор таким образом пытался импульс какой-то отследить, переход 0->1->0.
wasp
Цитата(rezident @ Apr 22 2008, 19:33) *
Видимо автор таким образом пытался импульс какой-то отследить, переход 0->1->0.

спасибо за быстрый ответ!
с СИ знаком поверхостно, поэтому не могу сообразить. Почему за обоими операторами стоит ";"?
То есть условие в скобках выполняется, но за этим не следует ничего... Программа переходит на следующую строку так и так.
Или я ошибаюсь?
tazik
Цитата(wasp @ Apr 22 2008, 23:46) *
спасибо за быстрый ответ!
с СИ знаком поверхостно, поэтому не могу сообразить. Почему за обоими операторами стоит ";"?
То есть условие в скобках выполняется, но за этим не следует ничего... Программа переходит на следующую строку так и так.
Или я ошибаюсь?


Синтаксис языка такой. Пока условие верно, перехода на следующую строку не происходит.

То же самое, что и while(nIRQ) {чего-то делаем}; - просто скобки опущены, т.к. во время ожидания все равно ничего не выполняется
wasp
Цитата(tazik @ Apr 22 2008, 20:02) *
Синтаксис языка такой. Пока условие верно, перехода на следующую строку не происходит.

То же самое, что и while(nIRQ) {чего-то делаем}; - просто скобки опущены, т.к. во время ожидания все равно ничего не выполняется

Вот оно что!
Ну тогда все становится на свои места, спасибо за ликбез! smile.gif
arttab
а nIRQ должны быть объявлены как изменяемые из вне. можете сами это указать, а именно эти указаны черех структуру тип регистр. так в iarе сделано.
wasp
в продолжение темы...
прошил и подключил PIC16F676, что был под рукой к передатчику RF02.
программа доходит как раз до этого места "while (!nIRQ);
while (nIRQ);"
и останавливается.
симулировал программку с пом. Протеус, если посадить на эту ногу генератор импульсов, все работает...
осциллографа под рукой нет, но видимо с RF02 не приходит этот самый пресловутый nIRQ.
в каком случае он должен генерироваться, в даташите не нашел.
да, в приведенной в даташите программе используется кварц на 10МГц, а у меня от внутреннего генератора - 4 МГц. Может от этого сбоит?

понимаю что вопрос типа "кто бы за меня разобрался?", но ничего в голову не лезет...
vank
Привет!
И мне интересует этая програма. Я покупал из Китаии RFM12BP и RFM12B. Я работаю под ассемблера и не могу разобраться с програмой на C, каторая находиться сдесь во файле RFM12B_manual.pdf стр.32-43. Можно ли кто то компилировать это програма и выслать код на ASM?
Спасибо вам!
tazik
Цитата(wasp @ Apr 26 2008, 03:07) *
в продолжение темы...
прошил и подключил PIC16F676, что был под рукой к передатчику RF02.
программа доходит как раз до этого места "while (!nIRQ);
while (nIRQ);"
и останавливается.
симулировал программку с пом. Протеус, если посадить на эту ногу генератор импульсов, все работает...
осциллографа под рукой нет, но видимо с RF02 не приходит этот самый пресловутый nIRQ.
в каком случае он должен генерироваться, в даташите не нашел.
да, в приведенной в даташите программе используется кварц на 10МГц, а у меня от внутреннего генератора - 4 МГц. Может от этого сбоит?

понимаю что вопрос типа "кто бы за меня разобрался?", но ничего в голову не лезет...


Сам не работал (.
Но судя по документации IRQn выдается при приеме очередного бита данных в том случае, если при конфигурации был установлен бит ebs. (В примере он устанавливается - RFXX_WRT_CMD(0xC220)).

Кстати, есть микросхема IA4222 - практически 1 в 1. Даже датащит совпадает
wasp
Цитата(tazik @ Apr 26 2008, 12:03) *
Сам не работал (.
Но судя по документации IRQn выдается при приеме очередного бита данных в том случае, если при конфигурации был установлен бит ebs. (В примере он устанавливается - RFXX_WRT_CMD(0xC220)).

Кстати, есть микросхема IA4222 - практически 1 в 1. Даже датащит совпадает

tazik, спасибо за ответ.
Но не совсем понятно, если IRQn выдается при приеме очередного бита данных, то как пройдет самый первый бит?
В приведенном выше фрагменте программа останавливается и ждет первого импульса IRQn.

vank, как все налажу, вышлю.
RCray
Цитата(tazik @ Apr 22 2008, 20:02) *
Синтаксис языка такой. Пока условие верно, перехода на следующую строку не происходит.

То же самое, что и while(nIRQ) {чего-то делаем}; - просто скобки опущены, т.к. во время ожидания все равно ничего не выполняется


while(nIRQ) {;}
tazik
Цитата(wasp @ Apr 28 2008, 14:18) *
Но не совсем понятно, если IRQn выдается при приеме очередного бита данных, то как пройдет самый первый бит?


Микросхема так работает, что при передаче команд, синхронизация осуществляется от сигнала SCK контроллера. А при передаче данных - от IRQn передатчика (при установленном бите ebs).

Еще в RF02.pdf на странице 16 помимо диаграмм есть фраза: "Do not send CLK pulses with TX data bits, otherwise they will be interpreted as commands".

То есть при настройке передатчика импульса IRQ и не должно быть.

Цитата
в приведенной в даташите программе используется кварц на 10МГц, а у меня от внутреннего генератора - 4 МГц. Может от этого сбоит?


Скорее всего, Вы правы и дело именно в этом. Длительность лог. 1 IRQn равна 1,6 мкс. 4МГц + PIC - получаем, что одна команда на asm (например, считывание состояния ножки) выполняется за 1мкс. А здесь программа вообще на Си - трудно гарантировать надежную фиксацию импульса. Видимо, без осциллографа не обойтись. Можно еще попробовать команду чтения статуса 0xCC00, во втором байте передатчик будет передавать свое состояние по линии IRQn, а синхронизация его передачи будет происходить от линии CLK контроллера
wasp
Цитата(tazik @ Apr 28 2008, 21:20) *
Микросхема так работает, что при передаче команд, синхронизация осуществляется от сигнала SCK контроллера. А при передаче данных - от IRQn передатчика (при установленном бите ebs).

Еще в RF02.pdf на странице 16 помимо диаграмм есть фраза: "Do not send CLK pulses with TX data bits, otherwise they will be interpreted as commands".

То есть при настройке передатчика импульса IRQ и не должно быть.
Скорее всего, Вы правы и дело именно в этом. Длительность лог. 1 IRQn равна 1,6 мкс. 4МГц + PIC - получаем, что одна команда на asm (например, считывание состояния ножки) выполняется за 1мкс. А здесь программа вообще на Си - трудно гарантировать надежную фиксацию импульса. Видимо, без осциллографа не обойтись. Можно еще попробовать команду чтения статуса 0xCC00, во втором байте передатчик будет передавать свое состояние по линии IRQn, а синхронизация его передачи будет происходить от линии CLK контроллера

Все верно 1.6 мкс при 4 МГц - нереально. Для начала надо попробовать с 10 Мгц, если не пойдет, тогда уже искать причину...

и еще раз вопрос по диаграмме.



из нее если я правильно понимаю, следует, что nIRQ включается при ebs=1, Ho после установки бита еа=1.
но какое отношение имеет этот бит к nIRQ - непонятно...
Power Management Command C000h:
tazik
Цитата(wasp @ Apr 29 2008, 02:38) *
из нее если я правильно понимаю, следует, что nIRQ включается при ebs=1, Ho после установки бита еа=1.


Давайте, наверное, перепишем следующим образом:
... nIRQ включается при ebs=1, Ho после включения усилителя мощности (бит ea)

Действительно, если усилитель передатчика отключен, то какой смысл передавать данные. По крайней мере мне так кажется. 07.gif

Еще из описания не понятно, в каком случае работает передача по FSK, а в каком - по SDI. Вроде бы, никакого переключения не делается.

Может сделать ход конем? - Поступить грубо и извращенно, удлинив IRQn с помощью интегрирующей RC цепочки? Зависит от степени азарта и нетерпения smile.gif
wasp
Цитата(tazik @ Apr 28 2008, 22:57) *
Давайте, наверное, перепишем следующим образом:
... nIRQ включается при ebs=1, Ho после включения усилителя мощности (бит ea)

Действительно, если усилитель передатчика отключен, то какой смысл передавать данные. По крайней мере мне так кажется. 07.gif

спасибо, немного прояснилось.
Цитата(tazik @ Apr 28 2008, 22:57) *
Может сделать ход конем? - Поступить грубо и извращенно, удлинив IRQn с помощью интегрирующей RC цепочки? Зависит от степени азарта и нетерпения smile.gif

нетерпение уже притупилось biggrin.gif
попробую с кварцем на 10 МГц - отпишусь smile.gif
wasp
мда, до nIRQ, как выяснилось, дело не доходит.
раздобыл осцилограф, на выводе nIRQ абсолютный ноль.
попробовал поменять программно частоту CLK (можно менять в диапазоне 1-10 МГц), безрезультатно.
держится 1 МГц - частота по умолчанию.
вывод - инициализация не проходит, а значит не выставляется бит ebs, ea как и все остальные.
поэтому и нет nIRQ.
вот код программки, может кому что в глаза бросится, буду премного благодарен.
Код
typedef unsigned char uchar;
typedef unsigned int uint;

#include <16F676.h>
#device adc=8
#FUSES NOWDT                     //No Watch Dog Timer
#FUSES HS                        //High speed Osc (> 4mhz)
#FUSES NOPROTECT                 //Code not protected from reading
#FUSES NOBROWNOUT                //No brownout reset
#FUSES NOMCLR                    //Master Clear pin used for I/O
#FUSES NOCPD                     //No EE protection
#FUSES NOPUT                     //No Power Up Timer
#FUSES BANDGAP_HIGH          
#use delay(clock=8000000)
#byte PORTC = 7
#byte PORTA = 5
#bit LED = PORTA.1
#bit SDI = PORTC.0
#bit SCK = PORTC.1
#bit nSEL = PORTC.2
#bit FSK = PORTC.3

#bit nIRQ = PORTC.4
#bit SDO = PORTC.5

void Write0( void );
void Write1( void );
void WriteCMD( uint CMD );
void RF2_Init( void );
void WriteFSKbyte( uchar DATA );

   uint ChkSum;

/*****************************************************************/

void RF2_Init( void )
{
   nSEL=1;
   SDI=1;
   SCK=0;
   FSK=0;
}

void main()
{
   ChkSum=0;
  
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_comparator(NC_NC);
   setup_vref(FALSE);
  
   SET_TRIS_C(0x30);
   SET_TRIS_A(0x0);
      LED=0;

   RF2_Init();
   WriteCMD( 0xCC00 );
   WriteCMD( 0x8B61 );
   WriteCMD( 0xA640 );
   WriteCMD( 0xD040 );
   WriteCMD( 0xC823 );
   WriteCMD( 0xC220 );
   WriteCMD( 0xC001 );

   while (1)
   {
      WriteCMD( 0xC039 );

      LED=1;
      delay_ms(100);
      LED=0;
      delay_ms(100);

      WriteFSKbyte( 0xAA );
      WriteFSKbyte( 0xAA );
      WriteFSKbyte( 0xAA );
      WriteFSKbyte( 0x2D );
      WriteFSKbyte( 0xD4 );

      WriteFSKbyte( 0x30 );
      ChkSum+=0x30;
      WriteFSKbyte( 0x31 );
      ChkSum+=0x31;
      WriteFSKbyte( 0x32 );
      ChkSum+=0x32;
      WriteFSKbyte( 0x33 );
      ChkSum+=0x33;
      WriteFSKbyte( 0x34 );
      ChkSum+=0x34;
      WriteFSKbyte( 0x35 );
      ChkSum+=0x35;
      WriteFSKbyte( 0x36 );
      ChkSum+=0x36;
      WriteFSKbyte( 0x37 );
      ChkSum+=0x37;
      WriteFSKbyte( 0x38 );
      ChkSum+=0x38;
      WriteFSKbyte( 0x39 );
      ChkSum+=0x39;
      WriteFSKbyte( 0x3A );
      ChkSum+=0x3A;
      WriteFSKbyte( 0x3B );
      ChkSum+=0x3B;
      WriteFSKbyte( 0x3C );
      ChkSum+=0x3C;
      WriteFSKbyte( 0x3D );
      ChkSum+=0x3D;
      WriteFSKbyte( 0x3E );
      ChkSum+=0x3E;
      WriteFSKbyte( 0x3F );
      ChkSum+=0x3F;

      ChkSum&=0x0FF;
      WriteFSKbyte( ChkSum );
      WriteFSKbyte( 0xAA );
      WriteCMD( 0xC001 );
      delay_ms(1000);
   }
}

/************************************************************/
void Write0( void )
{
   SDI=0;
   SCK=0;
   #asm
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP  
   NOP
   NOP
   NOP
   NOP
   #endasm
   SCK=1;
   #asm
   NOP
   #endasm
}

/****************************************************************/
void Write1( void )
{
   SDI=1;
   SCK=0;
   #asm
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   #endasm
   SCK=1;
   #asm
   NOP
   #endasm
}
/*****************************************************************/
void WriteFSKbyte( uchar DATA )
{
   uchar n=8;
   nSEL=1;
   while (n--)
      {
      while (!nIRQ);
      while (nIRQ);
      if (DATA&0x80) FSK=1;
      else FSK=0;
      DATA=DATA<<1;
      }
}
/*****************************************************************/
void WriteCMD( uint CMD )
{
   uchar n=16;
   SCK=0;
   nSEL=0;
   while (n--)
   {
      if (CMD&0x8000) Write1();
      else Write0();
      CMD=CMD<<1;
   }
   SCK=0;
   nSEL=1;

}
Сергей Борщ
Цитата(wasp @ Apr 29 2008, 23:57) *
вот код программки, может кому что в глаза бросится, буду премного благодарен
Скачал описание модуля по ссылке из первого поста. Не нашел в нем команд 0xD040, 0xC823.

Раз уж ветка по С:
1) Ээх, не любите вы себя - потратьте час, присвойте всем битам (и/или их комбинациям) осмысленные имена через #define и потом пишите WriteCMD( SET_CONFIG | BAND_433 | CLK_2MHZ | LOAD_CAP_11_5_PF | M1 ) - и программа читабельная станет и вероятность ошибиться гораздо меньше.

2) вот вам предложение:
Код
void WriteCMD( uint CMD )
{
   uchar n=16;
   // SCK тут уже равно 0
   nSEL=0;
   do
   {
      if (CMD & (1 << 15) )
           SDI = 1;
      else
           SDI = 0;
      SCK = 1;
      CMD <<= 1;  // в это время выдерживается пауза высокого уровня SCK, хотя она тут и не нужна, между командами все равно больше 25 нс
      SCK = 0;
   }
   while (--n);      // во время перехода по циклу выдерживается пауза низкого уровня SCK, хотя она тут и не нужна.

   // и тут SCK уже равно 0.
   nSEL=1;

}
циклы do {} while (--var); компилируются эффективнее, чем while(n--) {}. Длинные nop не нужны - по даташиту длительность высокого и низкого уровней SCK должна быть не меньше 25 нс, у вас процессор при всем желании так быстро ногами дергать не сможет. SDI после этой функции может оставаться в любом состоянии и сбрасывать его при инициализации тоже необязательно.

3) сделайте отдельную функцию для
Код
    WriteFSKbyte( n );
    ChkSum += n;
исключите возможность ошибки "передали одно, а прибавили другое".

4)Какой смысл команды 0xCC00 в вашем тексте? Она выдает содержимое регистра статуса во время последних 8 импульсов SCK, но вы его не читаете. Для начала добейтесь, чтобы модуль вам ответил что-то осмысленное на эту команду. Зациклите ее, засинхронизируйте осциллограф от nSEL, посмотрите, что творится на ногах.
vank
Извините, на моя просба никто не можеть помочь?
tazik
Цитата(vank @ Apr 30 2008, 12:47) *
Извините, на моя просба никто не можеть помочь?


А почему бы Вам самим не скомпилировать пример? Никаких трудностей при этом не было. Да и Вам должно быть удобней, чем лазить по asm+C тексту
В файлах код для передатчика с разными уровнями оптимизации для AVR.

Нажмите для просмотра прикрепленного файла

Может быть, я чего-то просто-напросто не понимаю?
wasp
Цитата(Сергей Борщ @ Apr 30 2008, 03:33) *
Скачал описание модуля по ссылке из первого поста. Не нашел в нем команд 0xD040, 0xC823.

Раз уж ветка по С:
1) Ээх, не любите вы себя - потратьте час, присвойте всем битам (и/или их комбинациям) осмысленные имена через #define и потом пишите WriteCMD( SET_CONFIG | BAND_433 | CLK_2MHZ | LOAD_CAP_11_5_PF | M1 ) - и программа читабельная станет и вероятность ошибиться гораздо меньше.

2) вот вам предложение:
Код
void WriteCMD( uint CMD )
{
   uchar n=16;
   // SCK тут уже равно 0
   nSEL=0;
   do
   {
      if (CMD & (1 << 15) )
           SDI = 1;
      else
           SDI = 0;
      SCK = 1;
      CMD <<= 1;  // в это время выдерживается пауза высокого уровня SCK, хотя она тут и не нужна, между командами все равно больше 25 нс
      SCK = 0;
   }
   while (--n);      // во время перехода по циклу выдерживается пауза низкого уровня SCK, хотя она тут и не нужна.

   // и тут SCK уже равно 0.
   nSEL=1;

}

Спасибо большое!
Действительно так гораздо компактнее. smile.gif
Цитата
Какой смысл команды 0xCC00 в вашем тексте? Она выдает содержимое регистра статуса во время последних 8 импульсов SCK, но вы его не читаете. Для начала добейтесь, чтобы модуль вам ответил что-то осмысленное на эту команду. Зациклите ее, засинхронизируйте осциллограф от nSEL, посмотрите, что творится на ногах.

Сделал как Вы посоветовали, обнаружилось, что на выходе SDI постоянно ноль.
Код
void RF2_Init( void )
{
   nSEL=1;
   SDI=1;
   SCK=0;
   FSK=0;
}

void main()
{
  
   RF2_Init();

   while (1)
   {
      WriteCMD( 0xCC00 );
   }
}

/*****************************************************************/
void WriteCMD( uint CMD )
{
   uchar n=16;
   // SCK тут уже равно 0
   nSEL=0;
   do
   {
      if (CMD & 0x8000)
              SDI = 1;
      else
              SDI = 0;

      SCK = 1;
      CMD = CMD<<1;  // в это время выдерживается пауза высокого уровня SCK, хотя она тут и не нужна, между командами все равно больше 25 нс
      SCK = 0;
   }
   while (--n);      // во время перехода по циклу выдерживается пауза низкого уровня SCK, хотя она тут и не нужна.

   // и тут SCK уже равно 0.
   nSEL=1;

}

причем клок синал SCK и nSEL идут , а SDI нету 07.gif


Причем даже когда делаю так:

Код
     if (CMD & 0x8000)
             SDI = 1;
      else
             SDI = 1;

все равно ноль.

Причем когда делаю так:
Код
//     if (CMD & 0x8000)
             SDI = 1;
   //   else
             SDI = 0;

генерит...

Что это - ошибка компилятора или мои кривые руки?
Да, компилер CCS_PCWHD_v4.057
vank
Цитата(tazik @ May 1 2008, 13:25) *
А почему бы Вам самим не скомпилировать пример? Никаких трудностей при этом не было. Да и Вам должно быть удобней, чем лазить по asm+C тексту
В файлах код для передатчика с разными уровнями оптимизации для AVR.

Спасибо "tazik"! Но мне необходим код для PIC-a. А я не знаю C и поетому не могу скомпилировать пример.
tazik
Цитата(vank @ May 1 2008, 20:20) *
Но мне необходим код для PIC-a. А я не знаю C и поетому не могу скомпилировать пример.


Пожалуйста, только для PIC`а у меня ничего нет (. Для AVR`а пример скомпилировался с 1-го раза без всяких замечаний.
wasp
поставил тип переменной CMD "unsigned long int" вместо "unsigned int" - все пошло.
я озадачен 05.gif
wasp
никак не получается инициализировать RFM02.
по прежнему после инициализации нет импульсов на выходе nIRQ и не меняется частота CLK (настраиваемый выход клоксигнала)
хотя когда гоняю в цикле команду CC00 (read status registor) выдает такой пакет (значит команды в принципе проходят) :

а что это значит?
в даташите об этом только это:


помогите советом. crying.gif
Different
Вот куски кода для модулей HopeRF с немецких сайтов. Может кому чего в них пригодится.
Ссылки дали сами китайцы... a14.gif
SashaGubov
а эти модули от 5 вольт можно питать?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.