Вопросы по С/С++ (СИ)
- IfoR
- Поставщик валерьянки для Кота
- Сообщения: 2029
- Зарегистрирован: Сб ноя 15, 2008 10:09:56
- Откуда: г. Тула
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Ну и зачем для этого нужно выполнять одновременно две команды? И при чём здесь ШИМ? Просто выкидываете данные на порт и всё.
-
demiurg301
- Опытный кот
- Сообщения: 812
- Зарегистрирован: Ср мар 18, 2009 21:14:33
Re: Вопросы по С/С++ (СИ)
Подскажите а как разбить попроще тот же float или long int на байты.
Т.е. вижу два варианта через union и пошаговый сдвиг на 8. По идее же можно и указателями это сделать?
Просто использовал объединение. А с long int чот не правильно работает... А со сдвижкой правильно...
union LI2Byte
{
unsigned long int I;
unsigned char c[4];
} I32;
I32.I=x// в общем какое то число
Выводишь с[i] , а там несоответсвие. Хотя со сдвигом -(unsgined char) x>>24&0xFF и так далее работает...
Т.е. вижу два варианта через union и пошаговый сдвиг на 8. По идее же можно и указателями это сделать?
Просто использовал объединение. А с long int чот не правильно работает... А со сдвижкой правильно...
union LI2Byte
{
unsigned long int I;
unsigned char c[4];
} I32;
I32.I=x// в общем какое то число
Выводишь с[i] , а там несоответсвие. Хотя со сдвигом -(unsgined char) x>>24&0xFF и так далее работает...
-
Мастер Ломастер
- Поставщик валерьянки для Кота
- Сообщения: 1995
- Зарегистрирован: Ср май 11, 2011 21:37:45
- Откуда: Цветочный город
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
а вы порядок байтов не путаете? в AVR байты многобайтного числа размещены от младшего к старшему, т.е. c[0] будет младшим байтом, c[3] - старшим для long intdemiurg301 писал(а):Просто использовал объединение. А с long int чот не правильно работает... А со сдвижкой правильно...
битва с дураками проиграна, победители торжествуют. слава победителям!
-
demiurg301
- Опытный кот
- Сообщения: 812
- Зарегистрирован: Ср мар 18, 2009 21:14:33
Re: Вопросы по С/С++ (СИ)
ДЫк я б тогда это увидел. Я разлагал на байты, и высылал в порт. А на компе для проверки вручную переводил.
Т.е. если бы было 0x01 0x02 0x03 0x04 , а получилось 0x04 0x03 0x02 0x01 - я бы заметил
Но в частности меня больше интересует , а нельзя ил указателями разлагать, как бы взять указатель unsigned char от формата unsigned int - т.е. представить вручную, чтобы не использовать переходную переменную в виде 4х байтов. Часто нужно просто для вывода и записи в ПЗУ. А использовать конструкции вида
unsigned long int crcEEP
..............
crcEEP=*PtE++;
crcEEP|=(unsigned long int)*PtE++<<8;
crcEEP|=(unsigned long int)*PtE++<<16;
crcEEP|=(unsigned long int)*PtE++<<24;
Слишком много кода(одной строчкой вылазит за экран ) ... вот если б напрямую обращаться к байтам в памяти...
Т.е. если бы было 0x01 0x02 0x03 0x04 , а получилось 0x04 0x03 0x02 0x01 - я бы заметил
Но в частности меня больше интересует , а нельзя ил указателями разлагать, как бы взять указатель unsigned char от формата unsigned int - т.е. представить вручную, чтобы не использовать переходную переменную в виде 4х байтов. Часто нужно просто для вывода и записи в ПЗУ. А использовать конструкции вида
unsigned long int crcEEP
..............
crcEEP=*PtE++;
crcEEP|=(unsigned long int)*PtE++<<8;
crcEEP|=(unsigned long int)*PtE++<<16;
crcEEP|=(unsigned long int)*PtE++<<24;
Слишком много кода(одной строчкой вылазит за экран ) ... вот если б напрямую обращаться к байтам в памяти...
-
Мастер Ломастер
- Поставщик валерьянки для Кота
- Сообщения: 1995
- Зарегистрирован: Ср май 11, 2011 21:37:45
- Откуда: Цветочный город
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
не подойдет?кстати, по вашему коду создалось впечатление, что вы пытаетесь подсчитать побайтную контрольную сумму области памяти, занятой многобайтными переменным - так? так ведь зная общее число байт в этой области можно объявить указатель на байт, присвоить ему адрес начала области и перебрать все байты без каких-либо преобразований типов...
Код: Выделить всё
#define b0(x) ((x) & 0xFF)
#define b1(x) (((x) >> 8) & 0xFF)
#define b2(x) (((x) >> 16) & 0xFF)
#define b2(x) (((x) >> 24) & 0xFF)битва с дураками проиграна, победители торжествуют. слава победителям!
-
demiurg301
- Опытный кот
- Сообщения: 812
- Зарегистрирован: Ср мар 18, 2009 21:14:33
Re: Вопросы по С/С++ (СИ)
Мастер Ломастер писал(а):не подойдет?кстати, по вашему коду создалось впечатление, что вы пытаетесь подсчитать побайтную контрольную сумму области памяти, занятой многобайтными переменным - так? так ведь зная общее число байт в этой области можно объявить указатель на байт, присвоить ему адрес начала области и перебрать все байты без каких-либо преобразований типов...Код: Выделить всё
#define b0(x) ((x) & 0xFF)
#define b1(x) (((x) >> 8) & 0xFF)
#define b2(x) (((x) >> 16) & 0xFF)
#define b2(x) (((x) >> 24) & 0xFF)
ДА, чот не подумал. Просто не люблю дефайны
Не, это я считывал 32 битный CRC настроек модема из ПЗУ. Потом сравниваю с полученным из функции, для проверки подлинности, если не совпало - ещё 3 копии сохранено тамже... НУ и так 3 штуки подряд. А вот чо делать если все накроется
ЗЫ Дето я читал или может это так ложные мысли..
ЧТо например
unsigned int I;
unsigned char *PtS;
PtS=(unsigned char*)I - не вернёт ли такая запись указательна 1( ну или 4) байт инта?
-
Мастер Ломастер
- Поставщик валерьянки для Кота
- Сообщения: 1995
- Зарегистрирован: Ср май 11, 2011 21:37:45
- Откуда: Цветочный город
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
не вернет. а вот так - вернет:demiurg301 писал(а):unsigned int I;
unsigned char *PtS;
PtS=(unsigned char*)I - не вернёт ли такая запись указательна 1( ну или 4) байт инта?
Код: Выделить всё
PtS = (void*)&I;битва с дураками проиграна, победители торжествуют. слава победителям!
-
demiurg301
- Опытный кот
- Сообщения: 812
- Зарегистрирован: Ср мар 18, 2009 21:14:33
Re: Вопросы по С/С++ (СИ)
PtS = (void*)&I;
Это мы типа приводим тип указателя к указателю на структуру соответствующу разрядности контроллера? ( 8 битам)
-
alexey6522
- Встал на лапы
- Сообщения: 149
- Зарегистрирован: Чт июл 28, 2011 18:12:28
Re: Вопросы по С/С++ (СИ)
Блииин, помогите! Спаял схему, до этого тестил на протеусе все работало, а в действительности вообще не принимаются не передаются данные, даже признаков жизни не подается, что делать, где капать, может кроме двух проводков еще нужно что-нибудь, куда-нибудь припоять, задействовано только 2 и 3 контакты Atmega8, на COM1 тоже 2 и 3.
-
Мастер Ломастер
- Поставщик валерьянки для Кота
- Сообщения: 1995
- Зарегистрирован: Ср май 11, 2011 21:37:45
- Откуда: Цветочный город
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
говорил я товарищу avreal: стандарт хоть и велик, но не всем понятен, проще надо быть, на вещи смотреть ширше, а к людям - помякше... вот и результат: он вам на моем скорбном примере доказал-рассказал, что такое указатель и с чем его едят... извините, это лирическое отступление...demiurg301 писал(а):Это мы типа приводим тип указателя к указателю на структуру соответствующу разрядности контроллера? ( 8 битам)PtS = (void*)&I;
это указателю PtS присваивается значение адреса переменной I - не более, не менее. а приведение типа этого самого адреса к void* нужно лишь для того, чтобы компилятор не матюкался - отлично сработает и без этого, но с варнингом.PtS = (void*)&I;
битва с дураками проиграна, победители торжествуют. слава победителям!
-
demiurg301
- Опытный кот
- Сообщения: 812
- Зарегистрирован: Ср мар 18, 2009 21:14:33
Re: Вопросы по С/С++ (СИ)
Да понял , я понял
Не встречал просто конструкцию такую с void...
Он кстати и вот так не ругается
PtS=(unsigned char *)&I; - или это просто масло масленное?
А стандарт на английском, поди разбери чо они там пишут... Даже со знанием инглиша...
Не встречал просто конструкцию такую с void...
Он кстати и вот так не ругается
PtS=(unsigned char *)&I; - или это просто масло масленное?
А стандарт на английском, поди разбери чо они там пишут... Даже со знанием инглиша...
-
Мастер Ломастер
- Поставщик валерьянки для Кота
- Сообщения: 1995
- Зарегистрирован: Ср май 11, 2011 21:37:45
- Откуда: Цветочный город
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
если компилятор видит, что вы переменной типа char* присваиваете значение типа int* - он чувствует здесь подвох: вы ведь имеете указатель на байт, а задаете адрес двух байт. поэтому он делает warning. принудительное приведение к типу char* снимает проблему - теперь компилятор видит два одинаковых типа. а тип void* является универсальным - он СОВМЕСТИМ с любым типом указателя и компилятор никогда не будет на него ругаться, поэтому к void* можно приводить любой указатель.demiurg301 писал(а):Он кстати и вот так не ругается
PtS=(unsigned char *)&I; - или это просто масло масленное?
битва с дураками проиграна, победители торжествуют. слава победителям!
- Necroteeth
- Потрогал лапой паяльник
- Сообщения: 362
- Зарегистрирован: Вс окт 10, 2010 17:43:48
- Откуда: Воронеж
Re: Вопросы по С/С++ (СИ)
добрый день!
подскажите, пожалуйста, почему у меня какая-то хрень происходит:
после входа в функцию convert программа переходит опять в начало функции main и в итоге ничего полезного не делает. где я допустил ошибку?
суть программы в том, чтобы на два индикатора АЛС321Б1 выводить число от 0 до 20. каунтер i должен перебирать число, а переменные decimal и entier хранить значения второго и первого разряда соответственно. текущий включенный индикатор должен определяться состоянием переменной state, которая изменяется (должна изменяться) по прерыванию таймера0.
подскажите, пожалуйста, почему у меня какая-то хрень происходит:
Код: Выделить всё
#define F_CPU 1000000UL // óêàçûâàåì ÷àñòîòó â ãåðöàõ
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/interrupt.h>
volatile int state=0;
volatile int decimal, entier;
int main()
{
init();
while(1)
{
for (int i=0;i<=20;i++)
{
decimal=i/10;
entier=i%10;
switch(state)
{
case 0: PORTD=0b00100000; PORTA=convert(entier); break;
case 1: PORTD=0b01000000; PORTA=convert(decimal); break;
}
_delay_ms(250);
}
}
}
//***********************************************************************************
ISR(TIMER0_COMP) //îáðàáîò÷èê ïðåðûâàíèÿ òàéìåðà0
{
state=~(state);
}
//***********************************************************************************
int Timer0_prepare() //ïðîöåäóðà èíèöèàëèçàöèè òàéìåðà0
{
TIMSK|=(1<<OCIE0); //ðàçðåøèòü ïðåðûâàíèÿ ïî êîìïàðàòîðó òàéìåðà0
TCCR0|=(1<<WGM00)|(1<<WGM01)|(1<<CS00)|(1<<CS02);//CTC mode, prescaler 1/1024
TCCR0&=~(1<<CS01);
OCR0=0b00001010; //êîìïàðàòîð íàñòðîåí ñðàáàòûâàòü ðàç â 10ms
TCNT0=0b00000000;
}
//***********************************************************************************
int convert(int digit) //ïðîöåäóðà ïðåîáðàçîâàíèÿ ÷èñëà â ñèãíàë
{ //7-ñåãìåòíîãî èíäèêàòîðà
int result;
switch (digit)
{
case 0: result=0b11000000; break;
case 1: result=0b11111001; break;
case 2: result=0b10100100; break;
case 3: result=0b10110000; break;
case 4: result=0b10011001; break;
case 5: result=0b10010010; break;
case 6: result=0b10000010; break;
case 7: result=0b11111000; break;
case 8: result=0b10000000; break;
case 9: result=0b10010000; break;
case 10: result=0b01111111; break;
}
return result;
}
int init()
{
DDRA=0b11111111;
DDRD=0b01100000;
PORTD=0b00000000;
Timer0_prepare();
sei();
}
после входа в функцию convert программа переходит опять в начало функции main и в итоге ничего полезного не делает. где я допустил ошибку?
суть программы в том, чтобы на два индикатора АЛС321Б1 выводить число от 0 до 20. каунтер i должен перебирать число, а переменные decimal и entier хранить значения второго и первого разряда соответственно. текущий включенный индикатор должен определяться состоянием переменной state, которая изменяется (должна изменяться) по прерыванию таймера0.
-
demiurg301
- Опытный кот
- Сообщения: 812
- Зарегистрирован: Ср мар 18, 2009 21:14:33
Re: Вопросы по С/С++ (СИ)
Мастер Ломастер
А можете ещё подсказать по такому вопросу ? :
такой кусок кода :
void func(flash unsigned char *PtF)
{
.......
}
flash unsigned char fstr[]="flash string";
func(fstr);
А нельзя ли сделать как то так :
func("flash string"); - типа как в С++ ?
А можете ещё подсказать по такому вопросу ? :
такой кусок кода :
void func(flash unsigned char *PtF)
{
.......
}
flash unsigned char fstr[]="flash string";
func(fstr);
А нельзя ли сделать как то так :
func("flash string"); - типа как в С++ ?
-
Мастер Ломастер
- Поставщик валерьянки для Кота
- Сообщения: 1995
- Зарегистрирован: Ср май 11, 2011 21:37:45
- Откуда: Цветочный город
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
до сего момента все написанные вами куски кода воспринимались, как написанные для WinAVR. так вот, у WinAVR нет ключевого слова flash и вообще, для работы со строками из памяти программ используются совсем другие подходы. Однако, сделать так, как вы написали в конце своего поста, все-таки можно:как поступать для других компиляторов - я не знаю.
Код: Выделить всё
#include <avr/pgmspace.h>
...
func(PSTR("эта строка будет лежать во flash"));битва с дураками проиграна, победители торжествуют. слава победителям!
-
demiurg301
- Опытный кот
- Сообщения: 812
- Зарегистрирован: Ср мар 18, 2009 21:14:33
Re: Вопросы по С/С++ (СИ)
НЕ, я СV сижу, хотя С в нём говорят кривоватый... Но пока устраивает...
Жалко, но СV я таких механизмов не нашёл.
Т.к. эти "простыни" из кучи строковых констант (AT команды и другие протоколы) напрягают. Код не особо читабелен, т.к. команду не задашь явно рядом с её выводом...
Почему в С нет типа string ...
Могли б уж изловчится... 
----------
Только что проверил
Функция вида
unsigned char* B1FIND(flash unsigned char *str,unsigned char time)
B1FIND("PIN: READY",1)
Работает
- У мну когнитивный диссонанс - раньше выдавало ошибку. Правда я версию сменил с 25.5 на 25.9
Жалко, но СV я таких механизмов не нашёл.
Т.к. эти "простыни" из кучи строковых констант (AT команды и другие протоколы) напрягают. Код не особо читабелен, т.к. команду не задашь явно рядом с её выводом...
Почему в С нет типа string ...
----------
Только что проверил
Функция вида
unsigned char* B1FIND(flash unsigned char *str,unsigned char time)
B1FIND("PIN: READY",1)
Работает
- avreal
- Опытный кот
- Сообщения: 842
- Зарегистрирован: Чт дек 31, 2009 19:27:45
- Откуда: Бровари, Україна
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Кстати, о константах. «А знаетели вы, что»™
В языке С (но не С++ !) символьная константа вида 'A' имеет тип int, а не char.
И допускаются многосимвольные константы, лишь бы лезло в int.
Например, так
Не скажу, что такое нужно часто
Но иногда может заменить отсутствующую в С возможность указывать строки в case
Чтобы уйти от непереносимости по длине int-а, достаточно
В языке С (но не С++ !) символьная константа вида 'A' имеет тип int, а не char.
И допускаются многосимвольные константы, лишь бы лезло в int.
Например, так
Код: Выделить всё
// проверить, являются ли первые два символа str 'A' и 'T' соответственно
unsigned char is_AT(char *str)
{
// Внимание! Работает только при sizeof(int) == 2
// задом наперёд, так как левый символ идёт в старший байт, как в числах
return ((int*)str)[0] == 'TA';
}Не скажу, что такое нужно часто
Но иногда может заменить отсутствующую в С возможность указывать строки в case
Код: Выделить всё
...
// Внимание! Работает только при sizeof(int) == 2
switch( *(int*)str ) {
case '1H':
// начало str -> "H1"
case '0H':
// начало str -> "H0"
case '1M':
// начало str -> "M1"
}Чтобы уйти от непереносимости по длине int-а, достаточно
Код: Выделить всё
int cmd = (unsigned char)str[0];
cmd += (unsigned char)str[1] << 8;
// старшие биты у 32-битного int будут нулевые и тут, и в двухсимвольных константах
swicth (cmd) {Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
-
demiurg301
- Опытный кот
- Сообщения: 812
- Зарегистрирован: Ср мар 18, 2009 21:14:33
Re: Вопросы по С/С++ (СИ)
avreal писал(а):Кстати, о константах. «А знаетели вы, что»™
В языке С (но не С++ !) символьная константа вида 'A' имеет тип int, а не char.
И допускаются многосимвольные константы, лишь бы лезло в int.
Например, такКод: Выделить всё
// проверить, являются ли первые два символа str 'A' и 'T' соответственно
unsigned char is_AT(char *str)
{
// Внимание! Работает только при sizeof(int) == 2
// задом наперёд, так как левый символ идёт в старший байт, как в числах
return ((int*)str)[0] == 'TA';
}
Не скажу, что такое нужно часто
Но иногда может заменить отсутствующую в С возможность указывать строки в caseКод: Выделить всё
...
// Внимание! Работает только при sizeof(int) == 2
switch( *(int*)str ) {
case '1H':
// начало str -> "H1"
case '0H':
// начало str -> "H0"
case '1M':
// начало str -> "M1"
}
Чтобы уйти от непереносимости по длине int-а, достаточноКод: Выделить всё
int cmd = (unsigned char)str[0];
cmd += (unsigned char)str[1] << 8;
// старшие биты у 32-битного int будут нулевые и тут, и в двухсимвольных константах
swicth (cmd) {
Интересная инфа, вот если бы только не надо было по 10-20 символов обрабатывать, а не по 2
Так вот такая запись func("abcdfk"); (объявление func(flash unsigned char PtF) ; ) - стандартна или это "происки компилятора" и при переходе придётся переделывать?
А в С можно реализовать конкатенацию вида
unsigned char A[]="abcdef"
unsigned char str[100];
str=0x0A+A+'a'+"abv" - или это фантастика?
- avreal
- Опытный кот
- Сообщения: 842
- Зарегистрирован: Чт дек 31, 2009 19:27:45
- Откуда: Бровари, Україна
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Только врукопашную.
Смотрите string.h, функции strcpy, strcat и компанию.
Смотрите string.h, функции strcpy, strcat и компанию.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
- Леонид Иванович
- Друг Кота
- Сообщения: 4779
- Зарегистрирован: Сб апр 02, 2011 12:40:46
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
avreal писал(а):Кстати, о константах. «А знаетели вы, что»™
Какой ужас!
Всегда с открытым ртом смотрю на людей, которые виртуозно владеют Си. Не понимаю, как им это удаётся. Но ещё больше не понимаю, зачем это нужно. Пользуюсь очень ограниченным подмножеством языка Си, благодаря чему удалось свести на нет такой минус этого языка, как плохая читаемость исходника. Например, места, где я использовал указатели, можно пересчитать по пальцам. И ничего, все задачи решаются.
