Всё чудесатей и чудесатейWiseLord писал(а):Если бы было так, то обнулялась бы, а такКод: Выделить всё
static up; up = 0;- не будет, как уже выше сказали.Код: Выделить всё
static up = 0;
Вопросы по С/С++ (СИ)
- Gudd-Head
- Друг Кота
- Сообщения: 20092
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: Вопросы по С/С++ (СИ)
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- Реклама
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
По поводу "@" - думаю, это какой-то атрибут, возможно специфический для какой-то архитектуры (а не вообще для языка C). Что-то наподобие "_at_" здесь.
Re: Вопросы по С/С++ (СИ)
Так, вы тут Gudd-Head давайте не путайте, обнуляется не обнуляется.Gudd-Head писал(а):Всё чудесатей и чудесатей
Статическая переменная объявленная в функции сохраняет свое значение между вызовами функции. Если при объявлении она инициализируется, то это происходит один раз при первом вызове функции. В остальном - это обычная переменная.
Хотя я сейчас посмотрел стандарт C99 и там написано, что static инициализируется перед запуском программы, а не при первом вызове функции. Перепутал с C#.
Последний раз редактировалось menzoda Чт окт 09, 2014 13:15:55, всего редактировалось 1 раз.
- просто КОТ
- Друг Кота
- Сообщения: 12364
- Зарегистрирован: Пт дек 17, 2010 15:07:50
- Откуда: Крымский Федеральный Округ
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Друзья, есть маленький вопрос и большая проблема. Я программист всего месяца полтора как. Если не меньше... Надо мне отправить строку следующего вида: L=xx /n. Где хх это содержимое переменной light.
Функция Out_Str отправляет строку и работает железно. Но вот сама строка не формируется никак. Код без этих шести строк занимал 37% памяти и работал чётко. Дописав их к основному коду получил 114% памяти и собственно кучу глюков. Вопрос -- что не так, и как быть?
Спойлер
Код: Выделить всё
#include "stdio.h"
char res[8];
/********Тут**по***идее**код*************/
if(send) {
sprintf (res, "%s %d", "L=", light);
Out_Str(res); mUart_Putch(0x0D);
send=0;
}Спойлер
Код: Выделить всё
#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>
#include "mUart.h"
#include "stdio.h"
char light = 1;
char b = 1;
char res[8];
/****************************************************************/
volatile unsigned char tx_fl=0;
volatile unsigned char TSK_CLR=0;
volatile unsigned char ID=83;
volatile unsigned char rx;
volatile unsigned char rx_buf[10];
volatile unsigned char rx_cnt=0;
volatile unsigned char rx_fl=0;
volatile unsigned char rx_size;
volatile unsigned char err=0;
volatile unsigned char send=0;
/****************************************************************/
/* Ñäåëàòü çàìåð ôîòîäàò÷èêà */
/****************************************************************/
ISR (TIM1_OVF_vect) {
if(ADCH > 0x63 && b < 6) b++;
if(ADCH < 0x63 && b > 0) b--;
light = 16*b + 1;
ADCSRA|= (1<<ADSC);
send=1;
}
/****************************************************************/
/* Ïðèíÿò áàéò */
/****************************************************************/
void CallBack_RX(char ch){
rx=ch;
if(err) return;
rx_buf[rx_cnt]=ch;
if(ch==13){ // '/n'
rx_fl=1;
rx_size = rx_cnt;
rx_cnt=0;
return;
}
if(++rx_cnt>=sizeof(rx_buf)){
err=1;
rx_cnt=0;
}
}
/****************************************************************/
/* Áàéò îòïðàâëåí */
/****************************************************************/
void CallBack_TX(void){
tx_fl=1;
}
/****************************************************************/
void Out_Str(char* s){
while(*s){
tx_fl=0;
mUart_Putch(*s++);
while(!tx_fl);
};
}
/****************************************************************/
int main (void){
CLKPR=(1<<CLKPCE);
CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);
DDRB = 0x03;
MCUCR = (0<<ISC01) | (1<<ISC00);
OCR1AH= 0xFF;
OCR1AL= 0xFF;
TCCR1B|=(1<<CS10)|(1<<CS12); // Çàïóñòèëè ÑÒÑ.
TIMSK1|=(1<<TOIE1); // Ðàçðåøàåì ïðåðûâàíèå ïî ñîâïàäåíèþ.
ADMUX=0x05; // ÀÖÏ íà ïÿòûé âõîä
ADCSRB|=(1<<ADLAR);
ADCSRA|=(1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
ADCH = 20;
sei();
mUart_Init();
while (1) {
if(err) { // Bufer overflow
err=0;
// Send error message
}
if(send) {
sprintf (res, "%s %d", "L=", light);
Out_Str(res); mUart_Putch(0x0D);
send=0;
}
}
}
- Gudd-Head
- Друг Кота
- Сообщения: 20092
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: Вопросы по С/С++ (СИ)
Да всё так. Sprintf занимает дофига места.просто КОТ писал(а):Вопрос -- что не так
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- Реклама
- просто КОТ
- Друг Кота
- Сообщения: 12364
- Зарегистрирован: Пт дек 17, 2010 15:07:50
- Откуда: Крымский Федеральный Округ
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Банально itoa() использовать
- просто КОТ
- Друг Кота
- Сообщения: 12364
- Зарегистрирован: Пт дек 17, 2010 15:07:50
- Откуда: Крымский Федеральный Округ
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Эм... Википедия сказала, что itoa принимает передаваемое целое число input и конвертирует его в число в основании корня radix. Полученное число (последовательность цифр основания radix) записывается в буфер вывода buffer. И я это совсем не понял. Какой корень, какое основание?
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18648
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
во-первых, так не надо делать. надо делать так: sprintf (res, "L= %d", light);просто КОТ писал(а):sprintf (res, "%s %d", "L=", light);
во-вторых, sprintf сожрет минимум 1,5 килобайта памяти. ну, 1,2 килобайта, если повезет. поэтому обходитесь itoa
в-третьих, можно попытаться уменьшить прожорливсть sprintf-а за счет отказа от некоторых возможностей при помощи опции компилятора -Wl,-u,vfprintf -lprintf_min подробнее читайте здесь: http://www.simple-devices.ru/attachment ... 1-2010.pdf
в-четрвертых, про itoa можно прочесть здесь: http://www.simple-devices.ru/attachment ... 2_2010.pdf
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Apparatchik
- Держит паяльник хвостом
- Сообщения: 908
- Зарегистрирован: Вс май 23, 2010 13:55:42
- Откуда: Украина, Александрия
Re: Вопросы по С/С++ (СИ)
Там же в википедии в низу есть реализация попрощепросто КОТ писал(а):Эм... Википедия сказала
Спойлер
Код: Выделить всё
/* itoa: конвертируем n в символы в s */
void itoa(int n, char s[]) {
int i, sign;
char c;
if ((sign = n) < 0) /* записываем знак */
n = -n; /* делаем n положительным числом */
i = 0;
do { /* генерируем цифры в обратном порядке */
s[i++] = n % 10 + '0'; /* берем следующую цифру */
} while ((n /= 10) > 0); /* удаляем */
if (sign < 0)
s[i++] = '-';
s[i] = '\0';
/*переворачиваем строку*/
for (i = 0, sign = strlen(s) - 1; i < sign; i++, sign--) {
c = s[i];
s[i] = s[sign];
s[sign] = c;
}
}
«И всё-таки она вертится!»
- просто КОТ
- Друг Кота
- Сообщения: 12364
- Зарегистрирован: Пт дек 17, 2010 15:07:50
- Откуда: Крымский Федеральный Округ
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Код: Выделить всё
if(send) {
itoa (light, res, 10);
res[4]='L';
res[3]='=';
Out_Str(res); mUart_Putch(0x0D);
send=0;
}- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Ерунда какая-то написана.
Допустим, ваш ligth = 5;
Тогда после itoa в строке res будет "5". Т.е., res[0] = '5', а res[1] = '\0'. Это и будет выводиться, и по барабану, что вы там пишете в остальные байты массива res (тем более, не в нужном порядке), так как символ конца строки - в позиции [1].
Можно попробовать со смещением писать:, но надо проверять, не будет ли ошибки.
Допустим, ваш ligth = 5;
Тогда после itoa в строке res будет "5". Т.е., res[0] = '5', а res[1] = '\0'. Это и будет выводиться, и по барабану, что вы там пишете в остальные байты массива res (тем более, не в нужном порядке), так как символ конца строки - в позиции [1].
Можно попробовать со смещением писать:
Код: Выделить всё
res[0]='L';
res[1]='=';
itoa (light, &res[2], 10); // Или itoa (light, res + 2, 10); - должно записать в res, начиная с res[2]Re: Вопросы по С/С++ (СИ)
Да отдельно строки вывести, чтоб не скливать их
Код: Выделить всё
Out_Str("L=");
Out_Str(res);- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18648
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
однахрень не заменяет другую. надо делать так:опередил, щустрик 
Код: Выделить всё
Out_Str("L=");
Out_Str(res);
Out_Str("\n");если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- просто КОТ
- Друг Кота
- Сообщения: 12364
- Зарегистрирован: Пт дек 17, 2010 15:07:50
- Откуда: Крымский Федеральный Округ
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
UART рукописный, причём не мной. Функцию Out_Str не выходит вызывать N раз подряд. Потому вот чего придумал:
работает.
Код: Выделить всё
if(send) {
itoa (light, res, 10);
res[2]=res[0];
res[3]=res[1];
res[0]='L';
res[1]='=';
res[4]='\0';
Out_Str(res); mUart_Putch(0x0D);
send=0;
}- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18648
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
это как вообще возможно?! что ж такое нужно написать в функции, чтобы ее нельзя было вызвать несколько раз подряд?!просто КОТ писал(а):UART рукописный, причём не мной. Функцию Out_Str не выходит вызывать N раз подряд.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- просто КОТ
- Друг Кота
- Сообщения: 12364
- Зарегистрирован: Пт дек 17, 2010 15:07:50
- Откуда: Крымский Федеральный Округ
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Ну она вроде как сразу после выполнения уходит в себя на некоторое время.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18648
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
да пусть она хоть в гости уходит - потом-то возвращается? вы же не останавливаете исполнение программы ПОСЛЕ обращения к этой функции? так почему в качестве продолжения работы нельзя СНОВА к ней возвратиться? не понимаю... тем более что наверняка отправка в USART у вас идет в главном ЦИКЛЕ, т.е. эта функция так или иначе вызывается МНОГОКРАТНО...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Вопросы по С/С++ (СИ)
Эта функция выглядит примерно такпросто КОТ писал(а):UART рукописный, причём не мной. Функцию Out_Str не выходит вызывать N раз подряд.
Код: Выделить всё
void Out_Str(char* p)
{
while(*p)
{
while(!(UCSRA & (1<<UDRE)));
UDR=*p;
p++;
}
}
- paskal
- Нашел транзистор. Понюхал.
- Сообщения: 160
- Зарегистрирован: Пн сен 05, 2011 10:03:06
- Откуда: Тула
Re: Вопросы по С/С++ (СИ)
Помогите справиться с особенностями кейла. Надо перевести программу с асма на Си. МК - AT89S52. В исходной программе было детектирование резета следующим образом: В некоторую определенную область ОЗУ пишется определенная сигнатура. При старте этот кусок памяти проверяется на сравнение с сигнатурой. Если совпадение, то считается что процессор стартовал после подачи резета. Если несовпадение то был старт по включению питания.
Так вот, программа на си при старте заполняет ОЗУ нулями, затирая сигнатуру. Как у Кейла отключить эту фичу?
И второй вопрос.
В исходной программе использовалось очень много битовых флагов. Позволяет ли Си пользоваться битовыми флагами. То есть чтоб на 1 флаг тратился бит, а не байт?
Так вот, программа на си при старте заполняет ОЗУ нулями, затирая сигнатуру. Как у Кейла отключить эту фичу?
И второй вопрос.
В исходной программе использовалось очень много битовых флагов. Позволяет ли Си пользоваться битовыми флагами. То есть чтоб на 1 флаг тратился бит, а не байт?
Если бы на станции "Мир" стояли Винды, она бы еще висела и висела...




