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

Zombie47

Members
  • Постов

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

  • Посещение

Весь контент Zombie47

  1. Вот есть регистр, и тут последние 4 бита определяют настройку прескайлер. Вот у меня есть адрес этого регистра и даже присвоенные имена каждому биту и регистр с этим адресом. А как мне сделать маску, для последних 4 битов? в том плане я хочу просто написать; T0OUTPS=0b00001111 или T0OUTPS=0b11111111 и чтоб применялись только последние 4 бита к регистру по тому адресу.
  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: Но у меня NOSC = 000 и должно быть reserved. Таймер 8-ми битный, считаем с 0 до 255, прескайлер 1:1. Итого 2 000 000hz делим на 256 и получаем ~7812 прерываний в секунду. (hz) Смотрим анализатор: У меня в коде при заходе в прерывание меняется состояние ноги. Так что просто смотрим на параметр 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 Ну и если прописать OSCFRQ = 0b00000111; то частота будет 32MHz. Почему работает по левому столбцу? И еще вопрос: Вот тут в даташите написано ставим (HFFRQ = 0110) это будет 16Mhz и активирует 2x PLL и частота по идее должна быть в два раза выше, но вот почему то у меня этого не происходит. А ниже написано для задания значения регистра смотрите register 6-6 , но такого в даташите нет и наверно тут опечатка имеется ввиду 7-6 то что скидывал выше.
  3. Опять вышел поиском на трехлетнее сообщение уже )))
  4. Умная мысля приходит напосля. К сожалению пока не изложишь вопрос на форуме, мой мозг не структурирует информацию, а вот как изложишь, так нахожу решение. В общем я точно не понял в чем было дело, но решил не умничать с каждым битом отдельно, а целиком весь регистр настраивал. Предположительно тут последовательность конфигурирования и обязательная задержка. В общем вот с этим кодом работает как надо: 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; }
  5. Понимаю тема старая. Но поиском с гугла вышел на эту тему. У меня похожая задача, но с ньюансом. Мне нужно замерять АЦП на ноге, и плюс замерять замерять 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(); } }
  6. Не знал что тут есть блоги, а не просто форум. Понимаю записи почти 5 лет. Я разбираюсь в электронике намного хуже чем многие комментаторы. Бурное обсуждение в комментариях навело смуту. Вообще меня сильно раздражала та же проблема. Что фонарик от лития сначала светит ярко, а потом тускнеет. И я рассуждал сначала как потребитель: "ну типо садиться вот и тускнеет." А потом я замерял емкость батареи и с удивлением обнаружил что она прям до разряженного состояния (3.7в) дает ток 1А без проблем. Это притом что светодиод на фонарике потребляет 350ма. при 4.2в. Тут уже некоторые знания мои проявились, плюс разобрал фонарь глянул схему. Как и предполагал, что просто подается напряжение через биполярный транзистор и резистор на 2Ом, и с падением напряжения падает и ток на светодиоде. Начал придумывать изобретать решение, ну и гуглить и наткнулся на эту статью в том числе. В итоге схема в самом верху она актуальная и правильная? Такие схемы для меня сложноваты для досканального понимания, понимаю очень поверхостно. Имею ввиду не могу объяснить что делает каждый элемент на схеме. Как я понимаю по потребляемому току мне идеально подходит AMC7135 , но так же я понимаю, что чудес не бывает и везде чем то приходится жертвовать, в данном случае как я понимаю КПД. Мне нравятся устройства с высоким КПД своей технологичностью. У схемы в закрепе что можно отнести к недостаткам? Как я понял из комментариев это то что она не позволит использовать акб полностью.
  7. Вот смотрите создаю структуру и в интернете пишут если не писать 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 которые содержат структуру? Мне просто важно понимать как оно устроено, я конечно могу забить и использовать в торой вариант, типо так все делают. Но хотелось бы понимания.
  8. Нормально так, сейчас поиском искал опять инфу как с PIC работать с кан шиной и поиском вышел на это свое двухлетнее сообщение, на которое никто не ответил )))
  9. я тоже подумал об этом и на всякий случай глянул осциллограму, думал вдруг анализатор просто не видет нарастания фронта и тд. Но нет там тоже самое. резисторы в Oled стоят какие то. Вроде по 10к
  10. Еслиб я был умный и грамотный я бы не задавал тут вопросов) Я просто попытался предоставить максимум информации, так как правильно заданный вопрос это 50% успеха.
  11. А что скорость никак не связана с герцами и милисекундами? и у 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 */ }
  12. Не понимаю в чем дело. Регистр SSP1ADD может иметь значение от 0 до 255 Fosc у меня 8mhz то-есть 8000000hz То-есть если он равен 255 то SCLx pin clock period будет равен 7812hz а если он будет равен 1 то частота будет 1Mhz И у меня это работает но на половину. Вот присваиваю регистру SSP1ADD=255; и шлю по i2c и что вижу анализатором: А то что частота в районе 7000hz и шим 56%, ну да ладно. Вбиваю SSP1ADD=19; в надежде получить скорость 100khz: Шим теперь почему то уплыл до 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 */ }
  13. Ну да вот он ответ то чего я не доглядел ))) Спасибо.
  14. Заливаю прошивку, код открыт. Еепром закрыта в конфигурации. Вручную вписываю айди в ячейку еепром. Заливаю, все работает. Далее еще раз На данном скриншоте заливаю туже самую прошивку, но еепром не редактирую, и убираю галочку. Он мне даже пишет мол не будет удалено. Заливаю и все еепром затирается, так как прибор сразу выдает что в еепром нет того айди что я вписал.
  15. ДА я знаю. Меня не считывание волнует. а ЗАПИСЬ. При записи ЕЕПРОМ затирается ВСЕГДА если стояла защита на чтение еепром!
  16. В этом и суть топика. Я так и делаю Галку СНИМАЮ. Но еепром затирается. У меня в коде идет проверка по еепром.
  17. Код у прошивки открытая, а еепром закрытая. При первой записи вручную что то пишу в еепром. Дальше делаю вторую запись другой прошивки, но галочку EEPROM снимаю в надежде на то что запишет только саму прогу а еепром не тронет. Но нет он сносит еепром. Если сделать еепром открытую, то все работает. В чем дело?
  18. Наверно мне бы стоило в вопросах для начинающих задать этот вопрос, но с другой стороны у меня уже это все давно работает, хоть я не знаю как))) Среда 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); Тоесть я правильно понимаю что всего там ограниченное количество фильтров которое я могу использовать на прием?
  19. где взять эту функцию? USART_ClearITPendingBit где взять это USART_IT_RXNE у меня этого просто нету. я понимаю что второе это регистр, но он где то должен быть определен. а у меня нигде не определен и как это сделать я не пойму.
  20. такого нет впринципе.
  21. Значит так флаг поднялся. Сработало прерывание, и обработчик прерываний? вызвался каллбэк? А как переконфигурировать сначала в ногу на выход а потом в ногу уарта? я переконфигурирую и у меня впринципе прием перестает работать
  22. Спасибо теперь понятнее стало почему так работает. Вообщем вопрос в следующем, как запретить поднимать эти флаги прерывания на прием пока я отправляю?
  23. да это понятно, но я же уже отправил, все , ниче не должно быть в приеме дублироваться.
  24. и еще вопрос, почему не работает этот код. у меня стоит драйвер, который параллелит при отправке 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);//запускает прием по уарту как токо придут все байты будут приняты сработает прерывание каллбэк каждый цикл срабатывает каллбэк на прием. но я же вроде как запретил прием.
×
×
  • Создать...