...http://www.labkit.ru/html/C_for_PIC
ИМХО лучше учитса на пиках,т.к. их легче понять,да и фьюзофренией пики не болеют в отличие от авр.
Ну, решений может быть столько, сколько людей будет это делать.FreshMan писал(а):это единственно возможное решение данной задачи ?
ой неправ, как неправ. это от мозга конкретного человека зависит, мы с товарищами с асма начинали и с основных процессов внутри процессора и работали с эмуляторами где пишешь хекс код и видишь из какого регистра в какой что идёт, и потом си пристроить к этому делу легко.HeLiO писал(а):полнаый бред. только запуешься если начинать с ассемблера. НУжно начинать на СИ писать и потом использовать только си, а ассемблер начать гораздо позже, и то достаточно на уровне понимания кода, самому писать вряд ли понадобится что либо
Код: Выделить всё
#include <mega8.h>
#include <delay.h>
#define kn_sec_reset PINC.0 // на 0 пин порта С подключена кнопка сброса секунд
#define kn_min_up PINC.1 // на 1 пин порта С подключена кнопка инкремента минут
unsigned char sec, min, x, i;
unsigned char number[4]; // в этом массиве мы будем хранить десятки и единици секунд и минут
unsigned char znak[4]={16,32,64,128}; // в этом массиве мы храним номер анода индикатора определенного разряда
interrupt [TIM1_COMPA] void timer1_compa_isr(void) // Timer1 срабатывает каждые 5мс
{
if (++x==200) {sec++; x=0;};
}
void output(unsigned char sec, unsigned char min)
{
number[0]=sec%10; //в массив записываем остаток от деления преременной sec
number[1]=sec/10; // в массив записываем целую часть от деления преременной sec
number[2]=min%10; // в массив записываем остаток от деления преременной min
number[3]=min/10; // в массив записываем целую часть от деления преременной min
for (i=0;i!=4;i++) // по очереди выводим на индикаторы выше вычесленные данные
{
PORTD=0;
PORTD=(number[i]|znak[i]);
};
}
void main(void)
{
// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=P State0=P
PORTC=0x03;
DDRC=0x00;
// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTD=0x00;
DDRD=0xFF;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
// Mode: CTC top=OCR1A
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x0A;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x02;
OCR1AL=0x71;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x10;
// Global enable interrupts
#asm("sei")
while (1)
{
output(min,sec);
if (sec==60) {sec=0; min++;};
if (min==60) min=0;
if (kn_sec_reset==0) {delay_ms(10);sec=0; while(kn_sec_reset==0){}; delay_ms(10);};
if (kn_min_up==0) {delay_ms(10);min++; while(kn_min_up==0){}; delay_ms(10);};
};
}
Ну, насчёт армовского ассемблера Вы неправы: он много удобней и мощнее, чем у AVR.DX168B писал(а):А я ведь тоже с ассемблера начинал, когда АВРки изучал. Но на Си так и не перешёл. За то, когда перешёл на ядра Cortex M3 \ A8, так там сразу с Си начал, ибо ассемблер там жуткий.
В комментарии написано, что выводите по очереди, а на самом деле очень быстро меняете числа. Настолько быстро (несколько микросекунд), что индикатор не успевает отобразить ничего кроме одной цифры. На нее тратится гораздо больше времени, потому что программе нужно выйти из функции, попасть в главный цикл, а потом снова вернуться. Нужно каким то образом сделать так, что бы показания изменялись равномерно во времени и помедленнее, например раз в 5мс. Для этого можно например убрать цикл и менять состояние порта только один раз во время вызова функции с соотв наращиванием счетчика, а в функции делать смену только если будет выставлен флаг в прерывании. Или перенести вывод в прерывание.FreshMan писал(а):Код: Выделить всё
for (i=0;i!=4;i++) // по очереди выводим на индикаторы выше вычесленные данные { PORTD=0; PORTD=(number[i]|znak[i]); }; }
Мне кажется надо for (i=0;i<4;i++)FreshMan писал(а):
for (i=0;i!=4;i++) // по очереди выводим на индикаторы выше вычесленные данные
Код: Выделить всё
#include <mega8.h>
#include <delay.h>
#define kn_sec_reset PINC.0 // на 0 пин порта С подключена кнопка сброса секунд
#define kn_min_up PINC.1 // на 1 пин порта С подключена кнопка инкремента минут
unsigned int x;
unsigned char sec, min,i;
unsigned char number[4]; // в этом массиве мы будем хранить десятки и единици секунд и минут
unsigned char znak[4]={16,32,64,128}; // в этом массиве мы храним номер анода индикатора определенного разряда
interrupt [TIM0_OVF] void timer0_ovf_isr(void)// Timer 0 срабатывает каждую мс
{
// Reinitialize Timer 0 value
TCNT0=0x83;
// Place your code here
if(++x==1000) {sec++; x=0;};
}
interrupt [TIM1_COMPA] void timer1_compa_isr(void)// Timer 1 срабатывает каждые 5мс
{
PORTD=0;
switch (i)
{
case 0:PORTD=number[i]|znak[i];break;
case 1:PORTD=number[i]|znak[i];break;
case 2:PORTD=number[i]|znak[i];break;
case 3:PORTD=number[i]|znak[i];break;
};
if (++i==4)i=0;
}
void main(void)
{
// Declare your local variables here
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;
// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=P State0=P
PORTC=0x03;
DDRC=0x00;
// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTD=0x00;
DDRD=0xFF;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
TCCR0=0x02;
TCNT0=0x83;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
// Mode: CTC top=OCR1A
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x0A;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x02;
OCR1AL=0x71;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x11;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// Global enable interrupts
#asm("sei")
while (1)
{
number[0]=sec%10; //в массив записываем остаток от деления преременной sec
number[1]=sec/10; // в массив записываем целую часть от деления преременной sec
number[2]=min%10; // в массив записываем остаток от деления преременной min
number[3]=min/10; // в массив записываем целую часть от деления преременной min
if (sec==60) {sec=0; min++;};
if (min==60) min=0;
if (kn_sec_reset==0) {delay_ms(10);sec=0; while(kn_sec_reset==0){}; delay_ms(10);};
if (kn_min_up==0) {delay_ms(10);min++; while(kn_min_up==0){}; delay_ms(10);};
};
}
Код: Выделить всё
#include <mega8.h>
#include <delay.h>
#define kn_sec_reset PINC.0 // на 0 пин порта С подключена кнопка сброса секунд
#define kn_min_up PINC.1 // на 1 пин порта С подключена кнопка инкремента минут
#define anod_sec_l (PORTD|=(1<<4))
#define anod_sec_h (PORTD|=(1<<5))
#define anod_min_l (PORTD|=(1<<6))
#define anod_min_h (PORTD|=(1<<7))
unsigned int var;
unsigned char sec, min,i;
unsigned char number[4]; // в этом массиве мы будем хранить десятки и единици секунд и минут
//unsigned char znak[4]={16,32,64,128}; // в этом массиве мы храним номер анода индикатора определенного разряда
interrupt [TIM0_OVF] void timer0_ovf_isr(void)// Timer 0 срабатывает каждую мс
{
// Reinitialize Timer 0 value
TCNT0=0x83;
// Place your code here
if(++var==1000) {sec++; var=0;};
}
interrupt [TIM1_COMPA] void timer1_compa_isr(void)// Timer 1 срабатывает каждые 5мс
{
PORTD=0;
switch (i)
{
case 0:PORTD=number[i]; anod_sec_l; break;
case 1:PORTD=number[i]; anod_sec_h; break;
case 2:PORTD=number[i]; anod_min_l; break;
case 3:PORTD=number[i]; anod_min_h; break;
};
if (++i==4)i=0;
}
void mathematics(unsigned char sec, min)
{
number[0]=sec%10; //в массив записываем остаток от деления преременной sec
number[1]=sec/10; // в массив записываем целую часть от деления преременной sec
number[2]=min%10; // в массив записываем остаток от деления преременной min
number[3]=min/10; // в массив записываем целую часть от деления преременной min
}
void main(void)
{
// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=P State0=P
PORTC=0x03;
DDRC=0x00;
// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTD=0x00;
DDRD=0xFF;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
TCCR0=0x02;
TCNT0=0x83;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
// Mode: CTC top=OCR1A
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x0A;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x02;
OCR1AL=0x71;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x11;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// Global enable interrupts
#asm("sei")
while (1)
{
mathematics (min,sec);
if (sec==60) {sec=0; min++;};
if (min==60) min=0;
if (kn_sec_reset==0) {delay_ms(10);sec=0; while(kn_sec_reset==0){}; delay_ms(10);};
if (kn_min_up==0) {delay_ms(10);min++; while(kn_min_up==0){}; delay_ms(10);};
};
}
Код: Выделить всё
interrupt [TIM0_OVF] void timer0_ovf_isr(void)// Timer 0 срабатывает каждую мс
{
// Reinitialize Timer 0 value
TCNT0=0x83;
// Place your code here
if(++var==1000) {sec++; var=0;};
}Код: Выделить всё
interrupt [TIM0_COMPA] void timer1_compa_isr(void) // Timer1 срабатывает каждые 5мс
{
if (++x==200) {sec++; x=0;};
}Код: Выделить всё
TCNT0 = 0;
OCR0 = ваше значение
TCCR0 = (0<< FOC0)|(0<<WGM00)| // разрешить работу и прерывание таймер0
(0<<COM01)|(0<<COM00)|
(1<<WGM01)|(1<< CS02)|
(0<< CS01)|(1<< CS00);а почему нужно делать так ? из каких соображений ?phanis писал(а):используйте прерывание по компаратору с автоматическим сбросом регистра TCNT0 бит WGM01