|
|
  |
Изменение текста программы при смене компилятора и чипа |
|
|
|
Jan 3 2011, 14:20
|
Частый гость
 
Группа: Участник
Сообщений: 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)) #define Rstop 1 #define Lstop 2 #define Run 0 //объявление прототипов функций void CD4094_init(void); void CD4094_CLK(void); void CD4094_STB(void); void Shift_Reg(void); void Shift_One_Byte(uint8_t r); uint16_t Analog(void); uint8_t Datchik_Pos(void); void Led_Pos(void); void RotorL(void); void RotorR(void);
//определение переменных volatile uint8_t TH; uint8_t Led[2]; uint8_t Povorot; uint8_t N;
void main(void){
// инициализация порта D и B PORTD=0x70; //установка битов порта D в 0 или 1 DDRD=0x06; //установка порта D на in или out DDRB=0x1C; //установка stb,data,clk на выход,уровень 0 //инициализация прерываний по переполнению таймера0 TIMSK=0x2; //инициализация аналогового компаратора ACSR=0x00;
Led[0]=Led[1]=0; Povorot=0; N=0; CD4094_init(); //инициализация регистров OffBit(DDRB,7); //выключаем транзистор OnBit(DDRB,0); //разряжаем кондёр _delay_ms(2); //время для разряда кондёраPovorot=0; sei(); //разрешение глобальных прерываний
//основной цикл while(1){ if((!(PIND&1<<PIND6))||(!(PIND&1<<PIND4))){ //если нажата одна из кнопок N=Datchik_Pos(); if(N<1) Povorot=Rstop; //определение конечного правого положения датчика else if(N>48) Povorot=Lstop; //определение конечного левого положения датчика else Povorot=Run; if(!(PIND&1<<PIND6)) RotorR(); //если нажата кнопка S0 if(!(PIND&1<<PIND4)) RotorL(); //если нажата кнопка S2 } else {OffBit(PORTD,1);OffBit(PORTD,2);} //если не нажата ни одна из кнопок } }
void RotorR(void){ if(Povorot==Rstop){ OffBit(PORTD,2); OffBit(PORTD,1); return;} //если в крайнем правом положении то стоп else{ OnBit(PORTD,2); //включить поворот (RUN) OffBit(PORTD,1); //реверс не включать Datchik_Pos(); Led_Pos(); Shift_Reg(); _delay_ms(300); } }
void RotorL(void){ if(Povorot==Lstop){ OffBit(PORTD,1); OffBit(PORTD,2); return;} //если в крайнем левом положении то стоп else{ OnBit(PORTD,2); //включить поворот (RUN) OnBit(PORTD,1); //реверс включить Datchik_Pos(); Led_Pos(); Shift_Reg(); _delay_ms(300); } } uint8_t Datchik_Pos(void){ //перевод тиков в номер положения датчика uint16_t n; uint8_t m; n=Analog(); //получаем тики m=((n-30)*100)/476; //переводим тики в номер положения переменника return(m); }
void Led_Pos(void){ //перевод номера положения датчика в код светодиода и группы uint8_t m; m=Datchik_Pos(); Led[0]=(1<<((m-(((m-1)>>3)<<3))-1)); //переводим номер положения переменника в номер светодиода в группе Led[1]=~(1<<((m-1)>>3)); //переводим номер положения переменника в номер группы с инверсией битов }
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); _delay_us(15); 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[1]);//загрузка кода группы в регистр Shift_One_Byte(Led[0]);//загрузка кода светодиода в группе регистр OffBit(CD4094_PORT,CD4094_PIN_DATA); CD4094_STB(); //зажигаем светодиоды }
void Shift_One_Byte(uint8_t r){ //загрузка одного байта uint8_t i=8; while(i--){ if(r&0x80) OnBit(CD4094_PORT,CD4094_PIN_DATA); else OffBit(CD4094_PORT,CD4094_PIN_DATA); CD4094_CLK(); r<<=1; } }
uint16_t Analog(void){ //используем аналоговый компаратор для замера времени заряда кондёра OffBit(DDRB,0); //переводим 0 выход порта В в третье состояние TCNT0=0; //очистим счётчик-накопитель TH=0; TCCR0B=2; //включаем таймер0 с пределителем CLK/8 OnBit(DDRB,7); //включить транзистор while(!(ACSR&(1<<ACO))); //ждём изменения состояния бита АСО на выходе компаратора TCCR0B=0; //выключаем таймер OffBit(DDRB,7); //выключаем транзистор OnBit(DDRB,0); //разряжаем кондёр _delay_ms(2); //время для разряда кондёра return(TH<<8|TCNT0); //возвращаем результат замера времени }
ISR(TIMER0_OVF_vect){ //обработка прерывания таймера0 по переполнению //при переполнении 8-битного счётчика таймера увеличивать байт ТН на 1 TH++; }
Почему эта зараза при заходе в главный цикл не проверяет условие первого if, а сразу лезет к else if(N>48)??????? И вообще при шаговом выполнении наблюдаются скачки в такие места кода, куда даже "Макар телят не гонял"  А когда я попробовал вместо Analog() вставить просто число что бы прогнать код по функциям, то он наотрез отказался заходить в Datchik_Pos(). Блок Код N=Datchik_Pos(); if(N<1) Povorot=Rstop; //определение конечного правого положения датчика else if(N>48) Povorot=Lstop; //определение конечного левого положения датчика else Povorot=Run; я пробовал заменить функцией - вообще код сбрендил и прыгал куда попало. Вообщем это не отладка кода, а отладка моей нервенной очень системы
|
|
|
|
|
Jan 3 2011, 16:32
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата Форматирование кода у вас никуда не годится. А что конкретно не так. Вроде старался всё по своим местам поставить?!  Цитата для начала проверьте отключена ли у вас оптимизация( -O0 ) Оптимизацию отключил, но всё осталось как прежде  Вот ещё чё заметил,если привести код к такому виду,то более-менее процесс идёт Код //инициализация аналогового компаратора ACSR=0x00;
sei(); //разрешение глобальных прерываний CD4094_init(); //инициализация регистров Povorot=0;
//основной цикл while(1){ if((!(PIND&1<<PIND6))||(!(PIND&1<<PIND4))){ //если нажата одна из кнопок N=Datchik_Pos(); if(N<1) Povorot=Rstop; //определение конечного правого положения датчика else if(N>48) Povorot=Lstop; //определение конечного левого положения датчика else Povorot=Run; if(!(PIND&1<<PIND6)) RotorR(); //если нажата кнопка S0 if(!(PIND&1<<PIND4)) RotorL(); //если нажата кнопка S2 } else {OffBit(PORTD,1);OffBit(PORTD,2);} //если не нажата ни одна из кнопок } } хотя прыжок сразу на else if(N>48)
Сообщение отредактировал RW6MKA - Jan 3 2011, 16:11
|
|
|
|
|
Jan 4 2011, 06:56
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата хотя прыжок сразу на else if(N>48) Прыжок у вас скорее всего на else перед if (N>=48). Похоже if (N<1) не сработал, а компилятор вероятно привязал номера строк к веткам then и else (для if места не нашлось  ) Переформатируйте код, как советовал sigmaN, возможно начнет ходить нормально
|
|
|
|
|
Jan 4 2011, 15:43
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата Переформатируйте код, как советовал sigmaN, возможно начнет ходить нормально Не совсем , сначала прыгает на N=Datchik_Pos(); а потом возвращается в начало и всё идёт по порядку,как надо. Цитата Организуйте для начала нормальный отладочный вывод, чтобы не шагами шагать, а реально в проге было видно чё куда и как. Зашел в if - зажглись диодеги соответствующие. Поясните,как это сделать в студии? Кстати залил всё в железо, индикация вроде нормальная,а вот реализация концевых ограничений где то глючит, да и с самими кнопками...Сразу после включения срабатывает только кнопка поворота вправо(PIND6, а по коду вроде всё нормально?). При прохождении вправо до срабатывания концевика реле начинает дёргатся, вместо того что бы просто выключится( опять же в коде такого не наблюдал,всё послушно шагает по циклу).Включаем вращение влево, уводим датчик от конца и нажимаем опять вращение вправо и понимаем что срабатывает не всегда(такое ощущение что где то нужна задержка). так же и в другую сторону.
|
|
|
|
|
Jan 4 2011, 18:20
|

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

|
Цитата Поясните,как это сделать в студии? также как и не в студии)) тут вообще без привязки к языку даже)) Цитата а вот реализация концевых ограничений где то глючит ну по науке вам не хватает гистерезиса. Т.е. допустим в попугаях 0 - это крайнее левое положение. Так вот надо сделать так, что бы вращение влево прекращалось при достижении значения 1(условно), а вот если мы однажды запретили движение влево - то разрешать его нужно только если мы уже прошли(вправо) до значения 7(опять таки условно). Т.е. обеспечить зазор на погрешности и механические неточности/инерцию... А ещё, при всём при этом должна быть чётко отлажена процедура замера положения. Опять таки тут нужно определиться с необходимой и достаточной частотой опроса + отфильтровать значения(если будет такая необходимость) хотя-бы вычисляя среднее по трём-пяти(двум или восьми) считанным значениям. Цитата Сразу после включения срабатывает только кнопка поворота вправо(PIND6, а по коду вроде всё нормально?). ну если было бы нормально - оно бы работало )) ищите)) и нормально код переформатируйте! неудобно же самому разбираться даже в этих ифах налеплных в одну строку и в кучу. Отступы, отступы. Пробелы где надо должны быть. еслиявоттаквотписатьбуду-этоженебудетнормальночитаться,хотявсебуквыинаместевродекакискомпилитьсядолжноваш иммоском)))
--------------------
The truth is out there...
|
|
|
|
|
Jan 5 2011, 15:51
|
Частый гость
 
Группа: Участник
Сообщений: 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)) #define Rstop 1 #define Lstop 2 #define RUN 2 #define REV 1 #define S0 6 #define S2 4
//объявление прототипов функций void CD4094_init(void); void CD4094_CLK(void); void CD4094_STB(void); void Shift_Reg(void); void Shift_One_Byte(uint8_t r); uint16_t Analog(void); uint8_t Datchik_Pos(void); void Led_Pos(void); void RotorL(void); void RotorR(void);
//определение переменных volatile uint8_t TH; uint8_t Led[2]; uint8_t Povorot; uint8_t N;
void main(void) {
// инициализация порта D и B PORTD = ((1 << S0) | (1 << S2)); //включение подтягивающих резисторов в S0,S2 DDRD = ((1 << RUN) | (1 << REV)); //установка RUN,REV на выход DDRB = ((1 << CD4094_PIN_DATA) | (1 << CD4094_PIN_CLK) | (1 << CD4094_PIN_STB)); //установка stb,data,clk на выход,уровень 0 //инициализация прерываний по переполнению таймера0 TIMSK = 0x2; //инициализация аналогового компаратора ACSR = 0x00;
sei(); //разрешение глобальных прерываний CD4094_init(); //инициализация регистров Led[0] = 0; Led[1] = 0; Povorot = 0;
//основной цикл while (1) { if ((!(PIND & 1 << PIND6)) || (!(PIND & 1 << PIND4))) { //если нажата одна из кнопок N = Datchik_Pos(); if (N > 48) { //определение конечного правого положения датчика Povorot = Rstop; } else if (N < 1) { //определение конечного левого положения датчика Povorot = Lstop; } else if ((N > 1) && (N < 48)) { Povorot = 0; } if (!(PIND & 1 << PIND6)) { //если нажата кнопка S0 RotorR(); } if (!(PIND & 1 << PIND4)) { //если нажата кнопка S2 RotorL(); } } else { //если не нажата ни одна из кнопок OffBit(PORTD, REV); OffBit(PORTD, RUN); } } }
void RotorR(void) { if (Povorot == Rstop) { //если в крайнем правом положении то стоп OffBit(PORTD, RUN); OffBit(PORTD, REV); _delay_ms(300); return; } else { OnBit(PORTD, RUN); //включить поворот (RUN) OffBit(PORTD, REV); //реверс не включать (REV) Led_Pos(); Shift_Reg(); _delay_ms(300); } }
void RotorL(void) { if (Povorot == Lstop) { //если в крайнем левом положении то стоп OffBit(PORTD, RUN); OffBit(PORTD, REV); _delay_ms(300); return; } else { OnBit(PORTD, RUN); //включить поворот (RUN) OnBit(PORTD, REV); //реверс включить (REV) Led_Pos(); Shift_Reg(); _delay_ms(300); } }
uint8_t Datchik_Pos(void) { //перевод тиков в номер положения датчика uint16_t n = 0; uint16_t i; uint8_t m = 8; while(m--) { n += Analog(); //накапливаем тики } i = n>>3; //получаем средние тики m = ((i - 36) * 100) / 474; //переводим тики в номер положения переменника return (m); }
void Led_Pos(void) { //перевод номера положения датчика в код светодиода и группы uint8_t m; m = Datchik_Pos(); Led[0] = (1 << ((m - (((m - 1) >> 3) << 3)) - 1)); //переводим номер положения переменника в номер светодиода в группе Led[1] = ~(1 << ((m - 1) >> 3)); //переводим номер положения переменника в номер группы с инверсией битов }
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); _delay_us(15); 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[1]);//загрузка кода группы в регистр Shift_One_Byte(Led[0]);//загрузка кода светодиода в группе регистр OffBit(CD4094_PORT, CD4094_PIN_DATA); CD4094_STB(); //зажигаем светодиоды }
void Shift_One_Byte(uint8_t r) { //загрузка одного байта uint8_t i = 8; while(i--) { if (r&0x80) { OnBit(CD4094_PORT, CD4094_PIN_DATA); } else { OffBit(CD4094_PORT, CD4094_PIN_DATA); } CD4094_CLK(); r <<= 1; } }
uint16_t Analog(void) { //используем аналоговый компаратор для замера времени заряда кондёра OffBit(DDRB, 0); //переводим 0 выход порта В в третье состояние TCNT0 = 0; //очистим счётчик-накопитель TH = 0; OnBit(TCCR0B, CS01); //включаем таймер0 с пределителем CLK/8 OnBit(DDRB,7); //включить транзистор while(!(ACSR &(1 << ACO)));//ждём изменения состояния бита АСО на выходе компаратора OffBit(TCCR0B, CS01); //выключаем таймер OffBit(DDRB, 7); //выключаем транзистор OnBit(DDRB, 0); //разряжаем кондёр _delay_ms(2); //время для разряда кондёра return(TH << 8 | TCNT0); //возвращаем результат замера времени }
ISR(TIMER0_OVF_vect) { //обработка прерывания таймера0 по переполнению //при переполнении 8-битного счётчика таймера увеличивать байт ТН на 1 TH++; }
Что касается исполнения кода, то прыжок с Povorot = 0; сразу на Povorot = Lstop; потом на Povorot = Rstop; и только после этого на if ((!(PIND & 1 << PIND6)) || (!(PIND & 1 << PIND4))) { // я не могу объяснить никак. Потом до момента получения среднего числа тиков всё идёт гладко и опять необъяснимый скачок на } else { //если не нажата ни одна из кнопок OffBit(PORTD, REV); OffBit(PORTD, RUN); (именно на выключение RUN) и дальше опять всё нормально. Что за скакалки-прыгалки?
Сообщение отредактировал RW6MKA - Jan 5 2011, 17:05
|
|
|
|
|
Jan 6 2011, 10:46
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата По крайней мере не будет неопределенности с номерами строк (со стороны компилятора) Пробовал и так, результат тот же. Цитата обязательно скурить: Так я этими статьями и пользуюсь. Больше по студии и почитать особо негде. Цитата и вот это вот тоже осмыслить бы и применить на практике: Это я так понимаю к вопросу о гистерезисе? Пока отложу, надо разобраться с тем что есть. Цитата ну не знаю....тоже отладка... сам не читал... Штука классная, но у меня тинька. Теперь вопрос. Прогнал код и вдоль и поперёк. Все пины, таймер,прерывание ну всё показывает нормально, а логики этих скачков не могу ни понять, ни отследить в чём причина. Как это побороть?
Сообщение отредактировал RW6MKA - Jan 6 2011, 10:59
|
|
|
|
|
Jan 6 2011, 11:48
|

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

|
Цитата Это я так понимаю к вопросу о гистерезисе? Пока отложу, надо разобраться с тем что есть. это к вопросу о том, что разрабатываемое вами устройство - есть не более чем конечный автомат ))) ну глючит там отладчик при шагах по си коду...что вы так на этом зацикливаетесь то а? я уже предлагал ведь вам организовать отладочный вывод и по нему определиться, правильно ли выполняется программа. ну + задержки где надо, чтоб успевать соображать что к чему.... и прямо на ходу всё проверите. выкладывайте проект + протеусовский тоже.
--------------------
The truth is out there...
|
|
|
|
|
Jan 6 2011, 13:04
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Вот проекты, povorot к Протеусу,povorot2 код.
povorot.rar ( 30.9 килобайт )
Кол-во скачиваний: 67
povorot2.rar ( 15.64 килобайт )
Кол-во скачиваний: 71
|
|
|
|
|
Jan 7 2011, 12:54
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата Это работа оптимизатора (посмотрите ассемблер). Так и не понял как это сделать в студии.  Да, а оптимизация то отключена
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|