Еще один вопрос. Приобрел дальномер HC-SR04 и никак не могу заставить работать. Слышно что пьезоэлемент издает звуки, но результата нет - то есть, если раскоментировать строку "_delay_us(1);" в цикле ожидания то А=1. Если закоментировать, то изменяется, но показывает значения 530-540 не зависимо от расстояния, а если закрыть приемник или передатчик то =1, хотя должно быть наибольшее число, так как по даташиту, если расстояние слишком велико то выдает импульс длиной 38мс. Попробовал с другим датчиком - результат тот же. Что не так делаю? Т_Т
Datasheet: http://www.micropik.com/PDF/HCSR04.pdf
...
SETBIT(DDRD,7);//TRIG OUT
CLEARBIT(DDRD,6);//ECHO IN
//SETBIT(PORTD,6);//pull-up
while(1)
{
long int A=0;
CLEARBIT(PORTD,7);
_delay_ms(1);
SETBIT(PORTD,7);//TRIG go HIGH
_delay_us(10);//wait
CLEARBIT(PORTD,7);//TRIG go LOW
while(bit_is_clear(PORTD,6)){};//ждем высокий фронт на ECHO
do
{
A++;
//_delay_us(1);
}
while(bit_is_set(PORTD,6));//ждем низкий фронт на ECHO
//long distance_cm = A/29/2;
String1("Дист. %u",(unsigned int)A);
}
/*******************************************************
*******************************************************/
#include <mega128.h>
// Declare your global variables here
// Standard Input/Output functions
#include <stdio.h>
char arrey[6]="HELO!";
char index;
void USART_Transmit( unsigned char data );
interrupt [USART0_TXC] void USART_TXC(void)
{
UDR0 = arrey[index];
index++;
if(index>4){index=0;}
}
void USART_Transmit( unsigned char data )
{
/* Ожидание освобождения буфера передатчика */
while ( !( UCSR0A & (1<<UDRE0)) );
/* Помещение данных в буфер, отправка данных */
UDR0 = data;
}
void main(void)
{
// USART0 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART0 Receiver: On
// USART0 Transmitter: On
// USART0 Mode: Asynchronous
// USART0 Baud Rate: 9600
UCSR0A=(0<<RXC0) | (1<<TXC0) | (0<<UDRE0) | (0<<FE0) | (0<<DOR0) | (0<<UPE0) | (0<<U2X0) | (0<<MPCM0);
UCSR0B=(0<<RXCIE0) | (1<<TXCIE0) | (0<<UDRIE0) | (1<<RXEN0) | (1<<TXEN0) | (0<<UCSZ02) | (0<<RXB80) | (0<<TXB80);
UCSR0C=(0<<UMSEL0) | (0<<UPM01) | (0<<UPM00) | (0<<USBS0) | (1<<UCSZ01) | (1<<UCSZ00) | (0<<UCPOL0);
UBRR0H=0x00;
UBRR0L=0x33;
#asm("sei")
UCSR0A|= (1<<TXC0);
//USART_Transmit(6);
while (1)
{
// Place your code here
}
}
передаю массив arrey по прерыванию по завершению передачи uartа
Не как не могу понять почему сразу прерывание не начинается вроде бы все условия сделал.
из даташита
Разряд 7 - RXCIEn: Разрешение прерывания по завершению приема
Запись в данный бит лог. 1 разрешает прерывание по флагу RXCn. Прерывание по
завершению приема УСАППn генерируется, если RXCIEn=1, флаг общего разрешения
прерываний I=1 (в регистре SREG), а также установлен бит RXCn в регистре UCSRnA.
а прерывание так и нету если раскоментировать строчку //USART_Transmit(6); то сначала передастся 6 а после уже и прерывания начнутся но почему ?
как правильно сделать управлением передачей ? Думал сделать по флагу TXC0 изначально установил в ноль записал в массив данные после установил флаг в единицу и по прерыванию массив передался.
Последний раз редактировалось pokk Пн авг 27, 2012 16:41:33, всего редактировалось 2 раза.
vitalik_1984. А смысл использовать прерывания и счетчики, если они также теоретически высчитывают время(т.е. настройки таймера), как и встроенная функция _delay_us/ms()(расчитывается исходя из частоты процессора). Дело в том что исходя из проведенного мною опыта выходит, что длина импульса не более 1мкс, а расстояние зависит от количества мкс импульса. Таким образом примитивным способом микросекунды можно высчитывать в цикле с инкерементом и задержкой в микросекунду
do
{
A++;
_delay_us(1);
}
while(bit_is_set(PORTD,6));//ждем низкий фронт на ECHO
Вот и проблема в том что программа выходит из цикла с А=1=> ошибочка где-то. Если убрать задержку, то как писал выше
изменяется, но показывает значения 530-540 не зависимо от расстояния, а если закрыть приемник или передатчик то =1, хотя должно быть наибольшее число, так как по даташиту, если расстояние слишком велико то выдает импульс длиной 38мс
Я могу и ошибаться, но пока аргументов для переосмысления и понимания ошибки в собственном размышлении и понимании не встретил =(
А смысл использовать прерывания и счетчики, если они также теоретически высчитывают время(т.е. настройки таймера), как и встроенная функция _delay_us/ms()(расчитывается исходя из частоты процессора).
...Таким образом примитивным способом микросекунды можно высчитывать в цикле с инкерементом и задержкой в микросекунду
Дело в том что если использовать цикл то процессор тратит на это своё время т.е он зависает в цикле и не может больше нечего делать.А если делать всё с помощью таймеров то как раз они то и считают(и выдают прерывания через нужное время) ,а то процессор освобождается и может параллельно выполнять что-нибудь нужное.
mr.boroda писал(а):Возможно ли на базе AVR сделать ph метр для аквариума? может схемы еть какие?
Электроды, действительно, непростые. Вообще, для полиграфии продаются pH-метры, разные, может быть проще купить. Причем, к ним могут даваться растворы для калибровки, с разными известными pH (например, 7 и 4). Некоторые pH метры должны храниться в специальном растворе.
А управляющую часть на чем угодно можно было бы сделать, AVR отлично подошли бы.
Добрый день. Микроконтроллер msp430. Среда разработки IAR. Хочу увеличить размер стека(по умолчанию 80). В options ставлю, к примеру, 100. Вылезают ошибки
Error[Pe136]: struct "<unnamed>" has no field "P4DIR_0"
Error[Pe136]: struct "<unnamed>" has no field "P4SEL_0"
Error[Pe136]: struct "<unnamed>" has no field "P4OUT_0"
Error[Pe136]: struct "<unnamed>" has no field "P4OUT_0"
Вроде народ стек увеличивал гораздо сильнее (чуть ли не до 500) и все было в порядке.
Заранее спасибо!
P.S. Вопрос решен. Пересборка прошла в другой версии IARа. Там объявляется как P4IN_bit.P0 и т.п. )))
Последний раз редактировалось Jukki Вт авг 28, 2012 08:06:46, всего редактировалось 1 раз.
Лютик писал(а):
но пока аргументов для переосмысления и понимания ошибки в собственном размышлении и понимании не встретил =(
То что товарищи советуют это по вашему не аргумент?Что же тогда вы тут ожидаете увидеть?
Могу обьяснить в чем ваша ошибка: когда вы делаете допущение, что в цикле все выполняется за два (или сколько там считаете)тактов вы ошибаетесь. Каждая команда в асм занимает минимум один такт контроллера. Посмотрите во что ваш код вылазит.Нужно для определения расстояния точно знать сколько времени прошло, только ТАЙМЕР позволяет одно и то же время перевести в одно и то же число.
Остальные варианты допустимы, но только с погрешностями.
Таким же образом пока вы делаете цикл делай_мс, вы никак не можете проверять состояние какого либо вывода.Вот и думайте как менять ваш код.
Дело в том что исходя из проведенного мною опыта выходит, что длина импульса не более 1мкс,
Сдается мне ваш опыт может быть ошибочным.Как вы делаете -осциллографом?
(c) я, конечно, как генерал тостов говорить не умею...
но режет глаз выражение
while(bit_is_set(PORTD,6));//ждем низкий фронт на ECHO
может, все-таки PIND ...
Нежданчики есть всегда, это понятно. Меня интересовало, нет ли каких-то проблем у Atmega16U4, которых могут сделать какое-то её применение невозможным или как-то серйозно повлиять.
urry писал(а):(c) я, конечно, как генерал тостов говорить не умею...
но режет глаз выражение
while(bit_is_set(PORTD,6));//ждем низкий фронт на ECHO
может, все-таки PIND ...
Лютик , так то urry прав, а то, что в макросе написано можете этим, простите, подтереться. Вообще там хоть что можно подписать.
Считайте что в макросе написано
эффект от этого макроса будет тот же а трактовать уже по другому можно.
можно и значение port читать, но это значение не меняется от внешних воздействий, только от действий контроллера.
Для чтения внешних сигналов всегда pin нужно читать.
Если в макросе написано port, это не значит, что писать надо всегда port. В какой переменной будем шевелить битами, то и пишем. port - это ПАРАМЕТР макроса, который нужно заменять на требуемое в теле программы. setbit(FLAGS,4) установит четвертый бит в переменной FLAG. setbit(DDRB,2) переключит второй разряд порта В на выход и т.д. PORT, PIN,DDR - это тоже переменные и используются при подстановке в макрос. А читаем состояние вывода мы всегда через регистр PIN.
Вообще-то это надо было прочитать перед тем, как садится писать программу. Иначе будет еще много неприятных неожиданностей.
pokk , прерывания в железе не возникают или в симуляторе?
Просто много раз сталкивался с глюками симулятора протеус, поэтому ничему не удивляюсь.
И находили глюки в симуляторе студии.
в протеусе не думаю что это его глюк т.к если раз комментировать строку //USART_Transmit(6);
то сначала передаётся 6 а после из массива всё улетает по прерываниям.