Перейти к содержанию

Zombie47

Members
  • Постов

    219
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные Zombie47

  1. Вот есть регистр, и тут последние 4 бита определяют настройку прескайлер.

    image.png.49388757cd3b3f0e4e2937bf1bf2c48e.png

    Вот у меня есть адрес этого регистра и даже присвоенные имена каждому биту и регистр с этим адресом.
    А как мне сделать маску, для последних 4 битов?
    в том плане я хочу просто написать; T0OUTPS=0b00001111
    или
    T0OUTPS=0b11111111
    и чтоб применялись только последние 4 бита к регистру по тому адресу.
    image.png.ee08dbc6a0e0e5ff5512d8970929787f.png

  2. Народ вопрос по настройке частоты таймера. Вот простой код, меняю состояние ноги в прерывании, и смотрю анализатором частоту.

    void init() { 
    TRISA = 0b00110000;//RA5,4,3,2,1,0
    WPUA4_bit=0;
    
    INTCON = 0b11000000; //page 89 enable all interrupts 
    
    ANSELA = 0b00000000;  //
    LATA = 0b00000000;
    }
    
    void interrupt() { 
            if(TMR0IF_bit == 1){ 
                     TMR0IF_bit=0;
                     LATA0_bit=~LATA0_bit; //main code for analyzator
                    }
    }
    
    void TMR0_Initialize(void)// PIC 16F18313 has 1Mhz ferq ref. But can freq 32mhz (edit project) page 52 , page 71, page 82
    {
        OSCCON1 = 0b0000000;//page 78 (0 000 0000) 0, 000 - NOSC (HFINTOSC with 2x PLL 32MHZ), 0000 - NDIV clock divider 1
        OSCFRQ = 0b00000001;//page 82 (---- 0001) 2MHZ
        T0CON0 = 0b10000000; //page 261 (1 - 0 0 0000) Timer enable, - , read only , 8 bit, postscaler 1:1
        T0CON1 = 0b01110000; //page 262 (011 0 0000) 011 = HFINTOSC, 1 = The input to the TMR0 counter is not synchronized to system clocks, 0000 - prescaler 1:1
        TMR0H = 255;// it is not just counter, in 8 bit mode it is register period // to what number to count
        TMR0L = 0x00;
        TMR0IF_bit = 0;// Clear Interrupt flag before enabling the interrupt
        TMR0IE_bit = 1; // Enabling TMR0 interrupt.
    
        // Set Default Interrupt Handler
       // TMR0_SetInterruptHandler(TMR0_DefaultInterruptHandler);
     }
    
    void main()
    {
        init ();
        TMR0_Initialize ();
        TRISA0_bit = 0;   
        ANSA0_bit = 0;
    
        while (1)
        {
           
        }
    }

    Например вот регистр по настройке частоты мк: 
    OSCCON1 = 0b0000000;//page 78 (0 000 0000) 0, 000 - NOSC (HFINTOSC with 2x PLL 32MHZ), 0000 - NDIV clock divider 1
    NOSC тут равен 000 то-есть режим HFINTOSC with 2x PLL
    OSCFRQ = 0b00000001;//page 82 (HFFRQ = 0001)
     это частота 2mhz при NOSC = 110: 
    image.png.6aa89ab82af4de9088830bc91b805a44.png
    Но у меня NOSC = 000 и должно быть reserved.
    Таймер 8-ми битный, считаем с 0 до 255, прескайлер 1:1.
    Итого 2 000 000hz делим на 256 и получаем ~7812 прерываний в секунду. (hz) 
    Смотрим анализатор:

      image.png.5ed76fd6b90d996efae0a418f04cf8d5.png

    У меня в коде при заходе в прерывание меняется состояние ноги. Так что просто смотрим на параметр width- = 7744hz. Ну типо ок пусть будет так. Частота 2mhz.

    Меняю:
    OSCFRQ = 0b00000110;//page 82 (---- 0110) 16MHZ if Nominal Freq. (MHz)(NOSC = 110)
    NOSC не трогаю остается 000
    Какая будет частота? 16 или 32MHz?
    Вроде должна быть 32Mhz, но по факту 16Mhz:
    16 000 000 / 256 = 62500
    image.png.42e12d1e17b488a4d8dbfe4a34ede91f.png

    Ну и если прописать  OSCFRQ = 0b00000111; 
    то частота будет 32MHz.
    Почему работает по левому столбцу?

    И еще вопрос:
    image.png.090103005e1264e115c5e933bf4dbef9.png

    Вот тут в даташите написано  ставим (HFFRQ = 0110) это будет 16Mhz и активирует 2x PLL и частота по идее должна быть в два раза выше, но вот почему то у меня этого не происходит.
    А ниже написано для задания значения регистра смотрите register 6-6 , но такого в даташите нет и наверно тут опечатка имеется ввиду 7-6 то что скидывал выше.

  3. Умная мысля приходит напосля. К сожалению пока не изложишь вопрос на форуме, мой мозг не структурирует информацию, а вот как изложишь, так нахожу решение.
    В общем я точно не понял в чем было дело, но решил не умничать с каждым битом отдельно, а целиком весь регистр настраивал. Предположительно тут последовательность конфигурирования и обязательная задержка.
    В общем вот с этим кодом работает как надо:
     

    unsigned int read_adc (){//функция чтения ацп
      int tmp;
               ADCON0=0b00010011; //даташит page 143 ниже описание:
               //7 read as 0
               //6-2bit=00100 (канал для АЦП RA4)
               //1bit=0 (GO/DONE как я понял это что вроде флага, в процессе АЦП или нет )
               //0bit=0 (ADON этот бит запускает работу ацп.)
              
                Delay_ms(1);//обязательна без нее не работает
                ADON_bit=1; //еще раз включаю ацп после задержки
                ADGO_bit=1; //этим битом запускаю замер  ацп на выбранном канале
              
               while (GO_bit){}; // если ацп работает и снимает показания то ниче не делаем  висим тут.
               tmp = (unsigned int)ADRESH << 8; //верхний регистр приводим к инту и сдвигаем влево на 8 бит так как это верхний регистр
               tmp |= ADRESL;//нижний регистр склеиваю
               ADCON0=0b01111111; //переконфигурирую под замер FVR
              return tmp;
      }
     
      unsigned int read_fvr (){//функция чтения ацп fvr
      int tmp_fvr;
               FVRCON = 0b11000010; //конфигурирую и включаю FVR page 133
              //bit 7 FVREN: 1 = Fixed Voltage Reference is enabled
              //bit 6 FVRRDY: 1 = Fixed Voltage Reference output is ready for use
              //bit 5 TSEN: 0 = Temperature Indicator is disabled
              //bit 4 TSRNG: 0 =VOUT = VDD - 2VT (Low Range)
              //bit 3-2 CDAFVR<1:0>: 00 = Comparator FVR Buffer is off
              //bit 1-0 ADFVR<1:0>: 10 = ADC FVR Buffer Gain is 2x, with output VADFVR = 2x VFVR(4)
                ADCON0=0b01111111; //обязательно еще раз конфигурирую ацп даташит page 143 ниже описание:
               //7 read as 0
               //6-2bit=00100 (канал для АЦП RA4)
               //1bit=0 (GO/DONE как я понял это что вроде флага, в процессе АЦП или нет )
               //0bit=0 (ADON этот бит запускает работу ацп.)
    
               while (GO_bit){}; // если ацп работает и снимает показания то ниче не делаем  висим тут.
               tmp_fvr = (unsigned int)ADRESH << 8; //верхний регистр
               tmp_fvr |= ADRESL;//нижний регистр склеиваю
               FVRCON = 0b00000000; //выключаю FVR page 133
               ADCON0=0b00010000; //переконфигурирую под ацп даташит page 143 ниже описание:
        return tmp_fvr;
      }

     

  4. В 22.04.2018 в 13:56, my504 сказал:

    Все очень просто. FVR уже подключен к АЦП, нужно только его выбрать  входным мультиплексором. Напряжение питания (если именно оно использовано в качестве опорного АЦП) будет равно  1024*Ufvr/N, где N - измеренное значение.

    Такие вещи не пишут в ДШ, поскольку они элементарны и следуют из простой формулы измерений:   N=Uизм*1024/UопАЦП

    ЗЫ. Совет применять делитель с мегаомным значением сопротивления совершенно безграмотен, ибо максимально допустимое внутреннее сопротивление источника сигнала ограничено даташитом величиной в 10 кОм. Иначе мы будем измерять "погоду на Кольском полуострове".

    ЗЗЫ. Учитывая, что включение FVR приводит к заметному росту потребления, следует его включать лишь на время измерения. Как и сам АЦП. В новых контроллерах Микрочипа управление включением периферии обычно делается с помощью специального регистра (PMD), что упрощает процессы администрирования потребления. Но это только начиная с "пятизначного" семейства  PIC16F1xxxx

    Понимаю тема старая. Но поиском с гугла вышел на эту тему.
    У меня похожая задача, но с ньюансом. Мне нужно замерять АЦП на ноге, и плюс замерять замерять FVR. (чтоб узнать напряжение питания МК) По отдельности получается замерять и то и то.
    А вот вместе не получается. Ну естественно пытаюсь по очереди замерять.
    Микроконтроллер PIC16F1847
    Я уже как только не пробовал, но где то косячу. При попытке замера по очереди, один сигнал влияет на другой причем очень сильно.
    Напряжение питания МК 5.0в (для теста)
    По отдельности например вот так:
    FVR 2.048в = ADC 415
    мультиметром на ноге RA4 3.950в = ADC 800.

    Если ничего не меняю физически но включаю замер по очереди то:
    FVR 2.048в = ADC 685
    мультиметром на ноге RA4  3.950в = ADC 640.

    Код (без лишнего) на данный момент выглядит так:

      unsigned int read_adc (){//функция чтения ацп
      int tmp;
                CHS4_bit=0;  //этими битами выбираю канал. page 143
                CHS3_bit=0;
                CHS2_bit=1;
                CHS1_bit=0;
                CHS0_bit=0;
                /*
                00000 = AN0
                00001 = AN1
                00010 = AN2
                00011 = AN3
                00100 = AN4
                00101 = AN5
                00110 = AN6
                00111 = AN7
                01000 = AN8
                01001 = AN9
                01010 = AN10
                01011 = AN11
                01100 = Reserved. No channel connected.
                
                11100 = Reserved. No channel connected.
                11101 = Temperature Indicator
                11110 = DAC output(1)
                11111 = FVR (Fixed Voltage Reference) Buffer 1 Output(2)
                */
    
                ADON_bit=1; //включаю ацп
                ADGO_bit=1; //этим битом запускаю замер  ацп на выбранном канале
               while (GO_bit){}; // если ацп работает и снимает показания то ниче не делаем  висим тут.
               tmp = (unsigned int)ADRESH << 8; //верхний регистр приводим к инту и сдвигаем влево на 8 бит так как это верхний регистр
               tmp |= ADRESL;//нижний регистр склеиваю
            
                ADON_bit=0; //вырубаю  ацп
                
                CHS4_bit=1;  //этими битами выбираю канал. page 143
                CHS3_bit=1;
                CHS2_bit=1;
                CHS1_bit=0;
                CHS0_bit=0;
      return tmp;
      }
      
      unsigned int read_fvr (){//функция чтения fvr
      int tmp_fvr;
                ADFVR1_bit=1;
                ADFVR0_bit=0;
                FVREN_bit=1;
                CHS4_bit=1;  //этими битами выбираю канал. page 143
                CHS3_bit=1;
                CHS2_bit=1;
                CHS1_bit=1;
                CHS0_bit=1;
      
    			ADON_bit=1; //запускаю работу ацп
                ADGO_bit=1; //этим битом запускаю замер  ацп на выбранном канале
    
               while (GO_bit){}; // если ацп работает и снимает показания то ниче не делаем  висим тут.
               
               tmp_fvr = (unsigned int)ADRESH << 8; //верхний регистр
               tmp_fvr |= ADRESL;//нижний регистр склеиваю
               
    		   ADON_bit=0; //вырубаю  ацп
               TRISA4_bit=1;//RA4 на вход
               ANSA4_bit=1;//аналоговый пин
               FVREN_bit=0; //пробую выррубать FVR
               ADFVR1_bit=0; //пробую вырубать буфер FVR
               ADFVR0_bit=0;
        return tmp_fvr;
      }
    
    void main() {
        while (1) {//основной цикл
        adc=read_adc(); 
        fvr=read_fvr();
          }
    }

    image.png.9f88e2b3b40d8c3a2a86a2c545028efe.png

  5. Вот смотрите создаю структуру и в интернете пишут если не писать typedef то sPWM_t не будет типом и нужно будет где то писать каждый раз struct

    typedef struct sPWM_t { 
      int phaseFull;
      int phaseOne_temp;
      long phaseOne;
      int timer;
      };
    
    struct sPWM_t sBlowerFan;
    struct sPWM_t sHeater;

    Я так и делаю, но если не писать struct при  создании элементов структуры то выдает ошибку.

    Чтобы не писать struct нужно делать так:

    typedef struct  {
      int phaseFull;
      int phaseOne_temp;
      long phaseOne;
      int timer;
      }sPWM_t;
    
    sPWM_t sBlowerFan;
    sPWM_t sHeater;

    В первом случае я создал новый тип данных sPWM_t содержащих структуру и два элемента структуры? Или структуры с типом данных содержащим структуру и именем sBlowerFan и sHeater?
    Во втором случае как я понял я создал Анонимную структуру? Или тип данных содержащий анонимную структуру? и элемент структуры sPWM_t? или что это? тоже тип? ну и две переменных типа sPWM_t которые содержат структуру?

    Мне просто важно понимать как оно устроено, я конечно могу забить и использовать в торой вариант, типо так все делают. Но хотелось бы понимания.

  6. Цитата

    А на линиях I2C подтягивающие резисторы какой величины используете? Похоже, какой-то клок-стретчинг происходит.

    я тоже подумал об этом и на всякий случай глянул осциллограму, думал вдруг анализатор просто не видет нарастания фронта и тд. Но нет там тоже самое.
    резисторы в Oled стоят какие то. Вроде по 10к

  7. А что скорость никак не связана с герцами и милисекундами? и у I2C шины шим произвольный? 
    Вот все функции по I2C
     

    
    //Initialize I2C in master mode, Sets the required baudrate
    void I2CInit(void)
    {
    long FOSC=8000000;
    long I2C_SPEED_HZ=5000;
       //SSP1ADD  = ((8000000/4000)/100) - 1;  //((_XTAL_FREQ/4000)/I2C_SPEED) - 1  // page 286 I2C_SPEED 100 ýòî 85khz, 1000 ýòî 380khz
       //SSP1ADD  = ((FOSC/4)/I2C_SPEED_HZ) - 1;  //((_XTAL_FREQ/4)/I2C_SPEED) - 1
       SSP1ADD  = 2;
       SSP1STAT = 0b10000000;   /* Slew rate disabled */
       SSP1CON1 = 0b00101000;   /* SSPEN = 1, I2C Master mode, clock = FOSC/(4 * (SSPADD + 1)) */
    //       SSPEN_bit=0;
    }
    
    //Send a start condition on I2C Bus
    void I2CStart(void)
    {
       SEN_bit = 1;       /* Start condition enabled */
       while(SEN_bit);    /* automatically cleared by hardware */
                                   /* wait for start condition to finish */
    }
    
    //Send a stop condition on I2C Bus
    void I2CStop(void)
    {
       PEN_bit = 1;           /* Stop condition enabled */
       while(PEN_bit);        /* Wait for stop condition to finish */
                                       /* PEN automatically cleared by hardware */
    }
    
    //Sends a repeated start condition on I2C Bus
    void I2CRestart(void)
    {
       RSEN_bit = 1;        /* Repeated start enabled */
       while(RSEN_bit);     /* wait for condition to finish */
    }
    
    //Generates acknowledge for a transfer
    void I2CNck(void)
    {
       ACKDT_bit = 0;     // 0 means ACK
       ACKEN_bit = 1;     // Send ACKDT value
       while(ACKEN_bit);    /* wait for ack data to send on bus */
    }
    
    //Generates Not-acknowledge for a transfer
    void I2CAck(void)
    {
       ACKDT_bit = 1;     // 0 means ACK
       ACKEN_bit = 1;     // Send ACKDT value
       while(ACKEN_bit);    /* wait for ack data to send on bus */
    }
    
    //wait for transfer to finish
    void I2CWait(void)
    {
       while ((SSP1CON2 & 0x1F ) || ( SSP1STAT & 0x04 ) );//SSP1STAT & 0x04  ýòîò áèò transmit in progress
       /* wait for any pending transfer */
    }
    
    //Send 8-bit data on I2C bus - 8-bit data to be sent on bus data can be either address/data byte
    void I2CSend(unsigned char dat)
    {
       SSP1BUF = dat;    /* Move data to SSPBUF */
       while(BF_bit);       /* wait till complete data is sent from buffer */
       I2CWait();       /* wait for any pending transfer */
    }
    
    //Read 8-bit data from I2C bus
    unsigned char I2CRead(void)
    {
      unsigned char temp;
    /* Reception works if transfer is initiated in read mode */
       RCEN_bit = 1;        /* Enable data reception */
       while(!BF_bit);      /* wait for buffer full */
       temp = SSP1BUF;   /* Read serial buffer and store in temp register */
       I2CWait();       /* wait to check any pending transfer */
       return temp;     /* Return the read data from bus */
    }

     

  8. Не понимаю в чем дело. Регистр SSP1ADD может иметь значение от 0 до 255
    2021-12-28_00-11-52.jpg.54193b50eb692e74b2408d21bb0ea62b.jpg

    Fosc у меня 8mhz то-есть 8000000hz
    То-есть если он равен 255 то SCLx pin clock period будет равен 7812hz а если он будет равен 1 то частота будет 1Mhz
    И у меня это работает но на половину.
    Вот присваиваю регистру SSP1ADD=255;  и шлю по i2c и что вижу анализатором:

    2021-12-28_00-20-45.jpg.0e2a17f975f8e11502c8aade0c1ec96b.jpg

    А то что частота в районе 7000hz и шим 56%, ну да ладно. 
    Вбиваю  SSP1ADD=19; в надежде получить скорость 100khz:
    2021-12-28_00-27-02.jpg.f93faaaad3dc9a3c5067c10985eacb45.jpg

    Шим теперь почему то уплыл до 76%
    Но самое интересное что импульс нижнего уровня по длине 5.66us и еслиб положительный импульс был тоже в районе 5.66us то это и была бы частота в районе 100khz.
    Что я делаю не так? По идее ШИМ должен быть в районе 50%
    Функции писал не сам. Функция которая как я понимаю формирует SCL вот эта:
     

    //wait for transfer to finish
    void I2CWait(void)
    {
       while ((SSP1CON2 & 0x1F ) || ( SSP1STAT & 0x04 ) );
       /* wait for any pending transfer */
    }

     

  9. 14 часов назад, snn_krs сказал:

    Все очень логично.

    Вы записываете в EEPROM пароль и защищаете его от считывания. Отдаете клиенту МК. Он стирает ваш код и записывает свой, в котором считывает ваш пароль из EEPROM и выдает его клиенту. Считывать защищенную EEPROM может только программа которую вы грузите при установке защиты.

    Ну да вот он ответ то чего я не доглядел ))) Спасибо.

  10. Заливаю прошивку, код открыт. Еепром закрыта в конфигурации. Вручную вписываю айди в ячейку еепром. Заливаю, все работает.
    Далее еще раз На данном скриншоте заливаю туже самую прошивку, но еепром не редактирую, и убираю галочку. Он мне даже пишет мол не будет удалено.
    Заливаю и все еепром затирается, так как прибор сразу выдает что в еепром нет того айди что я вписал.

    2021-12-20_00-47-07.jpg

  11. Цитата

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

    ДА я знаю. Меня не считывание волнует. а ЗАПИСЬ.
    При записи ЕЕПРОМ затирается ВСЕГДА если стояла защита на чтение еепром!

  12. Цитата

    Data protect это защита от СЧИТЫВАНИЯ кода из микросхемы. А не от программирования.  Если желаете оставить старый код в ЕЕпром-снимайте галку с блока ЕЕпром  и ЕЕпром не будет писаться-стираться

    В этом и суть топика. Я так и делаю Галку СНИМАЮ. Но еепром затирается. У меня в коде идет проверка по еепром.

  13. Код у прошивки открытая, а еепром закрытая.
    При первой записи вручную что то пишу в еепром.
    Дальше делаю вторую запись  другой прошивки, но галочку EEPROM снимаю в надежде на то что запишет только саму прогу а еепром не тронет.
    Но нет он сносит еепром.

    Если сделать еепром открытую, то все работает.
    В чем дело?

    2021-12-19_22-58-17.jpg

  14. Наверно мне бы стоило в вопросах для начинающих задать этот вопрос, но с другой стороны у меня уже это все давно работает, хоть я не знаю как)))
    Среда MicroC Pro
    У меня МК PIC16F1847 с кварцем 20Mhz, к нему подключен по SPI MCP2510 с кварцем 8Mhz а к нему MCP2551
    Вот у меня в коде что то вроде стандартной конфигурации CAN SPI

    void CANinit(void){
     Can_Init_Flags = 0;
      Can_Send_Flags = 0;                                         // clear flags
      Can_Rcv_Flags  = 0;                                         //
      Can_Send_Flags = _CANSPI_TX_PRIORITY_0 &                    // form value to be used
                       _CANSPI_TX_STD_FRAME &                     //     with CANSPIWrite
                       _CANSPI_TX_NO_RTR_FRAME;
      Can_Init_Flags = _CANSPI_CONFIG_SAMPLE_THRICE &             // Form value to be used
                       _CANSPI_CONFIG_PHSEG2_PRG_ON &             //  with CANSPIInit
                       _CANSPI_CONFIG_STD_MSG &
                       _CANSPI_CONFIG_DBL_BUFFER_ON &
                       _CANSPI_CONFIG_VALID_STD_MSG;
      //SPI1_Init();                                                     // initialize SPI1 module
      CANSPIInitialize(1,1,3,3,1,Can_Init_Flags);                      // Initialize external CANSPI module
      CANSPISetOperationMode(_CANSPI_MODE_CONFIG,0xFF);                // set CONFIGURATION mode
      CANSPISetMask(_CANSPI_MASK_B1,-1,_CANSPI_CONFIG_STD_MSG);        // set all mask1 bits to ones
      CANSPISetMask(_CANSPI_MASK_B2,-1,_CANSPI_CONFIG_STD_MSG);        // set all mask2 bits to ones
      CANSPISetFilter(_CANSPI_FILTER_B2_F3,ID_1st,_CANSPI_CONFIG_STD_MSG);        // set id of filter B2_F3 to 1st node ID    áåç ýòîé ñòðîêè íå ðàáîòàåò
        CANSPISetFilter(_CANSPI_FILTER_B2_F4,ID_2nd,_CANSPI_CONFIG_STD_MSG);        // set id of filter B2_F3 to 1st node ID    áåç ýòîé ñòðîêè íå ðàáîòàåò
        CANSPISetFilter(_CANSPI_FILTER_B1_F2,ID_3rd,_CANSPI_CONFIG_STD_MSG);        // set id of filter B2_F3 to 1st node ID    áåç ýòîé ñòðîêè íå ðàáîòàåò
        CANSPISetFilter(_CANSPI_FILTER_B2_F1,ID_4th,_CANSPI_CONFIG_STD_MSG);        // set id of filter B2_F3 to 1st node ID    áåç ýòîé ñòðîêè íå ðàáîòàåò
    
      CANSPISetOperationMode(_CANSPI_MODE_NORMAL,0xFF);
    }

    Не очень уже помню как и где это настраивается, но скорость работы у меня 500 000 байт в секунду вроде, ну или какие там единицы.
    Не хочу перегружать вопрос кучей кода поэтому буду вырезать главное чтобы было читабельно.
    В основном юзаю отправку например вот:
     

      zaderzka=180; //величина задержки 9765 это 1 сек. 190 задержка это 0.019сек
      zaderzka_flag=1; 
    if (i>zaderzka) {
     CANSPIWrite(ID_512, RxTx_Data512, 8, Can_Send_Flags);
     RxTx_Data512[5]++;//счетчик от 00 до FF
    }

    Вопросы и проблемы:
    1. я формирую задержку таймером, который запускаю флагом в коде, и я эту задержку использую для отправки в SPI шину, там проходит время по посылке в SPI и тд, поэтому тайминг отправки CAN не точный и плавает. А мне надо чтобы непосредственно MCP2510 слал мой пакет в шину с определенным таймингом как это сделать?
    2. в шине есть еще устройства, они тоже шлют в шину пакеты со своим таймингом. Вообщем иногда я вижу очень редко пакеты встречаются, но контроллер MCP2510 вроде как рулит чтобы не было нахлеста. По идее хорошо бы чтобы каждое устройство попадало в свой тайминг, но я не могу выдержать отправку раз в 20мсек. у меня плавает туда сюда то 25 то 22 то 26 и тд, и поэтому встречаются места там где пересекаются пакеты и как я вижу по счетчикам, один пакет у меня просто теряется, а другой пакет который я шлю почему то шлется два три раза подряд, именно MCP2510 так как счетчик без изменений то-есть программа не сделала цикла.
    3. Как вообще настраивается прием сообщений? как я понял настройкой фильтров типо этого:  CANSPISetFilter(_CANSPI_FILTER_B2_F1,ID_4th,_CANSPI_CONFIG_STD_MSG);
    Тоесть я правильно понимаю что всего там ограниченное количество фильтров которое я могу использовать на прием?

  15. 14.07.2020 в 01:38, Yurkin2015 сказал:

    Запретить невозможно, флаг поднимается в железе. Надо RXNE сбрасывать перед стартом приёма пакета, что-нибудь, типа, очистить висящие флаги прерывания 

    USART_ClearITPendingBit(USART1, USART_IT_RXNE);

    Ну, или сделать приёмник UART RX disabled, тогда приёмные байты будут игнорироваться, и флаги не поднимутся.

    где взять эту функцию? USART_ClearITPendingBit
    где взять это USART_IT_RXNE у меня этого просто нету.
    я понимаю что второе это регистр, но он где то должен быть определен. а у меня нигде не определен и как это сделать я не пойму.

  16. 10 часов назад, Yurkin2015 сказал:

    Запретить невозможно, флаг поднимается в железе. Надо RXNE сбрасывать перед стартом приёма пакета, что-нибудь, типа, очистить висящие флаги прерывания 

    USART_ClearITPendingBit(USART1, USART_IT_RXNE);

    Ну, или сделать приёмник UART RX disabled, тогда приёмные байты будут игнорироваться, и флаги не поднимутся.

    Значит так флаг поднялся. Сработало прерывание, и обработчик прерываний? вызвался каллбэк?
    А как переконфигурировать сначала в ногу на выход а потом в ногу уарта? я переконфигурирую и у меня впринципе прием перестает работать

  17. Только что, Yurkin2015 сказал:

    Честно говоря, Вас трудно понять: то какой-то драйвер параллелит эхо, то в каком-то цикле срабатывает коллбэк, то почему-то не должно в приёме дублироваться ...

    Одно могу добавить, функция HAL_UART_Receive_IT() не очищает флаги прерывания, а только разрешает их. Поэтому если когда-то UART принял байт, то установится RXNE флаг, что байт принят без всяких прерываний. И этот флаг будет ждать своего часа. Потом вы стартуете эту самую HAL_UART_Receive_IT(), обнаруживаете принятый байт и забираете его.

    Спасибо теперь понятнее стало почему так работает. Вообщем вопрос в следующем, как запретить поднимать эти флаги прерывания на прием пока я отправляю?

  18. Только что, Yurkin2015 сказал:

    Функция HAL_UART_Receive_IT() обратно разрешает прерывания по приёму.

    да это понятно, но я же уже отправил, все , ниче не должно быть в приеме дублироваться.

  19. и еще вопрос, почему не работает этот код.
    у меня стоит драйвер, который параллелит при отправке RX и TX ну вроде как эхо называется.
    поэтому пишу вот так:
    HAL_UART_Abort_IT (&huart1);//запрет прерываний по приему.
    HAL_UART_Transmit(&huart1, &start_posilka_abs, 1, 30); //отправляю 1 байт
    HAL_UART_Receive_IT(&huart1, (uint8_t*)buffers_first, 1);//запускает прием по уарту как токо придут все байты будут приняты сработает прерывание каллбэк

    каждый цикл срабатывает каллбэк на прием. но я же вроде как запретил прием.

  20. Исходные данные проц: STM32L053R8
    работаю с HAL
    мне надо ногу PA9 сначала подергать вручную, а потом чтоб она была уартом.
    я решил делать так:
    конфигурирую как ногу на выход:
     

      /*Configure GPIO pins : PA9 */

        GPIO_InitStruct.Pin = GPIO_PIN_9;
          GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
          GPIO_InitStruct.Pull = GPIO_NOPULL;
          GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
          HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    дергаю ногой:
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9,GPIO_PIN_RESET);
    HAL_Delay (582);// это будет 582 задержка
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9,GPIO_PIN_SET);
    HAL_Delay (158);// это будет 158 задержка
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9,GPIO_PIN_RESET);
    HAL_Delay (24); // это будет 24 задержка очень чувствительно. ставлю 25 перестает работать.
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9,GPIO_PIN_SET);
    HAL_Delay (24);// это будет 24 задержка

    конфигурирую как уарт:
    // ниже конфигурирую пин PA9 опять как уарт
        GPIO_InitStruct.Pin = GPIO_PIN_9;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF4_USART1;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    отправляю:
    HAL_UART_Transmit(&huart1, &start_posilka_abs, 1, 30);  //отправляю 1 байт
    принимаю:
    HAL_UART_Receive_IT(&huart1, (uint8_t*)buffers_first, 1);//запускает прием по уарту как токо придут все байты будут приняты сработает прерывание каллбэк

    вообщем вроде все работает кроме одного, перестает работать прием ) перестают работать прерывания на прием.

×
×
  • Создать...