Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Изменение текста программы при смене компилятора и чипа
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Страницы: 1, 2, 3, 4, 5, 6, 7
sigmaN
Цитата
Буду писать прогу под эту схему с нуля.
А вот это правильно ))
Ну за пять часов можно знаете скоолько написать всего ))
RW6MKA
Подтягиваю теорию и в качестве практики разбирая исходник столкнулся с таким кодом:__eeprom State ee_stat; State Status; Status=ee_stat; (пишу с телефона поэтому так криво)интересует предназначение __eeprom в объявлении переменной ee_stat типа State. И еще: #ifdef DEBUG; void sb(byte data); void phex(byte ch); #define CRLF sb(13);sb(10) #endif Вроде читаю об этом,а не до конца понимаю суть:-(
sigmaN
чё, опять 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);
RW6MKA
Цитата(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)условная компиляция???Что эт за зверь?
RW6MKA
Так я до конца и не понял строчку: return(TH<<8 | TCNT0);Зачем производить сдвиг переменной TH на 8 позиций .Нам то нужно значение TCNT0?Или это для того чтобы занести значение в старший байт?
sigmaN
Цитата
не пойму при чем здесь DEBUG
Программа пишется с учётом отладки(к примеру вывод значений по UART в нужных местах).
Куски кода, отвечающие за отладку делают внутри ifdef DEBUG. Таким образом, если символ DEBUG определен - компилятор скомпилирует то, что между ifdef и endif, а если нет - то пропустит. Для него тогда просто не существует этого кода. Препроцессор его вырежет, т.к. условие не выполнилось, DEBUG не определен(nod defined). Вот. Таким образом релиз программы делается без отладочного вывода путем простого комментирования строки #define DEBUG где-то в самом начале программы ) А ещё символы дефайнить можно из свойств проекта... В общем это уже не так важно.

Цитата
Или это для того чтобы занести значение в старший байт?
Да, TH ложится в старший байт, TCNT0 в младший. Я ооочень подробно там всё описал с примерами. Едва ли я смогу что-то новое придумать ) Там прям в двоичном виде кажется давал примеры же!
RW6MKA
Ага, спасибо с дебугом всё ясно.С ТН...Если не записать 0 в старший байт,то туда запишется значение TCNT0 ,поскольку сначала должен записываться именно старший байт?
sigmaN
Цитата
Если не записать 0 в старший байт,то туда запишется значение TCNT0 ,поскольку сначала должен записываться именно старший байт?
Как это? Откуда это? Ничего не понял. Имеется ввиду, что будет, если просто написать return TCNT0; ?

Так вот если просто присвоить 16ти битной переменной(у нас это значение функции) то этот TCNT0 пойдет, естественно, в младший байт, а в старшем будут нули сами собой. Ибо мы то присваиваем ЗНАЧЕНИЕ. Т.е. TCNT0 было равно к примеру 150. Мы и присваиваем переменной 150. Если переменная 16бит - то будет один старший байт нулей, а в младшем наши 150. Если переменная 32бита - будет три байта нулей, а в четвертом(самом младшем) будут наши 150. И значение переменной во всех случаях будет таки равно 150 и никак иначе.
И записать их можно в любом порядке(с помощью битовых операций, в которые, как мне кажется, Вы до сих пор так толком и не "въехали)".
RW6MKA
Что делает TH<<8,что и куда переносится я понимаю,я не пойму зачем это делать?Почему нельзя просто написать return TCNT0?
RW6MKA
Обязательно ли дергать строб при зажигании светодиодов, или достаточно подтянуть его к 1?

Как можно подобрать соотношение напряжение - светодиод? Моделировать в Протеусе?
sigmaN
Цитата
Что делает TH<<8,что и куда переносится я понимаю,я не пойму зачем это делать?Почему нельзя просто написать return TCNT0?
ну так вы же теряете старший байт в таком случае! Ну вот представьте, что TCNT0 - это секунды,а TH - минуты.
Засекаете время путём обнуления этих двух переменных и пошли тикать часы. Вот мы имеем два отсчёта времени
37 секунд
1 минута 12 секунд
А теперь представьте, что из функции вы возвращаете только секунды(return TCNT0;). При сравнении окажется, что второй промежуток меньше. Хотя на самом деле это не так. Вот и TCNT0 мотает от 0 до 255, а дальше опять 0 и снова до 255. Каждый раз, когда он пробегает через 0 - вызывается прерывание и значение TH увеличивается на 1(в примере - это минуты. минуты ведь тоже прибавляются в момент перехода секунд через 0).

Цитата
Обязательно ли дергать строб при зажигании светодиодов, или достаточно подтянуть его к 1?
читайте про сдвиговые регистры. Притянуть - это типа резистор поставить? Ггг wink.gif

Цитата
Как можно подобрать соотношение напряжение - светодиод? Моделировать в Протеусе?
http://www.casemods.ru/services/raschet_rezistora.html
http://novikovmaxim.narod.ru/index.htm?htt...ron/connect.htm
RW6MKA
Ага, с ТН разобрался, меня ввело в заблуждение то, что обработка прерываний по переполнению написана после описания функции(так можно делать?) Что касается строба то есть схемы где нога висит на + питания, а в других её дергают и как лучше поступить мне ?

Про соотношение я не правильно выразился. Нужно сделать макросы с байтами светодиодов для ввода в регистры. Каждый байт должен соответствовать определенному количеству тиков таймера. Для всего этого мне нужно знать сколько тиков какому напряжению от датчика соответствует?
sigmaN
Цитата
Ага, с ТН разобрался, меня ввело в заблуждение то, что обработка прерываний по переполнению написана после описания функции(так можно делать?)
Обработчик прерывания даже можно написать на чистом асме )) Не важно где он - важно, что он есть. И вообще, логика где? Он ведь исполняется по событию от таймера, независимо. Так какая разница где этот обработчик? Выше или ниже функции )

Цитата
Что касается строба то есть схемы где нога висит на + питания, а в других её дергают и как лучше поступить мне ?
Думаю, лучше дёргать 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 на нужное место - всё это будет видно в виде некоторых спецэффектов )
RW6MKA
Спасибо за развернутые ответы. Читал статью по вашей ссылке, про RC цепи. Там есть формула расчета времени зарядки конденсатора, но я не пойму какое сопротивление взять в моем случае? Зарядка идет через открытый транзисторный ключ, сопротивление которого очень мало,но какова его величина?
sigmaN
резистор R2.

Не заморачивайтесь там с расчётами, составьте таблицу, вращая переменный резистор.
RW6MKA
А как узнать сколько таймер натикал?
sigmaN
очевидно нужно как-то выводить значение функции.
тут либо uart либо из тех-же светодиодов двоичный индикатор сгородить) прикольно будет кстати.

А накакой вы уже стадии?
Что есть,чего нет?
RW6MKA
Я думаю смоделировать всё это в Протеусе.А пока я в стадии изучения теории, поскольку в данный момент до сих пор нахожусь на работе и домой попаду только 16. Как только напишу часть кода, сразу выложу на проверку.
RW6MKA
Итак прибыв домой попробовал свои силы в новой для меня 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 использовать команды на асме?
и вопрос как реализовать двоичный индикатор для отображения тиков таймера?
sigmaN
щас надо уезжать. вернусь часа через 3 и всё растолкую ))
sigmaN
Цитата
Какой файл нужно инклудить для тиньки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 может и перевод где найдете. не знаю...

Цитата
и вопрос как реализовать двоичный индикатор для отображения тиков таймера?
А вот как научитесь светодиодики зажигать через регистры сдвиговые - тогда и ясно станет. Зачем вам сейчас именно калибровать эту крутилку? Это можно оставить и на потом ведь)

RW6MKA
Цитата
инклудить надо 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 Главное чтобы оптимизация в свойствах проекта была включена.

Как включить оптимизацию?
RW6MKA
Вот что я накропал на данный момент.
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)
}

}
}

Посмотрите пожалуйста повнимательней, всё ли здесь так?
sigmaN
Цитата
Т.е. вместо бла бла бла
можно написать
Код
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> !!!
RW6MKA
Вот всё в исправленном состоянии
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 sm.gif//почему?
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...
_Pasha
Ниасилил весь топик, но
1. Автору - пользуйтесь codebox вместо code
2. Там - в последнем тексте - много чего неправильно, например, не проинициализировали таймер, неправильно main() объявили итд
Хотел типопоказать, как надо, но прямо сейчас не выйдет по времени. Я-то выложу, но и Вы тоже даром не сидите, в ожидании. Успехов.
sigmaN
Нда... остаётся теперь только догадываться что вы ставили и как создавали проект.... студия по идее сама мэйкфайл создаёт и с этим проблем быть не должно вообще...

Пробуйте для начала вообще создать новый проект и добавить туда ваш .c файлик.
Вы скачали и установили в точности то, что я Вам советовал несколькими страницами раньше? помнится я даже ссылки давал там.... проверьте всё ещё раз.
RW6MKA
Скачал и установил всё как вы рекомендовали.
Создаю новый проект-выбираю AVR GCC-пишу имя проекта-next-AVR simulator-ATtiny2113-finish
набираю или вставляю текст проги кнопка старта дебуга неактивна а при компиляции ругается wacko.gif
чё делать?????????
sigmaN
Для начала давайте ка всю папку проекта как есть запаковывайте WinRarом и присылайте сюда.
Надо определиться проблема с проектом или же со средой...
RW6MKA
Вот всё что там есть
Нажмите для просмотра прикрепленного файла

sigmaN
Путь к проекту не должен содержать русских букв и, наверное, sm.gif пробелов..
Лично я ВСЕГДА стараюсь выполнять эти правила.
Ещё где-то может вылезти ограничение на максимальную длину пути - поэтому не стоит заханыривать проект слишком далеко...
Это всё так..перестраховочные правила дабы не было проблем....

Создайте проект заново без русского "проба" в пути и всё у вас будет хорошо. Это я проверил лично, создав такой-же проект как у Вас и получив в точности такую же ошибку )
Если где-то нужен пробел - используйте нижнее подчёркивание. "project_2" например.
Файл, где описана функция main(), стараюсь всегда называть main.c
Может быть и вам будет полезно/удобно...
RW6MKA
заработало,вот немного исправленный код и результаты компиляции
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 регистра паровозиком?
sigmaN
открыть delay.h и глянуть, что там _delay_ms() - религия не позволяет? )

Цитата
:30: warning: implicit declaration of function 'Shift_One_Byte'
тут надо чтобы функция Shift_One_Byte была либо объявлена(прототип функции) либо уже реализована ДО вызова. Чтобы компилятор мог знать как организовать вызов(какие параметры функция принемает и что возвращает).
А вот массив Led не объявлен вообще нигде sad.gif

:35 исчезнет как только добавите прототип или переместите реализацию Shift_One_Byte() выше её первого использования.

Цитата
:42-эт почемуже?
ну а результат куда? у вас в строке записано действие(сдвиг) но результат никуда не присваивается.
надо
dig<<=1;
или
dig = dig<<1; (для начинающего так более наглядно)

Цитата
с:52-я так понимаю в начале нужно сделать типа TCCR0=0x00?
нет. это называется инициализация, а у вас рагается на undeclared - т.е. вообще не определен.
Быстро пробежался по iotn2313.h и обнаружил там TCCR0A
За подробностями надо в даташит лезть... но думаю, что это он и есть. Просто разные компиляторы и немного разные обозначения. Где-то они для удобства как в даташите, а где-то хрен знает как называются ))

Цитата
:69-так она ж вроде ничего не возвращает?

Там, где есть куда возвращаться(типа "в операционку") - возврат из main таки передаёт значение "наверх", поэтому по стандарту main() должен возвращать int.
В данной ситуации можно не обращать внимания на это...
_Pasha
Цитата(RW6MKA @ Dec 19 2010, 08:07) *
И вопрос по двоичному индикатору.достаточно будет возвращаемое функцией Analog() 16 битное число протолкнуть в 2 регистра паровозиком?

Да.
Хорошо, что заработало. Увидите, сколько там граблей...
По поводу delay_ms
Код
#define delay_ms(arg) _delay_ms(arg)

Я так думаю, что раз Вы то там, то сям пишете, лучше настраиваться на стандартное название.
sigmaN
Нет, он ни то там то сям - он теперь исключительно на avr-gcc пересел )))
RW6MKA
Вот исправленный код
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() laughing.gif
Подскажите как теперь правильно реализовать чтение датчика и индикацию?Во время цикла проверки нажатия кнопок или можно после опроса кнопок?
sigmaN
А вот теперь вам надо крепко подумать и реализовать всё по человечески, шаг за шагом... мне этот код не нравится и, ясное дело, тот факт, что он компилится - ещё ниичего не означает ))

Начинать надо не с заморочками с датчиком а с прикидывания общей структуры программы... с планирования надо начинать в общем...

Пока рекомендую Вам начать с самого малого - сделайте бегущий огонек на светодиодах подключенных прямо к портам.... и сделайте так, чтобы это заработало в протеусе. А там видно будет... надо потихонечку действовать, постепенно ))) начнем вот с легко отлаживаемого кода пока, я думаю..

Дальше делаете тот-же огонек на этих регистрах.. и сами всё пишите. Не копируйте готовый куски кода и идеи из того исходника.
А копировать чужие ошибки легче всего, но это умений и знаний не прибавляет к сожалению )
RW6MKA
Вот с помощью этого кода пытался узнать тики.К выходам регистров подключены светодиоды.Чтото не фурычит.Что не так?
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++;
}

sigmaN
Поймите вы меня, мил человек, я вам помогаю, но я не хочу делать за вас всю работу.
Тем более, что я ощущаю у вас некоторое нежелание реально разбираться и работать... ну сяду я сейчас и что я буду делать? А то-же, что и вы должны сделать, чтобы понять что не так: буду сначала думать что нужно было бы сделать(какие сигналы куда зачем и с какими задержками) и как оно реально получается тут у вас......
Цепляйте там у себя в протеусе пробники на каждую ногу - смотрите форму сигналов...думайте соответствует ли она требуемой... отлаживайте! ) всё для этого у вас есть. )

Не хотите вы своей головой думать. Вставляете чужой говнокод в проект. Копируете чужие косяки - дело Ваше ))

Я предлагаю начать с малого. Освоиться заодно и с протеусом...проверить, может он ваще мышей не ловит или тачка у вас слабая и там всё жутко тормозит... потом подумать и шаг за шагом реализовать свои функции для работы с регистрами вашими..
Так оно и помогать то будет приятней, когда человек разбирается, а не чужой говнокод правит )
RW6MKA
Да мне всего и нужно сказать в проге косяк или в схеме чтоб знать где рыть то.
sigmaN
ну мне то этот косяк тоже не с неба упадёт ))
Я могу вам даже сейчас написать рабочий код для ваших регистров... но толку то? вам толку то не будет от этого )
А вот умение эффективно отлаживать - не менее важно, чем умение грамотно проектировать и кодировать алгоритмы...
Так что... советую вам всё-таки потихонечку разбираться самостоятельно.
_Pasha
Цитата(RW6MKA @ Dec 19 2010, 20:51) *
в проге косяк

А не пора ли бить maniac.gif за такой образ мысли ? Ненавижу слово "прога" и тех, кто его произносит.
sigmaN
ничёё ничёё, научится.
Желание есть, судя по всему. Вообще, я думал он странице на третей с дистанции сойдет... а тут уже вон седьмая пошла ))
Вот только вот это потребительство немного победить, чтоб самому разбираться научиться и всёё, пойдет дело...если даст Бог продержится до конца этого проекта ))

Вот, RW6MKA, начнете сами разбираться с управлением регистрами и с тем, как это реализовать в коде - буду помогать.
А если почую халяву и нежелание разбираться и работать самостоятельно - не буду принципиально. Ибо это уже тогда просто пустая трата времени с моей стороны.
RW6MKA
Цитата
А не пора ли бить за такой образ мысли ? Ненавижу слово "прога" и тех, кто его произносит.

А вот это зря. Вы же поняли о чем речь, а прога или код или ещё как помоему не важно,лишь бы правильно написано было.Вот лучше подскажите человеку,который лишь полтора месяца назад услышал про С и пр.,что не так в функции 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).Блин,ну правильно же код написан,ну с возвращением значений может что не так,но сам процесс счёта времени заряда...?! wacko.gif
Вот кидаю на всякий случай файл протеуса. Да,кстати, как в студии устанавливать фьюзы? У тини2313 нужно отключить внутренний кварц и деление на 8.Нажмите для просмотра прикрепленного файла
sigmaN
Ну не считает таймер и не работает компаратор очевидно потому, что вы их не инициализировали.. ))

Кстати, если хотите шагать в отладчике - выключайте оптимизацию.
А это в свою очередь означает, что функции типа _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?
Кроме того, даже в даташите на регистр должны быть времянки, где будет показано, что высокий уровень, равно как и низкий - нужно держать не меньше определенного времени, чтобы триггер захватил состояние. Попробуйте в общем так... дожно получиться.

Цитата
Вот лучше подскажите человеку,который лишь полтора месяца назад услышал про С и пр.,
Ну ладно..может быть тогда мне стоит быть немного менее суровым... )
RW6MKA
Цитата
Ну не считает таймер и не работает компаратор очевидно потому, что вы их не инициализировали.. ))

Т.е. нужно сделать так:
Код
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?!?!?
sigmaN
Код
//инициализация таймера0
   TCCR0A=0x00;
   TCCR0B=0x00;
   TCNT0=0x00;
   OCR0A=0x00;
   OCR0B=0x00;

   //инициализация аналогового компаратора
   ACSR=0x00;

Боюсь, так дело не пойдет. Загляните в даташит(благо у Вас ест переведенный вариант) и посмотрите там все режимы работы таймера. Я думаю он не постоянно тикает и имеет разные режимы работы, которые нужно сначала задать и разрешить счёт. То-же и с компаратором наверно.


Цитата
dus2=4; я на правильном пути?
нет. Вы не учитываете то, что одна строка или действие на Си может вылиться в десятки инструкций процессора ) А по тактам исполняются именно они, а не строки Си. А некоторые инструкции требуют более одного такта для выполнения.
Но тут то надо всего-лишь для отладки, приблизительно.... В сущности там и вообще эти задержки можно было пустышками заменить. Это я уже повыделываться решил с макросами )
В студии, кстати, есть счётчик тактов проца. Его можно найти в левой части окна, когда отладчик активен. Вот там можете и посмотреть сколько тратится на одну Си строку ).

Цитата
Вот и я же смотрел,всё работает,а в модели всё работает кроме STB?!?!?
Оо, ужетолько STB. А то было
Цитата
Но почему то нет импульсов ни CLK ни STB?
STB я кстати вообще не сомотрел...


RW6MKA
Цитата
Боюсь, так дело не пойдет. Загляните в даташит(благо у Вас ест переведенный вариант) и посмотрите там все режимы работы таймера.

ВОТ!А в русском то даташите не было описания регистра 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, то вообще ничего не индицировалось.
sigmaN
Что значит
Цитата
импульс STB должен быть нулевым?
?

Давайте посмотрим на картинку.
Что делает STB? Для чего он вообще используется? И каким он должен быть?
RW6MKA
Ну насколько я могу понять пока STB=0 выходы Q0-8 не меняются, а дата без разницы какая. При смене 0 на 1 разрешается отображение даты в соответствующем выходе. Как то так!?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.