CodeVision AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Ответить
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18682
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

COKPOWEHEU и L.O.D, к вам обращаюсь:
1. мериться крутизной в познании глубин Си вы могли бы и где-нибудь в другой теме, или даже в личке.
2. вы, наверное, не в курсе, но сейчас вы находитесь в теме про CVAVR, которому глубоко покласть на volatile
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

Да? А как он регулирует доступ к переменным из прерывания? С cvavr дела не имел, было бы интересно узнать. Модификатор volatile это свойство самого языка Си, а не расширение какого-то диалекта как PROGMEM/flash или побитовый доступ к числам.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Есть мнение (не раз его уже слыхал на этом же форуме), что такое поделие как CVAVR, - это даже не язык C, а какой-то C-подобный диалект (взять тот же доступ к битам портов, не укладывающийся в рамки C). Поэтому лучше и не пытаться описать его поведение в рамках языка C.
Контактная информация:
Прорезались зубы
Аватара пользователя
Сообщения: 213
Зарегистрирован: Ср дек 15, 2010 14:37:38

Сообщение gdoom »

gdoom писал(а):Товарищи подскажите, что то не могу понять. Делаю простой счётчик вот к примеру код для mega8^

Код: Выделить всё

#include <mega8.h>

#asm
   .equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>
int s = 0;

// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
   s++;
   if(s>59)
   {
      s=0;
   }
   
  TCNT1H=0;
  TCNT1L=0;
}

void main(void)
{

TCCR1A=0x00;
TCCR1B=0x05;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x1E;
OCR1AL=0x85;

TIMSK=0x10; 

lcd_init(8);

#asm("sei")

while (1)
      {
       lcd_gotoxy(0,0);  
        lcd_putchar(s/10+0x30);
        lcd_putchar(s%10+0x30);
      };
}

- как видите на ногах B висит жки - частота 8Мгц работает всё, секунды считает.
Но вот когда пишу для tiny2313 молчит, вот код:

Код: Выделить всё


#include <lcd.h>
#include <tiny2313.h>
 
#asm
   .equ __lcd_port=0x18 ;PORTB
#endasm


int s = 0;

// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
   s++;
   if(s>59)
   {
      s=0;
   }
   
  TCNT1H=0;
  TCNT1L=0;
}

void main(void)
{
TCCR1A=0x00;
TCCR1B=0x05;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x1E;
OCR1AL=0x85;

TIMSK=0x10; 

lcd_init(8);

#asm("sei")
while (1)
      {
        lcd_gotoxy(0,0);  
        lcd_putchar(s/10+0x30);
        lcd_putchar(s%10+0x30);
      }
}
- где ошибка подскажите пожалуйста?

- товарищи вопрос снят! - даташит всему голова, у ещё плюс 5 чашек кофе :shock:
Реклама
Эиком - электронные компоненты и радиодетали
Держит паяльник хвостом
Сообщения: 963
Зарегистрирован: Чт апр 03, 2014 23:16:55
Откуда: Россия

Сообщение Rtmip »

COKPOWEHEU писал(а):Да? А как он регулирует доступ к переменным из прерывания?
Примерно так:
...To instruct the compiler to allocate a variable to registers, the register modifier must be used.
Example:

register int abc;

The compiler may automatically allocate a variable to registers, even if this modifier is not used.

The volatile modifier must be used to warn the compiler that it may be subject to outside change
during evaluation.
Example:

volatile int abc;

Variables declared as volatile will not be allocated to registers...
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18682
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 601
Зарегистрирован: Пт фев 13, 2009 20:58:13
Откуда: Донецк

Сообщение DataLife »

Ребят, как сделать программный Reset ?
Нужно, чтобы при достижения некого условия устройство прыгало в самое начало программы, как после аппаратного ресета.
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
Встал на лапы
Сообщения: 139
Зарегистрирован: Чт фев 11, 2016 18:35:37

Сообщение L.O.D »

ARV писал(а):COKPOWEHEU и L.O.D, к вам обращаюсь:
1. ... вы могли бы и где-нибудь в другой теме, или даже в личке.
2. ... вы находитесь в теме про CVAVR
1. Человеку, задавшему вопрос, был дан не вполне точный ответ, корректировать который в личке было бы глупо. :dont_know:
2. Вы и сами отметились в обсуждении этой темы, так что советовать кому-либо не делать этого не можете. :dont_know:
- Из овощей я больше всего люблю пельмени... © Соседский Мальчик
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18682
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

DataLife писал(а):Ребят, как сделать программный Reset ?
Нужно, чтобы при достижения некого условия устройство прыгало в самое начало программы, как после аппаратного ресета.
просто прыгала или все-таки выполнялся аппаратный сброс?
я бы рекомендовал следующий метод, осуществляющий "настоящий" сброс программным способом: запрещаете все прерывания, настраиваете WDT на самый короткий интервал срабатывания и уходите в бесконечный цикл. после того, как WDT отсчитает заданный интервал, МК пересбросится.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 601
Зарегистрирован: Пт фев 13, 2009 20:58:13
Откуда: Донецк

Сообщение DataLife »

ARV, большое спасибо :beer:
Буду пробовать.
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
Прорезались зубы
Аватара пользователя
Сообщения: 236
Зарегистрирован: Чт июн 25, 2009 16:00:25
Откуда: нижний новгород

Сообщение pashaumnov »

друзья , подскажите пожалуйста, кто нибудь подключал к контролеру серво привод??? заказал на эбее себе вот такой sg90 но не совсем понятно как им управлять, шимом или обычными импульсами с нулем и единицей и с временной задержкой
задумка такая , по наступлению какого либо события привод начинает движение от своей начальной точки до конечной и останавливается. затем при наступлении еще раз такого же события привод совершает обратное движение от конечной точки к начальной и останавливается.
Вложения
mikro-servoprivod-sg90_s4.jpg
(33.08 КБ) 472 скачивания
Друг Кота
Аватара пользователя
Сообщения: 6323
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Сообщение Jack_A »

ARV писал(а):[
запрещаете все прерывания, настраиваете WDT на самый короткий интервал срабатывания и уходите в бесконечный цикл. после того, как WDT отсчитает заданный интервал, МК пересбросится.
А я бы поступил проще: выполнить несуществующую команду или обратиться по несуществующему адресу. Сколько раз сам так ресетился, сам того не желая, из-за незамеченного бага в проге.
Последний раз редактировалось Jack_A Вс мар 13, 2016 08:36:40, всего редактировалось 1 раз.
Изображение
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18682
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Jack_A писал(а):А я бы поступил проще
видите ли, я дал 100% надежный, гарантированно работающий на любой платформе вариант получить аппаратный сброс без любых побочных эффектов. а что вы советуете что-то хорошее, еще надо доказать.

реакцию МК на несуществующую команду я не знаю, и ни в одном из даташитов не встречал описания поведения при этом. почему-то мне кажется, что несуществующий опкод будет воспринят, как NOP. обращение по несуществующему адресу? тоже сильно сомневаюсь, что данный метод, во-первых, не имеет побочных эффектов, и, во-вторых, вообще сработает, как источник сброса. понятное дело, я не говорю о всяких ARMах, где на такое поведение генерируется exception
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

был еще метод программного сброса AVR, с форума аврфрекс:

Код: Выделить всё

void reboot(void) 
{
	void (*fn_ptr) (void) = (void (*) (void)) 0;
	fn_ptr();
}
давно было - на железе вроде работало (но делал все таки для перестраховки на ватчдоге), в протеусе сейчас пробовал - похоже ресетится
Друг Кота
Аватара пользователя
Сообщения: 6323
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Сообщение Jack_A »

Хорошо, снимаю свое предложение как недостаточно аргументированное и основанное на воспоминаниях об выносе мозга непонятными ресетами из-за законспирировавшейся ошибки . В ДШ действительно молчок. В симуляторе попробовал читать из несуществующей памяти - он облизнулся и дальше продолжил. Видимо, это у меня фантомная память еще DECовской архитектуры :(
Изображение
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

oleg110592 писал(а):

Код: Выделить всё

void reboot(void) 
{
	void (*fn_ptr) (void) = (void (*) (void)) 0;
	fn_ptr();
}
Короче можно записать так ((void(*)(void))0)(); (отсюда). Но это опять не ресет, а только прыжок в начало - rcall 0. Кстати, это не сработает в области бутлоадера, потому что прыгнет не на его начало, а на начало основной программы.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18682
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

COKPOWEHEU писал(а):Но это опять не ресет, а только прыжок в начало - rcall 0
вот именно! об этом с самого начала я и говорю.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

дык
DataLife писал(а):Нужно, чтобы при достижения некого условия устройство прыгало в самое начало программы, как после аппаратного ресета.
листинг gcc:

Код: Выделить всё

void reboot(void) 
{
	void (*fn_ptr) (void) = (void (*) (void)) 0;
	fn_ptr();
      90:	e0 e0       	ldi	r30, 0x00	; 0
      92:	f0 e0       	ldi	r31, 0x00	; 0
      94:	09 95       	icall
}
указатель стека заново проинициализуруется... и т.д.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18682
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

oleg110592 писал(а):указатель стека заново проинициализуруется... и т.д.
господи, ну сколько можно одно и то же пережевывать?
бог знает когда я сказал:
ARV писал(а):просто прыгала или все-таки выполнялся аппаратный сброс?
и с тех пор ничего более нового никто не предложил, все повторяют одно и то же.

прыжок на 0 адрес != аппаратный сброс

неужели это не очевидно?!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

ARV писал(а):прыжок на 0 адрес != аппаратный сброс неужели это не очевидно?!
для тупых просьба объяснить в чем отличие, посмотрел в иаре для тини13 - не вижу почему прыжок на 0 адрес не равносилен сбросу:

Код: Выделить всё

void reboot(void)
{
   void (*fn_ptr) (void) = (void (*) (void)) 0;
   fn_ptr();
}

void main( void )
{
  while(1)
  {
    if((PINB & (1<<0)) == 0) reboot();
  }
}

Код: Выделить всё

    000000   C012             RJMP    0x026
    000002   9518             RETI
    000004   9518             RETI
    000006   9518             RETI
    000008   9518             RETI
    00000A   9518             RETI
    00000C   9518             RETI
    00000E   9518             RETI
    000010   9518             RETI
    000012   9518             RETI
    000014   99B0             SBIC    0x16,0
    000016   CFFE             RJMP    0x014
    000018   E0E0             LDI     R30,0x00
    00001A   E0F0             LDI     R31,0x00
    00001C   9509             ICALL
    00001E   CFFA             RJMP    0x014
    000020   0000             NOP
    000022   9588             SLEEP
    000024   CFFE             RJMP    0x022
    000026   E90F             LDI     R16,0x9F
    000028   BF0D             OUT     SP,R16
    00002A   E8C0             LDI     R28,0x80
    00002C   D003             RCALL   0x034
    00002E   DFF2             RCALL   0x014
    000030   DFF7             RCALL   0x020
    000032   CFF6             RJMP    0x020
    000034   E001             LDI     R16,0x01
    000036   9508             RET 
Ответить

Вернуться в «AVR»