20.11.2010, 12:32
|
|
Вид на жительство
Регистрация: 21.08.2007
Сообщений: 318
Сказал спасибо: 12
Сказали Спасибо 67 раз(а) в 61 сообщении(ях)
|
Re: Помощь в WinAvr
reti возвращает из прерывания. Но в ассемблере. В Си в функциях ISR оно подставляется автоматически. При входе в любую функцию на си - интерпритатор сохраняет в стэк рабочие регистры, а извлекает их оттуда только перед его собственным reti. Так что ваш вызывается когда в стэке еще находятся сохраненные регистры и компилятор пытается из него в PC загрузить адрес, который вовсе и не адрес. Короче один из вариантов утечки памяти.
Сообщение от WartKert
|
И возможно ли в #define такое написание
|
У вас получается условие
if (PINB=PINB & 0x01==0)
Трудно думать что оно делает, но выглядит немного не логично
Напишите
#define Knopka1 (PINB & 0x01) //PB0
и компилятор воспримет это как
if ((PINB & 0x01)==0)
Это условие будет работать
|
|
|
|
29.11.2010, 19:37
|
|
Прописка
Регистрация: 17.02.2009
Сообщений: 154
Сказал спасибо: 14
Сказали Спасибо 6 раз(а) в 6 сообщении(ях)
|
Re: Помощь в WinAvr
Здравствуйте.Вот снова нужна помощ. Есть буфер типа "us_buf[us_per++] = UDR;", как видно в него забиваюся ASCII-код,вот его то хочется преобразовать в целое число. Даже знаю что нужна функция "atoi" но вот как её оформить не пойму.Спасибо.
|
|
|
|
10.12.2010, 18:02
|
|
Прописка
Регистрация: 17.02.2009
Сообщений: 154
Сказал спасибо: 14
Сказали Спасибо 6 раз(а) в 6 сообщении(ях)
|
Re: Помощь в WinAvr
Доброе время суток! Может кто сталкивался с таким делом.
Отправляю данные с компа на контроллер контр дожен ответить и он отвечает но зацикливается,и ни как не могу исправить это дело вот. Проверял на протеусе всё чётко. ПРограмма для проверки COM Port Toolkit 3.7 да впрочем и другие программы так же работают, а зто отрывок
#include ‹stdlib.h›
#include ‹avr/interrupt.h› // прерывание
#include ‹stdio.h› // ввод вывод в UART
#include "com_io.h"
#include "com_io.c"
#include ‹avr/io.h› // библиотека I/O
#include ‹util/delay.h› // библиотеки пауз stdlib
int tr=0;
ISR(USART_RXC_vect) // USART, Rx Complete
{ scanf("%d",&tr);
printf("summa=%3u\n",tr);
}
int main(void)
UCSRA=0x00;
UCSRB=0x98;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x19;
sei(); // глобальное разрешение прерываний
while (1)
|
|
|
|
10.05.2011, 21:10
|
|
Частый гость
Регистрация: 12.07.2009
Сообщений: 22
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Помощь в WinAvr
Добрый день.
Тут понял чем дальше изучаеш программирование на С, тем больше понимаеш что надо изучать Asm. Теперь пытаю вставки на Asm в WinAvr. Написал ф-цию "паузы", т.к. WinAvr-ий, Proteus не совсем правильно понимает. Вроде всё работает, но почему-то мне не нравится метод как я написал (слишком много строк, да и запутанно как-то). Подскажите что можно поменять, или другую какую нибудь подсказку скажите.
Код:
|
void delay_us(int use) { //функция паузы от 1 до 65535 (с точностью +- 0,3 мкс, при F=16,5 МГц)
asm volatile(
"ldi r29,0x00" "\n\t" //обнуление счетчика (через которое происходит поправка по времени)
"ldi r20,0x02" "\n\t" //регистр поправки количества тактов на 1 мкс
"rjmp L_2%=" "\n\t" //переход на метку 2
"L_3%=:" "\n\t" //метка выполнение поправки по времени (ускорение на 2 такта)
"nop" "\n\t"
"nop" "\n\t"
"ldi r29,0x00" "\n\t" //обнуление счетчика (через которое происходит поправка по времени)
"breq L_4%=" "\n\t" //переход на метку убавления заданного времени паузы
"L_1%=:" "\n\t" //метка выполнения основной программы 1
"nop" "\n\t"
"nop" "\n\t"
"nop" "\n\t"
"cpi r29,0x06" "\n\t" //сравнение с регистром (через которое происходит поправка по времени)
"breq L_3%=" "\n\t" //переход на метку выполнения поправки (если R29 == 6)
"ldi r20,0x02" "\n\t" //регистр поправки количества тактов на 1 мкс
"L_2%=:" "\n\t" //переход на метку основной программы 2
"inc r29" "\n\t" //инкремент счётчика (через которое происходит поправка по времени)
"dec r20" "\n\t" //декремент счётчика поправки
"brne L_2%=" "\n\t" //зацикливание на метки 2, пока счётчик поправки по тактам не будет 0
"L_4%=:" "\n\t" //метка убавления заданного значения паузы
"sbiw r30,0x01" "\n\t" //уменьшение значения в слове на 1
"brne L_1%=" "\n\t" //если Z установлен, то идём дальше
: [us] "+e" (use) );
} |
|
|
|
|
10.05.2011, 21:26
|
|
Заблокирован
Регистрация: 26.12.2009
Сообщений: 3,124
Сказал спасибо: 116
Сказали Спасибо 867 раз(а) в 614 сообщении(ях)
|
Re: Помощь в WinAvr
Сообщение от WartKert
|
Добрый день.
Тут понял чем дальше изучаеш программирование на С, тем больше понимаеш что надо изучать Asm.
|
Значит СИ ещё не для вас...
АСМ нужен только в двух случаях, критическое ограничение по размеру или по скорости, и "разбор полётов" в особо тяжёлых случаях, когда по другому - никак...
|
|
|
|
10.05.2011, 21:52
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
|
Re: Помощь в WinAvr
Сообщение от WartKert
|
Подскажите что можно поменять, или другую какую нибудь подсказку скажите.
|
Используйте стандартную _delay_us. Она кстати написана на ассемблере.
Только куда проще и эффективней, чем у Вас вышло
|
|
|
|
09.06.2011, 17:03
|
|
Частый гость
Регистрация: 12.07.2009
Сообщений: 22
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Помощь в WinAvr
Цитата:
|
if (Data_port == 0x7F)
{
#define Free_pin 7
} else if (Data_port == 0xBF)
{
#define Free_pin 6
}
|
Проблема в том, что почему-то всегда выполняется #define во 2 части условия (независимо от значения). Хотя если задать реальное значение (действие), то условие работает. Но #define всеравно исполняется, который идёт последний. Так возможно ли задать такой выбор?
|
|
|
|
09.06.2011, 17:47
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
|
Re: Помощь в WinAvr
Сообщение от WartKert
|
Но #define всеравно исполняется, который идёт последний. Так возможно ли задать такой выбор?
|
Нет. Это директива препроцессора. Заведите обычную переменную и присваивайте ей значение.
Код:
|
uint8_t Free_pin;
if (Data_port == 0x7F)
{
Free_pin = 7;
} else if (Data_port == 0xBF)
{
Free_pin = 6;
} |
|
|
|
|
09.06.2011, 18:06
|
|
Частый гость
Регистрация: 12.07.2009
Сообщений: 22
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Помощь в WinAvr
А если мне нужно чтобы эта переменная назначала выбор (например #if #elif). Насколько я знаю там только через #define ?
|
|
|
|
09.06.2011, 19:38
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
|
Re: Помощь в WinAvr
Сообщение от WartKert
|
А если мне нужно чтобы эта переменная назначала выбор (например #if #elif). Насколько я знаю там только через #define ?
|
Я не понял. Все директивы препроцессора используются компилятором во время сборки проекта. И #define и #if и #elif. Соответственно их параметр должен быть известен во время компиляции. Вы же читаете что то с порта. Естественно что считается - неизвестно.
Вы можете сделать дальше выбор и по значению переменной.
Код:
|
uint8_t Free_pin;
if (Data_port == 0x7F)
{
Free_pin = 7;
} else if (Data_port == 0xBF)
{
Free_pin = 6;
}
if(Free_pin == 6) {...}
// и т.д. |
Вообще непонятно что хотите. Попробуйте переформулировать вопрос.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 03:02.
|
|