Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
urry
Сверлит текстолит когтями
Сообщения: 1262 Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:
Сообщение
urry » Пн авг 13, 2012 15:50:02
мужики такая проблема, программирую PIC18F452, пишу на Си в МСС18, и вот проблема не могу создать массив объёмом, больше 227 ячеек. а нужно 512. причём у пика памяти 1,5 килобайта. в чём проблема то ?
Проблема в нежелании смотреть документацию.
Смотрим файл линкера
Код: Выделить всё
ACCESSBANK NAME=accessram START=0x0 END=0x7F
DATABANK NAME=gpr0 START=0x80 END=0xFF
DATABANK NAME=gpr1 START=0x100 END=0x1FF
DATABANK NAME=gpr2 START=0x200 END=0x2FF
DATABANK NAME=gpr3 START=0x300 END=0x3FF
DATABANK NAME=gpr4 START=0x400 END=0x4FF
DATABANK NAME=gpr5 START=0x500 END=0x5FF
ACCESSBANK NAME=accesssfr START=0xF80 END=0xFFF PROTECTED
SECTION NAME=CONFIG ROM=config
STACK SIZE=0x100 RAM=gpr5
Размер страницы 256 байт.
Подключаем линкер к себе в проект и объединяем 2 страницы
Код: Выделить всё
DATABANK NAME=MY_RAM START=0x300 END=0x4FF PROTECTED
SECTION NAME=MY_RAM RAM=MY_RAM
gpr3 gpr4 естественно, вычеркнуть
в программе обращаемся как-то так
Код: Выделить всё
#pragma udata MY_RAM=0x300
unsigned char array[512];
Последний раз редактировалось
Аlex Пн авг 13, 2012 17:53:21, всего редактировалось 1 раз.
Причина: -
Аlex
Модератор
Сообщения: 4614 Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:
Сообщение
Аlex » Пн авг 13, 2012 17:52:53
Юра не выдержал.
А я хотел, что бы человек сам допёр
shads
Опытный кот
Сообщения: 882 Зарегистрирован: Ср фев 22, 2012 01:25:21
Сообщение
shads » Вт авг 14, 2012 09:32:19
Вопросик есть.....
Стал использовать #include <avr/eeprom.h> для работы с внутренней энергонезависимой памятью, вроде все работает, но постоянно выкидывает предупреждения. Что не так?
Например хочу стереть EEPROM, делаю так:
Код: Выделить всё
for (unsigned char i=0; i<64; i++) //цикл стирания
eeprom_write_byte(i, 0);
Вроде бы все работает, но почему то при компиляции пишет:
"warning: passing argument 1 of '_eewr_byte_tnl3a' makes pointer from integer without a cast"
Что сие значит..... ато глаза режут предупреждения постоянные.....
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482 Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:
Сообщение
vitalik_1984 » Вт авг 14, 2012 09:57:42
Видимо эта функция ждет указатель на область памяти, а вы в нее число суете.
Компилятор принимает это число как адрес в памяти, о чем вас и предупреждает.
Нужно преобразовать число в указатель вроде это так делается:
eeprom_write_byte((char*)i, 0)
проверить пока негде, к сожалению.
В поисках истины человек развивается.
БАТАРЕЙКУС
Потрогал лапой паяльник
Сообщения: 346 Зарегистрирован: Сб фев 07, 2009 19:21:25
Сообщение
БАТАРЕЙКУС » Вт авг 14, 2012 12:39:52
urry писал(а):
Проблема в нежелании смотреть документацию.
urry писал(а):
Юра не выдержал. А я хотел, что бы человек сам допёр
спасибо за помощь. всё получилось. яж откуда мог знать что линкер файл нужно подключать дополнительно к проекту, и там есчё чтото менять. в том, что что-то надо поменять я сразу догадался, но не мог разобраться где это надо менять. и где оно лежит.
сделал так.
Код: Выделить всё
ACCESSBANK NAME=accessram START=0x0 END=0x7F
DATABANK NAME=gpr0 START=0x80 END=0xFF
DATABANK NAME=buffer_section START=0x100 END=0x2FF
DATABANK NAME=gpr3 START=0x300 END=0x3FF
DATABANK NAME=gpr4 START=0x400 END=0x4FF
Код: Выделить всё
#pragma udata buffer_section
volatile char buffer[512];
#pragma udata
Мечтатель - не тот, кто сидит на диване и думает о несбыточном, а тот, кто всеми силами стремится воплотить несбыточное в реальность.
Tolmi
Говорящий с текстолитом
Сообщения: 1658 Зарегистрирован: Вс дек 11, 2011 05:25:04
Откуда: Киев, Украина
Контактная информация:
Сообщение
Tolmi » Вт авг 14, 2012 13:48:32
vitalik_1984 писал(а):
Нужно преобразовать число в указатель вроде это так делается:
eeprom_write_byte((char*)i, 0)
Или написать
тогда и eeprom_write_byte(i, 0) прокатит.
In theory, theory and practice are the same. In practice, they're not.
Аlex
Модератор
Сообщения: 4614 Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:
Сообщение
Аlex » Вт авг 14, 2012 15:14:24
яж откуда мог знать что линкер файл нужно подключать дополнительно к проекту
Дак яж Вам написал:
если только для одного проекта, то добавить его в папку с проектом и подключить к проекту
Или это было по
О лбански ?
что что-то надо поменять я сразу догадался, но не мог разобраться где это надо менять.
И где и что править я Вам тоже писал:
Нужно править файл линкера
и ссылку дал и страницу назвал - осталось только
. Или это было тоже по
О лбански ?
Это обычное нехотение работать с документацией, неумение пользоваться поиском и желание получить всё на блюдечке с голубой каёмочкой., без всяческих лишних телодвижений...
shads
Опытный кот
Сообщения: 882 Зарегистрирован: Ср фев 22, 2012 01:25:21
Сообщение
shads » Вт авг 14, 2012 18:47:04
vitalik_1984
Tolmi
Спасибо. Действительно надо указатели использовать..... Поправил так, и усе красиво стало.....
Код: Выделить всё
unsigned char eeprom_data[64] EEMEM; //массив данных в EEPROM
for (unsigned char i=0; i<64; i++) //цикл стирания
eeprom_write_byte(&eeprom_data[i], 0);
ut1wpr
Вымогатель припоя
Сообщения: 581 Зарегистрирован: Ср янв 05, 2011 10:03:18
Сообщение
ut1wpr » Вт авг 14, 2012 20:45:23
shads писал(а): Спасибо. Действительно надо указатели использовать..... Поправил так, и усе красиво стало.....
Код: Выделить всё
unsigned char eeprom_data[64] EEMEM; //массив данных в EEPROM
for (unsigned char i=0; i<64; i++) //цикл стирания
eeprom_write_byte(&eeprom_data[i], 0);
Попробуйте так. Я в IAR-e так пишу...
Код: Выделить всё
u8 e_data[] EEMEM;
u8 *p = (u8)e_data;
for( u8 i = 0; i < 64; i++ ) *p++ = 0x00;
В вашем случае, наверное надо:
Код: Выделить всё
for( u8 i = 0; i < 64; i++ ) eeprom_write_byte(p++,0);
Запись в Си с истинным указателем, но когда глянете на дизасм, увидите, что разницы почти никакой.
IAR сам различает классы памяти и нет необходимости в явном вызове функции eeprom_write_byte(). Просто применяется оператор присваивания.
Компилятор сам разбирается, как в какой класс писать. За что и люблю умничку. Но помнить о разнице в классах программисту надо всегда!
С уважением,
Виктор.
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482 Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:
Сообщение
vitalik_1984 » Вт авг 14, 2012 23:39:08
ut1wpr писал(а):
Запись в Си с истинным указателем, но когда глянете на дизасм, увидите, что разницы почти никакой.
IAR сам различает классы памяти и нет необходимости в явном вызове функции eeprom_write_byte(). Просто применяется оператор присваивания.
То же самое можно сказать про CVAVR-в нем обычный оператор присваивания.
В поисках истины человек развивается.
urry
Сверлит текстолит когтями
Сообщения: 1262 Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:
Сообщение
urry » Ср авг 15, 2012 09:33:16
БАТАРЕЙКУС , минус 1 к внимательности, свою память лучше защитить от компилятора.
Код: Выделить всё
DATABANK NAME=buffer_section START=0x100 END=0x2FF PROTECTED
в качестве лирического отступления -
в Вашем случае лучше пользовать 24 серию. 18 серию я использую тогда, когда нужен юсб и малоногость - например, пик18ф14к50 пик18ф2550 - а для "общего назначения" - только 24.
shads
Опытный кот
Сообщения: 882 Зарегистрирован: Ср фев 22, 2012 01:25:21
Сообщение
shads » Вс авг 19, 2012 16:54:41
Дошкрябал таки задачу - написал декодер радиоканала на С (всем спасибо за помощ в освоении ентого чуда) .
Вот что получилось
http://asis-kbr.ru/forum/viewtopic.php?f=9&t=122
Текст в гифе
Текст обычно
Спойлер Код: Выделить всё
//#######################################################################################################################
//#######################################################################################################################
// включаемые файлы
#define F_CPU 9600000
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
//eeprom_read_byte(), eeprom_write_byte(), eeprom_read_word(), eeprom_write_word()
//дефайны
#define BtnPort PINB /*порт подключения кнопки*/
#define BtnPin (1<<1) /*пин подключения кнопки*/
#define ReceivePort PINB /*порт подключения выхода приемника 433*/
#define ReceivePin (1<<3) /*пин подключения выхода приемника 433*/
#define LedPort PORTB /*порт подключения светодиода*/
#define LedPin (1<<2) /*пин подключения светодиода*/
#define RelayPort PORTB /*порт подключения реле*/
#define RelayPin (1<<4) /*пин подключения реле*/
//прототипы функций
void Receive (void); //ф-ция обработки данных радиоканала в прерывании с частотой 20000Гц
void Int100Hz (void); //обработка медленных функций с частотой 100Гц
//глобальные переменные
unsigned long ReceiveData; //4 байта для чтения кода с радиоканала
unsigned char RelayOnCoun=0; //счетчик времени включения реле
unsigned char LedCoun; //счетчик для мигания светика с частотой 1Гц
#define EEDataLen 60 /*длина буфера данных в EEPROM*/
unsigned char EEData[EEDataLen] EEMEM; //массив данных в EEPROM
unsigned char EEPnt EEMEM; //указатель на байт массива в EEPROM (0-59)
//#######################################################################################################################
//#######################################################################################################################
//Главная функция
int main (void)
{
DDRB = (LedPin|RelayPin); //включение линий порта на вывод
PORTB = BtnPin; //включит подтяжку на кнопке
TCCR0A = 0x02; //режим таймера - CTC (0x02 сброс при совпадении), выводы контроллера не исп-ся
TCCR0B = 0x02; //инициализация режима предделителя таймера (0x02 деление на 8)
TIMSK0 = 0x04; //инициализация таймера\счетчика по совпадению с OCR0A
OCR0A = 59; //настройка регистра сравнения 59 (f прерывания =20khz)
_delay_ms(200);
if (!(BtnPort & BtnPin)) //если кнопка нажата при старте - стереть EEPROM
{
for (unsigned char i=0; i<EEDataLen; i++)//цикл стирания данных EEPROM
eeprom_write_byte(&EEData [i], 0);
eeprom_write_byte(&EEPnt, 0); //сброс указателя
for (unsigned char i=0; i<30; i++)
{ //индикация стирания (частое мигание в течение 3 сек)
LedPort |= LedPin; //мигаем с периодом 100мс
_delay_ms(50);
LedPort &= ~LedPin;
_delay_ms(50);
}
}
sei (); //разрешаем глобально прерывания
while(1) //бесконечный цикл
{
}
}
//#######################################################################################################################
//#######################################################################################################################
//обработка прерывания (частота вызова 20 кГц)
ISR (TIM0_COMPA_vect)
{
Receive (); //функция обработки данных линии радиоканала
static unsigned char Div100=0; //счетчик, для деления частоты прохода с 20000 Гц до 100 Гц
if (++ Div100 >= 200)
{
Div100 =0;
Int100Hz (); //функции с частотой вызова 100Гц
}
}
//-----------------------------------------------------------------------------------------------------------------------
//часть функций с частотой вызова 100Гц
void Int100Hz (void)
{
sei (); //разрешить прерывания в медленной части (для выполнения прерываний с частотой 10000 Гц)
if (BtnPort & BtnPin)
{ //если кнопка отпущена - мигать в режиме StBy
if (++ LedCoun >= 100)
LedCoun=0;
if (LedCoun >= 50)
LedPort &= (~LedPin);
else
LedPort |= LedPin;
}
else //если кнопка нажата - погасить (ожидаем сигнала с брелка, для занесения в память)
LedPort &= (~LedPin);
if (RelayOnCoun) //обработка включения реле
{
RelayOnCoun --;
RelayPort |= RelayPin; //включить реле
}
else
RelayPort &= ~RelayPin; //выключить реле
}
//-----------------------------------------------------------------------------------------------------------------------
//ф-ция приема данных радиоканала
void Receive (void)
{
static unsigned char
Step=0, //переменная шагов алгоритма
BitHiPartCoun=0, //счетчик времени приема высокой части полу бита
BitLoPartCoun=0, //счетчик времени приема низкой части полу бита
BitCounter=0; //счетчик принятых бит
//Step==0 инициализация приема серии
if (Step==0)
BitCounter=0;
//Step==1 начало основного цикла приема бита
if (Step<2)
{
BitHiPartCoun=0;
BitLoPartCoun=0;
}
//Step==2 обработка высокого уровня полубита
if (Step<3)
{
if (ReceivePort & ReceivePin)
{
Step=2;
if (BitHiPartCoun < 50) //Подсчитываем длительность высокого уровня сигнала в линии
BitHiPartCoun ++;
return;
}
}
//Step==3 обработка низкого уровня полубита
if (ReceivePort & ReceivePin)
{
//завершено чтение бита, анализ временных параметров
Step=0;
unsigned char temp = (BitLoPartCoun + BitHiPartCoun);
if ((temp < 8)||(temp >= 15))
return; //временные параметры бита не соответствуют, инициализация
Step=1;
ReceiveData <<= 1UL; //сдвиг буфера и запись в младший разряд принятого бита
if (BitLoPartCoun < BitHiPartCoun)
ReceiveData |=1;
if (BitCounter < 24) //считаем скока бит приняли
BitCounter ++;
return;
}
else
{
Step =3;
if (++ BitLoPartCoun < 50) //если длительность низкого уровня сигнала в линии больше 50мс - значит серия принята
return;
Step=0;
if (BitCounter<24) //Если принято менее 24 бит - ошибка, начать прием заново
return;
ReceiveData &= 0x00ffffff; //очистить лишние старшие 8 бит
//идентификация принятых данных
unsigned char EEPntTmp = eeprom_read_byte(&EEPnt);
if (!(BtnPort & BtnPin))
{ //кнопка нажата - запомнить принятый код
if (EEPntTmp >= EEDataLen)
return; //память заполнена, выход
eeprom_write_byte (&EEPnt,(EEPntTmp +3));
eeprom_write_byte (&EEData[EEPntTmp +0], (unsigned char) (ReceiveData >> 0));
eeprom_write_byte (&EEData[EEPntTmp +1], (unsigned char) (ReceiveData >> 8));
eeprom_write_byte (&EEData[EEPntTmp +2], (unsigned char) (ReceiveData >> 16UL));
LedPort |= LedPin; //индикация выполненного программирования (включ LED на 2 сек)
_delay_ms(2000);
return;
}
else
{ //кнопка не нажата - проверить на соответствие кодам в памяти
while (EEPntTmp >= 3) //есть ли данные для сравнения
{
EEPntTmp -= 3;
if ((eeprom_read_byte (&EEData[EEPntTmp +0]) == (unsigned char) (ReceiveData >>0))
&&(eeprom_read_byte (&EEData[EEPntTmp +1]) == (unsigned char) (ReceiveData >> 8))
&&(eeprom_read_byte (&EEData[EEPntTmp +2]) == (unsigned char) (ReceiveData >> 16UL)))
{
RelayOnCoun=50; //включить реле на 500мс.
return;
}
}
}
}
}
//#######################################################################################################################
//#######################################################################################################################
Последний раз редактировалось
shads Вс авг 19, 2012 20:31:42, всего редактировалось 3 раза.
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482 Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:
Сообщение
vitalik_1984 » Вс авг 19, 2012 18:21:59
Зачем было в картинку переводить?Чтобы мы посмотрели как у вас редактор синтаксис подсвечивает?
Совет: чтобы сделать подсветку синтаксиса языка Си в форуме можно использовать сочетание тэгов
[/code]
В поисках истины человек развивается.
shads
Опытный кот
Сообщения: 882 Зарегистрирован: Ср фев 22, 2012 01:25:21
Сообщение
shads » Вс авг 19, 2012 20:33:44
Попробовал, при этом, текст программы магическим образом кудато испаряется.....
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482 Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:
Сообщение
vitalik_1984 » Вс авг 19, 2012 22:37:07
Странно
Спойлер Код: Выделить всё
Код:
//#######################################################################################################################
//#######################################################################################################################
// включаемые файлы
#define F_CPU 9600000
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
//eeprom_read_byte(), eeprom_write_byte(), eeprom_read_word(), eeprom_write_word()
//дефайны
#define BtnPort PINB /*порт подключения кнопки*/
#define BtnPin (1<<1) /*пин подключения кнопки*/
#define ReceivePort PINB
//прототипы функций
void Receive (void); //ф-ция обработки данных радиоканала в прерывании с частотой 20000Гц
void Int100Hz (void); //обработка медленных функций с частотой 100Гц
//глобальные переменные
unsigned long ReceiveData; //4 байта для чтения кода с радиоканала
unsigned char RelayOnCoun=0; //счетчик времени включения реле
unsigned char LedCoun; //счетчик для мигания светика с частотой 1Гц
всегда теперь этим пользуюсь, если не забываю
В поисках истины человек развивается.
shads
Опытный кот
Сообщения: 882 Зарегистрирован: Ср фев 22, 2012 01:25:21
Сообщение
shads » Пн авг 20, 2012 10:49:12
Буксую с указателями…..
Объявляю строку:
char TxtDflt [] = {"dflt"};
Есть функция печати сообщения, в которую хочу передать строку:
void DspMessageShow (char TxtDflt[]);
и есть функция печати символов, в которую передаю символ и позицию:
void DspSimbShow (unsigned char simbol, unsigned char position)
С последней ф-цией все нормально, символы печатает. Но как в нее по очереди передать символы из ф-ции печати сообщения, хелпмииииии…..
Аlex
Модератор
Сообщения: 4614 Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:
Сообщение
Аlex » Пн авг 20, 2012 11:56:52
Код: Выделить всё
void DspMessageShow (char *TxtDflt){
while(*TxtDflt){
DspSimbShow (*TxtDflt, mPos);
TxtDflt++;
}
}
Как то так...
ut1wpr
Вымогатель припоя
Сообщения: 581 Зарегистрирован: Ср янв 05, 2011 10:03:18
Сообщение
ut1wpr » Пн авг 20, 2012 16:54:00
Или для ленивых:
Код: Выделить всё
void DspMessageShow ( char *TxtDflt ){
while( char ch = *TxtDflt ) DspSimbShow ( ch, mPos );
}
По записи вроде бы и короче, на одно обращение по указателю меньше. Но введение переменной сводит на нет всю экономию...
Да и чревата такая форма записи.... Не все компиляторы и не всех платформах одинаково с ней разберутся.
С уважением,
Виктор.
Аlex
Модератор
Сообщения: 4614 Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:
Сообщение
Аlex » Пн авг 20, 2012 17:36:18
Или для ленивых:
Не нахожу инкремента указателя. Цикл будет вечным
Тогда уж так:
Код: Выделить всё
void DspMessageShow (char *pStr){
while(*pStr) DspSimbShow (*pStr++, mPos);
}
FreshMan
Друг Кота
Сообщения: 6296 Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine
Сообщение
FreshMan » Пн авг 20, 2012 20:00:16
Tell Me The Truth