Страница 2 из 3
Re: Научите писать программы для МК
Добавлено: Вс мар 06, 2011 09:12:32
К@Т
Вот неплохие самоучители по пикам
http://www.labkit.ru/html/Assembler_for_PIC....
...
http://www.labkit.ru/html/C_for_PIC
ИМХО лучше учитса на пиках,т.к. их легче понять,да и фьюзофренией пики не болеют в отличие от авр.
Re: Научите писать программы для МК
Добавлено: Вс мар 06, 2011 12:33:48
krant
Правильно, учится надо надо на пиках. Да и тем более Микрочип себя чуствует намного лучше нежели АВР.
Если програмирование не знаете вообще (т.е. не умеете строить алгоритмы), то вам будет очень тяжело, ведь кроме специфики контроллера, вы не знаете особенностей програмирования.
Вот путь которы я Вам советую:
Шпак Ю.А.
эта книга можно сказать основа основ в Си програмировании, учитывающая специфику програмирования для контроллеров. Там подробно изложена структура языка, с пояснением всего и вся.
Если Вы продолжите изучать пик контроллеры, то следующими книгами у вас должны быть:
Барри Брэй
Лусио Ди Джасио.
Лучше не пожалеть денег, а покупать книги в бумажном варианте, а не в электронном. Книги очень толковые, всё хорошо расписано (Правда по Брэю экран у меня работать не стал, но это единственный его косяк с которым я столкнулся).
Я советую кстати учиться не на живом общении, а на чтении исходников, это более действенный вариант

Re: Научите писать программы для МК
Добавлено: Вс мар 18, 2012 23:37:56
FreshMan
доброго времени суток многоуважаемые знатоки, для меня тоже очень актуальна данная тема т.к. сам толком не знаю с чего начать и как закончить написание проги............., есть опыт

при написании проги которая мигает светодиодами.........., пишу на Си в CodeVision..............., на данный момент поставил перед собой цель написать прогу для часов на atmega8............., в качестве индикаторов ИН-4.................., что должно составлять костяк проги, какова должна быть ее структура.........., подскажите плиз

Re: Научите писать программы для МК
Добавлено: Пн мар 19, 2012 12:53:36
korsaj
Костяк программы - часы (прерывания от таймера). В прерываниях (допустим каждые 50мс) подсчитываешь время (вначале милисикунды, до переполнения, далее секунды, далее единицы минут, далее десятки минут, до 6, далее единицы часов, далее десятки часов до 2 ), опрашиваешь кнопки и сравниваешь текущее время с будильником. В основном цикле можно ничего не размещать, а можно разместить будильник и опрос кнопок (не забываем о дребезге контактов).
ЗЫ Удачи!
Re: Научите писать программы для МК
Добавлено: Пн мар 19, 2012 19:05:44
FreshMan
это единственно возможное решение данной задачи ?
Re: Научите писать программы для МК
Добавлено: Пн мар 19, 2012 19:46:59
BVS
FreshMan писал(а):это единственно возможное решение данной задачи ?
Ну, решений может быть столько, сколько людей будет это делать.
Но не надо сразу идти своим путем, возьмите чужой проект, можно и не один, разберитесь в нем попробуйте изменить его, не бойтесь экспериментов.
Пока у вас одни вопросы и нет действий, все ответы есть в Интернете (Книги, даташиты, статьи)
Re: Научите писать программы для МК
Добавлено: Пн мар 19, 2012 20:57:58
mazda
HeLiO писал(а):полнаый бред. только запуешься если начинать с ассемблера. НУжно начинать на СИ писать и потом использовать только си, а ассемблер начать гораздо позже, и то достаточно на уровне понимания кода, самому писать вряд ли понадобится что либо
ой неправ, как неправ. это от мозга конкретного человека зависит, мы с товарищами с асма начинали и с основных процессов внутри процессора и работали с эмуляторами где пишешь хекс код и видишь из какого регистра в какой что идёт, и потом си пристроить к этому делу легко.
тем более на асме можно делать то чего нельзя на си, компилятор некоторые вещи не оптимизирует, бывают довольно оригинальные вычисления вобщето.
Главное научиться читать и писать, а там приложиться
Re: Научите писать программы для МК
Добавлено: Пн мар 19, 2012 21:25:51
DX168B
А я ведь тоже с ассемблера начинал, когда АВРки изучал. Но на Си так и не перешёл. За то, когда перешёл на ядра Cortex M3 \ A8, так там сразу с Си начал, ибо ассемблер там жуткий.
Re: Научите писать программы для МК
Добавлено: Вс мар 25, 2012 10:43:14
FreshMan
написал свою первую прогудля часов, но она почему-то не работает..........., подскажите
пожалуйста в чем может быть причина ?
в ней выводятся только секунды и минуты на индикаторы ИН-4, аноды этих индикаторов подключены к 4 старшим разрядам порта D, а катоди к 155ид1, информационные входы которой подключены к 4 младшим разрядам порта D.
Код: Выделить всё
#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);};
};
}
Re: Научите писать программы для МК
Добавлено: Вс мар 25, 2012 12:57:37
SII
DX168B писал(а):А я ведь тоже с ассемблера начинал, когда АВРки изучал. Но на Си так и не перешёл. За то, когда перешёл на ядра Cortex M3 \ A8, так там сразу с Си начал, ибо ассемблер там жуткий.
Ну, насчёт армовского ассемблера Вы неправы: он много удобней и мощнее, чем у AVR.
Изучать лучше, ИМХО, сначала Паскаль/Дельфи на ПК (написание консольных приложений), и лишь затем начинать работать с МК. Главное в программировании -- алгоритмистика, а отнюдь не конкретный язык программирования, и настоящим программистом делает не знание одного или нескольких языков, а умение превращать задачу в чёткий алгоритм её решения. Ну а на при работе с МК знание ассемблера абсолютно обязательно: есть масса вещей, которые ни на каком языке высокого уровня не сделаешь вообще или же сделаешь, но неэффективно. И если на ПК от таких вещей программиста-прикладника спасает ОС (не приходится напрямую работать с железом, обрабатывать прерывания и т.п.), то на МК всё надо делать самому.
Re: Научите писать программы для МК
Добавлено: Вс мар 25, 2012 20:15:49
Galizin
FreshMan писал(а):
Код: Выделить всё
for (i=0;i!=4;i++) // по очереди выводим на индикаторы выше вычесленные данные
{
PORTD=0;
PORTD=(number[i]|znak[i]);
};
}
В комментарии написано, что выводите по очереди, а на самом деле очень быстро меняете числа. Настолько быстро (несколько микросекунд), что индикатор не успевает отобразить ничего кроме одной цифры. На нее тратится гораздо больше времени, потому что программе нужно выйти из функции, попасть в главный цикл, а потом снова вернуться. Нужно каким то образом сделать так, что бы показания изменялись равномерно во времени и помедленнее, например раз в 5мс. Для этого можно например убрать цикл и менять состояние порта только один раз во время вызова функции с соотв наращиванием счетчика, а в функции делать смену только если будет выставлен флаг в прерывании. Или перенести вывод в прерывание.
Это можно сравнить с объявлениями на столбе. Если Вы хотите что бы увидели все 4 объявления, то должны будете их менять например с интервалов в один час. Если же Вы наклеете сразу все четыре друг на друга, то шанса увидеть нижние под последним нет.
Re: Научите писать программы для МК
Добавлено: Пн мар 26, 2012 15:07:43
ds1307
FreshMan писал(а):
for (i=0;i!=4;i++) // по очереди выводим на индикаторы выше вычесленные данные
Мне кажется надо for (i=0;i<4;i++)
Более глубоко не вникал
Re: Научите писать программы для МК
Добавлено: Пн мар 26, 2012 21:45:45
FreshMan
вот что получилось опосля переделки:
Код: Выделить всё
#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);};
};
}
какие будут предложения в плане модернизации и усовершенствования ?

Re: Научите писать программы для МК
Добавлено: Вт мар 27, 2012 17:27:29
FreshMan
немного модернезировал прогу но она перестала работать..............., вроде все так, но они стали идти ОЧЕНЬ медленно..........., подскажите, плиз, где я ошибся ?
Код: Выделить всё
#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);};
};
}
Re: Научите писать программы для МК
Добавлено: Вс апр 22, 2012 14:37:31
FreshMan
неуж то никто не знает

Re: Научите писать программы для МК
Добавлено: Пн апр 23, 2012 18:19:25
phanis
в место прерывания по переполнению
Код: Выделить всё
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;};
}
используйте прерывание по компаратору с автоматическим сбросом регистра TCNT0 бит WGM01
Код: Выделить всё
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);
Re: Научите писать программы для МК
Добавлено: Пн апр 23, 2012 18:43:51
ploop
FreshMan, всё замечательно, но или ты вложишь тексты во вложения, или придётся их снести. Смотри сам.
Re: Научите писать программы для МК
Добавлено: Пн апр 23, 2012 19:04:12
FreshMan
ploop, оформить их отдельным файлом ?
Re: Научите писать программы для МК
Добавлено: Пн апр 23, 2012 19:07:33
FreshMan
phanis писал(а):используйте прерывание по компаратору с автоматическим сбросом регистра TCNT0 бит WGM01
а почему нужно делать так ? из каких соображений ?

Re: Научите писать программы для МК
Добавлено: Пн апр 23, 2012 19:29:15
phanis
Так у вас будут четкие интервалы времени по сравнению с прерыванием по переполнению. Т.е сам интервал времени между прерываниями будет реализован на аппаратном уровне.
Посмотрите на полученный ассемблер из си кода. Или просто в протеусе по экспериментируйте.