|
Изменение текста программы при смене компилятора и чипа |
|
|
|
Oct 25 2010, 11:58
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Привет всем. Есть исходник программы написаный в IAR C v.3.10C для AT90S2313P, но такого камня уже не достать поэтому нужно переписать исходник для ATTINY2313V-10PU. Проблема в том,что IAR C v.3.10C триал или ломаная без библиотек и многого другого,поэтому изменять текст придётся в AVR Studio,но некоторые функции,как я понимаю,свойственны только IAR C v.3.10C(в частности h-файлы типа inavr.h и др.) Вообщем HELP!!! Проще говоря нужно чтобы прога работала и компилировалась в AVR Studio или Code Vision AVR под камень ATTINY2313V-10PU. Вот сам исходник(чёт не получается файлом выложить) /* Компилировать IAR C v.3.10C */ #include <2313.h> #include <inavr.h> //#define DEBUG 1 // Подручные макросы #define SetBit(address,bit) (address|=(1<<bit)) #define ClrBit(address,bit) (address&=~(1<<bit)) #define InvBit(address,bit) (address^=(1<<bit)) #define BitOn(address,bit) (address&(1<<bit)) #define BitOff(address,bit) (!(address&(1<<bit))) #define NOP __no_operation() #define IE __enable_interrupt() #define DI __disable_interrupt() #define DEBOUNCE 300 #define RUN 6 // Управление реле хода #define REV 7 // Управление реле реверса #define PRESC 2 // Прескалер таймера 0 (CLK/8) #define AIN0 0 #define AIN1 1 #define T 7 #define SUM 50 #define YES 1 #define NO 0 #define REVPAUSE 800 typedef enum {Idle, RotL, RotR, LStop, RStop} State; // Определения собственных типов данных typedef unsigned char byte; typedef unsigned int word; typedef unsigned long ulong; // Объявления прототипов функций #ifdef DEBUG void sb(byte data); void phex(byte ch); #define CRLF sb(13); sb(10) #endif byte GetKey(void); byte KbdRotate(byte m); byte KbdTest(void); void ShiftReg(void); void ShiftOne(byte r); void RegClk(void); void Strobe_1(void); void Strobe_2(void); void delayms (unsigned count); unsigned getcount(void); void RotCW(void); void RotCCW(void); void Stop(void); word measure(void); byte gp(void); void Convert(byte data); void Alarm(void); __eeprom word dummy[8]= {0,0,0,0,0,0,0,0}; __eeprom State ee_stat; __eeprom byte ee_angle; // Таблица перевода количества импульсов, соответствующих входному // напряжению в номер группы и номер светодиода в группе. __flash byte LedPos[] = { 0x00,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x04,0x04,0x04,0x05,0x05,0x06,0x06,0x06, 0x07,0x07, 0x10,0x10,0x10,0x11,0x11,0x12,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x15,0x16, 0x16,0x17, 0x17,0x17,0x20,0x20,0x21,0x21,0x21,0x22,0x22,0x23,0x23,0x23,0x24,0x24,0x25,0x25, 0x26,0x26, 0x26,0x27,0x27,0x30,0x30,0x30,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x34,0x34,0x35, 0x35,0x35, 0x36,0x36,0x37,0x37,0x37,0x40,0x40,0x41,0x41,0x41,0x42,0x42,0x43,0x43,0x43,0x44, 0x44,0x45, 0x45,0x46,0x46,0x46,0x47,0x47,0x50,0x50,0x50,0x51,0x51,0x52,0x52,0x52,0x53,0x53, 0x54,0x54, 0x54,0x55,0x55,0x56,0x56,0x57}; __flash byte Mask[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; // Определение переменных программы volatile word SysmS; byte Regs[2]; byte Btn; byte cnt; volatile byte TH; State Status; byte Merge; byte Angle; // Начало основного модуля программы __C_task void main(void){ // Настройка последовательного порта. Для настройки. #ifdef DEBUG UBRR = 25; SetBit(UCR,TXEN); #endif Regs[1]=Regs[0]=0; DDRD=0x71; PORTD=0x0E; // Настройка портов ввода/вывода KbdRotate(0xFF); // Очистка регистра кнопок ShiftReg(); // Очистка сдвигового регистра // Настройка системного таймера на прерывания раз в 1 мсек TCCR1B=0x0A; OCR1=500; TCNT1=0; SetBit(TIMSK,OCIE1A); SetBit(TIMSK,TOIE0); ClrBit(DDRB,T); // Выключить транзистор SetBit(DDRB,AIN0); // Разрядить конденсатор delayms(1); IE; // Разрешить глобальные прерывания Merge = NO; Status = ee_stat; if ((Status==RotL) || (Status==RotR)) Alarm(); else Convert(Angle = ee_angle); ee_stat = Status; // --------------------------------------------------------------- // Главная петля программы while(1){ if ((Status==RotL)||(Status==RotR)){ Angle = gp(); Convert(Angle); if (((Angle == 0x00)&&(Status==RotL)) || ((Angle == 0x57)&&(Status==RotR))){ Merge = YES; Stop(); } } cnt = 0; switch(Btn=GetKey()){ case 0x04: RotCW(); break; case 0x08: Stop(); break; case 0x10: RotCCW(); break; } } } void Alarm(void){ // Прокрутка трех кругов byte c,i,j; for (c=0; c!=3; c++) for (j=0; j!=6; j++) for (i=0; i!=8; i++){ Convert(i + (j<<4)); delayms(25); } Regs[0] = 0xFF; Regs[1] = 0x00; ShiftReg(); Status = Idle; } byte gp(void){ // Накопление и округление word m = 0; byte i = SUM; while(i--) m += measure(); i = m / SUM; return((LedPos[i-20] & 0x77)); } // Применение компаратора при измерении аналоговых величин. word measure(void){ ClrBit(DDRB,AIN0); // Перевести в Z-состояние TCNT0 = TH = 0; // Очистить счетчик-накопитель TCCR0 = PRESC; // Включить Таймер 0 SetBit(DDRB,T); // Включить транзистор while(BitOff(ACSR,ACO)); // Ждать изменения состояния компаратора TCCR0 = 0; // Выключить Таймер 0 ClrBit(DDRB,T); // Выключить транзистор SetBit(DDRB,AIN0); // Разрядить конденсатор delayms(2); // Время для разряда return(TH<<8 | TCNT0); // Возвращаем результат замера времени } #pragma vector = TIMER0_OVF0_vect // Обработчик прерывания системного таймера // Периодичность прерывания = 1 мсек __interrupt void MeasureTick(void){ TH++; } void RotCW(void){ // Вращение по часовой стрелке if (Status == RStop) return; Merge = NO; if (Status == RotL){ Stop(); delayms(REVPAUSE); } ClrBit(Regs[1],REV); // Выключить реле реверса SetBit(Regs[1],RUN); // Включить реле хода ShiftReg(); // Вывести в регистр delayms(DEBOUNCE); ee_stat = Status = RotR; } void RotCCW(void){ // Вращение против часовой стрелки // Аналогично предыдущей функции if (Status == LStop) return; Merge = NO; if (Status == RotR){ Stop(); delayms(REVPAUSE); } SetBit(Regs[1],REV); // но реле реверса включить SetBit(Regs[1],RUN); ShiftReg(); delayms(DEBOUNCE); ee_stat = Status = RotL; } void Stop(void){ // Останов вращения if ((Status==RotR)||(Status==RotL)){ ClrBit(Regs[1],REV); ClrBit(Regs[1],RUN); ShiftReg(); switch (Merge){ case YES: { if (Status==RotR) Status = RStop; else Status = LStop; break;} case NO : Status = Idle; break; } Merge = NO; ee_stat = Status; ee_angle = Angle; //CRLF; sb('S');sb('=');phex(Status);sb(' '); CRLF; } } void Convert(byte data){ byte led, group; static byte old; if (data != old){ old = data; led = data & 0x0F; group = (data & 0x70)>>4; Regs[0] = ~Mask[led]; Regs[1] &= 0xC0; Regs[1] |= Mask[group]; ShiftReg(); } } void ShiftReg(void){ // Загрузка сдвигового регистра ShiftOne(Regs[1]); ShiftOne(Regs[0]); Strobe_1(); } void ShiftOne(byte r){ // Загрузка одного байта в регистр char i=8; while(i--){ if(!(r & 0x80)) ClrBit(PORTD,5); else SetBit(PORTD,5); RegClk(); r <<=1; } } byte GetKey(void){ // Сканирование кнопок с возвратом кода нажатой byte Mask, temp = 0; Mask = 0x3E; temp |= KbdRotate(Mask); Mask = 0x3D; temp |= KbdRotate(Mask); Mask = 0x3B; temp |= KbdRotate(Mask); Mask = 0x37; temp |= KbdRotate(Mask); Mask = 0x2F; temp |= KbdRotate(Mask); Mask = 0x1F; temp |= KbdRotate(Mask); return(temp & 0x3F); } byte KbdRotate(byte m){ // Вспомогательная функция для опроса кнопок byte i=6, n = m; while (i--){ if(!(m & 0x20)) ClrBit(PORTD,5); else SetBit(PORTD,5); RegClk(); m <<=1; } Strobe_2(); if (BitOff(PIND,3)) return(~n); return(0); } void RegClk(void){ // Формирование импульса тактировки регистра SetBit(PORTD,4); ClrBit(PORTD,4); } void Strobe_1(void){ // Формирование строба первого регистра SetBit(PORTD,6); ClrBit(PORTD,6); } void Strobe_2(void){ // Формирование строба второго регистра SetBit(PORTD,0); ClrBit(PORTD,0); } #pragma vector = TIMER1_COMP1_vect // Обработчик прерывания системного таймера __interrupt void DelayTick(void){ ++SysmS; } unsigned getcount(void){ // Возвращает значение системного счетчика (мсек) unsigned t; IE; t = SysmS; DI; return (t); } void delayms (unsigned count){ // Функция формирования задержки в мсек unsigned t = getcount(); while ((getcount() - t) <= count){} } #ifdef DEBUG void phex(byte ch){ // Выводит байт в шестнадцатиричном формате byte n; n = (ch >> 4) + 0x30; if (n > 0x39) n += 7; sb(n); n = (ch & 0x0F) + 0x30; if (n > 0x39) n += 7; sb(n); } void sb(byte data){ // Передача одного байта по последовательному порту while ( !(USR & (1<<UDRE)) ); UDR = data; } #endif
|
|
|
|
21 страниц
1 2 3 > »
|
 |
Ответов
(1 - 99)
|
Oct 26 2010, 02:46
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата нужно чтобы прога работала и компилировалась в AVR Studio или Code Vision AVR под камень ATTINY2313V-10PU. Вот сам исходник(чёт не получается файлом выложить) Ну а так вообще чего там...обычное портирование... если не ставить целью перелазить на GNU(WinAVR) то будет не так уж и сложно. Кода не много...Работы, соответственно, тоже ) Ну вы же не ждете, что я сейчас полезу в даташиты и буду сравнивать названия регистров и номера байтов одного и другого контроллера и указывать Вам на конкретные изменения в коде? Эту работу Вам придётся проделать самостоятельно. Перелезть с IAR на GNU будет ещё чуть более хлопотно, т.к. слыхал, что IAR имеет(впрочем как и все компиляторы) немного своих специфичных примочек(не знаю используются ли они в вашем коде)..
--------------------
The truth is out there...
|
|
|
|
|
Oct 27 2010, 12:28
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Кода действительно немного и переделать эту программку тоже, я думаю, не составит большого труда опытному программеру,но...ОПЫТНОМУ!  Я в этом деле чайник и поэтому и прошу помощи у клуба знатоков. Есть,как мне кажется, два пути решения этой проблемы:1-выставить фьюзы для tyni2313 и прошить его прошивкой для 90s2313,по идее это должно сработать.2(более длинный путь)-переделка исходника и его компиляция в CodeVisionAVR под tyni2313.Это более трудный путь,но более предпочтительный.Если бы кто взялся помоч в этом хотя бы советами и комментариями к исходнику я был бы очень признателен.  Простая вставка текста в проект CodeVisionAVR даёт кучу ошибок начиная с заголовочных файлов <2313.h> <inavr.h>,которые видимо используются только в IAR,но если с первым понятно то чем заменить <inavr.h>вообще не понимаю и всё в таком духе...  Вообщем нужны коменты по строчкам какая что делает и совет как это написать в CodeVisionAVR По этому адресу описание устройства http://www.ut1wpr.newmail.ru/DirAnt/dir.htm а схему устройства и файл исходника вкладываю.
_________.txt ( 10.44 килобайт )
Кол-во скачиваний: 221
|
|
|
|
|
Oct 28 2010, 17:52
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Не волоку в специфике CodeVisionAVR, я от WinAWR и Атмеловской студии тащусь  Лично я начал бы с разбора существующего исходника. Нужно добиться того, чтобы каждая строка была понятна вам. Что куда и зачем. Это должно быть в голове. Как вариант, я бы таки поставил кряканый IAR и поглядел бы во все эти заголовки. А может быть даже компильнул бы из IARа данный исходник, а потом в симуляторе глянул бы что к чему(это поможет реально понять программу). Ну а дальше надо начинать портировать. Если вы будете понимать каждую строчку - это перестанет быть сложной задачей. Ну а в WinAVR всё начинается с выбора правильного камня и частоты в свойствах проекта и инкуда Код #include <avr/io.h> ну и привыкаем сразу к Код #include <stdint.h> а также может пригодиться Код #include <util/delay.h> И с этого момента вся переферия будет доступна вам! Код //конфигурируем пины, управляющие дисплеем как OUTPUT DDRB = (1 << 0) | (1 << 6) | (1 << 7); DDRD = (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7); //порт С весь используется как OUTPUT(на нем строки и спикер) DDRC = 0xFF; /* * включаем pull-up резисторы на пинах с кнопками * внешних резисторов нет и кнопки иначе работать небудут */ PORTD |= (1 << 2) | (1 << 3); как-то так..... Ну и даташит придётся полистать, а что делать что делать, кому щас легко? ) Блин, а программу маньяк какой-то писал)) Одно только Код Convert(Angle = ee_angle) чего стоит )) Но ничего, заодно и Си подучите ))
--------------------
The truth is out there...
|
|
|
|
|
Oct 29 2010, 17:08
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата Не волоку в специфике CodeVisionAVR, я от WinAWR и Атмеловской студии тащусь Да я сам не волоку,но это чуть ли не едиственный компилятор по которому есть неплохие книги на русском Цитата Лично я начал бы с разбора существующего исходника. Нужно добиться того, чтобы каждая строка была понятна вам. Что куда и зачем. Это должно быть в голове. Вот и я хочу разобраться с кодом,хотя честно сказать в С полный чайник.  Есть и hex этого исходника сделаный в IAR т.е.залить его в чип и дело с концом,но автор не уверен что это рабочая версия программы(за давностью разработки файлы перепутались и мне скинул что нашел)и поэтому желательно сначала проверить её на работоспособность. Наверно я всё таки не правильно подхожу к проблеме.Попытаюсь сформулировать свою просьбу по другому.1)Народ,скажите кто может проверить,это рабочая программа?2)Если выставить фьюзы на tiny2313 и прошить прошивкой с этой прогой(которая писалась напомню под 90s2313) будет ли tiny2313 работать правильно?Это что касается практической стороны вопроса(ну в самом деле отступать поздно,схема материализована и ждёт прошивки).  В теории же хочется разобраться какой кусок программы за что отвечает и имеющихся в проге коментов для меня явно маловато,поскольку повторюсь чайник я в этом. Посему прошу, если найдётся добрая душа, согласная помочь страждущему новичку,то пусть вооружится терпением и маркером и пометит разными цветами куски проги отвечающие за: 1.включение реле2,реле1 т.е.вращение двигателя 2.индикацию 3.прекращение поворота дальше определённого положения датчика(кстати я так понимаю происходит сравнение падения напряжения на датчике с эталонным?) 4.занесения показаний индикации в память и чтение оттуда и т.д. И может кто подсказать где посмотреть готовые куски программ с реализацией схожих задачь?
|
|
|
|
|
Oct 29 2010, 18:22
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Давайте разберемся какая у вас цель то? 1. Вам нужен просто рабочий девайс? Тогда реально один действенный выход: найти программера(практически любого программера, имющего опыт работы с микроконтроллерами) и он здесь разберется. Заплатите ему денег и все будут довольны. Тем более, что железо уже есть. А может заплатить тому человеку у которого взяли исходник?
2. Проект образовательный, вам надоело быть чайником и вы твёрдо решили разобраться и готовы потратить на это столько времени, сколько будет необходимо. На этот вариант будет свой roadmap(предложу, если интересно) и вы всё сможете.
И поймите же наконец, ну не станет никто копаться в этом коде и что-то там выяснять и выделять цветами. Тем более при такой постановке вопросоа. Вы по сути просите за вас выполнить работу. На этом форуме большинство людей ценит своё время, у каждого есть свои проекты начиная от хобби и заканчивая халтурами... Что-то реальное подсказать - всегда подскажут или направят, но работать придётся всё равно Вам.
Я просмотрел код по диагонали и мне он вообще не нравится! ИМХО тут хорошо бы заново сформулировать задачу и переписать всё по человечески.
И поймите, если времени нет и девайс реально нужен работающий - вы ничего не успеете и на много правильнее будет дать денег кому-нибудь.
--------------------
The truth is out there...
|
|
|
|
|
Oct 30 2010, 17:27
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата 1. Вам нужен просто рабочий девайс? Да,мне нужен рабочий девайс и эту проблему я решу,не заморачивайтесь. Цитата Проект образовательный, вам надоело быть чайником и вы твёрдо решили разобраться и готовы потратить на это столько времени, сколько будет необходимо. На этот вариант будет свой roadmap(предложу, если интересно) и вы всё сможете. Да,скорее так,не люблю когда что то не понятно и буду рад любой помощи.Я бы с радостью написал программу заново,если бы знал как.Если вы согласитесь изредко просматривать куски моей проги и корректировать их,то буду премного благодарен,но это наверно лучше уже через личку,а эту тему наверно стоит прикрыть поскольку не несёт ничего полезного.
|
|
|
|
|
Nov 2 2010, 16:16
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Хорошо. Вот с этого и начните. Делаем пустой проект, инициализируем нужные порты как выход( RUN и REV на вашей схеме) нужные на вход(кстати где там кнопки то?). Программа получится строк на 10 макс. Кнопки для начала можно опрашивать прямо в цикле типа вот так: Код //если нажата кнопка 2 - стоп if( !(PIND & 0x8) ) { PORTB &= ~0x0С; //очистить биты 2 и 3 порта B. Таким образом двигатель останавливается } Тут кнопка коротит порт на землю. Т.е. если кнопка нажата - соответствующий бит порта ставится в 0. В этом примере мы проверяем бит 3 порта D микроконтроллера. Именно на этот пин подключена кнопка. Ну а на B2 и B3 допустим подключены RUN и REV. Соответственно, в обработчике другой кнопки(RUN) будет установка соответствующего бита порта B. Подставьте свои значения из схемы и всё будет )
--------------------
The truth is out there...
|
|
|
|
|
Nov 4 2010, 16:15
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Вот кусочек моих стараний  ,при компиляции ошибок нет,но в протеусе не работает,что не так? Код #include <tiny2313.h> //загрузка библиотеки ATtiny2313 #include <delay.h>
void main(){ // инициализация порта D //PD1-2 func=out,state=0 //PD4-6 func=in,state=P PORTD=0x70; //установка битов порта D в 0 или 1 DDRD=0x06; //установка порта D на in или out ACSR=0x80; //настройки аналогового компаратора while (PIND.6==0){ //если кнопка S0(см.схему) нажата PORTD.2=1; //включить поворот вправо(RUN) } //цикл выполняется пока действительно условие while (PIND.4==0){ //если кнопка S2 нажата PORTD.1=1; //включить поворот влево(REV) } }
|
|
|
|
|
Nov 4 2010, 17:06
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Ну конечно не будет работать. Всё дело в том, что Ваша программа пробегает отдин раз(за доли секунды) и выходит из функции main. Вам нужно организовать бесконечный цикл и уже в нем проверять условие нажатия кнопок и выдавать соответствующие сигналы. Код while (1) { if (PIND.6==0) { //если кнопка S0(см.схему) нажата PORTD.2=1; //включить поворот вправо(RUN) } //цикл выполняется пока действительно условие if (PIND.4==0) { //если кнопка S2 нажата PORTD.1=1; //включить поворот влево(REV) } } Кстати, судя по схеме, у вас RUN 1/0 задаёт работает ли двигатель в принципе(старт/стоп), а вот REV 1/0 задаёт направление вращения. P.S. инициализацию PORTD=0x70; //установка битов порта D в 0 или 1 DDRD=0x06; //установка порта D на in или out ACSR=0x80; //настройки аналогового компаратора не проверял. Оставлю проверку битов Вам в качестве домашнего задания )) P.P.S. Это только мне кажется, что там на кнопках диоды не в ту сторону стоят? Дело в том, что из Вашей программы следует, что нажатие кнопки приводит к установке низкого уровня на порте(проверка на == 0). Т.е. кнопка должна цепляться на общий провод, а высокий уровень при размыкании контактов кнопки, по идее устанавливается за счёт внутренних подтяжек(pull-up резисторов) контроллера. Кстати не забудьте, что их можно случайно отключить и вообще я бы поставил ещё внешние для увеличения помехозащищенности. Таким образом, если кнопка нажата - ток через pull-up резистор вытекает из микроконтроллера и уходит в общий провод. Однако диоды установлены неправильно и при таком сценарии окажутся запертыми и ток не потечет. А значит лог. 0 на ноге контроллера установлен не будет.
--------------------
The truth is out there...
|
|
|
|
|
Nov 4 2010, 20:53
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата Ну конечно не будет работать. Всё дело в том, что Ваша программа пробегает отдин раз(за доли секунды) и выходит из функции main. Я об этом думал,но никто не пишет о таких простых вещах,поэтому не нашел подтверждения своим мыслям. Цитата Кстати, судя по схеме, у вас RUN 1/0 задаёт работает ли двигатель в принципе(старт/стоп), а вот REV 1/0 задаёт направление вращения. Нет,включается какое то одно реле и их переключение меняет полярность питания двигателя и соответственно направление его вращения. Цитата P.P.S. Это только мне кажется, что там на кнопках диоды не в ту сторону стоят? Знаете,у меня подозрение что это типа матричной клавы(строка PD3,столбцы - PD4-6) и диоды включены правильно,но тогда сопротивление R3 должно быть 470Ом.Если это не так,то я тогда не понимаю назначение вывода RET? На протеусе я моделировал без диодов кнопкой на землю(при включённых подтягивающих резисторах) Кстати вы не пользуетесь протеусом?Если пользуетесь подскажите как поменять номинал VCC. Цитата Кстати, судя по схеме, у вас RUN 1/0 задаёт работает ли двигатель в принципе(старт/стоп), а вот REV 1/0 задаёт направление вращения. Именно так,я сначала написал потом взглянул на схему,так что алгоритм работы поменяю на Код while(){ while (PIND.6==0){ //если кнопка S0(см.схему) нажата PORTD.2=1; //включить поворот (RUN) PORTD.1=0; //реверс не включать } //цикл выполняется пока действительно условие while (PIND.4==0){ //если кнопка S2 нажата PORTD.2=1; //включить поворот PORTD.1=1; //включить реверс(REV) } } } так я думаю правильно?Вот я ещё слышал как то дребезг контактов кнопок компенсируют?Да,и думаю от кнопки стоп вообще отказаться(используя не фиксируемые кнопки при таком алгоритме "пока держишь-крутится" я думаю стоп лишняя функция)
|
|
|
|
|
Nov 5 2010, 07:03
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата Цитата Кстати, судя по схеме, у вас RUN 1/0 задаёт работает ли двигатель в принципе(старт/стоп), а вот REV 1/0 задаёт направление вращения. Нет,включается какое то одно реле и их переключение меняет полярность питания двигателя и соответственно направление его вращения. Ну я хоть и программер, но по схеме же видно, что нижние по схеме контакты - это RUN. Когда они замкнуты на двигатель - он вращается в направлении, которое определяется положением верхних контактов, а следовательно: уровнем на выводе REV. Цитата Знаете,у меня подозрение что это типа матричной клавы(строка PD3,столбцы - PD4-6) и диоды включены правильно,но тогда сопротивление R3 должно быть 470Ом.Если это не так,то я тогда не понимаю назначение вывода RET? Как-то странно всё это....честное слово.... какой тут смысл во всех этих матрицах? В общем надо бы смотреть исходник тот оригинальный.... В протеусе там что-то типа Design->Power rails....кажется.В общем ищите Power rails. Сейчас протеус не установлен - точно сказать не смогу. Цитата Именно так,я сначала написал потом взглянул на схему,так что алгоритм работы поменяю на..... Вы кажется игнорируете то, что я вам говорю. Найдите 10 отличий между Вашим кодом и тем, что я привел в предыдущем сообщении. Ну не нужны там while, там if же! А в главном цикле нужно while(1) ! 1 в скобках означает истину. А while, как известно, исполняется пока значение в скобках истинно. В Си логический тип интерпретируется следующим образом: 0 - ложь; Не 0 - истина; т.е. запись while(1) создаёт бесконечный цикл, в котором мы непрепывно проверяем нажатие кнопок и меняем состояние пинов RUN и REV. Конечно, Ваши while (PIND.6==0){ тоже будут работать, но вообще if там более корректно.
--------------------
The truth is out there...
|
|
|
|
|
Nov 5 2010, 12:56
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата Вы кажется игнорируете то, что я вам говорю. Найдите 10 отличий между Вашим кодом и тем, что я привел в предыдущем сообщении. Ну не нужны там while, там if же! А в главном цикле нужно while(1) ! Я видел что у вас выражено через оператор if,но честно говоря не понимаю разницы.И там и там проверяется условие и если оно правильно работает тело,а 1 я просто забыл написать,потом то исправил когда при компиляции получил ошибку.Сам код я так понимаю правильный? Код while(1){ if (PIND.6==0){ //если кнопка S0(см.схему) нажата PORTD.2=1; //включить поворот (RUN) PORTD.1=0; //реверс не включать } //цикл выполняется пока действительно условие if (PIND.4==0){ //если кнопка S2 нажата PORTD.2=1; //включить поворот PORTD.1=1; //включить реверс(REV) } } Теперь такой вопрос.Мне не понятна реализация измерения напряжения датчика угла поворота.Как это делается и где можно почитать об этом?
|
|
|
|
|
Nov 5 2010, 15:18
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата Я видел что у вас выражено через оператор if,но честно говоря не понимаю разницы.И там и там проверяется условие и если оно правильно работает тело Да, но тогда у Вас зациклится присвоение значения регистру PORTD и пока кнопка нажата - мы будем непрерывно присваивать, в то время как остальные операторы исполняться не будут. Теперь представьте если у вас ниже в коде идет проверка состояния концевика(ну типа двигатель дошел до определенной точки - включить реверс), а тут вдруг кто-то нажал кнопку и держит - движок дойдет до упора, а может быть и сломает что-нибудь )) Ну это так, самый простой пример. Да и просто реально нет там необходимости в цикле. Ни малейшей. Но в вашем конкретном случае в таком виде как оно есть сейчас - работать конечно будет и с while. Цитата Мне не понятна реализация измерения напряжения датчика угла поворота. Напряжение измеряется с помощью ADC(АЦП). Советую не привыкать использовать стиль K&R в расстановке операторных скобок вместо if (PIND.4==0){ я рекомендовал бы писать if (PIND.4==0) { позднее, при отладке вложенных условий вы непременно оцените преимущества такого стиля.
--------------------
The truth is out there...
|
|
|
|
|
Nov 5 2010, 18:43
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата Да, но тогда у Вас зациклится присвоение значения регистру PORTD и пока кнопка нажата - мы будем непрерывно присваивать, в то время как остальные операторы исполняться не будут. Вот теперь всё ясно! Цитата Напряжение измеряется с помощью ADC(АЦП). ???Если можно несколько подробнее(эх,пример бы посмотреть).Из исходника Код // Применение компаратора при измерении аналоговых величин. word measure(void){ ClrBit(DDRB,AIN0); // Перевести в Z-состояние TCNT0 = TH = 0; // Очистить счетчик-накопитель TCCR0 = PRESC; // Включить Таймер 0 SetBit(DDRB,T); // Включить транзистор while(BitOff(ACSR,ACO)); // Ждать изменения состояния компаратора TCCR0 = 0; // Выключить Таймер 0 ClrBit(DDRB,T); // Выключить транзистор SetBit(DDRB,AIN0); // Разрядить конденсатор delayms(2); // Время для разряда return(TH<<8 | TCNT0); // Возвращаем результат замера времени } я практически ничего не понял??? Цитата я рекомендовал бы писать if (PIND.4==0) { Я сначала так и писал(так нагляднее),но посмотрев примеры кодов решил писать как все. Да,с настройкой портов ввода и вывода в исходнике я то же не пойму,на кнопках почему то выход а RUN REV как вход??? Код DDRD=0x71; PORTD=0x0E; // Настройка портов ввода/вывода видимо кнопки реализованы как то по другому
|
|
|
|
|
Nov 6 2010, 02:18
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата Цитата Напряжение измеряется с помощью ADC(АЦП). ???Если можно несколько подробнее(эх,пример бы посмотреть).Из исходника Да да, в этом контроллере нет АЦП, поэтому применяется компаратор. Измеряемое напряжение подаётся на один вход, а на другом входе имеем конденсатор С8 и транзистор Q1. В базе транзистора присутствует достаточно большое сопротивление, что ограничивает ТОК коллектора таким образом, чтобы конденсатор заряжался не мгновенно, а с достаточной задержкой. Т.е. если бы этот резистор был меньше - ток заряда конденсатора был бы больше и он заряжался бы ооочень быстро. Компаратор позволяет заметить момент, когда напряжение на AIN0(а значит на обкладках конденсатора) становится больше AIN1. Этого события мы и ожидаем в коде while(BitOff(ACSR,ACO)); // Ждать изменения состояния компаратора По времени, за которое конденсатор разрядился на столько, чтобы сравниться с измеряемым напряжением мы и можем судить о величине измеряемого напряжения. Думаю о конкретном значении можно говорить только после проведения калиборовки, подавая заранее известное значение напряжения и замечая, скольким тикам таймера оно соответствует. Цитата видимо кнопки реализованы как то по другому очень интересно. Диоды то почему тогда стоят не в ту сторону?! Да при таком раскладе даже если там и выход - через диод то всё равно не пройдет ничё! Но может быть я чего-то не знаю и тут какая-то неведомая хитрость присутствует ) И тут даже в коде всё это явно накручено и высосано из пальца. Ну нет смысла для трёх кнопок так извращаться. Рекомендую забить на это дело и сделать свои кнопки по простому. И вообще, честно, код не очень то хорош. Я бы не рекомендовал особо сильно подражать такому подходу. Я могу точно сказать, что программу, реализующую заявленный функционал можно написать на много более наглядно и просто. Что и рекомендую Вам сделать. И кнопки я бы сделал всего две. Стоп это когда ничего не нажато. Ну и по часовой/против часовой - понятно. Цитата Для экономии ресурсов НП, (производителем заявлено гарантированных 100000 циклов записи/стирания) запись состояния производится только в моменты его изменения. А именно, в моменты начала вращения или после останова. В моменты останова в энергонезависимую память заносяться параметры последнего угла положения. При включении устройства управления эти данные будут извлечены из памяти и отображены "поджиганием" необходимого светодиода. Если же останов произошел по вине пропадания питания (в этом случае последним зафиксированным состоянием будет состояние вращения), то при включении МК проинформирует о недостоверности указания направления трехкратной быстрой прокруткой светящейся точки по всем светодиодам, и табло останется погашенным. При первой же команде на вращение зажжется светодиод, реально отображающий положение антенны. ИМХО - хреновый подход. Не нужно там ничего записывать в EEPROM. Ведь достаточно при включении просто дёрнуть движком туда-сюда(причём на доли секунды) чтобы подать напряжение для измерения угла и засветить нужный светодиодегг ))
--------------------
The truth is out there...
|
|
|
|
|
Nov 6 2010, 18:35
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата Измеряемое напряжение подаётся на один вход, а на другом входе имеем конденсатор С8 и транзистор Q1. То есть если я правильно понял алгоритм следующий:включаем таймер для замера времени необходимого для изменения состояния компаратора - включаем транзистор - ждём пока конденсатор зарядится на уровень срабатывания компаратора - таймер выкл - транзистор выкл -кондёр разряжаем(для следущего заряда) - результат замера времени таймером отправляем для сравнения в Код // Таблица перевода количества импульсов, соответствующих входному // напряжению в номер группы и номер светодиода в группе. __flash byte LedPos[] = { 0x00,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x04,0x04,0x04,0x05,0x05,0x06,0x06,0x06, 0x07,0x07, 0x10,0x10,0x10,0x11,0x11,0x12,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x15, 0x16,0x16,0x17, 0x17,0x17,0x20,0x20,0x21,0x21,0x21,0x22,0x22,0x23,0x23,0x23,0x24,0x24,0x25, 0x25,0x26,0x26, 0x26,0x27,0x27,0x30,0x30,0x30,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x34,0x34, 0x35,0x35,0x35, 0x36,0x36,0x37,0x37,0x37,0x40,0x40,0x41,0x41,0x41,0x42,0x42,0x43,0x43,0x43, 0x44,0x44,0x45, 0x45,0x46,0x46,0x46,0x47,0x47,0x50,0x50,0x50,0x51,0x51,0x52,0x52,0x52,0x53, 0x53,0x54,0x54, 0x54,0x55,0x55,0x56,0x56,0x57};
__flash byte Mask[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; Кстати я думаю эту таблицу можно повзаимствовать из исходника,я думаю автор её составлял не наугад.Может кстати весь блок кода применения компаратора повзаимствовать?Только вот я не совсем с ним разобрался(но это видимо потому,что плохо знаю работу компаратора в МК)В частности загадка для меня Код #define ClrBit(address,bit) (address&=~(1<<bit)) &=~ что за сочетание??? & это порязрядное И или определение адреса?~ это поразрядное отрицание?(1<<bit) это умножение 1 на 2 в степени bit или это сдвиг 1 на bit влево?Не понимая этого я соответственно не понимаю Код ClrBit(DDRB,AIN0); Вообщем масса вопросов.Кстати, что то не могу найти примеров, где компаратор использовался бы подобным образом,не подскажите где поискать? Цитата Рекомендую забить на это дело и сделать свои кнопки по простому. Вот я так и сделаю.В принципе они как кнопки готовы вот только осталось ввести функцию концевиков,но для этого опять же нужно разобраться с компаратором. Цитата ИМХО - хреновый подход. Не нужно там ничего записывать в EEPROM. Ведь достаточно при включении просто дёрнуть движком туда-сюда(причём на доли секунды) чтобы подать напряжение для измерения угла и засветить нужный светодиодегг )) Совершенно согласен.
|
|
|
|
|
Nov 6 2010, 23:00
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата Кстати я думаю эту таблицу можно повзаимствовать из исходника,я думаю автор её составлял не наугад Вы знаете, я ещё не смотрел как там увАжаемый афтар реализовал все эти светодиоды, но почему-то моё чутьё подсказывает, что вероятность черезжопной реализации там также высока. Поэтому опять же нужно смотреть и очень хорошо подумать... В принципе можно и таблицу.. Вообще там всё зависит от схемы включения диодов. Там их просто довольно много и я подозреваю, что как раз таки они включены матрицей. 8*8=64. Т.е. на те два регистра можно нацепить 64 диода. И в принципе, если там задержка будет линейно зависеть от положения потенциометра - ничто не мешает использовать функцию, которая элементарно на ходу вычислит строку и диод в строке, который нужно засветить. Строки матрицы будут физически расположены по дуге. Все строки вместе составляют линию окружности. А вот если время заряда кондера будет нелинейно зависеть от поворота ручки, то проще будет таблицей ибо для начинающего там уже будет заморочка с расчётом на ходу... Цитата &=~ что за сочетание??? & это порязрядное И или определение адреса? Вопросы это хорошо! & здесь - поразрядное И. Запись a &=b; эквивалентна a = a & b; таким образом имеем address&=~(1<<bit) эквивалентно address = address & ~(1<<bit); И поскольку приоритет операции ~ выше, чем операции & - будет выполнено сначала то, что в скобках, потом к каждому биту результата будет применена операция НЕ, после этого выполняется оператор &. Таким образом мы очистим бит номер bit переменной address. Только опять таки address тут немного некорректное имя, т.к. всё же параметром этого макроса является переменная, а не указатель. Цитата Кстати, что то не могу найти примеров, где компаратор использовался бы подобным образом,не подскажите где поискать? Не знаю. А зачем? Ведь и так всё ясно. Главное знать как работает компаратор, а как его использовать - это дело разработчика ))
--------------------
The truth is out there...
|
|
|
|
|
Nov 7 2010, 17:35
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата Вы знаете, я ещё не смотрел как там увАжаемый афтар реализовал все эти светодиоды Насколько я понял 6 групп по 8 светодиодов через регистры CD4094N от МК0 по последовательному порту. Цитата Запись a &=b; эквивалентна a = a & b; таким образом имеем address&=~(1<<bit) эквивалентно address = address & ~(1<<bit); Вообщем понял,но конкретно видимо пока сложно для новичка в С. Насколько понял в скобках (1 сдвигаем влево на bit) - в полученом(например 011001 меняем наоборот 100110)проводим отрицание - address будет истина если address и полученное после отрицания тоже истинны?Бр-р-р.Нифига не понял.Нельзя это всё проще выразить? Цитата Не знаю. А зачем? Ведь и так всё ясно. Главное знать как работает компаратор, а как его использовать - это дело разработчика )) Да мне посмотреть примеры кодов,кто как пишет.Как запускают таймер,как отключают,как использовать результат замера времени и т.д.Я ж всё таки начинающий, мне легче когда есть посмотреть аналог,проанализировать и понять почему пишут так,а не иначе и как правильно. Цитата А ещё я тут подумал... Светодиоды(сдвиговые регистры) надо цеплять к контроллеру по интерфейсу Universal Serial Interface – USI. Тогда вся эта программная муть, формирующая клоки и выталкивающая данные в сдвиговые регистры будет заменена кодом конфигурации USI, а потом только регистр подгружай и прерывания лови. Сама передача и тактирование будут выполняться аппаратно. Правда немного схему переделать придётся, чтобы регистры на нужных пинах оказались, но я думаю это не проблема. Из сказаного понял немного,но схема то уже спаяна и не хотелось бы делать печатку заново.
|
|
|
|
|
Nov 7 2010, 19:11
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата Цитата Вы знаете, я ещё не смотрел как там увАжаемый афтар реализовал все эти светодиоды Насколько я понял 6 групп по 8 светодиодов через регистры CD4094N от МК0 по последовательному порту. Да я не о том. Я о программировании. То, что они там включены матрицей - сомнений не вызывает. Цитата Насколько понял в скобках (1 сдвигаем влево на bit) - в полученом(например 011001 меняем наоборот 100110)проводим отрицание - address будет истина если address и полученное после отрицания тоже истинны?Бр-р-р.Нифига не понял.Нельзя это всё проще выразить? Хорошо. Допустим address == 00101001 bit == 3 начинаем считать. первым делом надо вычислить значение в скобках. Что мы там видим. 1 << bit т.е. берем 1 и сдвигаем её на 3 позиции влево. Дело мы имеем с байтом. поэтому 1 мы запишем как 00000001 сдвигаем на 3 влево == 00001000 т.е. (1 << bit) == 00001000 запомнили далее операция ~ применяет НЕ ко всем битам байта. Т.е. ~00001000 == 11110111 далее нужно выполнить операцию & т.е. address & 11110111 address мы приняли за 00101001 а значит будет выполнено 00101001 & 11110111 и результат будет занесен в address. выполнив И над каждым битом - получаем результат 00100001 Таким образом мы сняли бит номер 3. Цитата Да мне посмотреть примеры кодов,кто как пишет.Как запускают таймер,как отключают,как использовать результат замера времени и т.д. Тут уж извините, в даташит смотрите как с таймером работать. Запускать его и останваливать. И где результат брать(в каком регистре). Тупое смотрение примеров и copy - paste врятли прибавит мозгов )) Цитата Из сказаного понял немного,но схема то уже спаяна и не хотелось бы делать печатку заново. Ну и ладно. Хотя конечно перекинуть 3 ноги, рзрезав дорожки иприпаяв провода - не так сложно. Может быть потом сделаете таким образом. Совет: старайтесь больше вникать в суть дела. В теорию. Тупое просматривание примеров не даст результата. Более того - вы можете научиться плохому. За примером далеко ходить не надо: приведенный в этой теме код автора едва ли можно назвать эталоном для подражания. В общем пользуйтесь своей головой и не бойтесь вникать в детали. И пусть даже на изучение работы таймера у вас уйдет неделя - вы потом сможете применить его как угодно и где угодно. А тупо скопировав код из примера - вы становитесь заложником своего непонимания.
--------------------
The truth is out there...
|
|
|
|
|
Nov 7 2010, 20:05
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата Таким образом мы сняли бит номер 3. Всё это для того что бы снять третий бит в байте???А проще нельзя? Цитата Ну и ладно. Хотя конечно перекинуть 3 ноги, рзрезав дорожки иприпаяв провода - не так сложно Да нет,не сложно это сделать,просто я никакой интерфейс не знаю и поэтому без разницы какой изучать.Можно и USI. Цитата Совет: старайтесь больше вникать в суть дела. В теорию. Тупое просматривание примеров не даст результата. Да вы не правильно поняли,не копирую я тупо куски кода из примеров,но эти куски реально помогают при изучении с нуля.Просто мало кто из "гуру" на форумах снисходит до того,что бы растолковать новичкам простые(отнюдь не для новичков)вещи как вот например на этом сайте:http://atmel.moy.su/publ/1-1-0-4.К сожалению везде обучение новичков сводится к миганию светодиодами и дальше этого дело не идёт,а жаль.
|
|
|
|
|
Nov 7 2010, 21:15
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата Всё это для того что бы снять третий бит в байте???А проще нельзя? Ну макрос же так и назывался ClrBit(); т.е. очистить бит. Есть там наверно ещё и SetBit(); И это очень просто. Кстати то, что в скобках и операцию ~ компилятор делает "в уме" и генерирует лишь код для операции &. Т.е. для контроллера это тоже очень просто(сам & за 1 такт) )) Цитата Да нет,не сложно это сделать,просто я никакой интерфейс не знаю и поэтому без разницы какой изучать.Можно и USI. Ну это на выбор. Просто так вы будете программно генерировать тактовую частоту и извлекать биты из байта, передавая их на ногу процессора чисто программно(опять же меняя соответствующий бит в байте порта, чтоб нога дёргалась). А с USI будет всё более цивилизованно - загрузили значение, которое нужно передать и пошел процесс передачи. Всё делает железо, проц свободен. Это более грамотный подход, хотя и не обязательно делать именно так. Цитата Просто мало кто из "гуру" на форумах снисходит до того,что бы растолковать новичкам простые(отнюдь не для новичков)вещи как вот например на этом сайте... К сожалению везде обучение новичков сводится к миганию светодиодами и дальше этого дело не идёт,а жаль. Все, кто чего-то добился - знают, что без самообучения никуда. Также я думаю, что на составление толкового толмуда по тому-же USI для новичков потребуется потратить немало часов. И то найдутся те, которым ничего не понятно. И "гуру" они от того и стали гуру, что берут доку и курят до наступления просветления. Не понимаешь первую же строку - поднимаешь материал по конкретному термину и снова куришь.... вот так становятся гуру. И вы не поверите, но те, кто для вас гуру - чуть ли не каждый день сталкиваются с чем-то новым и непрерывно самообучаются и решают проблемы. Да, подсказки, вопросы - всё это будет. Но основную работу придётся проделывать самому. Вы должны быть к этому готовы. И уж на что что, а на такие вещи как остановка таймера или включение/выключение ноги контроллера, чтобы открылся транзистор - смотреть нечено. Нужно читать даташит, рисовать на бумажечке, если нужно и в голове себе нарисовать чёткую картину что куда и зачем. Вот как только это произошло - считайте что вы на одну ступеньку приблизились к тем, кого сейчас называете гуру. Вот тут есть учебный курс по AVR. http://easyelectronics.ru/category/avr-uchebnyj-kurs кажется давал уже... или это не в этой теме.. не помню... И вообще есть и примеры, если и статьи и ответы на форумах тоже... и поиск в гугле тоже то, чем придётся овладеть не хуже, чем языком программирования )
--------------------
The truth is out there...
|
|
|
|
|
Nov 8 2010, 19:17
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата А с USI будет всё более цивилизованно - загрузили значение, которое нужно передать и пошел процесс передачи. Всё делает железо, проц свободен. Это более грамотный подход, хотя и не обязательно делать именно так. Пока не понимаю о чём речь,но звучит заманчиво.Не подскажите ссылочку а русскоязычный даташит по тиньке2313.У меня в книге Голубцова М.С. очень хорошо описана 90S2313,но она же не аналог тиньки.Нагуглил много но всё по аглицки(только не говорите что нужно учить английский) ))
|
|
|
|
|
Nov 8 2010, 20:40
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Нужно! Нужно знать минимальный набор слов для чтения даташитов. Это не так много. Говорить вас никто не просит, но понимать технический текст надо! Русский даташит... блин... лично у меня стойкая аллергия на подобные явления. На поиск в гугле потратил минуты 3.... И даже прикрепляю вам файлик прямо сюда. Added: тут на коте рекомендовали книжечку http://www.kodges.ru/34902-samouchitel-raz...rojjstv-na.html сам не читал, но говорят толковая для начинающих.
--------------------
The truth is out there...
|
|
|
|
|
Nov 9 2010, 05:55
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата На поиск в гугле потратил минуты 3.... За это время с моим "быстрым" инетом я хорошо если 5-6 страниц открою Спасибо за ссылки.Сажусь курить доки  до полного просветления.Жаль только с 14 ехать на вахту надо.Инет будет только по телефону,но вопросы,буде таковые возникнут,я и по телефону задам.
|
|
|
|
|
Nov 9 2010, 06:33
|
Частый гость
 
Группа: Участник
Сообщений: 139
Регистрация: 17-08-07
Пользователь №: 29 855

|
Вот Вам небольшой примерчик, как делать нежелательно, но возможно. Он под компилятор GCC. В данном устройстве интерфейсы контроллера заняты обменом с другими устройствами, поэтому вывод на цифровые индикаторы+линейка светодиодов сделан так кривенько, через последовательные регистры. Динамическая индикация, две строки по 6 цифр. Регистры 74164. PORTD,4 - вход сброса регистров, он инверсный, PORTB,6 - тактовый, PORTD,5 и PORTD,6 - входа данных регистров символов (цифры), PORTB,7 - вход регистра анодов индикаторов. Из нехорошестей этой функции - слишком большое использование глобальных переменных, неудобно отлаживать и портировать, а так, в общем, работает. Массив индикации 2 на 6 (2 строки на 6 ячеек), count_a - счетчик анодов, CODE void indicator (void)
{ register uint8_t i1,j1,A,hlp_ind1,hlp_ind2,hlp_ind3,hlp_ind; j1=0xff; if (count_a == 5) count_a = 0;
else count_a++ ;
for (i1=0;i1<2;i1++ ) { A=array_indic[i1][count_a];
switch (A) /* Знакогенератор */ { case 0: { hlp_ind=0xc0; break; } case 1: { hlp_ind=0xf9; break; } case 2: { hlp_ind=0xa4; break; } case 3: { hlp_ind=0xb0; break; } case 4: { hlp_ind=0x99; break; } case 5: { hlp_ind=0x92; break; } case 6: { hlp_ind=0x82; break; } case 7: { hlp_ind=0xf8; break; } case 8: { hlp_ind=0x80; break; } case 9: { hlp_ind=0x90; } } if (A>9) hlp_ind=0xff; if ((count_a==2)&(i1==0)) { hlp_ind=array_indic[0][2]; } if ((alarm==1)&(i1==1)) { if (counter_delay<20) hlp_ind=hlp_ind|0x80; else hlp_ind=hlp_ind&0x7f; } if ((count_a==1)&(i1==1)) // засветка точки на индикаторе напряжения { hlp_ind=hlp_ind&0x7f; } /*if ((count_a==pnt)&(i1==1)) // засветка точки на индикаторе времени { hlp_ind=hlp_ind&0x7f; } */
indic_symbol[i1]=hlp_ind; } if (count_a==0) j1=0xf7; if (count_a==1) j1=0xef; if (count_a==2) j1=0xdf; if (count_a==3) j1=0xfe; if (count_a==4) j1=0xfd; if (count_a==5) j1=0xfb; hlp_ind3=j1; hlp_ind1=indic_symbol[0]; hlp_ind2=indic_symbol[1]; cli(); cbi(PORTD,4); /* сброс регистров индикаторов */ for (i1=0;i1<=2;i1++); sbi(PORTD,4); for (i1=1;i1<=2;i1++); j1=0x80; for (i1=0;i1<8;i1++) /* последовательная выдача на регистры */ { cbi(PORTB,6); if (j1&hlp_ind1) sbi(PORTD,5); else cbi(PORTD,5); if (j1&hlp_ind2) sbi(PORTD,6); else cbi(PORTD,6); if (j1&hlp_ind3) sbi(PORTB,7); else cbi(PORTB,7); sbi(PORTB,6); j1>>=1; } sei(); }
|
|
|
|
|
Nov 11 2010, 10:28
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Не могли бы вы проверить этот кусок исходного кода Код word measure(void){ ClrBit(DDRB,AIN0); // Перевести в Z-состояние порты В TCNT0 = TH = 0; // Очистить счетчик-накопитель TCCR0 = PRESC; // Включить Таймер 0 SetBit(DDRB,T); // Включить транзистор while(BitOff(ACSR,ACO)); // Ждать изменения состояния компаратора TCCR0 = 0; // Выключить Таймер 0 ClrBit(DDRB,T); // Выключить транзистор SetBit(DDRB,AIN0); // Разрядить конденсатор delayms(2); // Время для разряда return(TH<<8 | TCNT0); // Возвращаем результат замера времени } Я пробовал посчитать с подстановкой битов у меня получается что возвращаться будет 0??? И ещё вопрос ,почему Code Vision AVR упорно не принимает команду запуска глобальных прерываний __enable_interrupt(); но команду на ассемблере хавает #asm("sei")?
|
|
|
|
|
Nov 11 2010, 18:40
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Всё проверять лень(чем-то же и вы должны заниматься ведь так? ) Но могу подсказать, что функция measure возвращает значение типа word - т.е. ДВА байта. Счётчик у таймера тоже 16ти битный. Т.е. состоит он из двух половинок. TH - хранит старший байт TCNT0 - младший. Последняя строка делает следующее: представим себе некую переменную с типом word. Назовем её по имени фунции - measure последняя строчка по сути делает присвоение measure = (TH<<8 | TCNT0); Т.е. берем TH и подвигаем его на один байт в сторону старших разрядов. Если TH был 11010010 то после операции <<8 получится 1101001000000000 - результат то у нас 16ти битный. Как-бы таким образом старший байт счётчика таймера встал на своё место (стал старшим байтом ) ). Дальше сюда надо как-то присовокупить младший байт(TCNT0). Примем TCNT0 = 00011011 У нас уже есть результат от TH<<8 и он равен 1101001000000000 выполним операцию логического ИЛИ со значением TCNT0 - 00011011 1101001000000000 | 00011011 Для выполнения этой операции TCNT0 будет приведен к типу word путём добавления восьми нулей в старшем байте т.е. будет так в итоге 1101001000000000 | 0000000000011011 А выполнив эту операцию мы получим 1101001000011011 Что и требовалось. Цитата И ещё вопрос ,почему Code Vision AVR упорно не принимает команду запуска глобальных прерываний __enable_interrupt(); но команду на ассемблере хавает #asm("sei")? Понятия не имею. Видимо нужно сделать #include или же __enable_interrupt(); - это вообще не из Code Vision AVR... я по WINAVR могу что-то подсказать. CVAVR у меня нет и я им не пользовался ни разу
--------------------
The truth is out there...
|
|
|
|
|
Nov 11 2010, 21:19
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата т.е. будет так в итоге 1101001000000000 | 0000000000011011 А выполнив эту операцию мы получим 1101001000011011 Т.е. в данном фрагменте программы,поскольку программа работает не в реальном МК и счётчик таймера ничего не считает,TH и TCNT0 имеют значение 0000000000000000 и в итоге функция = 0,поэтому компилятор выдаёт предупреждение и в принципе на это можно не обращать внимания? Цитата Видимо нужно сделать #include или же __enable_interrupt(); - это вообще не из Code Vision AVR... Но команда __enable_interrupt();это команда включения глобальных прерываний указаная в даташите к tiny2313 или она может меняться в зависимости от компилятора? И ещё вопрос - правильно ли я понял что,если не было установки портов, то они находяться в третьем состоянии(Z) т.е. в данном случае Код ClrBit(DDRB,AIN0); // Перевести в Z-состояние порты В DDRB = 0b00?Если это так ,то не вижу смысла в этой строке кода так как порт и так в нужном состоянии.
|
|
|
|
|
Nov 12 2010, 01:05
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата Т.е. в данном фрагменте программы,поскольку программа работает не в реальном МК и счётчик таймера ничего не считает,TH и TCNT0 имеют значение 0000000000000000 и в итоге функция = 0,поэтому компилятор выдаёт предупреждение и в принципе на это можно не обращать внимания? Что за предупреждение? Я думаю не должен он ни о чем предупреждать ибо TCNT0 и TH должны быть объявлены со словом volatile, что информирует компилятор(обратите внимание: Си компилятор!) о том, что значение переменной может меняться или считываться где-либо за пределами кода, который мы скормили компилятору. Заметьте, что это может быть аппаратное изменение значения(как в случае с таймером) так и программное изменение скажем из обработчика прерывания реализованного на асме ) Без volatile Си компилятор не может понять, что эта переменная нужна в конкретном месте программы и может "закешировать" её значение в одном из регистров и фактического чтения/записи в память не производить. В нашей функции конечно-же компилятор считает, что наши переменные равны нулю ибо видно их обнуление и не видно откуда у них может появиться что-то отличное от нуля и без volatile компилятор вообще выброст всё, что касается этих переменных, а в конце функции сделает return 0; Тем не менее Ваш компилятор может компилировать правильно, но всё равно предупреждать и это тоже сгодится за норму... я не могу точно сказать. Для верности надо бы посмотреть объявление этих самых TH и TCNT0. Цитата Но команда __enable_interrupt();это команда включения глобальных прерываний указаная в даташите к tiny2313 или она может меняться в зависимости от компилятора? Что Вы там в даташите вычитали - я не знаю но суть объясню: в языке Си(в стандарте) вообще не описано ничего относящегося к прерываниям. Равно как и много других особенностей имеющихся на конкретной архитектуре и реализуемой только на асме. Так вот для доступа к таким фишкам придуманы так называемые интринсики. Интринсики эти в каждом компиляторе для каждой платформы свои. Сам по себе интринсик выглядит как функция, но это не функция. На место интринсика во время компиляции вставляется заранее определенная ассемблерная вставка(это всё вшито в компилятор). Так вот я пологал, что __enable_interrupt(); - это и есть интринсик Вашего компилятора, взамен которого в код фактически вставляется то самое seiЧто там можно было вычитать в даташите про Си код - я не представляю! Даташит относится к девайсу, а не к компилятору. Однако вы читаете русский даташит, а это означает, что наши умники приложили к нему руку и там может быть что-то типа "все примеры приведены с расчётом на использование компилятора такого-то..." а вы это проморгали и поэтому __enable_interrupt(); у Вас не фурычит )) Цитата Код ClrBit(DDRB,AIN0); // Перевести в Z-состояние порты В DDRB = 0b00?Если это так ,то не вижу смысла в этой строке кода так как порт и так в нужном состоянии. Вам не кажется, что мы по кругу ходим? Ведь разбирали же не так давно макрос ClrBit(); Вы уже должны понимать, что этот код чистит бит AIN0 регистра DDRB. Это не тоже самое, что всему регистру присвоить 0! 0 присваивается одному единственному биту! Кстати тут по сути вывод AIN0 конфигурируется как входной. Никакого Z-состояния нет. В случае если встроенный pull-up резистор отключен - порт не будет создавать особого тока, но всё-же это не высокоимпедансное состояние(вывод порта физически соединен со схемой внутри контроллера). Так что это опять похоже заморочки вашего АФФТАРА  )
--------------------
The truth is out there...
|
|
|
|
|
Nov 12 2010, 09:07
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
sigmaN Цитата Что за предупреждение? Я думаю не должен он ни о чем предупреждать ибо TCNT0 и TH должны быть объявлены со словом volatile, Да, TH обьявлен как volatile byte.Компилятор по этой строке выдаёт два предупреждения: Warning: dira.c(173): shift result will be 0(перемещаемый результат = 0) Warning: dira.c(173): overflow is possible in 8 bit shift left, casting shifted operand to 'int' may be required(переполнение возможно в 8 битах перемещённых влево,для подсчёта преремещений может потребоваться операнд int. Тут у меня попутно созрел ещё вопрос Цитата Счётчик у таймера тоже 16ти битный. Т.е. состоит он из двух половинок. TH - хранит старший байт TCNT0 - младший. но таймер0 вроде 8-битный,откуда старший байт? Цитата "все примеры приведены с расчётом на использование компилятора такого-то..." а вы это проморгали и поэтому __enable_interrupt(); у Вас не фурычит )) В точку! Цитата Вам не кажется, что мы по кругу ходим? Ведь разбирали же не так давно макрос ClrBit(); Вы уже должны понимать, что этот код чистит бит AIN0 регистра DDRB. Это не тоже самое, что всему регистру присвоить 0! 0 присваивается одному единственному биту! Кстати тут по сути вывод AIN0 конфигурируется как входной. Никакого Z-состояния нет. Не совсем понимаю зачем чистить бит AIN0 если он установлен 0 Код #define AIN0 0 и биты этой ноги DDB0=0;PORTB0=0 а это третье состояние(так по крайней мере в даташите указано) 314 Цитата ТН скорее всего должна инкрементироваться где-то в обработчике прерывания по переполнению таймера0. Это как?Чуть подробнее можно,для чайника. Да,компилятор ругается ещё на одну строку Код __eeprom word dummy[8]= {0,0,0,0,0,0,0,0}; и предупреждает:Warning: dira.c(64): global variable 'dummy' was declared, but not referenced(глобальная переменная 'dummy' была обьявленна,но на неё нет ссылок.
|
|
|
|
|
Nov 12 2010, 09:45
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата Warning: dira.c(173): shift result will be 0(перемещаемый результат = 0) Warning: dira.c(173): overflow is possible in 8 bit shift left, casting shifted operand to 'int' may be required Это весьма странно, т.к. есть такая штука как integer promotion. Ааа, вот нашел http://electronix.ru/forum/index.php?showtopic=46523 Это фишка вашего компилятора. Цитата но таймер0 вроде 8-битный, откуда старший байт? в обработчике прерывания таймера должен быть инкремент TH каждый раз, когда TCNT0 "перескакивает через 255" в 0. Таким образом получается программная 16ти битность ) Цитата Не совсем понимаю зачем чистить бит AIN0 если он установлен 0 Код #define AIN0 0 и биты этой ноги DDB0=0;PORTB0=0 а это третье состояние(так по крайней мере в даташите указано) Уважаемые знатоки, а разве применительно к пину, сконфигурированному как input с отключенной подтяжкой можно применить термин Tri-state (Hi-Z) ?? Википедия говорит: Цитата Высокоимпедансное состояние или Z-состояние — такое состояние контакта логической схемы, при котором сопротивление между этим контактом и остальной схемой очень велико А зачем там аффтар чистит этот бит? Но ведь перед выходом из функции он его ставит Код SetBit(DDRB,AIN0); // Разрядить конденсатор значит до следующего вызова функции этот бит таки стоит и аффтар чистит его перед измерением.. Цитата Warning: dira.c(64): global variable 'dummy' was declared, but not referenced Ну у вас пока нет кода, который бы обращался к dummy. Объявление есть, но переменная не используется.
--------------------
The truth is out there...
|
|
|
|
|
Nov 12 2010, 16:00
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
За ссылку спасибо,разобрался всё работает. Цитата в обработчике прерывания таймера должен быть инкремент TH каждый раз, когда TCNT0 "перескакивает через 255" в 0. Таким образом получается программная 16ти битность ) Блин,а в даташите практически об этом ни слова. Цитата Уважаемые знатоки, а разве применительно к пину, сконфигурированному как input с отключенной подтяжкой можно применить термин Tri-state (Hi-Z) ?? ???Но ведь именно так написано в даташите:-"Третье или состояние Z,когда ({DDB0,PORTB0}=0b00),выводы являются входами и имеют высокое входное сопротивление". Я чёт совсем запутался.Как правильно то будет? Цитата значит до следующего вызова функции этот бит таки стоит и аффтар чистит его перед измерением.. Да,тут я проморгал.  Дествительно автор устанавливал этот бит. Цитата Ну у вас пока нет кода, который бы обращался к dummy. Объявление есть, но переменная не используется. Т.е.можно не обращать внимания на это предупреждение?
|
|
|
|
|
Nov 12 2010, 18:25
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата Блин,а в даташите практически об этом ни слова. Да там и об использовании компаратора для измерения напряжения - тоже ни слова  Это Ваша программа. Вы там можете хоть 128ми битный счётчик сделать.... об этом не должны писать в даташите. Даташит - это описание чипа. Там вообще подобную информацию искать бессмысленно. Даже удивительно, что вы такое написали.... Цитата Но ведь именно так написано в даташите:-"Третье или состояние Z,когда ({DDB0,PORTB0}=0b00),выводы являются входами и имеют высокое входное сопротивление". Я чёт совсем запутался.Как правильно то будет? Ну видел я там это, да. И понятно, что входное сопротивление такого пина получается весьма большим, но всё-же я высказал сомнение насчёт корректности термина в этом случае. Ведь Цитата Высокоимпедансное состояние или Z-состояние — такое состояние контакта логической схемы, при котором сопротивление между этим контактом и остальной схемой очень велико но между самой ногой контроллера и его схемой сопротивление то не большое! Большое сопротивление получается в таком случае относительно общего провода(GND) контроллера. Вот о чем я. Цитата Т.е.можно не обращать внимания на это предупреждение? конечно, забейте на это и всё.
--------------------
The truth is out there...
|
|
|
|
|
Nov 13 2010, 01:33
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Что-то чем дальше, тем меньше мне нравится Ваш этот CVAVR...слезайте с него, это не Си. Выбрось каку!!!И интегер промоушнз там не единственный прикол Заучите все эти примочки, а потом будете локти кусать... Переползайте ка вы на GNU. С сайта Atmel стяните студию и toolchain и начинайте с нормальным компилятором работать...мой Вам добрый совет ) http://www.atmel.com/dyn/products/tools_ca...sp?tool_id=2725 - страничка студии качать(ставить в порядке перечисления): AVR Studio 4.18 (build 684) (116 MB, updated 11/09) AVR Studio 4.18 SP3 (b716) (31 MB, updated 9/10) AVR Toolchain Installer (87 MB, updated 9/10) For use with AVR Studio 4.18 SP3 Вот. И давайте на теорию налягайте. Чувствуется, что даже в битовых операциях плаваете....
--------------------
The truth is out there...
|
|
|
|
|
Nov 13 2010, 10:59
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата Что-то чем дальше, тем меньше мне нравится Ваш этот CVAVR... Да,мне то же.Но зато по нему есть хорошая книга на русском,а остальные компиляторы этим похвастаться не могут. Студия4 у меня есть,но без SP3 и toolchain,а вот как и что там делать почитать негде. А с прогой от аффтара явно что то не то.Я прошил МК прошивкой которую он прислал вместе с исходником(соответственно выставив фьюзы чтобы tiny2313 иммитировала 90S2313),результат плачевный - вообще ничего не работает.Я грешил на неполную совместимость МК.В CVAVR преределал исходник под тиньку(осталось только предупреждение по __eeprom word dummy[8]= {0,0,0,0,0,0,0,0}  компилится без проблем, прошил этой прошивкой результат такой же.Аффтар пишет что устройство с этой прошивкой работало нормально,но прокомментировать фрагменты кода отказался,сылаясь на занятость.Вообщем что бы убедится в работоспособности данного кода нуна гдето родной МК раздобыть. Жаль что завтра на работу ехать,но литературку беру с собой,буду налегать на теорию
|
|
|
|
|
Nov 13 2010, 20:06
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Обидно,да.Я так понимаю,если человек выкладывает в инет на всеобщее обозрение свою конструкцию,то должен быть готов в любой момент дать исчерпывающие обьяснения по работе устройства и его програмному обеспечению.А он не смог даже сказать как включаются кнопки.Из схемы можно предположить что происходит замыкание контактов S0,S1,S2 с RET,но это ж предположение. Студию скачал,установил,но ещё не юзал.Приеду буду осваивать,а пока не порекомендуете литературку по ней на русском?
|
|
|
|
|
Nov 14 2010, 08:02
|
Частый гость
 
Группа: Участник
Сообщений: 139
Регистрация: 17-08-07
Пользователь №: 29 855

|
По мне, так проще все делать сразу в Programer_Notepad, без студии. Студия полезна как дебаггер, для пошаговой отладки (интерфейс удобный) и еще удобный программатор, а писать и компилить все-таки PN удобнее, ИМХО. А по-поводу автора, так может ему программу внук писал  .
Сообщение отредактировал 314 - Nov 14 2010, 08:04
|
|
|
|
|
Nov 14 2010, 10:23
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Всё установил как рекомендовали и спасибо за ссылочку.Литературки по студии немного накропал по инету(ну в смысле первые шаги и пр.)буду изучать.Жаль что через 5 часов уезжать на вахту. Да,об исходнике.Попробовал я его прокомпилить в IAR Systems Embedded Workbench 5.4 результат 70 ошибок и 0 предупреждений  вот так.Буду писать прогу под эту схему с нуля.
|
|
|
|
|
Nov 23 2010, 20:33
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
чё, опять IAR? вроде ж соскакивать с него решили... __eeprom указывает, что переменная будет храниться в EEPROM Код #ifdef DEBUG; void sb(byte data); void phex(byte ch); #define CRLF sb(13);sb(10) #endif нет, ну про #ifdef и #define то там пару страниц от силы прочитать.... ёмаё ))) объявление прототипа функций. Код void sb(byte data); void phex(byte ch); Код CRLF; препроцессор развернет в Код sb(13);sb(10);
--------------------
The truth is out there...
|
|
|
|
|
Nov 24 2010, 16:18
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата(sigmaN @ Nov 23 2010, 23:33)  чё, опять IAR? вроде ж соскакивать с него решили... __eeprom указывает, что переменная будет храниться в EEPROM Код #ifdef DEBUG; void sb(byte data); void phex(byte ch); #define CRLF sb(13);sb(10) #endif нет, ну про #ifdef и #define то там пару страниц от силы прочитать.... ёмаё ))) объявление прототипа функций. Код void sb(byte data); void phex(byte ch); Код CRLF; препроцессор развернет в Код sb(13);sb(10); Всё это в общих чертах я понимаю,но не пойму при чем здесь DEBUG и вообще можно же просто обьявить функцию.А в книге пишут что это (#ifdef ... #endif)условная компиляция???Что эт за зверь?
|
|
|
|
|
Nov 25 2010, 21:49
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата не пойму при чем здесь DEBUG Программа пишется с учётом отладки(к примеру вывод значений по UART в нужных местах). Куски кода, отвечающие за отладку делают внутри ifdef DEBUG. Таким образом, если символ DEBUG определен - компилятор скомпилирует то, что между ifdef и endif, а если нет - то пропустит. Для него тогда просто не существует этого кода. Препроцессор его вырежет, т.к. условие не выполнилось, DEBUG не определен(nod defined). Вот. Таким образом релиз программы делается без отладочного вывода путем простого комментирования строки #define DEBUG где-то в самом начале программы ) А ещё символы дефайнить можно из свойств проекта... В общем это уже не так важно. Цитата Или это для того чтобы занести значение в старший байт? Да, TH ложится в старший байт, TCNT0 в младший. Я ооочень подробно там всё описал с примерами. Едва ли я смогу что-то новое придумать ) Там прям в двоичном виде кажется давал примеры же!
--------------------
The truth is out there...
|
|
|
|
|
Nov 28 2010, 10:54
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата Если не записать 0 в старший байт,то туда запишется значение TCNT0 ,поскольку сначала должен записываться именно старший байт? Как это? Откуда это? Ничего не понял. Имеется ввиду, что будет, если просто написать return TCNT0; ? Так вот если просто присвоить 16ти битной переменной(у нас это значение функции) то этот TCNT0 пойдет, естественно, в младший байт, а в старшем будут нули сами собой. Ибо мы то присваиваем ЗНАЧЕНИЕ. Т.е. TCNT0 было равно к примеру 150. Мы и присваиваем переменной 150. Если переменная 16бит - то будет один старший байт нулей, а в младшем наши 150. Если переменная 32бита - будет три байта нулей, а в четвертом(самом младшем) будут наши 150. И значение переменной во всех случаях будет таки равно 150 и никак иначе. И записать их можно в любом порядке(с помощью битовых операций, в которые, как мне кажется, Вы до сих пор так толком и не "въехали)".
--------------------
The truth is out there...
|
|
|
|
|
Dec 7 2010, 00:33
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата Что делает TH<<8,что и куда переносится я понимаю,я не пойму зачем это делать?Почему нельзя просто написать return TCNT0? ну так вы же теряете старший байт в таком случае! Ну вот представьте, что TCNT0 - это секунды,а TH - минуты. Засекаете время путём обнуления этих двух переменных и пошли тикать часы. Вот мы имеем два отсчёта времени 37 секунд 1 минута 12 секунд А теперь представьте, что из функции вы возвращаете только секунды( return TCNT0;). При сравнении окажется, что второй промежуток меньше. Хотя на самом деле это не так. Вот и TCNT0 мотает от 0 до 255, а дальше опять 0 и снова до 255. Каждый раз, когда он пробегает через 0 - вызывается прерывание и значение TH увеличивается на 1(в примере - это минуты. минуты ведь тоже прибавляются в момент перехода секунд через 0). Цитата Обязательно ли дергать строб при зажигании светодиодов, или достаточно подтянуть его к 1? читайте про сдвиговые регистры. Притянуть - это типа резистор поставить? Ггг Цитата Как можно подобрать соотношение напряжение - светодиод? Моделировать в Протеусе? http://www.casemods.ru/services/raschet_rezistora.htmlhttp://novikovmaxim.narod.ru/index.htm?htt...ron/connect.htm
--------------------
The truth is out there...
|
|
|
|
|
Dec 8 2010, 03:49
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата Ага, с ТН разобрался, меня ввело в заблуждение то, что обработка прерываний по переполнению написана после описания функции(так можно делать?) Обработчик прерывания даже можно написать на чистом асме )) Не важно где он - важно, что он есть. И вообще, логика где? Он ведь исполняется по событию от таймера, независимо. Так какая разница где этот обработчик? Выше или ниже функции ) Цитата Что касается строба то есть схемы где нога висит на + питания, а в других её дергают и как лучше поступить мне ? Думаю, лучше дёргать http://www.alldatasheet.com/datasheet-pdf/...SIL/CD4094.html Цитата The data in each shift register stage is transferred to the storage register when the STROBE input is high. таким образом, если не дёргать вовремя - диоды будут отображать промежуточные состояния и скверно помигивать. А нужно делать правильно: загрузили в сдвиговый регистр данные, дёрнули строб на 1, чуть подержали и опять в 0 поставили. Таким образом данные из регистра сдвига будут отображены диодами именно в тот момент, когда уже всё готово. Если же строб притянуть к питанию - вы будете отображать не только нужное Вам(конечное) состояние, но и сам процесс заталкивания бита в регистры сдвига. И если при движении "вперед" это ещё может быть и приемлемо, то при движении "назад", когда эти сосиски(сдвиговые регистры ведь последовательно включены) чистить придётся(протикать клок, пока имеющаяся там 1 не проползет на выход), а потом затолкать другую 1 на нужное место - всё это будет видно в виде некоторых спецэффектов )
--------------------
The truth is out there...
|
|
|
|
|
Dec 17 2010, 04:33
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Итак прибыв домой попробовал свои силы в новой для меня AVRStudio. Сразу возникло несколько вопросов. Какой файл нужно инклудить для тиньки2313?Как разрешать и запрещать прерывания и нужно ли для этого что то инклудить?Вообщем вот код точнее даже заготовка Код typedef unsigned char byte;//определение собственных типов данных typedef unsigned int word;
volatile byte TH; //определение переменных
word Analog(void){ //используем аналоговый компаратор для замера времени заряда кондёра DDRB.0=0; //переводим 0 выход порта В в третье состояние PORTB.0=0; TCNT0=TH=0; //очистим счётчик-накопитель TCCR0=2; //включаем таймер0 с пределителем CLK/8 DDRB.7=1; //включить транзистор while(!(ACSR&(1<<5))); //ждём изменения состояния бита АСО на выходе компаратора TCCR0=0; //выключаем таймер DDRB.7=0; //выключаем транзистор DDRB.0=1; //разряжаем кондёр delay_ms(2); //время для разряда кондёра return(TH<<8 | TCNT0); //возвращаем результат замера времени }
#pragma vector = TIMER0_OVF0 //обработка прерывания таймера0 по переполнению interrupt void AnalogTick(void){ //при переполнении 8-битного счётчика таймера увеличивать байт ТН на 1 TH++; } что нужно добавить и что переделать?Функцию задержки delay_ms(x)ещё не делал поскольку не знаю как здесь правильно разрешать и запрещать глобальные прерывания.Можно ли как в CodeVision использовать команды на асме? и вопрос как реализовать двоичный индикатор для отображения тиков таймера?
|
|
|
|
|
Dec 17 2010, 10:15
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата Какой файл нужно инклудить для тиньки2313? инклудить надо avr/io.h. Для всех камней. А вот в свойствах проекта должен быть указан именно ваш контроллер. Этот io.h тогда сам и заинклудит чё надо ) Вообще, пока сделайте так: Код #include <stdint.h> #include <avr/io.h> #include <util/delay.h> к типам из stdint.h советую привыкать сразу. Цитата Как разрешать и запрещать прерывания и нужно ли для этого что то инклудить? Код sei();//разрешить cli(); //запретить Цитата то нужно добавить и что переделать?Функцию задержки delay_ms(x)ещё не делал используйте типы из stdint.h ну и почитайте что это и зачем http://lord-n.narod.ru/download/books/wall...20/stdint_h.htmна википедии русской статьи нет, есть инглиш http://en.wikipedia.org/wiki/Stdint.h в общем нагуглите если захотите... Функция delay_ms(x) уже есть в util/delay.h Главное чтобы оптимизация в свойствах проекта была включена. Эта фишка многих раздражает и есть люди, которые принципиально не используют задержки из delay.h. Для вас пока что пойдет, дальше решите. Единственное, ещё на частоту контроллера обратите внимание(в свойствах проекта) чтоб стояла раельная на которой камень работать будет. Код Можно ли как в CodeVision использовать команды на асме? команды на асме использовать можно, но нужно это делать только в тех редких случаях, когда на Си уж никак не описать того, что хотелось бы. Вот к примеру вместо sei(); конечно можно было бы команду асм вставить, но это подход неправильный, ведь есть интринсики sei() и cli() для этих целей и компилятор их более эффективно может использовать... но об этом потом... кстати, вот это бы изучить не мешало http://www.nongnu.org/avr-libc/user-manual/FAQ.html может и перевод где найдете. не знаю... Цитата и вопрос как реализовать двоичный индикатор для отображения тиков таймера? А вот как научитесь светодиодики зажигать через регистры сдвиговые - тогда и ясно станет. Зачем вам сейчас именно калибровать эту крутилку? Это можно оставить и на потом ведь)
--------------------
The truth is out there...
|
|
|
|
|
Dec 17 2010, 12:18
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата инклудить надо avr/io.h. Для всех камней. А вот в свойствах проекта должен быть указан именно ваш контроллер. С этим понятно Цитата к типам из stdint.h советую привыкать сразу. Т.е. вместо Код typedef unsigned char byte;//определение собственных типов данных typedef unsigned int word;
volatile byte TH; //определение переменных
word Analog(void){ можно написать Код volatile uint8_t TH; uintmax_t Analog(void){ так? Цитата Функция delay_ms(x) уже есть в util/delay.h Главное чтобы оптимизация в свойствах проекта была включена. Как включить оптимизацию?
|
|
|
|
|
Dec 17 2010, 14:10
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Вот что я накропал на данный момент. CODE #include <stdint.h> #include <avr/io.h> #include <util/delay.h>
#define CD4094_PORT PORTB #define CD4094_DDR DDRB #define CD4094_PIN_DATA 3 #define CD4094_PIN_CLK 2 #define CD4094_PIN_STB 4 #define CD4094_DATA_ON CD4094_PORT|=1<<CD4094_PIN_DATA //установка ноги data в 1 #define CD4094_DATA_OFF CD4094_PORT&=~(1<<CD4094_PIN_DATA)//установка ноги data в 0 #define CD4094_CLK {CD4094_PORT|=1<<CD4094_PIN_CLK; CD4094_PORT&=~(1<<CD4094_PIN_CLK);}//дёргаем ногу clk для проталкивания битов по регистру #define CD4094_STB {CD4094_PORT|=1<<CD4094_PIN_STB; CD4094_PORT&=~(1<<CD4094_PIN_STB);}//дёргаем ногу stb для поджига светодиодов CD4094_DDR=(1<<CD4094_PIN_DATA)|(1<<CD4094_PIN_CLK);// нужные ноги ставим в 1
void Shift_Reg(void){ //загрузка сдвигового регистра Shift_One_Byte(Led[0]);//загрузка байта в 1 регистр Shift_One_Byte(Led[1]);//загрузка байта во 2 регистр CD4094_STB; //зажигаем светодиоды }
void Shift_One_Byte(unsigned char dig){ //загрузка одного байта char i=8; while(i--){ if(dig&0X80){CD4094_DATA_ON} else{CD4094_DATA_OFF} dig<<1; CD4094_CLK; } }
typedef unsigned char byte;//определение собственных типов данных typedef unsigned int word;
volatile byte TH; //определение переменных
word Analog(void){ //используем аналоговый компаратор для замера времени заряда кондёра DDRB.0=0; //переводим 0 выход порта В в третье состояние PORTB.0=0; TCNT0=TH=0; //очистим счётчик-накопитель TCCR0=2; //включаем таймер0 с пределителем CLK/8 DDRB.7=1; //включить транзистор while(!(ACSR&(1<<5))); //ждём изменения состояния бита АСО на выходе компаратора TCCR0=0; //выключаем таймер DDRB.7=0; //выключаем транзистор DDRB.0=1; //разряжаем кондёр delay_ms(2); //время для разряда кондёра return(TH<<8 | TCNT0); //возвращаем результат замера времени }
#pragma vector = TIMER0_OVF_vect //обработка прерывания таймера0 по переполнению interrupt void AnalogTick(void){ //при переполнении 8-битного счётчика таймера увеличивать байт ТН на 1 TH++; }
void main(){ // инициализация порта D //PD1-2 func=out,state=0 //PD4-6 func=in,state=P PORTD=0x70; //установка битов порта D в 0 или 1 DDRD=0x06; //установка порта D на in или out while(1){ if (PIND.6==0){ //если кнопка S0(см.схему) нажата PORTD.2=1; //включить поворот (RUN) PORTD.1=0; //реверс не включать } //цикл выполняется пока действительно условие if (PIND.4==0){ //если кнопка S2 нажата PORTD.2=1; //включить поворот PORTD.1=1; //включить реверс(REV) } } } Посмотрите пожалуйста повнимательней, всё ли здесь так?
Сообщение отредактировал RW6MKA - Dec 18 2010, 11:47
|
|
|
|
|
Dec 17 2010, 16:54
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата Т.е. вместо бла бла бла можно написать Код volatile uint8_t TH; uintmax_t Analog(void){ а зачем uintmax_t то? ведь там же uint16_t ) Цитата Как включить оптимизацию? В свойствах проекта там есть -O0 -O1 -O2 -Os по дефолту стоит -Os и это нормально. Чтобы работали задержки из delay.h главное не ставить -O0. Кстати, если оптимизация не включена, а delay.h подключен - будет warning при компиляции. А что же касается коооода ))) Код #include <stdint.h> #include <avr/io.h> #include <util/delay.h>
#define CD4094_PORT PORTB #define CD4094_DDR DDRB #define CD4094_PIN_DATA 3 #define CD4094_PIN_CLK 2 #define CD4094_PIN_STB 4 #define CD4094_DATA_ON CD4094_PORT|=1<<CD4094_PIN_DATA //установка ноги data в 1 #define CD4094_DATA_OFF CD4094_PORT&=~(1<<CD4094_PIN_DATA)//установка ноги data в 0 //вот тут он очень быстро дёрнет, нет задержки между изменениями уровня. А ещё такие макросы - зло. Делать inline функцию сюда. #define CD4094_CLK {CD4094_PORT|=1<<CD4094_PIN_CLK; CD4094_PORT&=~(1<<CD4094_PIN_CLK);}//дёргаем ногу clk для проталкивания битов по регистру #define CD4094_STB {CD4094_PORT|=1<<CD4094_PIN_STB; CD4094_PORT&=~(1<<CD4094_PIN_STB);}//дёргаем ногу stb для поджига светодиодов //как-то у вас тут всё в куче... может быть сделать что-то вроде функции инициализации железа и туда это запихнуть? CD4094_DDR=(1<<CD4094_PIN_DATA)|(1<<CD4094_PIN_CLK);// нужные ноги ставим в 1
void Shift_Reg(void){ //загрузка сдвигового регистра Shift_One_Byte(Led[0]);//загрузка байта в 1 регистр //а вот тут будет error Shift_One_Byte undefined :) Shift_One_Byte(Led[1]);//загрузка байта во 2 регистр //а ещё я не знаю что такое Led[]. CD4094_STB; //зажигаем светодиоды }
void Shift_One_Byte(unsigned char dig){ //загрузка одного байта char i=8; //стандарты кодирования не учтены //ужасный стиль ) //не знаю чё тут и как.. будете отлаживать.. я думаю тут не хватает задержек.. но надо смотреть времянки этих сдвиговых регистров в даташите.. while(i--){ if(dig&0X80){CD4094_DATA_ON} else{CD4094_DATA_OFF} dig<<1; CD4094_CLK; } }
//вот это всё на мороз. есть же стдинт typedef unsigned char byte;//определение собственных типов данных typedef unsigned int word;
volatile byte TH; //определение переменных
//интересно, почему вы вверху макросы написали правильно, а тут перешли на применение CVAVRовских штучек. //DDRB.0 = 0; не прокатывает //чтобы очистить нулевой бит нужно как-то так //DDRB &= ~(1 << 0); //сдвигать на ноль бесполезно, но для наглядности оставил. word Analog(void){ //используем аналоговый компаратор для замера времени заряда кондёра DDRB.0=0; //переводим 0 выход порта В в третье состояние PORTB.0=0; //так можно, но лучше сделать два разных присвоения. Удобочитаемость кода всё-таки. TCNT0=TH=0; //очистим счётчик-накопитель TCCR0=2; //включаем таймер0 с пределителем CLK/8 //а вот тут надо DDRB |= 1 << 7; DDRB.7=1; //включить транзистор while(!(ACSR&(1<<5))); //ждём изменения состояния бита АСО на выходе компаратора TCCR0=0; //выключаем таймер DDRB.7=0; //выключаем транзистор DDRB.0=1; //разряжаем кондёр delay_ms(2); //время для разряда кондёра return(TH<<8 | TCNT0); //возвращаем результат замера времени }
//в avr-gcc прерывания оформляются иначе //не нужна никакая прагма //прагму нафиг - #pragma vector = TIMER0_OVF_vect //обработка прерывания таймера0 по переполнению //interrupt void AnalogTick(void){ //при переполнении 8-битного счётчика таймера увеличивать байт ТН на 1 //пишем так: ISR(TIMER0_OVF_vect) { TH++; }
void main(){ // инициализация порта D //PD1-2 func=out,state=0 //PD4-6 func=in,state=P PORTD=0x70; //установка битов порта D в 0 или 1 DDRD=0x06; //установка порта D на in или out while(1){ //ну тут опять эти цвавровские примочки пошли.... if (PIND.6==0){ //если кнопка S0(см.схему) нажата PORTD.2=1; //включить поворот (RUN) PORTD.1=0; //реверс не включать } //цикл выполняется пока действительно условие if (PIND.4==0){ //если кнопка S2 нажата PORTD.2=1; //включить поворот PORTD.1=1; //включить реверс(REV) } } } пробуйте исправить всё и компилить... да, ещё для прерываний нужно #include <avr/interrupt.h> !!!
--------------------
The truth is out there...
|
|
|
|
|
Dec 18 2010, 00:07
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Вот всё в исправленном состоянии CODE #include <stdint.h> #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #define CD4094_PORT PORTB #define CD4094_DDR DDRB #define CD4094_PIN_DATA 3 #define CD4094_PIN_CLK 2 #define CD4094_PIN_STB 4 #define OnBit(address,bit) (address|=(1<<bit)) #define OffBit(address,bit) (address&=~(1<<bit)) void CD4094_CLK(void){ //дёргаем ногу clk для проталкивания битов по регистру OnBit(CD4094_PORT,CD4094_PIN_CLK); delay_ms(2); OffBit(CD4094_PORT,CD4094_PIN_CLK); } void CD4094_STB(void){ //дёргаем ногу stb для поджига светодиодов OnBit(CD4094_PORT,CD4094_PIN_STB); delay_ms(2); OffBit(CD4094_PORT,CD4094_PIN_STB); } CD4094_DDR=(1<<CD4094_PIN_DATA)|(1<<CD4094_PIN_CLK);// нужные ноги ставим в 1 //Led[] макрос в первый элемент которого будет заноситься код строки а во второй код столбца соответствующие //тикам таймера в данный момент void Shift_Reg(void){ //загрузка сдвигового регистра Shift_One_Byte(Led[0]);//загрузка байта в 1 регистр//а вот тут будет error Shift_One_Byte undefined  //почему? Shift_One_Byte(Led[1]);//загрузка байта во 2 регистр CD4094_STB(); //зажигаем светодиоды } void Shift_One_Byte(unsigned char dig){ //загрузка одного байта char i=8; while(i--){ if(dig&0X80){OnBit(CD4094_PORT,CD4094_PIN_DATA)} else{OffBit(CD4094_PORT,CD4094_PIN_DATA)} dig<<1; CD4094_CLK(); } } volatile uint8_t TH; //определение переменных uint16_t Analog(void){ //используем аналоговый компаратор для замера времени заряда кондёра OffBit(DDRB,0); //переводим 0 выход порта В в третье состояние OffBit(PORTB,0); TCNT0=0; //очистим счётчик-накопитель TH=0; TCCR0=2; //включаем таймер0 с пределителем CLK/8 OnBit(DDRB,7); //включить транзистор while(!(ACSR&(1<<5))); //ждём изменения состояния бита АСО на выходе компаратора TCCR0=0; //выключаем таймер OffBit(DDRB,7); //выключаем транзистор OnBit(DDRB,0); //разряжаем кондёр delay_ms(2); //время для разряда кондёра return(TH<<8 | TCNT0); //возвращаем результат замера времени } ISR(TIMER0_OVF_vect){ //обработка прерывания таймера0 по переполнению //при переполнении 8-битного счётчика таймера увеличивать байт ТН на 1 TH++; } void main(void){ // инициализация порта D //PD1-2 выход,уровень 0 //PD4-6 вход,подтягивающие резисторы включены PORTD=0x70; //установка битов порта D в 0 или 1 DDRD=0x06; //установка порта D на in или out while(1){ if (PIND6==0){ //если кнопка S0(см.схему) нажата OnBit(PORTD,2); //включить поворот (RUN) OffBit(PORTD,1); //реверс не включать } //цикл выполняется пока действительно условие if (PIND4==0){ //если кнопка S2 нажата OnBit(PORTD,2); //включить поворот OnBit(PORTD,1); //включить реверс(REV) } } } Пробовал компилить вот как ругается make: Makefile: No such file or directory make: *** Нет правила для сборки цели `Makefile'. Останов. Build failed with 1 errors and 0 warnings...
Сообщение отредактировал RW6MKA - Dec 18 2010, 11:38
|
|
|
|
|
Dec 18 2010, 14:40
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Скачал и установил всё как вы рекомендовали. Создаю новый проект-выбираю AVR GCC-пишу имя проекта-next-AVR simulator-ATtiny2113-finish набираю или вставляю текст проги кнопка старта дебуга неактивна а при компиляции ругается чё делать?????????
|
|
|
|
|
Dec 18 2010, 20:54
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Путь к проекту не должен содержать русских букв и, наверное,  пробелов.. Лично я ВСЕГДА стараюсь выполнять эти правила. Ещё где-то может вылезти ограничение на максимальную длину пути - поэтому не стоит заханыривать проект слишком далеко... Это всё так..перестраховочные правила дабы не было проблем.... Создайте проект заново без русского "проба" в пути и всё у вас будет хорошо. Это я проверил лично, создав такой-же проект как у Вас и получив в точности такую же ошибку ) Если где-то нужен пробел - используйте нижнее подчёркивание. "project_2" например. Файл, где описана функция main(), стараюсь всегда называть main.c Может быть и вам будет полезно/удобно...
--------------------
The truth is out there...
|
|
|
|
|
Dec 19 2010, 02:07
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
заработало,вот немного исправленный код и результаты компиляции CODE #include <stdint.h> #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h>
#define CD4094_PORT PORTB #define CD4094_DDR DDRB #define CD4094_PIN_DATA 3 #define CD4094_PIN_CLK 2 #define CD4094_PIN_STB 4 #define OnBit(address,bit) (address|=(1<<bit)) #define OffBit(address,bit) (address&=~(1<<bit))
volatile uint8_t TH; //определение переменных
void CD4094_CLK(void){ //дёргаем ногу clk для проталкивания битов по регистру OnBit(CD4094_PORT,CD4094_PIN_CLK); delay_ms(2); OffBit(CD4094_PORT,CD4094_PIN_CLK); }
void CD4094_STB(void){ //дёргаем ногу stb для поджига светодиодов OnBit(CD4094_PORT,CD4094_PIN_STB); delay_ms(2); OffBit(CD4094_PORT,CD4094_PIN_STB); }
void Shift_Reg(void){ //загрузка сдвигового регистра Shift_One_Byte(Led[0]);//загрузка байта в 1 регистр Shift_One_Byte(Led[1]);//загрузка байта во 2 регистр CD4094_STB(); //зажигаем светодиоды }
void Shift_One_Byte(uint8_t tmp){ //загрузка одного байта uint8_t i,dig; i=8; dig=Led[tmp]; while(i--){ if(dig&0x80){OnBit(CD4094_PORT,CD4094_PIN_DATA);} else{OffBit(CD4094_PORT,CD4094_PIN_DATA);} dig<<1; CD4094_CLK(); } }
uint16_t Analog(void){ //используем аналоговый компаратор для замера времени заряда кондёра OffBit(DDRB,0); //переводим 0 выход порта В в третье состояние OffBit(PORTB,0); TCNT0=0; //очистим счётчик-накопитель TH=0; TCCR0=2; //включаем таймер0 с пределителем CLK/8 OnBit(DDRB,7); //включить транзистор while(!(ACSR&(1<<5))); //ждём изменения состояния бита АСО на выходе компаратора TCCR0=0; //выключаем таймер OffBit(DDRB,7); //выключаем транзистор OnBit(DDRB,0); //разряжаем кондёр delay_ms(2); //время для разряда кондёра return(TH<<8 | TCNT0); //возвращаем результат замера времени }
ISR(TIMER0_OVF_vect){ //обработка прерывания таймера0 по переполнению //при переполнении 8-битного счётчика таймера увеличивать байт ТН на 1 TH++; }
void main(void){ // инициализация порта D //PD1-2 выход,уровень 0 //PD4-6 вход,подтягивающие резисторы включены PORTD=0x70; //установка битов порта D в 0 или 1 DDRD=0x06; //установка порта D на in или out DDRB=0x1C; //установка stb,data,clk на выход,уровень 0
while(1){ if (PIND6==0){ //если кнопка S0(см.схему) нажата OnBit(PORTD,2); //включить поворот (RUN) OffBit(PORTD,1); //реверс не включать } //цикл выполняется пока действительно условие if (PIND4==0){ //если кнопка S2 нажата OnBit(PORTD,2); //включить поворот OnBit(PORTD,1); //включить реверс(REV) } }
}
Цитата avr-gcc -mmcu=attiny2313 -Wall -gdwarf-2 -std=gnu99 -DF_CPU=4000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT povorot1.o -MF dep/povorot1.o.d -c ../povorot1.c ../povorot1.c: In function 'CD4094_CLK': ../povorot1.c:19: warning: implicit declaration of function 'delay_ms' ../povorot1.c: In function 'Shift_Reg': ../povorot1.c:30: warning: implicit declaration of function 'Shift_One_Byte' ../povorot1.c:30: error: 'Led' undeclared (first use in this function) ../povorot1.c:30: error: (Each undeclared identifier is reported only once ../povorot1.c:30: error: for each function it appears in.) ../povorot1.c: At top level: ../povorot1.c:35: warning: conflicting types for 'Shift_One_Byte' ../povorot1.c:30: note: previous implicit declaration of 'Shift_One_Byte' was here ../povorot1.c: In function 'Shift_One_Byte': ../povorot1.c:38: error: 'Led' undeclared (first use in this function) ../povorot1.c:42: warning: statement with no effect ../povorot1.c: In function 'Analog': ../povorot1.c:52: error: 'TCCR0' undeclared (first use in this function) ../povorot1.c: At top level: ../povorot1.c:69: warning: return type of 'main' is not 'int' make: *** [povorot1.o] Ошибка 1 Build failed with 5 errors and 5 warnings... c:19-я не понял как мне задекларировать эту функцию?она же входит в util/delay. с:30-ну тут более или менее понятно с:35-что тут с типами не так? с:38-понятно с:42-эт почемуже? с:52-я так понимаю в начале нужно сделать типа TCCR0=0x00? с:69-так она ж вроде ничего не возвращает? И вопрос по двоичному индикатору.достаточно будет возвращаемое функцией Analog() 16 битное число протолкнуть в 2 регистра паровозиком?
|
|
|
|
|
Dec 19 2010, 03:47
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
открыть delay.h и глянуть, что там _delay_ms() - религия не позволяет? ) Цитата :30: warning: implicit declaration of function 'Shift_One_Byte' тут надо чтобы функция Shift_One_Byte была либо объявлена(прототип функции) либо уже реализована ДО вызова. Чтобы компилятор мог знать как организовать вызов(какие параметры функция принемает и что возвращает). А вот массив Led не объявлен вообще нигде  :35 исчезнет как только добавите прототип или переместите реализацию Shift_One_Byte() выше её первого использования. Цитата :42-эт почемуже? ну а результат куда? у вас в строке записано действие(сдвиг) но результат никуда не присваивается. надо dig<<=1; или dig = dig<<1; (для начинающего так более наглядно) Цитата с:52-я так понимаю в начале нужно сделать типа TCCR0=0x00? нет. это называется инициализация, а у вас рагается на undeclared - т.е. вообще не определен. Быстро пробежался по iotn2313.h и обнаружил там TCCR0A За подробностями надо в даташит лезть... но думаю, что это он и есть. Просто разные компиляторы и немного разные обозначения. Где-то они для удобства как в даташите, а где-то хрен знает как называются )) Цитата :69-так она ж вроде ничего не возвращает? Там, где есть куда возвращаться(типа "в операционку") - возврат из main таки передаёт значение "наверх", поэтому по стандарту main() должен возвращать int. В данной ситуации можно не обращать внимания на это...
--------------------
The truth is out there...
|
|
|
|
|
Dec 19 2010, 04:30
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(RW6MKA @ Dec 19 2010, 08:07)  И вопрос по двоичному индикатору.достаточно будет возвращаемое функцией Analog() 16 битное число протолкнуть в 2 регистра паровозиком? Да. Хорошо, что заработало. Увидите, сколько там граблей... По поводу delay_ms Код #define delay_ms(arg) _delay_ms(arg) Я так думаю, что раз Вы то там, то сям пишете, лучше настраиваться на стандартное название.
|
|
|
|
|
Dec 19 2010, 11:27
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Вот исправленный код CODE
#include <stdint.h> #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h>
#define CD4094_PORT PORTB #define CD4094_DDR DDRB #define CD4094_PIN_DATA 3 #define CD4094_PIN_CLK 2 #define CD4094_PIN_STB 4 #define OnBit(address,bit) (address|=(1<<bit)) #define OffBit(address,bit) (address&=~(1<<bit))
//определение переменных volatile uint8_t TH; uint8_t Led[2]; //объявление прототипов функций void CD4094_CLK(void); void CD4094_STB(void); void Shift_Reg(void); void Shift_One_Byte(uint8_t tmp); uint16_t Analog(void);
void main(void){ // инициализация порта D //PD1-2 выход,уровень 0 //PD4-6 вход,подтягивающие резисторы включены PORTD=0x70; //установка битов порта D в 0 или 1 DDRD=0x06; //установка порта D на in или out DDRB=0x1C; //установка stb,data,clk на выход,уровень 0
while(1){ if (PIND6==0){ //если кнопка S0(см.схему) нажата OnBit(PORTD,2); //включить поворот (RUN) OffBit(PORTD,1); //реверс не включать } //цикл выполняется пока действительно условие if (PIND4==0){ //если кнопка S2 нажата OnBit(PORTD,2); //включить поворот OnBit(PORTD,1); //включить реверс(REV) } }
}
void CD4094_CLK(void){ //дёргаем ногу clk для проталкивания битов по регистру OnBit(CD4094_PORT,CD4094_PIN_CLK); _delay_ms(2); OffBit(CD4094_PORT,CD4094_PIN_CLK); }
void CD4094_STB(void){ //дёргаем ногу stb для поджига светодиодов OnBit(CD4094_PORT,CD4094_PIN_STB); _delay_ms(2); OffBit(CD4094_PORT,CD4094_PIN_STB); }
void Shift_Reg(void){ //загрузка сдвигового регистра Shift_One_Byte(Led[0]);//загрузка байта в 1 регистр Shift_One_Byte(Led[1]);//загрузка байта во 2 регистр CD4094_STB(); //зажигаем светодиоды }
void Shift_One_Byte(uint8_t tmp){ //загрузка одного байта uint8_t i,dig; i=8; dig=Led[tmp]; while(i--){ if(dig&0x80){OnBit(CD4094_PORT,CD4094_PIN_DATA);} else{OffBit(CD4094_PORT,CD4094_PIN_DATA);} dig=dig<<1; CD4094_CLK(); } }
uint16_t Analog(void){ //используем аналоговый компаратор для замера времени заряда кондёра OffBit(DDRB,0); //переводим 0 выход порта В в третье состояние OffBit(PORTB,0); TCNT0=0; //очистим счётчик-накопитель TH=0; TCCR0A=2; //включаем таймер0 с пределителем CLK/8 OnBit(DDRB,7); //включить транзистор while(!(ACSR&(1<<5))); //ждём изменения состояния бита АСО на выходе компаратора TCCR0A=0; //выключаем таймер OffBit(DDRB,7); //выключаем транзистор OnBit(DDRB,0); //разряжаем кондёр _delay_ms(2); //время для разряда кондёра return(TH<<8 | TCNT0); //возвращаем результат замера времени }
ISR(TIMER0_OVF_vect){ //обработка прерывания таймера0 по переполнению //при переполнении 8-битного счётчика таймера увеличивать байт ТН на 1 TH++; }
Компил ругается только на main() Подскажите как теперь правильно реализовать чтение датчика и индикацию?Во время цикла проверки нажатия кнопок или можно после опроса кнопок?
|
|
|
|
|
Dec 19 2010, 14:11
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Вот с помощью этого кода пытался узнать тики.К выходам регистров подключены светодиоды.Чтото не фурычит.Что не так? CODE #include <stdint.h> #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h>
#define CD4094_PORT PORTB #define CD4094_DDR DDRB #define CD4094_PIN_DATA 3 #define CD4094_PIN_CLK 2 #define CD4094_PIN_STB 4 #define OnBit(address,bit) (address|=(1<<bit)) #define OffBit(address,bit) (address&=~(1<<bit))
//объявление прототипов функций void CD4094_init(void); void CD4094_CLK(void); void CD4094_STB(void); void Shift_Reg(void); void Shift_One_Byte(uint16_t dig); uint16_t Analog(void);
//определение переменных volatile uint8_t TH; uint16_t tik;
void main(void){ while(1){ sei(); tik=Analog(); CD4094_init(); Shift_Reg(); } }
void CD4094_init(void){ //инициализация регистров uint16_t i; for(i=0;i<16;i++){OffBit(CD4094_PORT,CD4094_PIN_DATA) ; CD4094_CLK(); } }
void CD4094_CLK(void){ //дёргаем ногу clk для проталкивания битов по регистру OnBit(CD4094_PORT,CD4094_PIN_CLK); OffBit(CD4094_PORT,CD4094_PIN_CLK); }
void CD4094_STB(void){ //дёргаем ногу stb для поджига светодиодов OnBit(CD4094_PORT,CD4094_PIN_STB); OffBit(CD4094_PORT,CD4094_PIN_STB); }
void Shift_Reg(void){ //загрузка сдвигового регистра Shift_One_Byte(tik);//загрузка 2 байтов в регистр CD4094_STB(); //зажигаем светодиоды }
void Shift_One_Byte(uint16_t tik){ //загрузка одного байта uint16_t i=16; uint16_t dig=tik; while(i--){ if(dig&0x8000){OnBit(CD4094_PORT,CD4094_PIN_DATA);} else{OffBit(CD4094_PORT,CD4094_PIN_DATA);} dig<<=1; CD4094_CLK(); } }
uint16_t Analog(void){ //используем аналоговый компаратор для замера времени заряда кондёра OffBit(DDRB,0); //переводим 0 выход порта В в третье состояние OffBit(PORTB,0); TCNT0=0; //очистим счётчик-накопитель TH=0; TCCR0A=2; //включаем таймер0 с пределителем CLK/8 OnBit(DDRB,7); //включить транзистор while(!(ACSR&(1<<ACO))); //ждём изменения состояния бита АСО на выходе компаратора TCCR0A=0; //выключаем таймер OffBit(DDRB,7); //выключаем транзистор OnBit(DDRB,0); //разряжаем кондёр _delay_ms(2); //время для разряда кондёра return(TH<<8 | TCNT0); //возвращаем результат замера времени }
ISR(TIMER0_OVF_vect){ //обработка прерывания таймера0 по переполнению //при переполнении 8-битного счётчика таймера увеличивать байт ТН на 1 TH++; }
|
|
|
|
|
Dec 19 2010, 14:43
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Поймите вы меня, мил человек, я вам помогаю, но я не хочу делать за вас всю работу. Тем более, что я ощущаю у вас некоторое нежелание реально разбираться и работать... ну сяду я сейчас и что я буду делать? А то-же, что и вы должны сделать, чтобы понять что не так: буду сначала думать что нужно было бы сделать(какие сигналы куда зачем и с какими задержками) и как оно реально получается тут у вас...... Цепляйте там у себя в протеусе пробники на каждую ногу - смотрите форму сигналов...думайте соответствует ли она требуемой... отлаживайте! ) всё для этого у вас есть. )
Не хотите вы своей головой думать. Вставляете чужой говнокод в проект. Копируете чужие косяки - дело Ваше ))
Я предлагаю начать с малого. Освоиться заодно и с протеусом...проверить, может он ваще мышей не ловит или тачка у вас слабая и там всё жутко тормозит... потом подумать и шаг за шагом реализовать свои функции для работы с регистрами вашими.. Так оно и помогать то будет приятней, когда человек разбирается, а не чужой говнокод правит )
--------------------
The truth is out there...
|
|
|
|
|
Dec 20 2010, 16:37
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата А не пора ли бить за такой образ мысли ? Ненавижу слово "прога" и тех, кто его произносит. А вот это зря. Вы же поняли о чем речь, а прога или код или ещё как помоему не важно,лишь бы правильно написано было.Вот лучше подскажите человеку,который лишь полтора месяца назад услышал про С и пр.,что не так в функции Analog(). CODE #include <stdint.h> #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h>
#define CD4094_PORT PORTB #define CD4094_DDR DDRB #define CD4094_PIN_DATA 3 #define CD4094_PIN_CLK 2 #define CD4094_PIN_STB 4 #define OnBit(address,bit) (address|=(1<<bit)) #define OffBit(address,bit) (address&=~(1<<bit))
//объявление прототипов функций void CD4094_init(void); void CD4094_CLK(void); void CD4094_STB(void); void Shift_Reg(void); void Shift_One_Byte(uint16_t tik); uint16_t Analog(void);
//определение переменных volatile uint8_t TH; uint8_t Led[2];
void main(void){ CD4094_DDR = 0x0E;//конфигурируем пины 2,3,4 на выход CD4094_PORT = 0x00;//на входах выкл подтягивающие резисторы,на выходах уровень 0 sei(); CD4094_init(); while(1){ Led[0]=Analog(); Shift_Reg(); _delay_ms(100); } }
void CD4094_init(void){ //инициализация регистров,прогоняем 0 по всем пинам uint16_t i; for(i=0;i<16;i++){OffBit(CD4094_PORT,CD4094_PIN_DATA) ; CD4094_CLK(); } }
void CD4094_CLK(void){ //дёргаем ногу clk для проталкивания битов по регистру OnBit(CD4094_PORT,CD4094_PIN_CLK); _delay_us(10); OffBit(CD4094_PORT,CD4094_PIN_CLK); }
void CD4094_STB(void){ //дёргаем ногу stb для поджига светодиодов OnBit(CD4094_PORT,CD4094_PIN_STB); _delay_us(10); OffBit(CD4094_PORT,CD4094_PIN_STB); }
void Shift_Reg(void){ //загрузка сдвигового регистра Shift_One_Byte(Led[0]);//загрузка 1 байта в регистр Shift_One_Byte(Led[1]);//загрузка 2 байта в регистр CD4094_STB(); //зажигаем светодиоды }
void Shift_One_Byte(uint16_t r){ //загрузка одного байта uint16_t i=8; while(i--){ if(r&0x80){OnBit(CD4094_PORT,CD4094_PIN_DATA);} else{OffBit(CD4094_PORT,CD4094_PIN_DATA);} r<<=1; CD4094_CLK(); } }
uint16_t Analog(void){ //используем аналоговый компаратор для замера времени заряда кондёра OffBit(DDRB,0); //переводим 0 выход порта В в третье состояние TCNT0=0; //очистим счётчик-накопитель TH=0; TCCR0A=2; //включаем таймер0 с пределителем CLK/8 OnBit(DDRB,7); //включить транзистор while(!(ACSR&(1<<ACO))); //ждём изменения состояния бита АСО на выходе компаратора TCCR0A=0; //выключаем таймер OffBit(DDRB,7); //выключаем транзистор OnBit(DDRB,0); //разряжаем кондёр _delay_ms(2); //время для разряда кондёра Led[1]=TH; return(TCNT0); //возвращаем результат замера времени }
ISR(TIMER0_OVF_vect){ //обработка прерывания таймера0 по переполнению //при переполнении 8-битного счётчика таймера увеличивать байт ТН на 1 TH++; }
При запуске debugging нормально шагает до while(!(ACSR&(1<<ACO))); и виснет(понятно,бит то не меняется) пропускаем это цикл и всё нормально шагает и работает до конца но... Ведь если этот цикл выкинуть то первый и второй элемент массива Led будут иметь значение 0 и при моделировании всё должно работать просто ни один из светодиодов не будет гореть?Но почему то нет импульсов ни CLK ни STB? Такое ощущение что гдето всё висит. При присвоении TH и TCNT0 каких либо значений,эти значения благополучно отображаются на индикаторах,но импульса строба опять таки нет. Что я недопонимаю? Цитата Вот, RW6MKA, начнете сами разбираться с управлением регистрами и с тем, как это реализовать в коде Да нормально регистры работают,(я писал отдельно код,треннировался загонять в регистры разные комбинации) просто хоть убей не пойму почему функция строба не работает и не дёргает ногу,при этом на ней устойчивая 1???Пин сконфигурирован как выход с уровнем 0 и по коду его меняет только строб,а на деле по другому. Другая проблема с счетчиком тиков.Ну хоть чтото должен же он насчитать и выдать???А он помоему зависает в while(!(ACSR&(1<<ACO)));и дальше программа не выполняется(это видно по отсутствию импульсовCLK).Блин,ну правильно же код написан,ну с возвращением значений может что не так,но сам процесс счёта времени заряда...?!  Вот кидаю на всякий случай файл протеуса. Да,кстати, как в студии устанавливать фьюзы? У тини2313 нужно отключить внутренний кварц и деление на 8.
tiki.rar ( 19.04 килобайт )
Кол-во скачиваний: 68
Сообщение отредактировал RW6MKA - Dec 20 2010, 16:47
|
|
|
|
|
Dec 20 2010, 21:37
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Ну не считает таймер и не работает компаратор очевидно потому, что вы их не инициализировали.. )) Кстати, если хотите шагать в отладчике - выключайте оптимизацию. А это в свою очередь означает, что функции типа _delay_ms() надо будет переопределить а delay.h вообще не инклюдить. Набросал вот такую штуковину для отладки сгодится... можете чуть подтюнинговать, чтоб правдоподобную задержку давало Код #include <stdint.h> #include <avr/io.h> #ifdef __OPTIMIZE__ #include <util/delay.h> #else //нужно накрутить инициализацию _dms2 таким образом, чтобы на цикл уходила примерно 1ms //я ставлю 255 просто от фонаря )) #define _delay_ms(d) do{ uint16_t _dms2, _dms1 = (d); \ for(;_dms1;_dms1--) \ for(_dms2 = 255;_dms2;_dms2--);\ } while(0) //нужно накрутить инициализацию _dus2 таким образом, чтобы на цикл уходила примерно 1us #define _delay_us(d) do{ uint16_t _dus2, _dus1 = (d); \ for(;_dus1;_dus1--) \ for(_dus2 = 1;_dus2;_dus2--);\ } while(0) #endif #include <avr/interrupt.h> Далее, убрал цикл, прошагал, посмотрел изменение регистров средствами студии - регистры меняет. так что ноги должны дрыгаться. Как смотреть всё это в студии - прилагаю скриншот )) Фьюзы устанавливаются при прошивке... думаю, вам следует искать их в протеусе.. В свойствах проекта же есть Frequency в герцах - вот туда надо записать правдоподобное значение частоты, на которой потом будет работать проц. Это для установки задержек в коде. Цитата Да нормально регистры работают,(я писал отдельно код,треннировался загонять в регистры разные комбинации) просто хоть убей не пойму почему функция строба не работает и не дёргает ногу,при этом на ней устойчивая 1??? т.е. прямо в протеусе вы это дело отработали и у вас всё дёргалось? А почему бы не добавить вторую задержку? Вот так Код void CD4094_CLK(void){ //дёргаем ногу clk для проталкивания битов по регистру OnBit(CD4094_PORT,CD4094_PIN_CLK); _delay_us(10); OffBit(CD4094_PORT,CD4094_PIN_CLK); _delay_us(10); } ибо если Ваш вариант функции вызывают в цикле(повторяющемся много быстрее 10uS) то у вас получается OnBit(); задержка 10uS; OffBit(); и сразу опять OnBit(); т.е. уже следующий вызов же пошел. И задержка будет зависеть только от периода итерации цикла, вызывающего эту функцию. А это не есть хорошо. Может быть поэтому вы там ловите 1? Кроме того, даже в даташите на регистр должны быть времянки, где будет показано, что высокий уровень, равно как и низкий - нужно держать не меньше определенного времени, чтобы триггер захватил состояние. Попробуйте в общем так... дожно получиться. Цитата Вот лучше подскажите человеку,который лишь полтора месяца назад услышал про С и пр., Ну ладно..может быть тогда мне стоит быть немного менее суровым... )
Эскизы прикрепленных изображений
--------------------
The truth is out there...
|
|
|
|
|
Dec 21 2010, 01:58
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата Ну не считает таймер и не работает компаратор очевидно потому, что вы их не инициализировали.. )) Т.е. нужно сделать так: Код void main(void){ CD4094_DDR = 0x0E;//конфигурируем пины 2,3,4 на выход CD4094_PORT = 0x00;//на входах выкл подтягивающие резисторы,на выходах уровень 0 //инициализация таймера0 TCCR0A=0x00; TCCR0B=0x00; TCNT0=0x00; OCR0A=0x00; OCR0B=0x00;
//инициализация аналогового компаратора ACSR=0x00; Цитата //нужно накрутить инициализацию _dus2 таким образом, чтобы на цикл уходила примерно 1us При частоте генератора 4 MHz периот импульсов=0,25мкс т.е. это время выполнения одной операции и в Код #define _delay_us(d) do{ uint16_t _dus2, _dus1 = (d); \ for(;_dus1;_dus1--) \ for(_dus2 = 1;_dus2;_dus2--);\ } while(0) dus2=4; я на правильном пути? Вот тайминги регистра  я правильно понимаю что импульс STB должен по длительности в 2 раза превышать импульс CLK и при этом должен быть нулевым? Цитата Далее, убрал цикл, прошагал, посмотрел изменение регистров средствами студии - регистры меняет. так что ноги должны дрыгаться. Вот и я же смотрел,всё работает,а в модели всё работает кроме STB?!?!?
Эскизы прикрепленных изображений
|
|
|
|
|
Dec 21 2010, 02:20
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Код //инициализация таймера0 TCCR0A=0x00; TCCR0B=0x00; TCNT0=0x00; OCR0A=0x00; OCR0B=0x00;
//инициализация аналогового компаратора ACSR=0x00; Боюсь, так дело не пойдет. Загляните в даташит(благо у Вас ест переведенный вариант) и посмотрите там все режимы работы таймера. Я думаю он не постоянно тикает и имеет разные режимы работы, которые нужно сначала задать и разрешить счёт. То-же и с компаратором наверно. Цитата dus2=4; я на правильном пути? нет. Вы не учитываете то, что одна строка или действие на Си может вылиться в десятки инструкций процессора ) А по тактам исполняются именно они, а не строки Си. А некоторые инструкции требуют более одного такта для выполнения. Но тут то надо всего-лишь для отладки, приблизительно.... В сущности там и вообще эти задержки можно было пустышками заменить. Это я уже повыделываться решил с макросами ) В студии, кстати, есть счётчик тактов проца. Его можно найти в левой части окна, когда отладчик активен. Вот там можете и посмотреть сколько тратится на одну Си строку ). Цитата Вот и я же смотрел,всё работает,а в модели всё работает кроме STB?!?!? Оо, ужетолько STB. А то было Цитата Но почему то нет импульсов ни CLK ни STB? STB я кстати вообще не сомотрел...
--------------------
The truth is out there...
|
|
|
|
|
Dec 21 2010, 07:49
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата Боюсь, так дело не пойдет. Загляните в даташит(благо у Вас ест переведенный вариант) и посмотрите там все режимы работы таймера. ВОТ!А в русском то даташите не было описания регистра TCCR0B, а ведь Цитата • Bits 2:0 – CS02:0: Clock Select The three Clock Select bits select the clock source to be used by the Timer/Counter. находится именно в этом регистре, а не TCCR0A!!! Теперь с исправленным вариантом кода таймер работает, но импульса STB по прежнему нет! Повторю свой вопрос с предыдущего сообщения:- я правильно понимаю что импульс STB должен быть нулевым? Ага, опять невнимательность. Код CD4094_DDR = 0x0E;//конфигурируем пины 2,3,4 на выход на самом деле устанавливается 1,2,3 биты(когда считал забыл про 0 бит). Странно как то работает все. Вроде и показывает тики, но...Вообщем вот скрины .
А когта я убирал бесконечный цикл в main, то вообще ничего не индицировалось.
Сообщение отредактировал RW6MKA - Dec 21 2010, 13:18
|
|
|
|
|
Dec 21 2010, 12:34
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Что значит Цитата импульс STB должен быть нулевым? ? Давайте посмотрим на картинку. Что делает STB? Для чего он вообще используется? И каким он должен быть?
Эскизы прикрепленных изображений
--------------------
The truth is out there...
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|