|
Виж темите без отговор | Виж активните теми
Дата и час: Пон Юли 27, 2026 10:32 pm
| Автор |
Съобщение |
|
Predator_MF
Ранг: Форумен бог
Регистриран на: Чет Окт 07, 2004 1:22 pm Мнения: 1949 Местоположение: София
|
Не само в програмирането сме ги надскочили приятелю (те още пишат на асемблер  ), и откъм хардуер ги минахме 
|
| Сря Сеп 14, 2005 12:03 pm |
|
 |
|
Edesign
Ранг: Форумен бог
Регистриран на: Сря Авг 31, 2005 1:57 pm Мнения: 1103
|
Голямо самохвалство  Добре че все пак ги има и онези "неуки" хорица та и ние да има какво да програмираме пък после да казваме :
|
| Сря Сеп 14, 2005 12:27 pm |
|
 |
|
¶
Ранг: Форумен бог
Регистриран на: Пет Фев 25, 2005 1:58 pm Мнения: 4585 Местоположение: US
|
Ако сте забелязали, повечето документи, които четете за чипове, приложения и т.н. са писани от индийци, източноевропейци и доста малка част от хамериканци. По напред са благодарение на политиката на привличане на мозъци от цял свят. По природа средностатистическия хамериканец е толкова прост, колкото и средностатистическия българин. След 250г. чист капитализъм е такова положението. И тук след толкова години ( стига бат'Серго да не ни завлече в пропаста, както ни завлече бат'Жан ) няма да се спори на такива теми, ами ще се обсъждат например бизнес идеи. И все пак, без да обобщавам, техните совалки падат и гърмят много по-често от да речем изостаналите рашъни.
А TMR0 си работи като пич и не съм срещал проблеми с него, дори и за RTC, просто трябва да се знае, че след презареждането му, трябва няколко инструкции да минат, преди да започнеш да го четеш ( ако го полираш ).
|
| Сря Сеп 14, 2005 1:10 pm |
|
 |
|
Predator_MF
Ранг: Форумен бог
Регистриран на: Чет Окт 07, 2004 1:22 pm Мнения: 1949 Местоположение: София
|
Не е самохвалство, а самочувствие  Смятам да не наводнявам 
|
| Сря Сеп 14, 2005 3:37 pm |
|
 |
|
Dimitar
Ранг: Форумен бог
Регистриран на: Пет Ное 12, 2004 3:38 pm Мнения: 9103 Местоположение: Chicago, IL
|
Това е възможно най-изпадналата фирма бе - закакво въобще спорите.
|
| Сря Сеп 14, 2005 9:55 pm |
|
 |
|
ToHu
Ранг: Форумен бог
Регистриран на: Нед Сеп 26, 2004 9:21 pm Мнения: 30686 Местоположение: София
|
Абе много зависи как си го направиш това прекъсване .... ти може и да забранява прекъсвания но таймера да си расте, аок го прекъсваш на всеки 10 мс не виждам никакъв проблем ... и да изтървеш едно две прекъсвания няма да седиш 2 сек в това състояние я .. та ... така ... той си расте, а ти ще си го обслужиш при следващото прекъсване, това естествено ако качваш секундата на всеки 100 прекъсвания, и след това вместо да зареждаш стойност в таймера, само вадиш 100, така имаш резерв от 1550 мс ... което е дооооста време ... не виждам аз тука големи проблеми ... а това че таймера пропуска няколко такта .. ами това лесно се коригира
|
| Чет Сеп 15, 2005 2:34 am |
|
 |
|
alek
Ранг: Минаващ
Регистриран на: Пет Фев 04, 2005 9:54 am Мнения: 50 Местоположение: Null
|
Всички ли четат само последното мнение в темите?!? За какво му е да се прекъсва 10 пъти в секундата, кагато може само два и ще му остава колкото си иска време и за серийни трансфери... Ама както и да е! Може да си го направи и без таймер и да си се прекъсва 1048576 пъти в секунда ако иска!
|
| Чет Сеп 15, 2005 8:17 am |
|
 |
|
PIC
Ранг: Новодошъл
Регистриран на: Чет Дек 09, 2004 3:15 pm Мнения: 123 Местоположение: Благоевград
|
Доста неща се изписаха , но според мен при препълване на таймера се генерира прекъсване ако е разрешено и може да бъде обслужено при положение , че таймера започва да брои отначало без да пропуска нито един такт и така до следващото прекъсване. Проблема , за който Edesign пише е когато в таймера трябва да се чете или да се записва стойност от/в него. При това положение се пропускат два цикъла , но при мен се отчитат само прекъсванията и се обслужват без да се чете или записва таймера и по този начин мисля , че няма да се получава грешка. А времето за обслужване на прекъсването е доста малко , тъй като се инкрементира софтуерен брояч и се прави някоя проверка и съответно няма вероятност да дойде следващо прекъсване преди да е обслужено предишното. 
|
| Пет Сеп 16, 2005 10:04 am |
|
 |
|
Predator_MF
Ранг: Форумен бог
Регистриран на: Чет Окт 07, 2004 1:22 pm Мнения: 1949 Местоположение: София
|
Ще ме накарате ей сега да го напиша  На TMR1 на пикльовците закачаш 32.768 кристал, ползваш прескалера...получаваш най-перфектинте прекъсвания, за какво продължаваме да си говорим има още 1001 варианта 
|
| Пет Сеп 16, 2005 10:40 am |
|
 |
|
¶
Ранг: Форумен бог
Регистриран на: Пет Фев 25, 2005 1:58 pm Мнения: 4585 Местоположение: US
|
Използвам подходящата тема, за да опиша следния проблем. Имам PIC18F252, TMR1 работи с външен кварц 32.768 kHz. Прекъсването от него обаче не е на 1 секунда, а на всеки 7.8125ms ( или 128 Hz ), като освен за RTC, това прекъсване го използвам за опресняване на LCD индикация без управление. Дава много големи отклонения ( закъснява ) от порядъка на 2-3 минути само за 2-3 часа работа. Предварителния ми делител е 1:1, TMR1L не го закачам, а само презареждам TMR1H с 0xFF, при което получавам време от 256 / 32768 = 7.8125 ms. При използване на PIC16F873 също дава отклонение, но са само 2-3 секунди за 2-3 часа, което е приемливо, при положение, че не съм настройвал кварца с тример кондензатор. Ако го направя да генерира прекъсване на 1 секунда, точността е същата като при PIC16F873, но не ми върши работа, защото професора трябва да поспива от време на време, през което разчитам само на TMR1 за да мога да се оправям с индикацията и RTC. Излиза, че промяната на TMR1H, явно води до промяна в TMR1L ( в смисъл някакво закъснение при следващите отброявания, след презареждане на TMR1H )
Ето и кода на програмата:  |  |  |  | Код: #include <18f252.h> //#DEVICE ICD=TRUE #DEVICE *=8 //#DEVICE HIGH_INTS=TRUE #FUSES RC, NOWDT, NOPROTECT, NOBROWNOUT, PUT, NOLVP, NOWRT #CASE #define OSC_CLOCK 2450000 #USE Delay(Clock=OSC_CLOCK)
#USE FAST_IO(A) #USE FAST_IO(B) #USE FAST_IO(C)
#rom 0x2100={'W','r','i','t','t','e','n',' ','b','y',' ','S','v','e','t','o','s','l','a','v',' ','P','i','r','e','v'}
// Брой дни във всеки месец const char Months[12] = {31,28,31,30,31,30,30,31,30,31,30,31};
// Имена на месеците - bcd code enum MonthsName { Jan = 1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct=0x10, Nov, Dec };
// Подредба на дисплейните символи в CharTable enum Characters { char0 = 0, char1, char2, char3, char4, char5, char6, char7, char8, char9, charA, charB, charC, charD, charE, charF, charT, charH, charP, charL, UpLine, Minus, BotLine, Space, charU, charN, charO, charR, HiDegree, LowPulse, HiPulse, LoDegree = charO, charY = 31 };
typedef struct { char fflashDigits; // bit0 - Flashing Digit 0 are enabled // bit1 - Flashing Digit 1 are enabled // bit2 - Flashing Digit 2 are enabled // bit3 - Flashing Digit 3 are enabled // bit4 - // bit5 - // bit6 - // bit7 - char cflashDigits; char lcd[4]; // 4 байта видеопамет, lcd[3]=MSB, lcd[0]=LSB int semicolon:1; // флаг показване/скриване на двуеточието int dp2:1; // флаг показване/скриване на десетична точка 2 int dp3:1; // флаг показване/скриване на десетична точка 3 int dp4:1; // флаг показване/скриване на десетична точка 4 int fflashDegree:1; // флаг за мигане на показвания аналогов канал } Display;
// // used from RTC clock: year,month,day,hour,minute,second . // typedef struct { char year, // година month, // месец day, // ден hour, // час minute, // минута second; // секунда int fPwrDown:1; // Индикатор за отпаднало захранване int fSecond:1; // Индикатор за смяна на секундата int fMinute:1; // Индикатор за смяна на минутата int fHour:1; // Индикатор за смяна на часа } RTC;
RTC rtc; Display display; int8 flags, adcflags, kflags, Mode, Menu;
#bit time7ms8125=flags.1 // 7.8125 ms
#bit an_chn0=adcflags.0 #bit an_chn1=adcflags.1 #bit an0_complete=adcflags.2 #bit an1_complete=adcflags.3 #bit an_hex_mode=adcflags.4
#bit _BackPlane=PORTB.4
void UpdateDisplay(void) {
if( ! _BackPlane ) { /* ........ */ } else { /* ........ */ } _BackPlane = ! _BackPlane; }
// Interrupt every 7.8125ms ( for 64Hz LCD refresh rate ) void InitRTC(void) { TRISC |= 0b00000011; // Make RC1/T1OSI & RC0/T1OSO to be inputs TMR1H = 0xFF; TMR1L = 0x00; T1CON = 0b00001110; // 1:1 prescaler, do not synchronize, external clock from crystal // two 8-bit registers TMR1IP = 1; // High interrupt priority TMR1IF = 0; // Clear interrupt flag TMR1IE = 1; // Enable interrupt from TMR1 module TMR1ON = 1; // Start TMR1 to work }
#define IncBCD(reg) \ #asm \ movf reg,W \ addlw 1 \ daw \ movwf reg \ #endasm
#define BCD_RTC
#INT_TIMER1 void Tmr1Handler(void) { static int8 counter = 128, r;
TMR1H = 0xFF; // interrupt every 7.8125s ( for 64Hz LCD refresh rate ) TMR1IF = 0;
UpdateDisplay();
time7ms8125 = 1;
if( --counter ) return; counter = 128;
rtc.fSecond = 1;
#ifdef BIN_RTC // Binary version of RTC rtc.fSecond = 1; if( ++rtc.second > 59 ) { rtc.second = 0; if( ++rtc.minute > 59 ) { rtc.minute = 0; if( ++rtc.hour > 23 ) { rtc.hour = 0; r = Months[ rtc.month ]; if( rtc.month == Feb ) { if( rtc.year % 4 == 0 ) r++; } if( ++rtc.day > r ) { rtc.day = 1; if( ++rtc.month > Dec ) { rtc.month = Jan; // Happy new year :) if( ++rtc.year > 0x99 ) rtc.year = 0x00; } } } } } #else #ifdef BCD_RTC // BCD version of RTC IncBCD( rtc.second ); rtc.fSecond = 1; if( rtc.second > 0x59 ) { rtc.second = 0; IncBCD( rtc.minute ); if( rtc.minute > 0x59 ) { rtc.minute = 0; IncBCD( rtc.hour ); if( rtc.hour > 0x23 ) { rtc.hour = 0; r = Months[ rtc.month ]; if( rtc.month == Feb ) { if( rtc.year % 4 == 0 ) r++; } IncBCD( rtc.day ); if( rtc.day > r ) { rtc.day = 1; IncBCD( rtc.month ); if( rtc.month > Dec ) { rtc.month = Jan; IncBCD( rtc.year ); // Happy new year :) if( rtc.year > 0x99 ) rtc.year = 0; } } } } } #endif #endif }
void ScanKey(void) { /* .....
..... */ }
void InitHardware(void) { INTCON = 0; PORTA = 0; PORTB = 0; PORTC = 0; TRISA = 0b00011111; TRISB = 0b11100000; TRISC = 0b11011011;
memset( &display, 0, sizeof(display) );
if( ! POR && NOT_PD ) { POR = 1; rtc.hour = 0x12; rtc.minute = 0x00; rtc.second = 0x57; rtc.day = 0x16; rtc.month = 0x09; rtc.year = 0x05; display.lcd[0] = display.lcd[1] = display.lcd[2] = display.lcd[3] = Space; } INTCON2 = 0; // Enable PORTB pull-up resistors T0CON = 0; // Stop TMR0 _BackPlane = 0; InitRTC(); flags = 0; kflags = 0; rtc.fPwrDown = 0; rtc.fSecond = 0; Menu = 0; Mode = 0; /* IPEN = 1; // Set interrupt priority scheme GIEH = 1; // Enable all unmasked interrupts with high priority GIEL = 1; // Enable all unmasked interrupts with low priority */ INTCON |= 0b11000000; // Enable all unmasked interrupts }
main() {
InitHardware();
while ( 1 ) {
sleep();
if( time7ms8125 ) { // 7.8125 ms
time7ms8125 = 0;
ScanKey();
switch( Mode ) { case 0: // Mode = Normal mode if( rtc.fSecond ) { rtc.fSecond = 0; /* ....... */ } break;
case 1: // Mode = Set Clock switch( Menu ) { case 0: /* ..... */ break; case 1: /* ..... */ break; case 2: /* ..... */ break; case 3: /* ..... */ break; } break;
case 2: // Mode = Show temperature from AN0 if( an0_complete ) { an0_complete = 0; /* ..... */ } break;
case 3: // Mode = Show temperature from AN1 if( an1_complete ) { an1_complete = 0; /* ..... */ } break;
case 4: // Show AN0 - AN1 if( an0_complete && an1_complete ) an0_complete = 0; an1_complete = 0; /* ..... */ break; } } } }
|  |  |  |  |
|
| Пет Сеп 16, 2005 12:29 pm |
|
 |
|
PIC
Ранг: Новодошъл
Регистриран на: Чет Дек 09, 2004 3:15 pm Мнения: 123 Местоположение: Благоевград
|
Ясно че има много варианти , но не е ли все едно откъде ще се инкрементира таймера - вътрешния такт или кварц на таймер1. Ако използваме вътрешния такт обаче ще имаме възможност да ползваме за друга цел изводите за кварц на таймер1. 
|
| Пет Сеп 16, 2005 1:04 pm |
|
 |
|
¶
Ранг: Форумен бог
Регистриран на: Пет Фев 25, 2005 1:58 pm Мнения: 4585 Местоположение: US
|
Ако използваш вътрешния генератор, не можеш да вкараш професора в sleep режим, а ако използваш батерийно захранване това е почти наложително.
|
| Пет Сеп 16, 2005 1:07 pm |
|
 |
|
TheHungry
Ранг: Почетен член
Регистриран на: Съб Сеп 03, 2005 11:31 am Мнения: 766 Местоположение: Пловдив
|
Много ми е интересно как се справяте с температурната нестабилност  ) ако използвате обикновенни кварцове.
Frequency Stability: (over temperature range)
± 50 ppm
сравнено със това
±0.3ppm and operating temperature ranges as wide as -55 to 95°C за необикновенните такива. 
|
| Пет Сеп 16, 2005 1:30 pm |
|
 |
|
¶
Ранг: Форумен бог
Регистриран на: Пет Фев 25, 2005 1:58 pm Мнения: 4585 Местоположение: US
|
Не се притеснявам за температурната нестабилност, понеже при високи и/или ниски температури самия PIC няма да работи  Поне аз не рискувам да използвам PIC при температури под 20 градуса, както и при над 35 градуса. Не че в -20 +35 не си е риск, ама все пак е по-малък.
Значи моето твърдение по-горе, че не пипам TMR1L при прекъсване от TMR1, а само презареждам TMR1H в прекъсването, при което за 2-3 часа се получават 2-3 минути закъснение на процесора си е бъг на всички PIC процесори с TMR1 модул, работещ с външен кварцов кристал. За това свидетелствува пикльочипския документ 80233a.pdf
Това което разбрах от този документ е, че системния осцилатор трябва да е > 4MHz, за да може още по-време на високия импулс на 32.768kHz кристала да се извърши презареждането на TMR1H. Или казано по друг начин, след възникването на препълването на TMR1, трябва в рамките на 15.25 us да се презареди TMR1H, ако искаме TMR1L да не пропуска цикли. Аз обаче работя на 2.45 MHz и освен това бях спокоен, че дори и да се забавя в обработката на прекъсването от АЦП-то, все пак има 7ms до следващото прекъсване на TMR1, през което време мога спокойно да си презаредя TMR1H. Да ама съм си правил сметката без кръчмаря.
Реших да прецакам кръчмаря, като включа използването на приоритетите при прекъсвания в PIC18F, предвидливо обаче този път първо прочетох errata документите и се оказа, че кръчмаря е пак едни гърди пред мен. И в модула за приоритет на прекъсванията има отново бъгове. Workaround на ПикльоЧип e да не се използва този модул или ако се използва, асинхронните прекъсвания да са с нисък приоритет.
Workaround, който намерих, е като включих TMR3, като и него го насочих към TMR1 осцилатора. С TMR3 правя прекъсване на 7.8125ms, като дебна когато дойде момента на прекъсване на TMR1 да спра временно всички прекъсвания ( това го смятам в прекъсването на TMR3 ), т.е. за 15ms заебавам LCD-то и АЦП-то, за да ме прекъсне TMR1, да му заредя нова стойност в TMR1H, след което си продължавам с останалите прекъсвания. Сложно, но друг начин не намерих. Омръзнаха ми тия говеда от MicroChip ! За най-елементарна програма, трябва да губя сума ти време да им търся WorkAround на простотиите. В следващата версия ще сложа хардуерен часовник с някой PCF чип по I2C. В още по-следващата ще заменя PIC18F252 с Mega16.
|
| Пет Сеп 16, 2005 4:54 pm |
|
 |
|
Dimitar
Ранг: Форумен бог
Регистриран на: Пет Ное 12, 2004 3:38 pm Мнения: 9103 Местоположение: Chicago, IL
|
Все същата работа - от трън та на глог  .
|
| Пет Сеп 16, 2005 6:56 pm |
|
|
Кой е на линия |
Потребители разглеждащи този форум: 0 регистрирани и 2 госта |
|
Вие не можете да пускате нови теми Вие не можете да отговаряте на теми Вие не можете да променяте собственото си мнение Вие не можете да изтривате собствените си мнения Вие не можете да прикачвате файл
|
|