токо при компиляции вылезли ошибки, я в личку отписался
CodeVision AVR в вопросах и ответах
Re: CodeVision AVR в вопросах и ответах
vitalik_1984 спасибо огромное
спс,есть же хорошие люди
токо при компиляции вылезли ошибки, я в личку отписался
токо при компиляции вылезли ошибки, я в личку отписался
- Реклама
-
maxim___71rus
- Родился
- Сообщения: 9
- Зарегистрирован: Пт май 04, 2012 17:31:06
Re: CodeVision AVR в вопросах и ответах
vitalik_1984 писал(а):И какую сигнатуру показывает? если не совпадает с must be: ,то значит не читает.возможно короткое замыкание между ногами мисо моси.
at90usb162 or at90usb82
Замыкания точно нету.
Re: CodeVision AVR в вопросах и ответах
Помогите пожалуйста решить задачу с UART. Посылает то, что нужно. Но когда приходит нужный ответ - все рубится и дальше ничего не происходит...Уже голову сломал, а причина наверняка банальная...
Как под спойлер засунуть не понял, прошу прощения
Спойлер
/Код: Выделить всё
/
void main(void)
{
// Declare your local variables here
char rxdata=0;
char i;
char j;
char p;
char xor=0;
char len;
char BUFFER_ADR=0;
xyu:
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=P State6=P State5=P State4=P State3=P State2=P State1=P State0=P
PORTB=0x01;
DDRB=0x00;
// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=P State5=P State4=P State3=P State2=P State1=P State0=P
PORTC=0x00;
DDRC=0x00;
DDRC.0=1;
// Port D initialization
// Func7=In Func6=In Func5=In Func4=Out Func3=Out Func2=Out Func1=Out Func0=In
// State7=P State6=P State5=P State4=1 State3=1 State2=1 State1=1 State0=T
PORTD=0xEE;
DDRD=0x1E;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
// 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;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2A output: Disconnected
// OC2B output: Disconnected
ASSR=0x00;
TCCR2A=0x00;
TCCR2B=0x00;
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-14: Off
// Interrupt on any change on pins PCINT16-23: Off
EICRA=
while (1)
{
PORTC.4=0;
PORTD.2=0;
PORTD.3=0;
while (!(PINB & (0x01)))
{
for (j=1;j<4;j++) //3 попытки связи
{
#asm("cli") //запр прерываний
delay_ms(300); //
UCSR0B &= ~(1<<3); //TxD als normalen Port schalten
PORTD.1=0; //TxD aus Low
delay_ms(25); //задержка
PORTD.1=1; //TxD auf High
UCSR0B |= (1<<3); //TxD wieder aktivieren
delay_ms(25);
UCSR0B &= ~(1<<4); // выкл-вкл приема (очистка буфера)
UCSR0B |= (1<<4); //
#asm("sei") //разреш прерываний
for (i=1;i<4;i++) //3 повтора команды
{
PORTD.2=1;
putchar (0xF4); // команда 21
putchar (0x03);
putchar (0x21);
putchar (0x3b);
putchar (0xed);
PORTD.2=0;
PORTD.3=1;
while ((rx_counter0)&&(BUFFER_ADR==0)) //пока счетчик буфера приема не пуст и адрес
{ //буфера команд равен 0
PORTD.3=0;
rxdata = getchar(); //принимаем байты
if (rxdata==0x4f) //если принят ответ
{
rx_buffer[BUFFER_ADR]=rxdata; //сохраняем в буфере команды
xor=rxdata; //начинаем считать ксумму
BUFFER_ADR++; //инкрементируем адрес буфера команд
}
}
if (BUFFER_ADR) break; //если принят ответ покидаем цикл повтора команд
delay_ms(1250); //иначе задежка
}
if (BUFFER_ADR) break; //если принят ответ покидаем цикл повтора попыток уст связи.
}
while (BUFFER_ADR==0) //если ничего не получено
{
for(i=1;i<10;i++)
{
PORTD.2=1; //сигнализируем миганием 0,5сек
delay_ms (250);
PORTD.2=0;
delay_ms (250);
}
goto xyu;
}
rx_buffer[BUFFER_ADR]=getchar(); //принимаем второй байт (длина команды)
len=rx_buffer[BUFFER_ADR]; //сохраняем
xor=xor^rx_buffer[BUFFER_ADR]; //счтаем ксумму
BUFFER_ADR++; //инкрементируем адрес буфера команд
for (p=1;p<len;p++) //принимаем следующие len-1 байт
{
rx_buffer[BUFFER_ADR]=getchar();
xor=xor^rx_buffer[BUFFER_ADR];
BUFFER_ADR++;
}
rx_buffer[BUFFER_ADR]=getchar(); //принимаем байт ксуммы
//if (xor==0xd6){PORTC.0=0;}
if (xor!=rx_buffer[BUFFER_ADR]) //если суммы не совпадают
{
for (j=1;j<20;j++)
{
PORTD.2=1; //сигнализируем миганием 0,1сек
delay_ms (100);
PORTD.2=0;
delay_ms (100);
}
BUFFER_ADR=0;
goto xyu;
}
PORTC.0=1;
while (!(PINB & (0x01)))
{
putchar (0xF4); //пока есть питание
putchar (0x04);
putchar (0x44); //посылаем подтверждения каждые 15сек
putchar (0x21);
putchar (0x00);
putchar (0x95);
//PORTC.2=1;
PORTD.3=1; //сигнализируем миганием 15сек
delay_ms(250);
PORTD.3=0;
delay_ms(2000);
//PORTC.2=0;
while (rx_counter0) rxdata=getchar(); //очищаем буфер приема
}
//отключение
delay_ms(1000);
PORTD.2=1;
putchar (0xF4);
putchar (0x02);
putchar (0x10);
putchar (0xE6);
delay_ms(1000);
while (rx_counter0) rxdata=getchar(); //очищаем буфер приема
PORTD.3=1;
delay_ms(120000);
BUFFER_ADR=0;
PORTC.0=0;
}
}
}Как под спойлер засунуть не понял, прошу прощения
Последний раз редактировалось idadron Пн май 14, 2012 11:54:44, всего редактировалось 2 раза.
- vitalik_1984
- Поставщик валерьянки для Кота
- Сообщения: 2482
- Зарегистрирован: Пт авг 27, 2010 05:57:06
- Откуда: Тюмень
- Контактная информация:
Re: CodeVision AVR в вопросах и ответах
под спойлер то одно дело не понял,но нафига нам пустая инициализация типа portb=0x00;???
для справки спойлеры добавляются вручную пишем
или тут копируем и сохраняем в блокноте.
а по делу пока заметил,что в коде каша- переменные вперемешку с функциями.
те глобальные переменные,что используются не в одном месте нужно объявлять как volatile.и что это у вас тут за матерные метки
для справки спойлеры добавляются вручную пишем
Код: Выделить всё
[spoiler][/spoiler]или тут копируем и сохраняем в блокноте.
а по делу пока заметил,что в коде каша- переменные вперемешку с функциями.
те глобальные переменные,что используются не в одном месте нужно объявлять как volatile.и что это у вас тут за матерные метки
Код: Выделить всё
char xor=0;
char len;
char BUFFER_ADR=0;
xyu:
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_S
В поисках истины человек развивается.
Re: CodeVision AVR в вопросах и ответах
vitalik_1984 писал(а):те глобальные переменные,что используются не в одном месте нужно объявлять как volatile.
Немножко не так. Использоваться они могут где угодно и сколько угодно. Другое дело - как. К примеру, читать их можно до бесконечности, при этом volatile не нужен. А вот если они могут быть модифицированы в прерываниях или при обращении к периферии (портам) - тут уж надо быть осторожным. Квалификатор volatile не позволит компилятору оптимизировать код с этой переменной на свое усмотрение. И не больше.
http://www.pic24.ru/doku.php/osa/articles/volatile_for_chainiks
vitalik_1984 Это не тебе, ты наверняка уже из этих штанишек вырос
С уважением,
Виктор.
Виктор.
- Реклама
Re: CodeVision AVR в вопросах и ответах
Обнаружил в КВ такую вещь, как идентификация причины ресета мк. Вот код, который выдвает мастер кода
Прописал обработчики каждого if. Возникли вопросы. External Reset - выключает мк при каждом включении питания. Какой тогда смысл в вышерпиведенном куске кода? И еще, последняя ветвь
подразумевает, что если нет вышестоящих ресетов, то при включении питания стопроцентно выполнится код, вписанный как для сброса по причине сторожевого таймера.. Кто может объяснить, в чем тут смысл?
Код: Выделить всё
// Reset Source checking
if (MCUCSR & 1) // Power-on Reset
MCUCSR=0;
// Place your code here }
else if (MCUCSR & 2) {
// External Reset
MCUCSR=0;
// Place your code here }
else if (MCUCSR & 4) {
// Brown-Out Reset
MCUCSR=0;
// Place your code here }
else {
// Watchdog Reset
MCUCSR=0;
// Place your code here }Прописал обработчики каждого if. Возникли вопросы. External Reset - выключает мк при каждом включении питания. Какой тогда смысл в вышерпиведенном куске кода? И еще, последняя ветвь
else {
// Watchdog Reset
подразумевает, что если нет вышестоящих ресетов, то при включении питания стопроцентно выполнится код, вписанный как для сброса по причине сторожевого таймера.. Кто может объяснить, в чем тут смысл?
Re: CodeVision AVR в вопросах и ответах
vitalik_1984 писал(а):под спойлер то одно дело не понял,но нафига нам пустая инициализация типа portb=0x00;???
для справки спойлеры добавляются вручную пишемКод: Выделить всё
[spoiler][/spoiler]
или тут копируем и сохраняем в блокноте.
а по делу пока заметил,что в коде каша- переменные вперемешку с функциями.
те глобальные переменные,что используются не в одном месте нужно объявлять как volatile.и что это у вас тут за матерные меткиКод: Выделить всё
char xor=0;
char len;
char BUFFER_ADR=0;
xyu:
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_S
Каша - это работа код виззарда...а почему программа стопорится при приеме соответствующега байта? где я не углядел?
У меня сейчас голова лопнет...с передачей я разобрался, все работает. А вот с приемом понять не могу! Помогите примером пожалуйста! Допустим, в ответ пришло это 4f 03 a1 3b d6. Мне не интересен весть пакет, мне нужен только XOR, в данном примере d6. Как мне написать чтобы программа отреагировала именно на этот XOR?
Спустя час разобрался с проблемой приема, теперь весь код приведенный выше работает полностью, на плате тоже. Только выяснилась другая проблема. На мой взгляд чуть сложнее
Когда принят ответ, начинающийся с 4f, считается XOR всей посылки и программа продолжается если он правильный. Но это несколько не правильно, ведь не зависимо от того, что принято (какая посылка) XOR все равно посчитается верным и программа продолжится... а мне нужно чтобы программа продолжалась только при определенной принятой посылке...я наверное уже достал Вас своими вопросами
- vitalik_1984
- Поставщик валерьянки для Кота
- Сообщения: 2482
- Зарегистрирован: Пт авг 27, 2010 05:57:06
- Откуда: Тюмень
- Контактная информация:
Re: CodeVision AVR в вопросах и ответах
R_ura писал(а): Кто может объяснить, в чем тут смысл?
Видать потому, что никаких других причин для сброса в МК не существует...
idadron писал(а):Каша - это работа код виззарда
А засунуть на форум эту кашу это ваша работа!
idadron писал(а):Как мне написать чтобы программа отреагировала именно на этот XOR?
например сделать массив и проверять пятый по счету элемент массива.
Только чтобы точно определять, что это именно пятый элемент нужно придумать протокол, по которому осуществляется посылка/прием.
В поисках истины человек развивается.
Re: CodeVision AVR в вопросах и ответах
Извиняюсь за кашу
Решил проблему так
работает
Решил проблему так
Код: Выделить всё
while ((rx_counter0)&&(BUFFER_ADR==0)) //пока счетчик буфера приема не пуст и адрес буфера команд равен 0
{
rxdata = getchar(); //принимаем байты
if (rxdata==0x4f) //если принят ответ
{
rx_buffer[BUFFER_ADR]=rxdata; //сохраняем в буфере команды
xor=rxdata; //начинаем считать ксумму
BUFFER_ADR++; //инкрементируем адрес буфера команд
}
}Код: Выделить всё
rx_buffer[BUFFER_ADR]=getchar(); //принимаем второй байт (длина команды)
len=rx_buffer[BUFFER_ADR]; //сохраняем
xor=xor^rx_buffer[BUFFER_ADR]; //счтаем ксумму
BUFFER_ADR++; //инкрементируем адрес буфера команд
for (p=1;p<len;p++) //принимаем следующие len-1 байт
{
rx_buffer[BUFFER_ADR]=getchar();
xor=xor^rx_buffer[BUFFER_ADR];
BUFFER_ADR++;
}
rx_buffer[BUFFER_ADR]=getchar(); //принимаем байт XOR
if (xor!=0xd6) //если XOR не совпадает с XOR ответа на командуработает
Re: CodeVision AVR в вопросах и ответах
vitalik_1984 писал(а):
Видать потому, что никаких других причин для сброса в МК не существует...
Вроде как програмно можно перепрыгнуть на Ресет..
Все же не понял, как можно использовать эту, в общем-то полезную фичу, если при каждом включении питания она находит внешний ресет? Как это обойти?
- vitalik_1984
- Поставщик валерьянки для Кота
- Сообщения: 2482
- Зарегистрирован: Пт авг 27, 2010 05:57:06
- Откуда: Тюмень
- Контактная информация:
Re: CodeVision AVR в вопросах и ответах
idadron писал(а):работает
Это в одном конкретном случае, а вообще это быдлокод какой то...
участок пересмотрите
Код: Выделить всё
rx_buffer[BUFFER_ADR]=getchar(); //принимаем байт XOR
if (xor!=0xd6) //если XOR не совпадает с XOR ответа на команду Если вы приняли ХОР зачем вы пишете сравнивать посчитанный ХОР с константой????
И еще можно добавить синронизацию сигналов типа вдруг начало посылки не совпало с началом приема или средние байты были утеряны и программа все ждет последних байт, в это время на другом конце провода устройство начинает посылать следующие данные.
В общем это дело нужно как то обработать.
R_ura писал(а):Все же не понял, как можно использовать эту, в общем-то полезную фичу, если при каждом включении питания она находит внешний ресет? Как это обойти?
Это никак не нужно обходить.Каждый флаг сброса устанавливается аппаратно и не снимается до отключения питания.
Чтобы продолжить пользоваться флагами при работе, нужно программно сбросить эти флаги
Для этого КВ добавляет в код
Код: Выделить всё
else if (MCUCSR & 4) {
// Brown-Out Reset
MCUCSR=0; <<<<----------ВОТ ЭТУ СТРОЧКУ
// Place your code here } Тема где это обсуждалось
В поисках истины человек развивается.
Re: CodeVision AVR в вопросах и ответах
Я сравниваю с константой, потому что именно этот XOR меня и интересует. Ответ может прийти любой другой, их почти 96штук, длинной до 16 байт. Из них всех мне нужна только одна посылка, ее XOR d6. Мне показалось сделать проще так, чем выводить каждый принятый байт из буфера и собирать из них принятую команду. Я могу ошибаться, но на данном этапе меня это устроило. В таком виде уже чудесно работает на плате.
Глупый вопрос, это BUFFER_ADR=0; команда очистки буфера приема? или я ошибаюсь?
Или это очистка while ( !(UCSRA & (1 << UDRE)) ); ? Или это rx_counter=0; ?
Извиняюсь за такое количество глупых вопросов, неделю назад я вообще не представлял как писать программы для МК
Глупый вопрос, это BUFFER_ADR=0; команда очистки буфера приема? или я ошибаюсь?
Извиняюсь за такое количество глупых вопросов, неделю назад я вообще не представлял как писать программы для МК
- vitalik_1984
- Поставщик валерьянки для Кота
- Сообщения: 2482
- Зарегистрирован: Пт авг 27, 2010 05:57:06
- Откуда: Тюмень
- Контактная информация:
Re: CodeVision AVR в вопросах и ответах
вообще то контрольная сумма может быть такой же и у другой команды.
может быть даже такое,что при самой команде может быть это же число.и в один прекрасный момент может выйти,что программа ошибочно посчитает,что это контрольная сумма.
BUFFER_ADR=0; в вашем случае это обнуление счетчика принятых байт.а сам буфер останется на месте,пока вы его не перезапишете.
можно для очистки использовать
правда такая конструкция работает,только если принятые байты не равны нулю.
может быть даже такое,что при самой команде может быть это же число.и в один прекрасный момент может выйти,что программа ошибочно посчитает,что это контрольная сумма.
BUFFER_ADR=0; в вашем случае это обнуление счетчика принятых байт.а сам буфер останется на месте,пока вы его не перезапишете.
можно для очистки использовать
Код: Выделить всё
BUFFER_ADR=0;
while(rx_buffer[BUFFER_ADR]){rx_buffer[BUFFER_ADR]=0;}
В поисках истины человек развивается.
Re: CodeVision AVR в вопросах и ответах
Сделал так:
Вроде так по даташиту. Завтра проверю, надеюсь заработает...А что Вы думаете по этому поводу?
По поводу XOR, вероятность совпадения XOR очень мала в принципе, не даром ее часто используют для сравнения данных. Но она есть конечно. В моем случае этот XOR больше не повторяется. В самих посылках есть пару раз такой байт. Но для этого я написал именно алгоритм счета XOR посылки, а не просто ловить в буфере этот байт.
Код: Выделить всё
void USART_Flush()
{
unsigned char dummy;
while ( UCSR0A & (1<<RXC0) ) dummy = UDR0;
} Код: Выделить всё
USART_Flush();Вроде так по даташиту. Завтра проверю, надеюсь заработает...А что Вы думаете по этому поводу?
По поводу XOR, вероятность совпадения XOR очень мала в принципе, не даром ее часто используют для сравнения данных. Но она есть конечно. В моем случае этот XOR больше не повторяется. В самих посылках есть пару раз такой байт. Но для этого я написал именно алгоритм счета XOR посылки, а не просто ловить в буфере этот байт.
- urry
- Сверлит текстолит когтями
- Сообщения: 1262
- Зарегистрирован: Пн дек 08, 2008 10:58:48
- Откуда: Винница
- Контактная информация:
Re: CodeVision AVR в вопросах и ответах
неправильно циклить, тем более в прерывании.
Кусок моего кода.
Кусок моего кода.
- Вложения
-
- test.c
- (5.5 КБ) 226 скачиваний
- __Alexander
- Потрогал лапой паяльник
- Сообщения: 335
- Зарегистрирован: Вт сен 11, 2007 10:27:08
- Откуда: Киев
Re: CodeVision AVR в вопросах и ответах
idadron писал(а):Помогите пожалуйста решить задачу с UART. Посылает то, что нужно. Но когда приходит нужный ответ - все рубится и дальше ничего не происходит...Уже голову сломал, а причина наверняка банальная...Код: Выделить всё
#asm("cli") //запр прерываний
delay_ms(300); //
UCSR0B &= ~(1<<3); //TxD als normalen Port schalten
PORTD.1=0; //TxD aus Low
delay_ms(25); //задержка
PORTD.1=1; //TxD auf High
UCSR0B |= (1<<3); //TxD wieder aktivieren
delay_ms(25);
}
K-LINE detected
Кстати, CRC это не XOR, а просто сложение.
Re: CodeVision AVR в вопросах и ответах
Ну да, K-line, я же не скрывал
контрольных сумм много разных бывает. Тут именно XOR (сложение по модулю).
Re: CodeVision AVR в вопросах и ответах
Помогите сделать функцию. Есть участок программы ,часто повторяющийся, в котором меняется порт(PORTn), вывод порта, направление порта (т е DDRn) и необходимо считывать состояние порта(PINn), хотелось бы сделать функцию, но как сделать чтоб параметрами функции были регистры PORTn,DDRn и PINn сие большой вопрос есть?
Re: CodeVision AVR в вопросах и ответах
Правильнее будет определить макрос. Экономия места, стека данных и времени выполнения.Dimon4ir писал(а):Помогите сделать функцию. Есть участок программы ,часто повторяющийся, в котором меняется порт(PORTn), вывод порта, направление порта (т е DDRn) и необходимо считывать состояние порта(PINn), хотелось бы сделать функцию, но как сделать чтоб параметрами функции были регистры PORTn,DDRn и PINn сие большой вопрос есть?
С уважением,
Виктор.
Виктор.
- vitalik_1984
- Поставщик валерьянки для Кота
- Сообщения: 2482
- Зарегистрирован: Пт авг 27, 2010 05:57:06
- Откуда: Тюмень
- Контактная информация:
Re: CodeVision AVR в вопросах и ответах
Насчет экономии места я бы поспорил.Если реально много раз меняется то никакой экономии мне кажется не будет.А остальное согласен экономится.
Кстати при включенной оптимизации размера КВ сам функции мастерит, так что не парьтесь насчет этого
Можно хоть двести макросов сделать, кв сделает двести вызовов 1 функции.Если больше трех раз повторяется фрагмент асма, то делает.Это видно в листинге.
Кстати при включенной оптимизации размера КВ сам функции мастерит, так что не парьтесь насчет этого
В поисках истины человек развивается.


