Научите писать программы для МК
- К@Т
- Говорящий с текстолитом
- Сообщения: 1573
- Зарегистрирован: Сб окт 09, 2010 12:33:48
- Откуда: Незалежная
Re: Научите писать программы для МК
Вот неплохие самоучители по пикам http://www.labkit.ru/html/Assembler_for_PIC....
...http://www.labkit.ru/html/C_for_PIC
ИМХО лучше учитса на пиках,т.к. их легче понять,да и фьюзофренией пики не болеют в отличие от авр.
...http://www.labkit.ru/html/C_for_PIC
ИМХО лучше учитса на пиках,т.к. их легче понять,да и фьюзофренией пики не болеют в отличие от авр.
У кошки 4 ноги и хвост-плюс,минус,вход,выход,а хвост-земля.....Надо переходить с китайской бурды на канифоль.......[url=http://infobar.hsdn.org/][img]http://static.hsdn.org/infobar/350x60.gif[/img][/url]
Re: Научите писать программы для МК
Правильно, учится надо надо на пиках. Да и тем более Микрочип себя чуствует намного лучше нежели АВР.
Если програмирование не знаете вообще (т.е. не умеете строить алгоритмы), то вам будет очень тяжело, ведь кроме специфики контроллера, вы не знаете особенностей програмирования.
Вот путь которы я Вам советую:
Шпак Ю.А.
эта книга можно сказать основа основ в Си програмировании, учитывающая специфику програмирования для контроллеров. Там подробно изложена структура языка, с пояснением всего и вся.
Если Вы продолжите изучать пик контроллеры, то следующими книгами у вас должны быть:
Барри Брэй
Лусио Ди Джасио.
Лучше не пожалеть денег, а покупать книги в бумажном варианте, а не в электронном. Книги очень толковые, всё хорошо расписано (Правда по Брэю экран у меня работать не стал, но это единственный его косяк с которым я столкнулся).
Я советую кстати учиться не на живом общении, а на чтении исходников, это более действенный вариант
Если програмирование не знаете вообще (т.е. не умеете строить алгоритмы), то вам будет очень тяжело, ведь кроме специфики контроллера, вы не знаете особенностей програмирования.
Вот путь которы я Вам советую:
Шпак Ю.А.
эта книга можно сказать основа основ в Си програмировании, учитывающая специфику програмирования для контроллеров. Там подробно изложена структура языка, с пояснением всего и вся.
Если Вы продолжите изучать пик контроллеры, то следующими книгами у вас должны быть:
Барри Брэй
Лусио Ди Джасио.
Лучше не пожалеть денег, а покупать книги в бумажном варианте, а не в электронном. Книги очень толковые, всё хорошо расписано (Правда по Брэю экран у меня работать не стал, но это единственный его косяк с которым я столкнулся).
Я советую кстати учиться не на живом общении, а на чтении исходников, это более действенный вариант

Re: Научите писать программы для МК
доброго времени суток многоуважаемые знатоки, для меня тоже очень актуальна данная тема т.к. сам толком не знаю с чего начать и как закончить написание проги............., есть опыт
при написании проги которая мигает светодиодами.........., пишу на Си в CodeVision..............., на данный момент поставил перед собой цель написать прогу для часов на atmega8............., в качестве индикаторов ИН-4.................., что должно составлять костяк проги, какова должна быть ее структура.........., подскажите плиз 
Tell Me The Truth
Re: Научите писать программы для МК
Костяк программы - часы (прерывания от таймера). В прерываниях (допустим каждые 50мс) подсчитываешь время (вначале милисикунды, до переполнения, далее секунды, далее единицы минут, далее десятки минут, до 6, далее единицы часов, далее десятки часов до 2 ), опрашиваешь кнопки и сравниваешь текущее время с будильником. В основном цикле можно ничего не размещать, а можно разместить будильник и опрос кнопок (не забываем о дребезге контактов).
ЗЫ Удачи!
ЗЫ Удачи!
Re: Научите писать программы для МК
это единственно возможное решение данной задачи ?
Tell Me The Truth
Re: Научите писать программы для МК
FreshMan писал(а):это единственно возможное решение данной задачи ?
Ну, решений может быть столько, сколько людей будет это делать.
Но не надо сразу идти своим путем, возьмите чужой проект, можно и не один, разберитесь в нем попробуйте изменить его, не бойтесь экспериментов.
Пока у вас одни вопросы и нет действий, все ответы есть в Интернете (Книги, даташиты, статьи)
Re: Научите писать программы для МК
HeLiO писал(а):полнаый бред. только запуешься если начинать с ассемблера. НУжно начинать на СИ писать и потом использовать только си, а ассемблер начать гораздо позже, и то достаточно на уровне понимания кода, самому писать вряд ли понадобится что либо
ой неправ, как неправ. это от мозга конкретного человека зависит, мы с товарищами с асма начинали и с основных процессов внутри процессора и работали с эмуляторами где пишешь хекс код и видишь из какого регистра в какой что идёт, и потом си пристроить к этому делу легко.
тем более на асме можно делать то чего нельзя на си, компилятор некоторые вещи не оптимизирует, бывают довольно оригинальные вычисления вобщето.
Главное научиться читать и писать, а там приложиться
я его в гугл на дрц прогнал, вы знаете, пи-када нет.
- DX168B
- Друг Кота
- Сообщения: 4468
- Зарегистрирован: Вс янв 24, 2010 19:19:52
- Откуда: Главный Улей России (Moscow)
- Контактная информация:
Re: Научите писать программы для МК
А я ведь тоже с ассемблера начинал, когда АВРки изучал. Но на Си так и не перешёл. За то, когда перешёл на ядра Cortex M3 \ A8, так там сразу с Си начал, ибо ассемблер там жуткий.
I am DX168B and this is my favourite forum on internet!
Re: Научите писать программы для МК
написал свою первую прогудля часов, но она почему-то не работает..........., подскажите пожалуйста в чем может быть причина ?
в ней выводятся только секунды и минуты на индикаторы ИН-4, аноды этих индикаторов подключены к 4 старшим разрядам порта D, а катоди к 155ид1, информационные входы которой подключены к 4 младшим разрядам порта D.
в ней выводятся только секунды и минуты на индикаторы ИН-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);};
};
}
Tell Me The Truth
-
SII
- Вымогатель припоя
- Сообщения: 635
- Зарегистрирован: Пт янв 30, 2009 14:50:35
- Откуда: Солнечногорск
Re: Научите писать программы для МК
DX168B писал(а):А я ведь тоже с ассемблера начинал, когда АВРки изучал. Но на Си так и не перешёл. За то, когда перешёл на ядра Cortex M3 \ A8, так там сразу с Си начал, ибо ассемблер там жуткий.
Ну, насчёт армовского ассемблера Вы неправы: он много удобней и мощнее, чем у AVR.
Изучать лучше, ИМХО, сначала Паскаль/Дельфи на ПК (написание консольных приложений), и лишь затем начинать работать с МК. Главное в программировании -- алгоритмистика, а отнюдь не конкретный язык программирования, и настоящим программистом делает не знание одного или нескольких языков, а умение превращать задачу в чёткий алгоритм её решения. Ну а на при работе с МК знание ассемблера абсолютно обязательно: есть масса вещей, которые ни на каком языке высокого уровня не сделаешь вообще или же сделаешь, но неэффективно. И если на ПК от таких вещей программиста-прикладника спасает ОС (не приходится напрямую работать с железом, обрабатывать прерывания и т.п.), то на МК всё надо делать самому.
Re: Научите писать программы для МК
FreshMan писал(а):Код: Выделить всё
for (i=0;i!=4;i++) // по очереди выводим на индикаторы выше вычесленные данные
{
PORTD=0;
PORTD=(number[i]|znak[i]);
};
}
В комментарии написано, что выводите по очереди, а на самом деле очень быстро меняете числа. Настолько быстро (несколько микросекунд), что индикатор не успевает отобразить ничего кроме одной цифры. На нее тратится гораздо больше времени, потому что программе нужно выйти из функции, попасть в главный цикл, а потом снова вернуться. Нужно каким то образом сделать так, что бы показания изменялись равномерно во времени и помедленнее, например раз в 5мс. Для этого можно например убрать цикл и менять состояние порта только один раз во время вызова функции с соотв наращиванием счетчика, а в функции делать смену только если будет выставлен флаг в прерывании. Или перенести вывод в прерывание.
Это можно сравнить с объявлениями на столбе. Если Вы хотите что бы увидели все 4 объявления, то должны будете их менять например с интервалов в один час. Если же Вы наклеете сразу все четыре друг на друга, то шанса увидеть нижние под последним нет.
Re: Научите писать программы для МК
FreshMan писал(а):
for (i=0;i!=4;i++) // по очереди выводим на индикаторы выше вычесленные данные
Мне кажется надо for (i=0;i<4;i++)
Более глубоко не вникал
Учиться, учиться, ...
Re: Научите писать программы для МК
вот что получилось опосля переделки:
какие будут предложения в плане модернизации и усовершенствования ?
Код: Выделить всё
#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);};
};
}
какие будут предложения в плане модернизации и усовершенствования ?

Tell Me The Truth
Re: Научите писать программы для МК
немного модернезировал прогу но она перестала работать..............., вроде все так, но они стали идти ОЧЕНЬ медленно..........., подскажите, плиз, где я ошибся ?
Код: Выделить всё
#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);};
};
}
Tell Me The Truth
-
phanis
- Вымогатель припоя
- Сообщения: 513
- Зарегистрирован: Сб фев 19, 2011 18:04:08
- Откуда: Татарстан, пос. Актюбинский
- Контактная информация:
Re: Научите писать программы для МК
в место прерывания по переполнению
используйте прерывание по компаратору с автоматическим сбросом регистра TCNT0 бит WGM01
Код: Выделить всё
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: Научите писать программы для МК
FreshMan, всё замечательно, но или ты вложишь тексты во вложения, или придётся их снести. Смотри сам.
Re: Научите писать программы для МК
phanis писал(а):используйте прерывание по компаратору с автоматическим сбросом регистра TCNT0 бит WGM01
а почему нужно делать так ? из каких соображений ?

Tell Me The Truth
-
phanis
- Вымогатель припоя
- Сообщения: 513
- Зарегистрирован: Сб фев 19, 2011 18:04:08
- Откуда: Татарстан, пос. Актюбинский
- Контактная информация:
Re: Научите писать программы для МК
Так у вас будут четкие интервалы времени по сравнению с прерыванием по переполнению. Т.е сам интервал времени между прерываниями будет реализован на аппаратном уровне.
Посмотрите на полученный ассемблер из си кода. Или просто в протеусе по экспериментируйте.
Посмотрите на полученный ассемблер из си кода. Или просто в протеусе по экспериментируйте.