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

 
 
> Вопросы новичка, Первая программа, первые вопросы
Anjey_N
сообщение Jan 21 2007, 21:43
Сообщение #1


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

Группа: Участник
Сообщений: 80
Регистрация: 12-01-07
Из: Энергодар Украина
Пользователь №: 24 374



Добрый вечер уважаемые знатоки! help.gif Написал первую программу в IAR 4.20/
У меня 2 вопроса:
1. Как разрешить глобальные прерывания?
2.Не работает команда PORTD=decode[Tens], хоть компилятор ошибок не выдаёт. Проверку производил в AVRStudio.
Программу прилагаю.

/*Программа выводит на индикатор числа с возрастанием
с 0 до 99 или с убыванием с 99 до 0 с частотой 1 сек
Если кнопка на выводе 0 порта С отжата - происходит счёт на увеличение,
если нажата - на уменьшение.
Среда IAR 4.20
Микроконтроллер AtMega 16
Кварц 16 МГц*/

#include <ioavr.h>

// Описание глобальных переменных
unsigned char n,c,flag,Ones,Tens;
char decode[10]={0xC0,0xFC,0xA4,0xB0,0x99,0x92,0x02,0xF8,0x80,0x90};
#define Bit(n) (1<<(n))

// Обработка прерываний по таймеру ТС0
#pragma vector=TIMER0_OVF_vect
__interrupt void FIRST (void)
{
PORTB=0x03; // выключаем индикатор
if (n){
PORTD=decode[Ones];
PORTB&=~Bit(0); // включаем 1 индикатор
}
else{
PORTD=decode[Tens];
PORTB&=~Bit(1); // включаем 2 индикатор
}
n=!n;
}

// Обработка прерываний по таймеру ТС1
#pragma vector=TIMER1_OVF_vect
__interrupt void SECOND (void)
{
TCNT1=0xC35A;
flag=1;
if ((PINC & Bit(0))!=0) c++; // увеличиваем, если кнопка отжата
else c--; // уменьшаем, если кнопка нажата
if (c==0x64) c=0x00;
if (c==0xFF) c=0x63;
}

// Преобразование 2-10 кода в 2-й
char CharToBCD(char c)
{
char high;
high=0;
while (c>=10){

high++;
c-=10;
}
return (high<<4)|c;
}

// Настройка регистров контроллера
void unit_avr (void)
{
//Порт А
PORTA=0x00;
DDRA=0xFF;
//Порт B
PORTB=0x03;
DDRB=0x03;
//Порт C
PORTC=0x01;
DDRC=0x00;
//Порт DD
PORTD=0xFF;
DDRD=0xFF;

// Настройка таймера ТС0
// Источник синхронизации: внутренний
// Частота на входе: 62,500 kHz
// Переполнение каждые 4 мс
TCCR0=0x03;
TCNT0=0x00;
OCR0=0x00;

// Настройка таймера ТС1
// Источник синхронизации: внутренний
// Частота на входе: 15,625 kHz
// Переполнение каждую секунду
TCCR1A=0x00;
TCCR1B=0x04;
TCNT1=0xC35A;
ICR1=0x00;
OCR1A=0x00;
OCR1B=0x00;

// Таймер 2 отключён
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// Внешние прерывания отключены
MCUCR=0x00;
MCUCSR=0x00;

// Разрешены прерывания по переполнению таймеров ТС0 и ТС1
TIMSK=0x05;

// Аналоговый компаратор отключён
ACSR=0x80;
SFIOR=0x00;
}

void main (void)
{
unit_avr();
// Разрешены глобальные прерывания
// __enable interrupt(); // здесь выдаёт ошибку
SREG|=Bit(7);

while (1){
while(flag){
// Place your code here
flag=0;
Tens=CharToBCD©;
PORTA=Tens;
Ones=Tens;
Ones=Ones&(0x0F);
Tens=Tens>>4;
}
}
}



Помогите разобраться!

Сообщение отредактировал Anjey_N - Jan 21 2007, 21:47
Go to the top of the page
 
+Quote Post
3 страниц V   1 2 3 >  
Start new topic
Ответов (1 - 32)
prottoss
сообщение Jan 21 2007, 21:53
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(Anjey_N @ Jan 22 2007, 01:43) *
Помогите разобраться!


чтобы использовать __enable_interrupt надо подключить intrinsics.h.

А вообще я разрешаю глобальные прерывания с помощью

Код
#define SEI() asm("sei")


команда PORTD=decode[Tens], не работает, возможно, из-за того что прерывания не разрешены


--------------------
Go to the top of the page
 
+Quote Post
Anjey_N
сообщение Jan 21 2007, 22:07
Сообщение #3


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

Группа: Участник
Сообщений: 80
Регистрация: 12-01-07
Из: Энергодар Украина
Пользователь №: 24 374



Эта строчка "чтобы использовать __enable_interrupt надо подключить intrinsics.h." не сработала.
Помогло #define SEI() asm("sei")

Спасибо
А вот PORTD=decode[Tens] так и не работает

Сообщение отредактировал Anjey_N - Jan 21 2007, 22:08
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 21 2007, 22:15
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(Anjey_N @ Jan 22 2007, 02:07) *
Эта строчка "чтобы использовать __enable_interrupt надо подключить intrinsics.h." не сработала.
Помогло #define SEI() asm("sei")

Спасибо
А вот PORTD=decode[Tens] так и не работает
Прерывания то хоть заработали?


--------------------
Go to the top of the page
 
+Quote Post
junoSynthesizer
сообщение Jan 22 2007, 00:47
Сообщение #5


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

Группа: Свой
Сообщений: 83
Регистрация: 25-11-05
Из: odessa
Пользователь №: 11 397



Цитата(Anjey_N @ Jan 21 2007, 21:07) *
А вот PORTD=decode[Tens] так и не работает


в чём выражается "не работает" ?


--------------------
Вся жизнь - ништяк, все бабы - леди, а солнце - шар дающий свет
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jan 22 2007, 02:18
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



__enable_interrupt(); // Разрешить прерывания
Go to the top of the page
 
+Quote Post
satellite-plus
сообщение Jan 22 2007, 10:45
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 51
Регистрация: 8-01-07
Из: Одесса
Пользователь №: 24 196



Цитата(Anjey_N @ Jan 21 2007, 20:43) *
Помогите разобраться!


#pragma language=extended
#include <iom16.h>
#include <ina90.h>
#include <string.h>


__flash char decode[10]={0xC0,0xFC,0xA4,0xB0,0x99,0x92,0x02,0xF8,0x80,0x90};


_SEI(); // разрешение прерываний
_CLI(); // запрет прерываний


--------------------
Опыт - это та чудесная штука, которая позволяет вам узнать ошибку, когда вы ее повторите.
Go to the top of the page
 
+Quote Post
Anjey_N
сообщение Jan 22 2007, 11:31
Сообщение #8


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

Группа: Участник
Сообщений: 80
Регистрация: 12-01-07
Из: Энергодар Украина
Пользователь №: 24 374



junoSynthesizer Дата Сегодня, 01:47

(Anjey_N @ Jan 21 2007, 21:07)

А вот PORTD=decode[Tens] так и не работает



в чём выражается "не работает" ?


В PORTD должно выводится значение из массива decode[11] с порядковым номером, вычисленном для переменной Tens. Это не работает.



Прерывания работают как по команде __enable_interrupt(); при #include <intrinsics.h>, так и при _SEI();


Может посмотрите ещё раз код, может я где-то ошибаюсь?


#include <ioavr.h>
#include <intrinsics.h> // для команды __enable_interrupt
#pragma language=extended
#include <iom16.h>
#include <ina90.h>
#include <string.h>
// Описание глобальных переменных
unsigned char n,c,flag,Ones,Tens;
//char decode[10]={0xC0,0xFC,0xA4,0xB0,0x99,0x92,0x02,0xF8,0x80,0x90};
__flash char decode[10]={0xC0,0xFC,0xA4,0xB0,0x99,0x92,0x02,0xF8,0x80,0x90};
#define Bit(n) (1<<(n))
#define Key (PINC & Bit(0))

// Обработка прерываний по таймеру ТС0
#pragma vector=TIMER0_OVF_vect
__interrupt void FIRST (void)
{
PORTB=0x03; // выключаем индикатор
if (n){
PORTD=decode[Ones]; // не работает
PORTB&=~Bit(0); // включаем 1 индикатор
}
else{
PORTD=decode[Tens]; // не работает
PORTB&=~Bit(1); // включаем 2 индикатор
}
n=!n;
}

// Обработка прерываний по таймеру ТС1
#pragma vector=TIMER1_OVF_vect
__interrupt void SECOND (void)
{
TCNT1=0xC35A;
flag=1;
if (Key) c++; // увеличиваем, если кнопка отжата
else c--; // уменьшаем, если кнопка нажата
if (c==0x64) c=0x00;
if (c==0xFF) c=0x63;
}

// Преобразование 2-10 кода в 2-й
char CharToBCD(char c)
{
char high;
high=0;
while (c>=10){

high++;
c-=10;
}
return (high<<4)|c;
}

// Настройка регистров контроллера
void unit_avr (void)
{
//Порт А
PORTA=0x00;
DDRA=0xFF;
//Порт B
PORTB=0x03;
DDRB=0x03;
//Порт C
PORTC=0x01;
DDRC=0x00;
//Порт DD
PORTD=0xFF;
DDRD=0xFF;

// Настройка таймера ТС0
// Источник синхронизации: внутренний
// Частота на входе: 62,500 kHz
// Переполнение каждые 4 мс
TCCR0=0x03;
TCNT0=0x00;
OCR0=0x00;

// Настройка таймера ТС1
// Источник синхронизации: внутренний
// Частота на входе: 15,625 kHz
// Переполнение каждую секунду
TCCR1A=0x00;
TCCR1B=0x04;
TCNT1=0xC35A;
ICR1=0x00;
OCR1A=0x00;
OCR1B=0x00;

// Таймер 2 отключён
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// Внешние прерывания отключены
MCUCR=0x00;
MCUCSR=0x00;

// Разрешены прерывания по переполнению таймеров ТС0 и ТС1
TIMSK=0x05;

// Аналоговый компаратор отключён
ACSR=0x80;
SFIOR=0x00;
}

void main (void)
{
unit_avr();
// Разрешены глобальные прерывания
__enable_interrupt();
while (1){
while(flag){
// Place your code here
flag=0;
Tens=CharToBCD©;
PORTA=Tens;
Ones=Tens;
Ones=Ones&(0x0F);
Tens=Tens>>4;
}
}
}
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 22 2007, 11:38
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(Anjey_N @ Jan 22 2007, 15:31) *
...

PORTD=decode[Tens]; // не работает
PORTB&=~Bit(1); // включаем 2 индикатор

...
А что, строчка ниже подчеркнутой работает?


--------------------
Go to the top of the page
 
+Quote Post
otrog
сообщение Jan 22 2007, 11:54
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 232
Регистрация: 22-02-06
Из: Воронеж
Пользователь №: 14 589



Цитата(Anjey_N @ Jan 22 2007, 11:31) *
#include <ioavr.h>
#include <intrinsics.h> // для команды __enable_interrupt
#pragma language=extended
#include <iom16.h>
#include <ina90.h>
#include <string.h>
// Описание глобальных переменных
unsigned char n,c,flag,Ones,Tens;
//char decode[10]={0xC0,0xFC,0xA4,0xB0,0x99,0x92,0x02,0xF8,0x80,0x90};
__flash char decode[10]={0xC0,0xFC,0xA4,0xB0,0x99,0x92,0x02,0xF8,0x80,0x90};
#define Bit(n) (1<<(n))
#define Key (PINC & Bit(0))

// Обработка прерываний по таймеру ТС0
#pragma vector=TIMER0_OVF_vect
__interrupt void FIRST (void)
{
PORTB=0x03; // выключаем индикатор
if (n){
PORTD=decode[Ones]; // не работает
PORTB&=~Bit(0); // включаем 1 индикатор
}
else{
PORTD=decode[Tens]; // не работает
PORTB&=~Bit(1); // включаем 2 индикатор
}
n=!n;
}

Похоже что компилятор заоптимизировал переменную n.
Попробуйте объявить ее так:
Код
volatile unsigned char n;


--------------------
Истина рождается в спорах; но когда страсти кипят, истина испаряется.
Go to the top of the page
 
+Quote Post
satellite-plus
сообщение Jan 22 2007, 12:11
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 51
Регистрация: 8-01-07
Из: Одесса
Пользователь №: 24 196



Посмотри как это делается.

Сообщение отредактировал satellite-plus - Jan 22 2007, 12:15
Прикрепленные файлы
Прикрепленный файл  volt.zip ( 2.43 килобайт ) Кол-во скачиваний: 68
 


--------------------
Опыт - это та чудесная штука, которая позволяет вам узнать ошибку, когда вы ее повторите.
Go to the top of the page
 
+Quote Post
GDI
сообщение Jan 22 2007, 12:13
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Цитата
n=!n;


здесь инверсию хотите сделать? Имхо надо n = ~n;


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 22 2007, 12:48
Сообщение #13


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(GDI @ Jan 22 2007, 11:13) *
Цитата
n=!n;

здесь инверсию хотите сделать? Имхо надо n = ~n;
Как раз в этом случае правильнее !n, ибо переменная по логике программы должна принимать два значения - "ноль" и "не ноль". И конструкция !n это обеспечивает. А вот если n в программе каким-то образом примет любое значение, отличное от 0 или 0xFF, то конструкция ~n всегда будет давать в результате "не ноль":
Код
if(n) {

} else {

}
Для Anjey_N:
Код
Tens=CharToBCD©;   // A
PORTA=Tens;
Ones=Tens;                // B
Ones=Ones&(0x0F);
Tens=Tens>>4;          // C
                                 // D
Некорректно написан кусок программы. Если прерывание FIRST возникнет в любом месте между A и D то Tens будет иметь значение выходящее за пределы массива decode. Также между B и C Ones имеет некорректное значение. Надо пользоваться временной переменной или запрещать прерывания:
Код
__disable_interrupt();
Tens=CharToBCD( с );
PORTA=Tens;
Ones=Tens;
Ones=Ones&(0x0F);
Tens=Tens>>4;
__enable_interrupt();

или

unsigned char Tmp = CharToBCD( c );
PORTA=Tmp;
Ones=Tmp & 0x0F;
Tens=Tmp >> 4;

Кстати, чтобы компилятор не ругался на __enable_interrupt(), __disable_interrupt() и т.п. достаточно включить <inavr.h>, intrinsic.h подключится из него автоматически.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Anjey_N
сообщение Jan 22 2007, 12:51
Сообщение #14


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

Группа: Участник
Сообщений: 80
Регистрация: 12-01-07
Из: Энергодар Украина
Пользователь №: 24 374



Цитата(prottoss @ Jan 22 2007, 12:38) *
Цитата(Anjey_N @ Jan 22 2007, 15:31) *


...

PORTD=decode[Tens]; // не работает
PORTB&=~Bit(1); // включаем 2 индикатор

...
А что, строчка ниже подчеркнутой работает?


Да, эта строчка работает
Go to the top of the page
 
+Quote Post
aesok
сообщение Jan 22 2007, 13:13
Сообщение #15


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Переменные 'flag', 'c' - должны быть volatile

Анатолий.
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 22 2007, 13:26
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(Anjey_N @ Jan 22 2007, 16:51) *
Цитата(prottoss @ Jan 22 2007, 12:38) *

Цитата(Anjey_N @ Jan 22 2007, 15:31) *

...
PORTD=decode[Tens]; // не работает
PORTB&=~Bit(1); // включаем 2 индикатор
...
А что, строчка ниже подчеркнутой работает?
Да, эта строчка работает
Тогда читайте, что сказал выше Сергей Борщ

Цитата(Сергей Борщ @ Jan 22 2007, 16:48) *
Кстати, чтобы компилятор не ругался на __enable_interrupt(), __disable_interrupt() и т.п. достаточно включить <inavr.h>, intrinsic.h подключится из него автоматически.
smile.gif Привожу текст inavr.h (IAR 4.10B)

Код
/**************************************************************
**             - INAVR.H -
**
**     Intrinsics for iccAVR
**
**     Used with iccAVR.
**
**     Copyright IAR Systems 1999. All rights reserved.
**
**     File version: $Revision: 1.10 $
**
**************************************************************/

#include <intrinsics.h>
/* The intrinsics for iccAVR has been moved to intrinsics.h */
Усе


--------------------
Go to the top of the page
 
+Quote Post
Anjey_N
сообщение Jan 22 2007, 22:32
Сообщение #17


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

Группа: Участник
Сообщений: 80
Регистрация: 12-01-07
Из: Энергодар Украина
Пользователь №: 24 374



Спасибо всем, кто мне помогал, особенно Сергею Борщу. Он оказался прав. Программа теперь работает
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 23 2007, 10:04
Сообщение #18


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Anjey_N @ Jan 22 2007, 21:32) *
Он оказался прав. Программа теперь работает
На самом деле правы были все. Обратите внимание на замечания otrog и aesok по поводу volatile. Без этого вполне возможно что программа у вас сейчас работает, а при смене уровня оптимизации, версии компилятора или просто добавлении лишней команды вдруг перестанет. Причем компилятор будет совершенно не виноват. Поскольку вы только начинаете - лучше сразу приучить себя писать правильно, чтобы потом не наступать на эти очень распространенные грабли на ровном месте.

Успехов!


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Anjey_N
сообщение Jan 23 2007, 11:27
Сообщение #19


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

Группа: Участник
Сообщений: 80
Регистрация: 12-01-07
Из: Энергодар Украина
Пользователь №: 24 374



Согласен, правы были все и всем за это спасибо.

Объясните, пожалуйста. как понимать слово volatile!
И чем отличаются строки
char decode[10]={0xC0,0xFC,0xA4,0xB0,0x99,0x92,0x02,0xF8,0x80,0x90};

и

__flash char decode[10]={0xC0,0xFC,0xA4,0xB0,0x99,0x92,0x02,0xF8,0x80,0x90};

И с той и с этой программа работает!


И спасибо за пожелание успехов!
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Jan 23 2007, 11:45
Сообщение #20


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(Anjey_N @ Jan 23 2007, 10:27) *
Объясните, пожалуйста. как понимать слово volatile!
И чем отличаются строки
char decode[10]={0xC0,0xFC,0xA4,0xB0,0x99,0x92,0x02,0xF8,0x80,0x90};
и
__flash char decode[10]={0xC0,0xFC,0xA4,0xB0,0x99,0x92,0x02,0xF8,0x80,0x90};
И с той и с этой программа работает!

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

Строки, приведённые Вами, отличаются местом их хранения. Первая хранится в ОЗУ (грузится туда из flash при старте), вторая хранится во flash памяти.
Go to the top of the page
 
+Quote Post
satellite-plus
сообщение Jan 23 2007, 11:46
Сообщение #21


Участник
*

Группа: Участник
Сообщений: 51
Регистрация: 8-01-07
Из: Одесса
Пользователь №: 24 196



Цитата(Anjey_N @ Jan 23 2007, 10:27) *
Согласен, правы были все и всем за это спасибо.

Объясните, пожалуйста. как понимать слово volatile!
И чем отличаются строки
char decode[10]={0xC0,0xFC,0xA4,0xB0,0x99,0x92,0x02,0xF8,0x80,0x90};

и

__flash char decode[10]={0xC0,0xFC,0xA4,0xB0,0x99,0x92,0x02,0xF8,0x80,0x90};

И с той и с этой программа работает!


И спасибо за пожелание успехов!


char decode[10] - переменные в ОЗУ. Параметры прописываются во флэш и при старте переписываются в ОЗУ.

__flash char decode[10] - константы. Расположены во флэши.

volatile - указывает компилятору что переменная может изменится , например в прерывании. Т.е. он должен работать с ней по ее физичекому расположению и не создавать копию( например перегружая в регистр, хотя так и быстрее).


--------------------
Опыт - это та чудесная штука, которая позволяет вам узнать ошибку, когда вы ее повторите.
Go to the top of the page
 
+Quote Post
Anjey_N
сообщение Jan 23 2007, 12:07
Сообщение #22


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

Группа: Участник
Сообщений: 80
Регистрация: 12-01-07
Из: Энергодар Украина
Пользователь №: 24 374



Цитата(satellite-plus @ Jan 23 2007, 12:46) *
Цитата(Anjey_N @ Jan 23 2007, 10:27) *

Согласен, правы были все и всем за это спасибо.

Объясните, пожалуйста. как понимать слово volatile!
И чем отличаются строки
char decode[10]={0xC0,0xFC,0xA4,0xB0,0x99,0x92,0x02,0xF8,0x80,0x90};

и

__flash char decode[10]={0xC0,0xFC,0xA4,0xB0,0x99,0x92,0x02,0xF8,0x80,0x90};

И с той и с этой программа работает!


И спасибо за пожелание успехов!


char decode[10] - переменные в ОЗУ. Параметры прописываются во флэш и при старте переписываются в ОЗУ.

__flash char decode[10] - константы. Расположены во флэши.

volatile - указывает компилятору что переменная может изменится , например в прерывании. Т.е. он должен работать с ней по ее физичекому расположению и не создавать копию( например перегружая в регистр, хотя так и быстрее).



Т.е. если записать __flash char decode[10]={0xC0,0xFC,0xA4,0xB0,0x99,0x92,0x02,0xF8,0x80,0x90};, то экономим ОЗУ?
Тогда все константы, таблицы лучше размещать во flash? Например какую-нибудь таблицу перекодировки!

Сообщение отредактировал Anjey_N - Jan 23 2007, 12:09
Go to the top of the page
 
+Quote Post
SpiritDance
сообщение Jan 23 2007, 12:30
Сообщение #23


Дух погибшего транзистора
****

Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288



Да.


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post
GDI
сообщение Jan 23 2007, 12:38
Сообщение #24


Профессионал
*****

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Только лучше написать __flash const char decode[10]={0xC0,0xFC,0xA4,0xB0,0x99,0x92,0x02,0xF8,0x80,0x90};, а то при оптимизации компилятор может скопировать массив в ОЗУ

Сообщение отредактировал GDI - Jan 23 2007, 12:45


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
Anjey_N
сообщение Jan 23 2007, 12:56
Сообщение #25


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

Группа: Участник
Сообщений: 80
Регистрация: 12-01-07
Из: Энергодар Украина
Пользователь №: 24 374



Ура! Жизнь налаживается! cheers.gif
Пора заводить словарик!
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 23 2007, 13:40
Сообщение #26


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(GDI @ Jan 23 2007, 11:38) *
Только лучше написать __flash const char decode[10]={0xC0,0xFC,0xA4,0xB0,0x99,0x92,0x02,0xF8,0x80,0x90};, а то при оптимизации компилятор может скопировать массив в ОЗУ
Это имеет еще одно скрытое преимущество - если вы захотите перенести код на другую платформу (например для отладки алгоритма на PC), где нет понятия флеш или ключевого слова __flash, вы просто добавите в начало исходника строчку #define __flash и переменная будет продолжать вести себя адекватно, т.е. константой, и компилятор сможет проконтролировать попытки записи в нее.

И сразу на будущее - наверняка придется таскать код между платформами (пример только что привел), сразу же наткнетесь на то, что int, ling, float, double, в общем практически все типы имеют различный размер. Например int у AVR, MSP430, win16 = 2 байта, а у ARM, win32 - 4 байта. И чтобы не попадать в зависимость от этой неоднозначности есть два пути -
1)подключаете стандартный файл <stdint.h> и везде в программе используете переопределенные в нем типы uint8_t, int8_t, uin16_t, int16_t и т.д. (по названию понятно что они означают)
2)пишете для каждой платформы свой файл в котором подбираете подходящий тип:
Код
typedef unsigned char  byte;
typedef signed char    sbyte;
typedef unsigned short word;
typedef unsigned long  dword;

typedef volatile byte  sfr_byte;
typedef volatile word  sfr_word;


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
SpiritDance
сообщение Jan 23 2007, 14:17
Сообщение #27


Дух погибшего транзистора
****

Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288



эээ...
long и float разный размер на разных платформах?
насчет long может и соглашусь, так как нигде не указана его длина, но float - 32 разряда.


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 23 2007, 15:17
Сообщение #28


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(SpiritDance @ Jan 23 2007, 13:17) *
эээ...
long и float разный размер на разных платформах?
насчет long может и соглашусь, так как нигде не указана его длина, но float - 32 разряда.

про long (никаких домыслов, только факты):
Цитата
http://en.wikipedia.org/wiki/64-bit

However, in many programming environments on 64-bit machines, "int" variables are still 32 bits wide, but "long"s and pointers are 64 bits wide. These are described as having an LP64 data model.
Про float подловили :-) Действительно:
Цитата
http://en.wikipedia.org/wiki/IEEE_754
IEEE 754 specifies four formats for representing floating-point values: single-precision (32-bit), double-precision (64-bit),
И файл называется <stdint.h>, т.е. только целые типы. Правда есть исключения, но тут уже ничего не поможет:
Цитата
http://gcc.gnu.org/ml/gcc-patches/2006-11/msg00475.html

MIPS32 rev 2 optionally supports 64bit floating unit. This patch allows the use of 64bit floats by passing the -mfp64 option when used along with a MIPS32R2 cpu (the 24k/34k family with float point all have 64bit floating point units).


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
SpiritDance
сообщение Jan 23 2007, 17:25
Сообщение #29


Дух погибшего транзистора
****

Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288



Да собственно и нужны то только целые, так как с плавающей запятой никаких размерозависимых операций обычно не производится кроме операций выделения памяти, но тут спасает оператор sizeof. smile.gif
А вот насчет stdint.h... дело в том что он введен в только в стандарт c99, и по этой причине отсутсвует во многих писюковых компиляторах, например в msvc. sad.gif Так что для пущей портируемости, когда не хочется править ни строчки в исходниках, проще пользоватся своими переопределеными целыми типами.

Ладно хватит умничать... smile.gif (это я себе)


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jan 24 2007, 03:11
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(Сергей Борщ @ Jan 23 2007, 14:40) *
1)подключаете стандартный файл <stdint.h> и везде в программе используете переопределенные в нем типы uint8_t, int8_t, uin16_t, int16_t и т.д. (по названию понятно что они означают)


Вау! Я прямо горд за себя. Пришёл к этому самостоятельно когда оценивал компиляторы. Файлик свиснул из GCC. Правда подправлял чего-то там, а то не шло на IAR.

smile.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 24 2007, 11:10
Сообщение #31


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(SpiritDance @ Jan 23 2007, 16:25) *
А вот насчет stdint.h... дело в том что он введен в только в стандарт c99, и по этой причине отсутсвует во многих писюковых компиляторах, например в msvc. sad.gif Так что для пущей портируемости, когда не хочется править ни строчки в исходниках, проще пользоватся своими переопределеными целыми типами.
Об этом мы долго спорили с коллегой dxp в привате. Да, конечно можно пользоваться своим. Но тогда придется его создавать его и на тех платформах, где есть stdint.h. Я сторонник stdint.h. Если его в каком-то компиляторе нет - написать руками тот же свой файл, но обозвать его stdint.h. Зато там, где stdint.h есть - писать не придется ничего. Мелочь, а приятно smile.gif
P.S. А стандарту С99 уже 8 лет как-никак. А мы (и разработчики компиляторов, к сожалению) все на С89 оглядываемся, который уже "не девочка" glare.gif .


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
SpiritDance
сообщение Jan 24 2007, 12:22
Сообщение #32


Дух погибшего транзистора
****

Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288



Можно в этом файле для тех компиляторов в котрых есть stdint.h преопределить через этот файл свои типы. Ну это имеет смысл делать для того чтобы файл был все-таки в одном экземпляре на все проекты. Писать свой stdint можно конечно, но если работаешь не один, то придется включать его во все проекты + если проект портируется между pc и компилятором с поддержкой C99, то приходится следить за тем какой stdint используется. В конечном итоге поступать приходится так как диктуют внешние условия разработки и требования к проекту. smile.gif

Кстати и называется этот файл во многих случаях по-разному sad.gif в компилерах которые поддерживают, так сказать, C89 с расширениями, например
codewarrior HCS12 stdtypes.h
realview inttypes.h


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 24 2007, 13:46
Сообщение #33


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(SpiritDance @ Jan 24 2007, 11:22) *
В конечном итоге поступать приходится так как диктуют внешние условия разработки и требования к проекту. smile.gif
Ну я ведь не настаиваю (кажется wink.gif )

Цитата(SpiritDance @ Jan 24 2007, 11:22) *
Кстати и называется этот файл во многих случаях по-разному sad.gif
Не знал. Запомню.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 01:14
Рейтинг@Mail.ru


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