CodeVision AVR в вопросах и ответах
в даташите на контроллер есть примеры работы с EEPROM/ Сложно оттуда скопировать?
Ставим плюсы: )
- Реклама
Благодарю! Чет, судя по даташитам на пики, думал там тоже все примеры на асме. И посмотрел, только технические характеристики. В дальнейшем буду более внимательно изучать литературу!
Вопрос по компиляции проекта. МК Atmega 128. Программа большая, много функций и переменных, пробую их уменьшить но сложно.
После составления всех функций появилась ошибка "Hardware Stack size has a dangerously low value: 11 Byte(s)". Я понимаю проблему так: аппаратный стек используется для вызова функций. И так как у меня их много, то часто получается большая вложенность. Поэтому и ошибка, стек для меток возврата заполнен. Программа при этом компилится и шьется нормально.
Как можно исправить данную ошибку? Можно ли этот аппаратный стек увеличить? В родной среде atmel по-моему была такая опция, а в Codevision я её не нашёл.
После составления всех функций появилась ошибка "Hardware Stack size has a dangerously low value: 11 Byte(s)". Я понимаю проблему так: аппаратный стек используется для вызова функций. И так как у меня их много, то часто получается большая вложенность. Поэтому и ошибка, стек для меток возврата заполнен. Программа при этом компилится и шьется нормально.
Как можно исправить данную ошибку? Можно ли этот аппаратный стек увеличить? В родной среде atmel по-моему была такая опция, а в Codevision я её не нашёл.
Это не аппаратный, а стек данных, фича кодевижена. Лень картинку снимать, посмотрите в опциях проекта - его можно там увеличить.
Docendo discimus
Да действительно. Был задан большой размер стека данных (700 байт). Хотя ожидаемое использование всего 64. Уменьшил стек данных до 500, аппаратный стек сразу на эти 200 увеличился.pyzhman писал(а):Это не аппаратный, а стек данных, фича кодевижена. Лень картинку снимать, посмотрите в опциях проекта - его можно там увеличить.
Не понял только зачем такое значение было задано (700) если компилятор говорит что 64 используется всего?
- Реклама
Помогите найти ошибку. Хочу подключить 2 датчика DS18B20 к ATtiny2313 на один вывод, изучив даташит написал такой код, но на дисплей выводится белибирда.
Код: Выделить всё
unsigned char RC[];//массив для записи РОМ кода датчика
unsigned char i;//переменная положения элемента массива
...
w1_init();
w1_write(0xF0);
for(i=0;i<8;i++){
RC[i]=w1_read;}//чтение РОМ кода(если правильно)
//обращение к конкретному датчику с кодом записанным в RC
w1_init;
w1_write(0x55);
for(i=0;i<8;i++){
w1_write(RC[i]);}
w1_write(0x44);
delay_ms(800);
w1_write(0x55);
for(i=0;i<8;i++){
w1_write(RC[i]);}
w1_write(0xBE);
//дальше чтение температуры и вывод на дисплей
Ну для чего в разных темах постить ? Есть же уже тема по DS-кам.
Вам же уже сказали, что одной командой не отделаться. Курите литературу, или ищите примеры.
PS: Не нужно тут постить по DS-ам, пишите в соответствующей теме.
Вам же уже сказали, что одной командой не отделаться. Курите литературу, или ищите примеры.
И какого размера Ваш массив, извольте поинтересоваться ?Код: Выделить всё
unsigned char RC[];//массив для записи РОМ кода датчика
PS: Не нужно тут постить по DS-ам, пишите в соответствующей теме.
Извиняюсь. Просто решил поспрашивать везде, может тут есть люди, которые не заходят в ту тему, а могут дать ответ массив на 8 символов, надо было писать unsigned char RC[8];, это потом решил опробовать.
Есть в последних версиях (пользуюсь 2.05.3) поддержка дисплея от Нокии3310. Так мне запендюрилось подключить именно таким способом и застрял. Фонты генерятся особым извращённым способом с помощью родной LCD Vision, которая платная, в бесплатной нет сохранения, только в ручную набивать. Поиск в интеренете ни к чему не привёл. Помогите с этой програмулькой или шрифтами с поддержкой русского. В идеале хочется конечно последнюю 2.60 Advanced (в ней встроена LCD Vision).
- Сообщения: 812
- Зарегистрирован: Ср мар 18, 2009 21:14:33
При попытке вычитки attiny2313A CVAVR ругается на несовпадение сигнатур.
При это CVAVR вычитывает с кучей ошибок и ошибкой сигнатуры, а ponyprog и читает и пишет всё нормально.
Где собака порылась?
При это CVAVR вычитывает с кучей ошибок и ошибкой сигнатуры, а ponyprog и читает и пишет всё нормально.
Где собака порылась?
Доброго времени суток! Grott, ibiza11, моё почтение!
Прошу помощи здесь, т.к. не знаю куда ещё обратиться. Столкнулся с проблемой. Разрабатываю устройство с батарейным питанием на ATtiny24A. Данный МК выбран из-за его "мелкоты", наличия АЦП, достаточного кол-ва портов в/в, ну и, конечно, цены. Поскольку в данном МК аппаратный, способный пробудить ядро, внешний INT только один, было решено использовать Watch Dog таймер в режиме генерации прерываний, которые также способны пробудить ядро МК, находящегося в режиме Power Down. И уже тогда производить опрос нужных портов, и по условию снова отправлять МК в "спячку". В CVAVR были выставлены соответствующие настройки и сгенерирован код.
#include <delay.h>
#define red PORTB.2
#define yellow PORTB.1
#define green PORTB.0
#define left PINA.5
#define right PINA.6
// Watchdog timeout interrupt service routine
interrupt [WDT] void wdt_timeout_isr(void)
{
WDTCSR|=0x40;
// Place your code here
yellow=1;
//delay_ms(10);
//yellow=0;
}
#include <delay.h>
#define ADC_VREF_TYPE 0xC0
// ADC interrupt service routine
interrupt [ADC_INT] void adc_isr(void)
{
unsigned int adc_data;
// Read the AD conversion result
adc_data=ADCW;
// Place your code here
}
// Declare your global variables here
void main(void)
{
// Declare your local variables here
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
// Input/Output Ports initialization
// Port A initialization
// Func7=Out Func6=In Func5=In Func4=In Func3=Out Func2=In Func1=In Func0=In
// State7=0 State6=P State5=P State4=T State3=0 State2=T State1=T State0=T
PORTA=0x60;
DDRA=0x88;
// Port B initialization
// Func3=In Func2=Out Func1=Out Func0=Out
// State3=T State2=0 State1=0 State0=0
PORTB=0x00;
DDRB=0x07;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 8000,000 kHz
// Mode: Fast PWM top=FFh
// OC0A output: Disconnected
// OC0B output: Non-Inverted PWM
TCCR0A=0x23;
TCCR0B=0x01;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x64;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// External Interrupt(s) initialization
// INT0: Off
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-11: Off
MCUCR=0x00;
GIMSK=0x00;
// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x00;
// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=0x00;
// Universal Serial Interface initialization
// Mode: Disabled
// Clock source: Register & Counter=no clk.
// USI Counter Overflow Interrupt: Off
USICR=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
ADCSRB=0x00;
// ADC initialization
// ADC Clock frequency: 1000,000 kHz
// ADC Voltage Reference: 1.1V, cap. on AREF
// ADC Bipolar Input Mode: Off
// ADC Auto Trigger Source: None
// Digital input buffers on ADC0: Off, ADC1: Off, ADC2: Off, ADC3: On
// ADC4: On, ADC5: On, ADC6: On, ADC7: On
DIDR0=0x07;
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x8B;
ADCSRB&=0x7F;
ADCSRB|=0x10;
// Watchdog Timer initialization
// Watchdog Timer Prescaler: OSC/8k
// Watchdog Timer interrupt: On
#pragma optsize-
#asm("wdr")
WDTCSR=0x1A;
WDTCSR=0x4A;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
// Global enable interrupts
#asm("sei")
while (1)
{
// Place your code here
};
} Вот тут-то и начались проблемы. Прерывания так и не включились. Посмотрел в даташит, пробовал записывать в WDTCSR все возможные комбинации, пробовал также устанавливать и фуз WDTON. Я не получил ни прерываний, ни сбросов.
Пробовал сохранять WDTCSR в EEPROM, решив что не все биты корректно записываются. При считывании программатором оказалось, что всё что я писал в этот регистр, устанавливалось в нём один к одному без искажений.
В панике решил что у меня "дохлый" МК и попробовал всё то же самое проделать на одноимённой модели МК в Протеусе. К моему удивлению и разочарованию виртуальная модель вела себя абсолютно так же, как и реальный МК - никаких ни прерываний по WDT, ни сбросов.
В ещё больший ступор меня ввела попытка сгенерировать в CVAVR и запустить на виртуальной модели в Протеусе код инициализации WDT для ATtiny2313. Результат тот же - при любом сочетании битов в регистре сторожевого таймера и его фуз-бита ни сбросов, ни прерываний я не получил.
Уже даже думал, что ошибка в самом файле-хидере <tiny24.h> из штатного набора CVAVR. По ДШ адрес WDTCSR - 0x21h. В файле-хидере, прописан тот же самый адрес - 0x21h.
Туплю, не могу понять что не так и куда копать дальше. Пробовал создать тему http://radiokot.ru/forum/viewtopic.php? ... 0#p1503710 но никто ничего дельного не подсказал.
Спасайте! Рятуйте! Help!
Прошу помощи здесь, т.к. не знаю куда ещё обратиться. Столкнулся с проблемой. Разрабатываю устройство с батарейным питанием на ATtiny24A. Данный МК выбран из-за его "мелкоты", наличия АЦП, достаточного кол-ва портов в/в, ну и, конечно, цены. Поскольку в данном МК аппаратный, способный пробудить ядро, внешний INT только один, было решено использовать Watch Dog таймер в режиме генерации прерываний, которые также способны пробудить ядро МК, находящегося в режиме Power Down. И уже тогда производить опрос нужных портов, и по условию снова отправлять МК в "спячку". В CVAVR были выставлены соответствующие настройки и сгенерирован код.
Спойлер
#include <tiny24.h>#include <delay.h>
#define red PORTB.2
#define yellow PORTB.1
#define green PORTB.0
#define left PINA.5
#define right PINA.6
// Watchdog timeout interrupt service routine
interrupt [WDT] void wdt_timeout_isr(void)
{
WDTCSR|=0x40;
// Place your code here
yellow=1;
//delay_ms(10);
//yellow=0;
}
#include <delay.h>
#define ADC_VREF_TYPE 0xC0
// ADC interrupt service routine
interrupt [ADC_INT] void adc_isr(void)
{
unsigned int adc_data;
// Read the AD conversion result
adc_data=ADCW;
// Place your code here
}
// Declare your global variables here
void main(void)
{
// Declare your local variables here
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
// Input/Output Ports initialization
// Port A initialization
// Func7=Out Func6=In Func5=In Func4=In Func3=Out Func2=In Func1=In Func0=In
// State7=0 State6=P State5=P State4=T State3=0 State2=T State1=T State0=T
PORTA=0x60;
DDRA=0x88;
// Port B initialization
// Func3=In Func2=Out Func1=Out Func0=Out
// State3=T State2=0 State1=0 State0=0
PORTB=0x00;
DDRB=0x07;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 8000,000 kHz
// Mode: Fast PWM top=FFh
// OC0A output: Disconnected
// OC0B output: Non-Inverted PWM
TCCR0A=0x23;
TCCR0B=0x01;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x64;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// External Interrupt(s) initialization
// INT0: Off
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-11: Off
MCUCR=0x00;
GIMSK=0x00;
// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x00;
// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=0x00;
// Universal Serial Interface initialization
// Mode: Disabled
// Clock source: Register & Counter=no clk.
// USI Counter Overflow Interrupt: Off
USICR=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
ADCSRB=0x00;
// ADC initialization
// ADC Clock frequency: 1000,000 kHz
// ADC Voltage Reference: 1.1V, cap. on AREF
// ADC Bipolar Input Mode: Off
// ADC Auto Trigger Source: None
// Digital input buffers on ADC0: Off, ADC1: Off, ADC2: Off, ADC3: On
// ADC4: On, ADC5: On, ADC6: On, ADC7: On
DIDR0=0x07;
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x8B;
ADCSRB&=0x7F;
ADCSRB|=0x10;
// Watchdog Timer initialization
// Watchdog Timer Prescaler: OSC/8k
// Watchdog Timer interrupt: On
#pragma optsize-
#asm("wdr")
WDTCSR=0x1A;
WDTCSR=0x4A;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
// Global enable interrupts
#asm("sei")
while (1)
{
// Place your code here
};
}
Пробовал сохранять WDTCSR в EEPROM, решив что не все биты корректно записываются. При считывании программатором оказалось, что всё что я писал в этот регистр, устанавливалось в нём один к одному без искажений.
В панике решил что у меня "дохлый" МК и попробовал всё то же самое проделать на одноимённой модели МК в Протеусе. К моему удивлению и разочарованию виртуальная модель вела себя абсолютно так же, как и реальный МК - никаких ни прерываний по WDT, ни сбросов.
В ещё больший ступор меня ввела попытка сгенерировать в CVAVR и запустить на виртуальной модели в Протеусе код инициализации WDT для ATtiny2313. Результат тот же - при любом сочетании битов в регистре сторожевого таймера и его фуз-бита ни сбросов, ни прерываний я не получил.
Уже даже думал, что ошибка в самом файле-хидере <tiny24.h> из штатного набора CVAVR. По ДШ адрес WDTCSR - 0x21h. В файле-хидере, прописан тот же самый адрес - 0x21h.
Туплю, не могу понять что не так и куда копать дальше. Пробовал создать тему http://radiokot.ru/forum/viewtopic.php? ... 0#p1503710 но никто ничего дельного не подсказал.
Спасайте! Рятуйте! Help!
- Сообщения: 23
- Зарегистрирован: Вт янв 31, 2012 22:43:10
Уже молю о помощи тут - Как в кодвижин сделать обработку прерывания??? в сети находил
interrupt [TIM0_COMPA] void timer0_compa_isr(void) {}
компилятор ругается
interrupt[SIG_OVERFLOW1] {}
Компилятор ругается
interrupt(SIG_OVERFLOW1) {}
Компилятор ругается
ISR[SIG_OVERFLOW1] {}
Компилятор ругается
ISR(SIG_OVERFLOW1) {}
Компилятор ругается
Error: ledD.c(8): declaration syntax error
как же всё таки в кодвижене обработать прерывание? должна же быть какая-то логика?! где взять список векторов прерываний в CV. Уж если влом писать прямой ответ на вопрос - бросьте хоть ссылку на хвалёный "туториал" в котором написан РАБОЧИЙ вариант обработки прерываний. запарился уже
Листинг моей первой программы
interrupt [TIM0_COMPA] void timer0_compa_isr(void) {}
компилятор ругается
interrupt[SIG_OVERFLOW1] {}
Компилятор ругается
interrupt(SIG_OVERFLOW1) {}
Компилятор ругается
ISR[SIG_OVERFLOW1] {}
Компилятор ругается
ISR(SIG_OVERFLOW1) {}
Компилятор ругается
Error: ledD.c(8): declaration syntax error
как же всё таки в кодвижене обработать прерывание? должна же быть какая-то логика?! где взять список векторов прерываний в CV. Уж если влом писать прямой ответ на вопрос - бросьте хоть ссылку на хвалёный "туториал" в котором написан РАБОЧИЙ вариант обработки прерываний. запарился уже
Листинг моей первой программы
Код: Выделить всё
//модель мегии
#include <tiny2313.h>
//частота кристала
#define _hz 4000000
//
//------------------------------------------------
interrupt[SIG_OVERFLOW1] // тут обрабатываем прерывание от таймера
{
//
TCNT1 = 0x10000 - (_hz/1024); // 65536(число переполнения таймера так как он 16бит) - частоту разделив на 1024 получаем 3906 - это насчитает таймер за секунду
PORTB ^= 0x01; //1 - т.е. в регистре у нас 00000001 и на ноге РСВ0 у нас напряжение
//
}
//------------------------------------------------
int main(void)
{
//
DDRB = 0x01; //направление передачи , в регистре 00000001, т.е. нога РСВ0 эявляется выходом
//для мазохизма пользуем сложный таймер Т/С1 в котором есть регистры сравнений
TCCR1A =0; // TCCR1A - заносим в регистр 0, отключаем ШИМ
TCCR1B = 5; // TCCR1B - ставим 5 или 101 (в регисьре значащие 3 разряда 0-2) тем самым устанавливая частоту тактирования таймера системная/1024 это 3906 тактов в секунду при частоте 4000000
TCN1 = 0x10000 - (_hz/1024); // ложим в регистр 61630 что б сработало на следующую секунду после запуска
TIFR = 0; //сбрасываем флаги прерываний
TIMSK = 0x80; // пишем в регистр 10000000 , разрешаем прерывание Т/С1
GIMSK = 0; // запрещаем внешние прерывания
sei(); //прерывания разрешены
while(1); //ждём прерывания таймера (сидим в бесконечном цыкле)
//
} tools->codewizardavr ставьте галочки, где нужно.
Прерывание по переполнению 1 таймера в кодевижин
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
не забудьте их разрешить TIMSK=0x04;
И, вообще-то, там хелп есть...
Прерывание по переполнению 1 таймера в кодевижин
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
не забудьте их разрешить TIMSK=0x04;
И, вообще-то, там хелп есть...
- Сообщения: 23
- Зарегистрирован: Вт янв 31, 2012 22:43:10
urry ОГРОМНОЕ СПАСИБО
!
Несколько уточнений:
я думал так нужно прерывания разрешать в нём
Прерывания по переполнению таймера/счетчика вроде как так
Снова я не прав?
Несколько уточнений:
Мне кажется или кодвижн совсем на изнанку??????urry писал(а): не забудьте их разрешить TIMSK=0x04;
я думал так нужно прерывания разрешать в нём
Код: Выделить всё
#asm
sei //прерывания разрешены
#endasm
Код: Выделить всё
TIMSK = 0x80;#asm ("sei") - общее разрешение всех прерываний вообще. TIMSK - регистр масок прерываний таймеров по конкретным возможным событиям. То есть для срабатывания прерывания от таймера должны быть выставлены конкретные события в TIMSK, разрешены прерывания вообще #asm ("sei"), кроме того сам таймер должен быть инициализирован - выбран источник тактовой частоты, выставлен предделитель и задан режим работы.
- Вложения
-
- 3.png
- (61.36 КБ) 553 скачивания
-
- 2.png
- (28.47 КБ) 254 скачивания
-
- 1.png
- (30.1 КБ) 554 скачивания
Так про мастера уже подсказали где найти вот еще смотрите Ссылка на учебник по CVAVR автор лебедев
Разобрался с WDT.
В функциях встроенной библиотеки ...\cvavr\inc\delay.h содержатся команды "wdr" сброса WD таймера. Таким образом при использовании WDT в CVAVR следует избегать применения функций delay_us или delay_ms, если ожидаются прерывания или сбросы по WDT.
Особая благодарность a_skr за подсказку.
В функциях встроенной библиотеки ...\cvavr\inc\delay.h содержатся команды "wdr" сброса WD таймера. Таким образом при использовании WDT в CVAVR следует избегать применения функций delay_us или delay_ms, если ожидаются прерывания или сбросы по WDT.
Особая благодарность a_skr за подсказку.
- Сообщения: 541
- Зарегистрирован: Вт фев 09, 2010 17:52:26
Не стоит боятся функции delay_ms, так как в ней встроен автоматический сброс WDT через 1 мсELcat писал(а):Разобрался с WDT.
В функциях встроенной библиотеки ...\cvavr\inc\delay.h содержатся команды "wdr" сброса WD таймера. Таким образом при использовании WDT в CVAVR следует избегать применения функций delay_us или delay_ms, если ожидаются прерывания или сбросы по WDT.
(delay_us тоже безопасна, написать почему?)
Вы, наверно не поняли, товарищ хотел нестандартно использовать собаку, и делать в прерывании от WD свои грязные делишки.Не стоит боятся функции delay_ms,
Просто следовало уточнить, что если нужно, чтобы прерывания от WD происходили регулярно, то желательно не использовать стандартные задержки.
- Сообщения: 541
- Зарегистрирован: Вт фев 09, 2010 17:52:26
Верно я не вникал что он хочет делать, но натягивать трусы через голову не правильно.vitalik_1984 писал(а):Вы, наверно не поняли, товарищ хотел нестандартно использовать собаку, и делать в прерывании от WD свои грязные делишки.Не стоит боятся функции delay_ms,.
Если разве только все таймеры уже заняты.
С третьего раза мне дошлоvitalik_1984 писал(а):Просто следовало уточнить, что если нужно, чтобы прерывания от WD происходили регулярно, то желательно не использовать стандартные задержки.


