if(PORTB==0b10000000)
PORTB=0b00000001;
else
PORTB<<=1;
и так далее.
Код: Выделить всё
// PERIOD sets the pin toggle freq; toggle PERIOD = (xtal / 4 / freq / 2)
#define PERIOD 10000 // (xtal 4Mhz) TMR0 1MHz, 10000 = 100Hz toggle (50Hz output)
#define PER_COUNTS ((PERIOD / 100) - 1) // don't edit this!
#define PER_REMAINDER (PERIOD - (PER_COUNTS * 100)) // don't edit this!
unsigned int pcount; // used in interrupt to count PER_COUNTS
//-----------------------------------------------------------------------------
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void interrupt()
{
//-----------------------------------------------------
// this is the TMR0 overflow interrupt.
// Note! TMR0 has a 3 tick write latency, writes must be -3
//-----------------------------------------------------
// check if time to toggle the output pin
if(!pcount)
{
asm {
movlw 0x01 ; // mask for pin 0
xorwf GPIO,f ; // toggle PIC pin GPIO.0
}
pcount = (PER_COUNTS+1); // how many delays to make total
TMR0 -= (PER_REMAINDER-3); // first delay will be ==remainder
}
// else make a normal delay
else
{
TMR0 -= (100-3); // make another 100 tick delay
}
pcount--;
//-----------------------------------------------------
// clear the TMR0 overflow flag and exit
INTCON.T0IF = 0;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//=======================
// MAIN
//=======================
void main ()
{
//-----------------------------------------------------
// PIC 12F675 setup ports
ANSEL = 0; // ADC off
CMCON = 0x07; // comparators off
GPIO = 0b00000000; // clear GPIO
TRISIO = 0b00000000; // All outputs
WPU = 0b00000000; // pin pullups; 1 = pullup on (for button)
//-----------------------------------------------------
// timer setup etc
OPTION_REG = 0b00001000; // TMR0 on, 1:1 prescale
pcount = 0;
INTCON = 0b10100000; // GIE on, T0IE on (turn interrupt on)
//-----------------------------------------------------
// main run loop here
while(1)
{
continue; // loop and do nothing, just let the interrupt happen
}
}
//-----------------------------------------------------------------------------
Код: Выделить всё
#define PERIOD 5000000
#define PER_COUNTS ((PERIOD / 100) - 1) // don't edit this!
#define PER_REMAINDER (PERIOD - (PER_COUNTS * 100)) // don't edit this!
static void interrupt Int(void)
{
if(T0IF)
{
if(!pcount)
{
sec++;
pcount = (PER_COUNTS+1);
TMR0 -= (PER_REMAINDER-3);
}
else
{
TMR0 -= (100-3);
}
pcount--;
T0IF = 0;
}
if(TMR1IF)
{
TMR1H = 0xFF; // preset for timer1 MSB register
TMR1L = 0xE7; // preset for timer1 LSB register
LCDIF=1;
TMR1IF=0;
}
}
вот блин расстроился:)Лютик писал(а): Но вот беда- часы уходят за 6 часов на секунд 20(вперед), хотя должны идти точно =). Вопрос- чтото я делаю не так? А также, надо ли учитывать такты(машиные циклы) на выполнение сравнения "if(T0IF)", "if(!pcount)", инкрементирования переменной sec, в общем операции ДО сброса флага прерывания T0IF или я чтото неправильно понимаю
интересное предложение это что означает программно менять частоту кварца??Лютик писал(а):судя по всему выход один - частотомером измерить частоту генерируемой единицы при помощи данного метода и изменяя значение #define PERIOD , а следовательно и частоты кварца добиться желаемого значения
дело в том, что я конденсаторы не использую(в макетке), кварц и так возбуждается, поэтому считаю что можно подогнать частоту программно, тем более так проще имхоvitalik_1984 писал(а):Вы, наверно, хотели сказать что подобрать значение,которое подходит для этой частоты кварца.интересное предложение это что означает программно менять частоту кварца??Лютик писал(а):судя по всему выход один - частотомером измерить частоту генерируемой единицы при помощи данного метода и изменяя значение #define PERIOD , а следовательно и частоты кварца добиться желаемого значения
Не частоту кварца тогда, а частоту секундных импульсов программно менять:)Лютик писал(а):дело в том, что я конденсаторы не использую(в макетке), кварц и так возбуждается, поэтому считаю что можно подогнать частоту программно, тем более так проще имхоvitalik_1984 писал(а): Вы, наверно, хотели сказать что подобрать значение,которое подходит для этой частоты кварца.интересное предложение это что означает программно менять частоту кварца??
Код: Выделить всё
#include <pic.h>
__CONFIG(HS & WDTDIS & LVPDIS & BORDIS & MCLREN);
#define FREQ 20000000 // частота кварца
#define FREQ_IN FREQ/4 // частота на таймер = частота кварца/4
// выбираем число сигнед инт в пределах 1 -32767 для нашей входной
// число должна делиться с 5 000 000 до кратного герцу значению
// останавливаемся на 25000, это будет квант
#define KVANT 25000
#define CMAX FREQ_IN/KVANT // получаем значения для дополнительного счетчика,
// по которому добиваем до секунды - число будет 200
volatile unsigned char cCounterSek; // сам дополнительный счетчик
volatile signed int iCounterKvant; // счетчик кванта
#define OVERFL 256*8 // значение переполнения 0 таймера при делителе = 8
volatile unsigned char cFlagSek; // флаг срабатывания секунды
void init_port(void);
interrupt void intrTimer(void)
{
if (T0IF&& T0IE)
{
T0IF=0;
iCounterKvant-= OVERFL;
if(iCounterKvant <= 0)
{
iCounterKvant+= KVANT;
cCounterSek++;
if(cCounterSek == CMAX)
{
cFlagSek=1;
cCounterSek=0;
}
}
}
}
//----------------------------------------------------------------
void main()
{
init_port();
for(;;)
{
if(cFlagSek)
{
cFlagSek=0;
PORTB^=0xFF;
}
}
}
//----------------------------------------------------------------
void init_port()
{
CMCON=7;//выключаем компараторы
TRISA=0xfF;
TRISB=0x0;
cCounterSek=0;
cFlagSek=0;
iCounterKvant= KVANT;
T0CS=0;
PSA=0;//делитель на таймер 0
PS2=0; // делим до 8
PS1=1;
PS0=0; //
T0IE=1;
PIR1 = 1;
PEIE = 1;
GIE = 1;
}
//--------------------------------------------------
не свосем понял, а если частота 500Гц, допустим, а не 1?urry писал(а):А попроще нельзя ? Так, например
Код: Выделить всё
u8 Power; //требуемое значение мощности
u8 Phase;
s8 Delta;
Phase = MAXPOW; //инициализация, делать 1 раз
Power = MyPower; //задаем требуемое значение мощности
//делать по вылавливанию перехода через 0:
Delta = Power + Delta;
if (Delta < 0)
{
TriacOff();
}
else
{
TriacOn();
Delta = Delta - MAXPOW;
}
Phase = Phase - 1;
if (Phase == 0)
{
Phase = MAXPOW;
Delta = - (Phase / 2);
}
Теперь я не понял, в чем разница ?Лютик писал(а):не свосем понял, а если частота 500Гц, допустим, а не 1?urry писал(а):А попроще нельзя ? Так, например
Код: Выделить всё
char a = 24 ;
char b = 55 ;
int c = 0 ;
c = a*b ; // и тут косяк.отличия Брезенхема состоит как раз в том, что оно дает точный результат, как написано на том сайте. выходит там написана не правда?urry писал(а):Теперь я не понял, в чем разница ?Лютик писал(а): не свосем понял, а если частота 500Гц, допустим, а не 1?
По алгоритму Брезенхема частота очень редко будет соответствовать именно значению 500 Герц, она будет бегать от 499 до 501, скажем, в зависимости от того, на каком участке сейчас находимся.
Но суммарная - за какое -то время - будет именно 500, и чем больше время измерения, тем ближе к требуемой.
Особое значение играет именно знаковая переменная - в моем примере signed int iCounterKvant;
в примере Леонида Ивановича s8 Delta;
в в зависимости от ее знака, принимается решение, в какую сторону регулировать.
Немного упустил нить вашего рассуждения, но это похоже на делитель частоты с дробным коэффициентом деления... тема моего диплома (правда, там всё было "в железе")avreal писал(а):Вот в данном случае если сделать
10 10 10 9 9 9 9 9 9 9
то за 10 периодов среднее будет 9.3, но за первые 3 периода среднее будет 10, отклонение +0.7.
Брезенхем даст что-то в духе
9 10 9 9 10 9 9 9 10 9
1) HEAP, CSTACK, RSTACK - посмотрите настройки этих/подобных параметров в используемой среде. Могут быть заполнены вектора прерываний.БАТАРЕЙКУС писал(а):и ещё непонятно 2-е вещи.
1) вопрос почему в пустом проекте где кроме функции main(){} нечего нету а память программ занята ажжж на 116 байт а озу вооще аж на 268 байт. эт куда такое излишество. чем они там занеты?
2) вопрос как мне зарезервировать некоторое количество байт в озу чтобы хранить там ассемблерные переменные и Си компилятор их не поубивал там.
Код: Выделить всё
__no_init int a @ 0x80;