Страница 145 из 386
Re: Вопросы по С/С++ (СИ)
Добавлено: Ср мар 20, 2013 12:29:44
IM1
shads писал(а):У меня 6-ка выдает
Код:
x = 6, a = 3 (как и в 4-ке. IM1 проверь еще раз у себя, скорее всего у тебя ошибка)
x = 2, a = 2 (в 4-ке было 2 и 3)
Странно. У нас с Вами вроде одна и та же сборка студии (судя по сообщению в соседней ветке).
Да, и наверное, стоит это воспринимать как некий казус и впредь не давать компилятору двусмысленных задач, и тогда все будет ОК.
Re: Вопросы по С/С++ (СИ)
Добавлено: Ср мар 20, 2013 13:19:13
Kavka
Выше написал же
http://radiokot.ru/forum/viewtopic.php? ... 9#p1619519 (см. подчёркнутое).
Язык допускает только такое
написание, но как оно должно работать
в стандарте не указано.
Re: Вопросы по С/С++ (СИ)
Добавлено: Ср мар 20, 2013 14:55:41
unalex
shads писал(а):Именно поэтому, в моем случае (первоначальном, с указателями), компилятор считает что я сравниваю данные под одним адресом, а они, по мнению компилятора не могут быть разными, и он просто вырезает условие (делает свое дело - оптимизирует)....
unalex писал(а):это называется оптимизация
зачем их сравнивать, если изначално понятно, что они указывают на одинаковые/разные объекты?
через 2 страницы выяснилось, что мои выводы подтвердились, что именно так и думает компилятор, обрабатывая эту строку кода
Совесть писал(а):Один нашел в этой строчке "одинаковые/разные объекты". Второй не разбираясь лепит "volatile". Браво!!!

браво, Совесть, как всегда ни слова по делу, ни строчки о том с чем связана проблема, а лишь попытки обгадить других
не очень удачный способ поднять свою самооценку
Re: Вопросы по С/С++ (СИ)
Добавлено: Ср мар 20, 2013 21:22:29
FreshMan
ограничен ли размер массива ?
вот что у меня выдает
http://www.imgup.ru/image-wpgx101141220.html
Re: Вопросы по С/С++ (СИ)
Добавлено: Ср мар 20, 2013 21:30:18
ibiza11
Не ограничен. Вы объявили массив содержащий 50 значений, а пытаетесь впихнуть в него больше чем 50. уберите число 50, оставьте только скобки []
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт мар 21, 2013 09:36:13
baron_P
Чтоб закрыть вопрос по этой программе:
Спойлер
Код: Выделить всё
#include<avr/io.h>
#define F_CPU 1200000UL
#include<util/delay.h>
int main(void)
{
unsigned long lfsr = 1;
unsigned char temp;
DDRB = 0xff;
while(1)
{
lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xd0000001u);
temp = (unsigned char) lfsr;
DDRB = ~temp;
PORTB = temp;
temp = (unsigned char) (lfsr >> 24);
_delay_loop_2(temp<<7);
}
}
В итоге получилось, что если заменить это
Код: Выделить всё
lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xd0000001u);
на это
Код: Выделить всё
lfsr = (lfsr >> 1) ^ ((lfsr & 1u) ? 0x80000057u : 0u);
, то генерируется примерно то же самое. На глаз на осциллограмме по крайней мере. Второе выражение - цитата из вики для конфигурации Галуа регистра сдвига с линейной обратной связью. В плане однозначности понимания, думаю, лучше вышло.
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт мар 21, 2013 13:06:09
Goldsmith
baron_P писал(а):В плане однозначности понимания, думаю, лучше вышло.
С моей точки зрения - намного лучше. И логика понятна (ушли шарады вроде беззнаковых чисел со знаком "минус"), и машиннозависимых выкрутасов нет.
Я бы еще заменил типы переменных на те, имена которых явно подчеркивают разрядность, например,
uint32_t. Для битовых операций нагляднее.
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт мар 21, 2013 13:07:09
shads
Ха.....
Эта библиотечка, которую я последнее время леплю, выдала мне столько сюрпризов в Си, что аж смешно уже.....
Очередной тупняк..... Нужно сравнить 2 элемента массива. Если так то все нормально.....
Код: Выделить всё
#include <avr/io.h>
char massiv [2] = {0,0};
int main (void)
{
if (massiv[0] == massiv[1])
PORTB = 0xff;
else
PORTB = 0x00;
}
Но если у меня условие, что байты массива должны быть инвертированы относительно друг друга (одно из чтений массива инвертирую), то результат сравнения всегда отрицательный.....
Код: Выделить всё
#include <avr/io.h>
char massiv [2] = {0x00, 0xff};
int main (void)
{
if (~massiv[0] == massiv[1])
PORTB = 0xff;
else
PORTB = 0x00;
}]
Оказывается компиль на этот раз, байтовые данные массива - превращает в двубайтовые
Естественно что при инверсии считанного байта инвертируется и добавленный компилятором 0 (хотя в другом числе он остается 0-м), в результате сравнение всегда имеет отрицательный результат
Код: Выделить всё
+00000027: 91200060 LDS R18,0x0060 Load direct from data space
+00000029: E030 LDI R19,0x00 Load immediate
+0000002A: 9520 LAT R18 Load and Toggle
+0000002B: 9530 LAT R19 Load and Toggle
+0000002C: 91800061 LDS R24,0x0061 Load direct from data space
+0000002E: E090 LDI R25,0x00 Load immediate
+0000002F: 1728 CP R18,R24 Compare
+00000030: 0739 CPC R19,R25 Compare with carry
+00000031: F419 BRNE PC+0x04 Branch if not equal
7: PORTB = 0xff;
+00000032: EF8F SER R24 Set Register
+00000033: BB88 OUT 0x18,R24 Out to I/O location
+00000034: C001 RJMP PC+0x0002 Relative jump
9: PORTB = 0x00;
+00000035: BA18 OUT 0x18,R1 Out to I/O location
10: }
+00000036: E080 LDI R24,0x00 Load immediate
+00000037: E090 LDI R25,0x00 Load immediate
+00000038: 9508 RET Subroutine return
ВОПРОС..... КАКОЙ СТАНДАРТ Я НА ЭТОТ РАЗ НАРУШИЛ
PS решается опять с помощью доп переменной.....
Код: Выделить всё
#include <avr/io.h>
char massiv [2] = {0x00, 0xff};
int main (void)
{
char temp = ~massiv[0];
if (temp == massiv[1])
PORTB = 0xff;
else
PORTB = 0x00;
}
Код: Выделить всё
+00000027: 91800060 LDS R24,0x0060 Load direct from data space
+00000029: 9580 LAT R24 Load and Toggle
+0000002A: 91900061 LDS R25,0x0061 Load direct from data space
+0000002C: 1789 CP R24,R25 Compare
+0000002D: F419 BRNE PC+0x04 Branch if not equal
8: PORTB = 0xff;
+0000002E: EF8F SER R24 Set Register
+0000002F: BB88 OUT 0x18,R24 Out to I/O location
+00000030: C001 RJMP PC+0x0002 Relative jump
10: PORTB = 0x00;
+00000031: BA18 OUT 0x18,R1 Out to I/O location
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт мар 21, 2013 13:42:44
Goldsmith
shads писал(а):ВОПРОС..... КАКОЙ СТАНДАРТ Я НА ЭТОТ РАЗ НАРУШИЛ

Например,
ISO/IEC 9899:1999, п.
6.3.1.1 Boolean, characters, and integers:
2 The following may be used in an expression wherever an int or unsigned int may be used:
— An object or expression with an integer type whose integer conversion rank is less than the rank of int and unsigned int.
— A bit-field of type _Bool, int, signed int, or unsigned int.
If an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. All other types are unchanged by the integer promotions.
Перед инвертированием значение элемента массива "продвигается" до
int, а затем инвертируется. Само собой, результат не совпадает с тем, который ожидали увидеть.
Добавьте явное преобразование типов:
Код: Выделить всё
if ((unsigned char)~massiv[0] == massiv[1])
, и не придется добавлять лишнюю переменную.
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт мар 21, 2013 13:49:13
shads
thank you very much

Вопросы по С/С++ (СИ)
Добавлено: Чт мар 21, 2013 16:38:50
Alkarax
Здравствуйте! Я недавно заинтересовался микроконтроллерами и появилось желание сделать ик приемник и передатчик, схему-то я сделал, а вот с прошивкой возникли проблемы, пытаясь понять алгоритм передачи и приема ик сигнала перелопатил кучу инфы, но все было не то, но вот наткнулся на очень доступное объяснение, но команды тут мне не очень понятны. СИ я знаю так себе и привык к коду вида как в codevision. Не могли бы вы перевести данную програмку в вид попроще, например: TCCR1A = (1<<COM1A1) | (1<<COM1A0) | (1<<WGM11); - TCCR1A=0b11000010 или хотя бы объяснить каждую строчку предельно упрощенно
//36kHz Trager
TCCR1A = (1<<COM1A1) | (1<<COM1A0) | (1<<WGM11);
TCCR1B = (1<<WGM12) | (1<<WGM13) | (1<<CS10);
OCR1A = 111;
ICR1 = 222;
//Прерывание таймера каждые 2,048 ms для генерации сигнала --> 1/(8MHz/256/64)
TCCR0 = (1<<CS01) | (1<<CS00);
TIMSK |= (1<<TOIE0);
//Реализация сканирования
//Прерывание таймера каждые 0,256ms для приема сигнала --> 1/(8MHz/256/8)
TCCR0 |= (1<<CS01);
TIMSK |= (1<<TOIE0);
ISR передатчика должен на определенное время подавать несущую на передатчик. Длительность определяется переменной pulse. Переменная empty служит функции передачи в качестве индикатора того, продолжается ли процесс передачи или уже завершен. Таким образом предотвращается изменение переменной pulse во время процесса передачи.
volatile unsigned char empty = 0;
volatile unsigned char pulse = 0;
SIGNAL (SIG_OVERFLOW0) {
if (pulse) {
DDRB |= (1<<PB1);
empty = 1;
pulse--;
}
if (!pulse) {
empty = 0;
DDRB &= ~(1<<PB1);
}
}
void ir_send (unsigned char byte) {
if (!empty)
pulse = byte;
}
ISR приемника должна ожидать, пока на выходе TSOP не появится сигна низкого уровня. Если это произошло, то можно начинать процесс сканирования длины импульсов. В зависимости от длины импульса сигнал может интерпретироваться как та или иная команда. Количество команд может быть увеличено в любой момент за счет применения импульсов другой длины, здесь же для наглядности используется набор из двух команд.
volatile unsigned short timecount = 0;
volatile unsigned char empty = 0;
volatile unsigned char rec_byte = 0;
SIGNAL (SIG_OVERFLOW0) {
//------------
if (!(PINB & (1<<PB0))) { //Low-Pegel = log. 1 am Sender
timecount++;
empty = 1;
}
else
empty = 0;
if ((!empty) && (timecount)) {
//----------- //8fache Abtastung
if ((timecount > 70) && (timecount < 90)) { //pulse war 10
rec_byte = 10;
}
if ((timecount > 150) && (timecount < 170)) { //pulse war 20
rec_byte = 20;
}
timecount = 0;
}
}
unsigned char ir_receive (void) {
//Empfangsroutine
return rec_byte;
}
особенно интересую строчки типа: TIMSK |= (1<<TOIE0); как будет выглядеть весь байт целивом
DDRB &= ~(1<<PB1); "&= ~"- что это значит? как байт порта B будет выглядеть после этой манипуляции?
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт мар 21, 2013 22:03:36
shads
Alkarax писал(а):Здравствуйте!
появилось желание сделать ик приемник и передатчик
Привет.
Прикол в том, что предыдущие пару страниц, я мучил народ тоже по поводу библиотечки обработки ИК канала.....
Решил свою смастерить, стандарта NEC, все уже работает, мелочи остались..... поделюсь если что.
А так по теме:
Alkarax писал(а):Не могли бы вы перевести данную програмку в вид попроще, например: TCCR1A = (1<<COM1A1) | (1<<COM1A0) | (1<<WGM11)
var = (1<<X) oзначает загрузку в var числа с установленным в 1 битом под номером X (X может быть от 0 до 7)
Например, выражение var = (1<<5)|(1<<7) - будет эквивалентно выражению var = 0b10100000.
В твоем случае выражение типа TCCR1A = (1<<COM1A1) | (1<<COM1A0) | (1<<WGM11) означает что в регистр TCCR1A будет загружено число с установленными битами COM1A1, СOM1A0, WGM11. Эти названия битов, где то задефайнены во включаемых библиотеках.
Alkarax писал(а):особенно интересую строчки типа: TIMSK |= (1<<TOIE0); как будет выглядеть весь байт целивом
Это выражение равнозначно TIMSK = TIMSK | (1<<TOIE0); т.е. установить (знак |) в регистре TIMSK бит с названием TOIE0, а остальные не трогать.
Alkarax писал(а):DDRB &= ~(1<<PB1);
Это выражение равнозначно TIMSK = TIMSK & ~(1<<PB1)
такая комбинация (& и ~) означает, что надо сбросить в регистре TIMSK бит с названием PB1, а остальные не трогать.....
Вообще то это описывается в любом пособии по Си, надо вникать, ато замучишся вопросы задавать, и других замучиш....

Тут если что почитай:
http://www.helloworld.ru/texts/comp/lang/c/c/dir.htm
или тут:
http://lib.ru/MAN/DEMOS210/c.txt
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт мар 21, 2013 22:50:08
Alkarax
Больше спасибо буду разбираться! Дело в том, что когда я учил си эти же операции делались совсем другими командами, то есть смысл их я написать могу, но выглядеть будет подругому, печально, но кожется придется переучивать.
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт мар 21, 2013 23:04:20
shads
Да вроде Си он и в африке Си, и не меняется со временем.....
Например, практически все ответы на твои вопросы, можно найти тут
http://www.helloworld.ru/texts/comp/lang/c/c/h13.htm
в табличке 7 описания, а дальше примерчики идут.....
Re: Вопросы по С/С++ (СИ)
Добавлено: Вс мар 24, 2013 19:55:08
vladimersv
здравствуйте .
в програмировании я неочень разбераюсь ,вот возможно помжете .
имеется кусок кода :
void RUN_HOLD(void)
{
if(ButtonsBits == UP){ pnt_gOSC_MODE->Condition = RUN; btn->Text = "RUN"; }
else if(ButtonsBits == DOWN){ pnt_gOSC_MODE->Condition = HOLD; btn->Text = "HOLD";
}
else if(ButtonsBits == OK){ pnt_gOSC_MODE->Condition = HOLD; btn->Text = "HOLD"}
}
тоесть две кнопки переключают вверх-вниз -работаю нормально и есть 3я кнопка -ОК ,тоесть она при нажатии дублирует -вниз сейчас.
подскажите как правельно написать чтобы и влево-вправо остались как есть (тоесть их функции работы ) а вот кнопкой- ОК можно было переключать их также .(тоесть при разовом нажатии срабатывало как нажатие -вниз,а при повторном -вверх )
зарание спасибо .
Re: Вопросы по С/С++ (СИ)
Добавлено: Вс мар 24, 2013 20:47:38
Аlex
Re: Вопросы по С/С++ (СИ)
Добавлено: Вс мар 24, 2013 21:44:38
vitalik_1984
vladimersv писал(а):здравствуйте .
в програмировании я не_очень разбИраюсь ,вот возможно помОжете .
имеется кусок кода :
то_есть две кнопки переключают вверх-вниз -работаюТ нормально и есть 3я кнопка -ОК ,то_есть она при нажатии дублирует -вниз сейчас.
подскажите как правИльно написать чтобы и влево-вправо остались как есть (то_есть их функции работы ) а вот кнопкой- ОК можно было переключать их также .(то_есть при разовом нажатии срабатывало как нажатие -вниз,а при повторном -вверх )
заранЕе спасибо .
Честно говоря глаза кровью облились от режущего обилия ошибок в тексте.
Теперь по теме.
1. Непонятно назначение кнопки ОК зачем нужно дублирование вверх и вниз.
2.Приведенный кусок можно обработать через switch визуально понятнее выглядит.
Код: Выделить всё
void RUN_HOLD(void)
{
switch (ButtonsBits){
case(UP): pnt_gOSC_MODE->Condition = RUN; btn->Text = "RUN";break;
case(DOWN): pnt_gOSC_MODE->Condition = HOLD; btn->Text = "HOLD";break;
case(OK): pnt_gOSC_MODE->Condition = HOLD; btn->Text = "HOLD";break;
}
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн мар 25, 2013 00:36:46
vladimersv
за ошибки извеняюсь(вобщемто клавивиатура без руских почти) .
просто стояли в схеме 2 кнопки но поставил одну на 3 положения (тоесть вверх-вниз по меню они и при нажатии замыкает внутренняя -ОК ) тоесть при наведении в меню на кнопку RUN-HOLD нет теперь надобности влючать -отключать функцию кнопками верх-вниз а достаточно просто одним нажатием кномки ОК переключать .(но и изьять из меню фунции кнопок вверх-вниз нельзя ,это лично у меня просто кнопка на 3 положения )
за ответ и пример огромное спасибо ,попробую.
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн мар 25, 2013 00:39:59
unalex
Код: Выделить всё
void RUN_HOLD(void)
{
static unsigned char Last = UP;
unsigned char State;
State = ButtonBits;
switch(State)
{
case(OK):
State = (Last == DOWN) ? UP : DOWN;
Last = State;
case(UP):
pnt_gOSC_MODE->Condition = RUN; btn->Text = "RUN"; break;
case(DOWN):
pnt_gOSC_MODE->Condition = HOLD; btn->Text = "HOLD"; break;
}
}
как-то перекак-то так
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн мар 25, 2013 00:41:59
unalex
vladimersv писал(а):за ошибки извеняюсь(вобщемто клавивиатура без руских почти)
а у меня клавиатура без русских ВООБЩЕ(интересно а как это без русских ПОЧТИ)
печатаю методом тыка, но это не мешает мне писать грамотно