реклама на сайте
подробности

 
 
> Изменение текста программы при смене компилятора и чипа
RW6MKA
сообщение Oct 25 2010, 11:58
Сообщение #1


Частый гость
**

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



Привет всем. rolleyes.gif
Есть исходник программы написаный в IAR C v.3.10C для AT90S2313P, но такого камня уже не достать поэтому нужно переписать исходник для ATTINY2313V-10PU. Проблема в том,что IAR C v.3.10C триал или ломаная без библиотек и многого другого,поэтому изменять текст придётся в AVR Studio,но некоторые функции,как я понимаю,свойственны только IAR C v.3.10C(в частности h-файлы типа inavr.h и др.) Вообщем HELP!!! help.gif
Проще говоря нужно чтобы прога работала и компилировалась в 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
Go to the top of the page
 
+Quote Post
21 страниц V  « < 8 9 10 11 12 > »   
Start new topic
Ответов (135 - 149)
RW6MKA
сообщение Jan 3 2011, 14:20
Сообщение #136


Частый гость
**

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



Всё, башка больше не рубит. wacko.gif Объясните мне тупому smile3046.gif почему этот код не хочет выполняться по порядку, как положено любому добропорядочному коду????????
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)??????? И вообще при шаговом выполнении наблюдаются скачки в такие места кода, куда даже "Макар телят не гонял" biggrin.gif А когда я попробовал вместо Analog() вставить просто число что бы прогнать код по функциям, то он наотрез отказался заходить в Datchik_Pos(). Блок
Код
N=Datchik_Pos();
         if(N<1) Povorot=Rstop; //определение конечного правого положения датчика
         else if(N>48) Povorot=Lstop; //определение конечного левого положения датчика
         else Povorot=Run;
я пробовал заменить функцией - вообще код сбрендил и прыгал куда попало. Вообщем это не отладка кода, а отладка моей нервенной очень системы rolleyes.gif
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jan 3 2011, 14:44
Сообщение #137


I WANT TO BELIEVE
******

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



для начала проверьте отключена ли у вас оптимизация( -O0 )
с оптимизацией код и будет прыгать куда даже "Макар телят не гонял" biggrin.gif

Форматирование кода у вас никуда не годится. почитали бы Вы немного по стандартам кодирования наверно...


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
RW6MKA
сообщение Jan 3 2011, 16:32
Сообщение #138


Частый гость
**

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



Цитата
Форматирование кода у вас никуда не годится.
А что конкретно не так. Вроде старался всё по своим местам поставить?! laughing.gif
Цитата
для начала проверьте отключена ли у вас оптимизация( -O0 )

Оптимизацию отключил, но всё осталось как прежде crying.gif

Вот ещё чё заметил,если привести код к такому виду,то более-менее процесс идёт
Код
//инициализация аналогового компаратора
   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
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jan 3 2011, 18:08
Сообщение #139


I WANT TO BELIEVE
******

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



Организуйте для начала нормальный отладочный вывод, чтобы не шагами шагать, а реально в проге было видно чё куда и как. Зашел в if - зажглись диодеги соответствующие. Вышел - погасли и т.д. а то вообще не понятно чему там в действительности ваша N равно вначале....
не очень то полагайтесь на все эти шаги... или шагайте там, где вместе с Си кодом - асм видно. тогда уж сможете сориентироваться хоть как-то...
прыжок на строку с if ещё не означает, что выполнился блок кода, который под этим if. а уж с вашим форматированием всё в кучу - так и вообще не понять ничего....
заверните вот так
if(N<1)
{
Povorot=Rstop; //определение конечного правого положения датчика
}
а Povorot в Watch и наблюдайте. вот если реально Povorot изменился - значит попал в if. ну и т.д.
самый надежный канеш вариант - это отладочный вывод прямо из работающей программы(задержки добавить если чё).
Было-бы идеально, если бы у вас был UART(но можно софтовый наверно приладить) и вы прямо выводили человеческим языком отладочную инфу прямо на терминал ) Но тут то можно и диодегами обойтись. Благо у вас их ооочень много там )


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
XVR
сообщение Jan 4 2011, 06:56
Сообщение #140


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата
хотя прыжок сразу на else if(N>48)
Прыжок у вас скорее всего на else перед if (N>=48). Похоже if (N<1) не сработал, а компилятор вероятно привязал номера строк к веткам then и else (для if места не нашлось sm.gif )
Переформатируйте код, как советовал sigmaN, возможно начнет ходить нормально
Go to the top of the page
 
+Quote Post
RW6MKA
сообщение Jan 4 2011, 15:43
Сообщение #141


Частый гость
**

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



Цитата
Переформатируйте код, как советовал sigmaN, возможно начнет ходить нормально
Не совсем , сначала прыгает на N=Datchik_Pos(); а потом возвращается в начало и всё идёт по порядку,как надо.

Цитата
Организуйте для начала нормальный отладочный вывод, чтобы не шагами шагать, а реально в проге было видно чё куда и как. Зашел в if - зажглись диодеги соответствующие.
Поясните,как это сделать в студии?

Кстати залил всё в железо, индикация вроде нормальная,а вот реализация концевых ограничений где то глючит, да и с самими кнопками...Сразу после включения срабатывает только кнопка поворота вправо(PIND6, а по коду вроде всё нормально?). При прохождении вправо до срабатывания концевика реле начинает дёргатся, вместо того что бы просто выключится( опять же в коде такого не наблюдал,всё послушно шагает по циклу).Включаем вращение влево, уводим датчик от конца и нажимаем опять вращение вправо и понимаем что срабатывает не всегда(такое ощущение что где то нужна задержка). так же и в другую сторону.
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jan 4 2011, 18:20
Сообщение #142


I WANT TO BELIEVE
******

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



Цитата
Поясните,как это сделать в студии?
также как и не в студии)) тут вообще без привязки к языку даже))

Цитата
а вот реализация концевых ограничений где то глючит
ну по науке вам не хватает гистерезиса. Т.е. допустим в попугаях 0 - это крайнее левое положение. Так вот надо сделать так, что бы вращение влево прекращалось при достижении значения 1(условно), а вот если мы однажды запретили движение влево - то разрешать его нужно только если мы уже прошли(вправо) до значения 7(опять таки условно).
Т.е. обеспечить зазор на погрешности и механические неточности/инерцию...


А ещё, при всём при этом должна быть чётко отлажена процедура замера положения. Опять таки тут нужно определиться с необходимой и достаточной частотой опроса + отфильтровать значения(если будет такая необходимость) хотя-бы вычисляя среднее по трём-пяти(двум или восьми) считанным значениям.

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


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
RW6MKA
сообщение Jan 5 2011, 15:51
Сообщение #143


Частый гость
**

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
XVR
сообщение Jan 5 2011, 16:16
Сообщение #144


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



'Нормальный стиль' - это
Код
N = Datchik_Pos();
if (N > 48)
{ //определение конечного правого положения датчика
  Povorot = Rstop;
}
else
if (N < 1)
{ //определение конечного левого положения датчика
  Povorot = Lstop;
}
else
if ((N > 1) && (N < 48))
{
  Povorot = 0;
}

По крайней мере не будет неопределенности с номерами строк (со стороны компилятора)
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jan 5 2011, 17:26
Сообщение #145


I WANT TO BELIEVE
******

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



обязательно скурить:
http://easyelectronics.ru/avr-uchebnyj-kur...mm-chast-1.html
http://easyelectronics.ru/avr-uchebnyj-kur...mm-chast-2.html
http://easyelectronics.ru/avr-uchebnyj-kur...mm-chast-3.html
http://easyelectronics.ru/avr-uchebnyj-kur...mm-chast-4.html
и то, что там всё на асме - не так уж и важно, ибо сам подход остаётся тем-же и для Си

и вот это вот тоже осмыслить бы и применить на практике:
http://easyelectronics.ru/avr-uchebnyj-kur...yj-avtomat.html

ну не знаю....тоже отладка... сам не читал...
http://easyelectronics.ru/vnutrisxemnaya-o...z-jtag-ice.html


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
RW6MKA
сообщение Jan 6 2011, 10:46
Сообщение #146


Частый гость
**

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



Цитата
По крайней мере не будет неопределенности с номерами строк (со стороны компилятора)
Пробовал и так, результат тот же.

Цитата
обязательно скурить:
Так я этими статьями и пользуюсь. Больше по студии и почитать особо негде.
Цитата
и вот это вот тоже осмыслить бы и применить на практике:
Это я так понимаю к вопросу о гистерезисе? Пока отложу, надо разобраться с тем что есть.
Цитата
ну не знаю....тоже отладка... сам не читал...
Штука классная, но у меня тинька. crying.gif
Теперь вопрос. Прогнал код и вдоль и поперёк. Все пины, таймер,прерывание ну всё показывает нормально, а логики этих скачков не могу ни понять, ни отследить в чём причина. Как это побороть? smile3009.gif

Сообщение отредактировал RW6MKA - Jan 6 2011, 10:59
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jan 6 2011, 11:48
Сообщение #147


I WANT TO BELIEVE
******

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



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

ну глючит там отладчик при шагах по си коду...что вы так на этом зацикливаетесь то а?
я уже предлагал ведь вам организовать отладочный вывод и по нему определиться, правильно ли выполняется программа.
ну + задержки где надо, чтоб успевать соображать что к чему.... и прямо на ходу всё проверите.


выкладывайте проект + протеусовский тоже.


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
RW6MKA
сообщение Jan 6 2011, 13:04
Сообщение #148


Частый гость
**

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



Вот проекты, povorot к Протеусу,povorot2 код.Прикрепленный файл  povorot.rar ( 30.9 килобайт ) Кол-во скачиваний: 67
Прикрепленный файл  povorot2.rar ( 15.64 килобайт ) Кол-во скачиваний: 71
Go to the top of the page
 
+Quote Post
XVR
сообщение Jan 6 2011, 16:55
Сообщение #149


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Это работа оптимизатора (посмотрите ассемблер). Он вынес константы Lstop и Rstop (для их последующего присваивания в Povorot) на регистры, и загрузку этих регистров константами (перед циклом) привязал к строкам Povorot = Lstop; и Povorot = Lstop;
Вот он по ним и прыгает
Далее идет нормальный код, т.ч. первые прыжки можете игнорировать

Go to the top of the page
 
+Quote Post
RW6MKA
сообщение Jan 7 2011, 12:54
Сообщение #150


Частый гость
**

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



Цитата
Это работа оптимизатора (посмотрите ассемблер).
Так и не понял как это сделать в студии. sad.gif Да, а оптимизация то отключена blink.gif
Go to the top of the page
 
+Quote Post

21 страниц V  « < 8 9 10 11 12 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 12th August 2025 - 06:53
Рейтинг@Mail.ru


Страница сгенерированна за 0.01585 секунд с 7
ELECTRONIX ©2004-2016