Вопросы по С/С++ (СИ)
Народ, а есть уже написанная кем нибуть библиотека на С++ для RS-232? Начал изучать С++ на windows в консоле, охота побыстрее применить уже полученные знания по С++, чтоб управлять МК. А как в консоле на С++ работать с RS-232 не знаю. Если кто знает, дайте ссылочку на готовую библиотеку или на материал учебный, чтоб самому сделать свою библиотеку.
Кот должен прожить жизнь без сожаления.
- Реклама
я уже давно пользуюсь этим
http://www.codeforge.cn/read/22611/SerialPort.cpp__html
http://www.codeforge.cn/read/22611/SerialPort.cpp__html
Спасибо urry, а как собрать этот исходник? Я установи себе Visual Studio 2012(professional) на Windows 8 x64. Скачал на сайте http://www.naughter.com/serialport.html полностью проект, загрузил его через студию 2012, студия его загружала в себя выдавая сообщения о том, что проект состоит в системе управления версиями. А когда я решил скомпиллировать код, выдал ошибку в библиотеке <altwinverapi.h> на строке:urry писал(а):я уже давно пользуюсь этим
http://www.codeforge.cn/read/22611/SerialPort.cpp__html
Код: Выделить всё
#if _WIN32_WINNT < 0x0403
#error This file requires _WIN32_WINNT to be #defined at least to 0x0403. Value 0x0501 or higher is recommended. <- ТУТ ОШИБКА
#endifКот должен прожить жизнь без сожаления.
Это - версия винды и версия эксплорера, естественно, все старое. Незачем это собирать - вас в проекте интересует 2 файла - serialport.cpp serialport.h.
Скопируйте оттуда в свой консольный проект и появится класс CSerialPort. Дальше - как обычно,
CSerialPort port;
port.Open(
и так далее.
Не знаю, как это заработает на винде 8 - проверял только на хп и семерке, кстати, только на 32 битной...
Скопируйте оттуда в свой консольный проект и появится класс CSerialPort. Дальше - как обычно,
CSerialPort port;
port.Open(
и так далее.
Не знаю, как это заработает на винде 8 - проверял только на хп и семерке, кстати, только на 32 битной...
Спасибо за совет.
Создал консольный проект, с пометкой добавить общие файлы заголовка для библиотек MFC. Заинклудил хидер, объект для класса создается, никаких ошибок. urry, не мог бы выложить кусок кода, как с помощью Методов ты конфигурируешь порт, я так понял это .Open(). И принимаешь и отправляешь данные. Я бы по аналогии сделал 100% работающую программу. Я глянул на Класс, там этих Методов очень много. Я запутался.
Создал консольный проект, с пометкой добавить общие файлы заголовка для библиотек MFC. Заинклудил хидер, объект для класса создается, никаких ошибок. urry, не мог бы выложить кусок кода, как с помощью Методов ты конфигурируешь порт, я так понял это .Open(). И принимаешь и отправляешь данные. Я бы по аналогии сделал 100% работающую программу. Я глянул на Класс, там этих Методов очень много. Я запутался.
Кот должен прожить жизнь без сожаления.
- Реклама
основных - 4 Open Write Read Close
CSerialPort port;
COMMTIMEOUTS rCommTimeouts;
port.Open(theApp.cV->strSetup.nCom, 9600, CSerialPort::NoParity, 8, CSerialPort::OneStopBit, CSerialPort::XonXoffFlowControl);
port.Write(temp,len); - массив данных и длина
Для чтения нужно ставить таймаут, чтобы ждало разумное время
rCommTimeouts.ReadTotalTimeoutConstant =tmOut*10; // миллисекунд
rCommTimeouts.ReadTotalTimeoutMultiplier = 1;
port.SetTimeouts(rCommTimeouts);
int bt = port.Read(temp,n); n - количество ожидаемых байт, bt - реально принятых
Если прочитает ожидаемое количество байт, выскочит сразу после чтения, не получит - выскочит по таймауту.
Поскольку процедура достаточно тормознутая, я обычно запускаю порт в отдельном потоке.
CSerialPort port;
COMMTIMEOUTS rCommTimeouts;
port.Open(theApp.cV->strSetup.nCom, 9600, CSerialPort::NoParity, 8, CSerialPort::OneStopBit, CSerialPort::XonXoffFlowControl);
port.Write(temp,len); - массив данных и длина
Для чтения нужно ставить таймаут, чтобы ждало разумное время
rCommTimeouts.ReadTotalTimeoutConstant =tmOut*10; // миллисекунд
rCommTimeouts.ReadTotalTimeoutMultiplier = 1;
port.SetTimeouts(rCommTimeouts);
int bt = port.Read(temp,n); n - количество ожидаемых байт, bt - реально принятых
Если прочитает ожидаемое количество байт, выскочит сразу после чтения, не получит - выскочит по таймауту.
Поскольку процедура достаточно тормознутая, я обычно запускаю порт в отдельном потоке.
- Сообщения: 5
- Зарегистрирован: Пн окт 22, 2012 07:50:16
в чем тут ошибка?
#include <mega8.h>
#include <delay.h>
void main(void)
{
char i;
DDRC=0xff; //на вывод
DDRD=0x00; // на вход
PORTD=0xff; //устанавливаем "1"
while (1) //бесконечный цикл
{
if (!(PIND & (1<<PIND1))); //проверка условия
{
start: //метка для перехода
PORTC |= _BV(PC1); // установить "1" на линии 1 порта C
PORTC &= ~_BV(PC2); // установить "0" на линии 2 порта C
PORTC |= _BV(PC3); // установить "1" на линии 3 порта C
PORTC &= ~_BV(PC4); // установить "0" на линии 4 порта C
for ( i = 0; i<<200; i++);//задержка для движения вперед
PORTD = 0x00; //устанавливаем "0"
endstart; //конец переход, продолжение команды
}
else
{
// ---------- вращаем моторы назад ----------
PORTC &= ~_BV(PC1); // установить "0" на линии 1 порта C
PORTC |= _BV(PC2); // установить "1" на линии 2 порта C
PORTC &= ~_BV(PC3); // установить "0" на линии 3 порта C
PORTC |= _BV(PC4); // установить "1" на линии 4 порта C
}
//поворачиваем в одну сторону
PORTD=0xff; //устанавливаем "1"
for(i=0;i<200;i++); //задержка для поворота
PORTC &= ~_BV(PC3);
PORTC |= _BV(PC4);
_delay_ms(200);
goto start; //переход, для движения вперед
}
//поворачиваем в другу сторону
for(i=0;i<200; i++); //задержка для поворота
{
PORTC &= ~_BV(PC4)
PORTC |= _BV(PC3)
_delay_us(200)
goto start;
}
}
#include <mega8.h>
#include <delay.h>
void main(void)
{
char i;
DDRC=0xff; //на вывод
DDRD=0x00; // на вход
PORTD=0xff; //устанавливаем "1"
while (1) //бесконечный цикл
{
if (!(PIND & (1<<PIND1))); //проверка условия
{
start: //метка для перехода
PORTC |= _BV(PC1); // установить "1" на линии 1 порта C
PORTC &= ~_BV(PC2); // установить "0" на линии 2 порта C
PORTC |= _BV(PC3); // установить "1" на линии 3 порта C
PORTC &= ~_BV(PC4); // установить "0" на линии 4 порта C
for ( i = 0; i<<200; i++);//задержка для движения вперед
PORTD = 0x00; //устанавливаем "0"
endstart; //конец переход, продолжение команды
}
else
{
// ---------- вращаем моторы назад ----------
PORTC &= ~_BV(PC1); // установить "0" на линии 1 порта C
PORTC |= _BV(PC2); // установить "1" на линии 2 порта C
PORTC &= ~_BV(PC3); // установить "0" на линии 3 порта C
PORTC |= _BV(PC4); // установить "1" на линии 4 порта C
}
//поворачиваем в одну сторону
PORTD=0xff; //устанавливаем "1"
for(i=0;i<200;i++); //задержка для поворота
PORTC &= ~_BV(PC3);
PORTC |= _BV(PC4);
_delay_ms(200);
goto start; //переход, для движения вперед
}
//поворачиваем в другу сторону
for(i=0;i<200; i++); //задержка для поворота
{
PORTC &= ~_BV(PC4)
PORTC |= _BV(PC3)
_delay_us(200)
goto start;
}
}
Аналогично могу задать вопрос: Как вы узнали что есть ошибка? И как вообще по вашему должно работать?
Я бы для начала посоветовал изменять состояния ног порта одновременно, чтобы было меньше моментов из-за переходных процессов.
Я бы для начала посоветовал изменять состояния ног порта одновременно, чтобы было меньше моментов из-за переходных процессов.
В поисках истины человек развивается.
по крайней мере здесьRond писал(а):в чем тут ошибка?
if (!(PIND & (1<<PIND1))); //проверка условия
for ( i = 0; i<<200; i++);//задержка для движения вперед
endstart; //конец переход, продолжение команды
PORTC &= ~_BV(PC4)
PORTC |= _BV(PC3)
_delay_us(200)
- Сообщения: 581
- Зарегистрирован: Ср янв 05, 2011 10:03:18
Работаю в VS2010. В прикрученном проектике работа через СОМ-порт с МК и обмен с диском. Проект рабочий.DruidCat писал(а):Спасибо за совет.
Создал консольный проект, с пометкой добавить общие файлы заголовка для библиотек MFC. Заинклудил хидер, объект для класса создается, никаких ошибок. urry, не мог бы выложить кусок кода, как с помощью Методов ты конфигурируешь порт, я так понял это .Open(). И принимаешь и отправляешь данные. Я бы по аналогии сделал 100% работающую программу. Я глянул на Класс, там этих Методов очень много. Я запутался.
- Вложения
-
- KeyLoader.7z
- (38.38 КБ) 145 скачиваний
С уважением,
Виктор.
Виктор.
я не знаю, что такое PIND1 // if (!(PIND & (1<<PIND1))); //проверка условия
компилятор, видимо. тоже
компилятор, видимо. тоже
WinAvr знает:
iom8.h:CodeVision тоже:
mega8_bits.h:правда по данному листингу там какой-то винегрет из winavr (_BV, _delay_ms,..) и codevision (#include <mega8.h>,..)
iom8.h:
Код: Выделить всё
#define PIND1 1mega8_bits.h:
Код: Выделить всё
#define PIND1 1 // Port D Input Pins bit 1Да, действительно, знает.
Давать лучше смысловые имена - в данном случае нагляднее было бы
#define BUTTON 1
Дальше пошли, вот идет проверка условия и что ?
if (!(PIND & (1<<PIND1))); //проверка условия
Почему здесь точка с запятой ? Выбросить выражение, как ничего не делающее, компилятор не может, потому что PIND - volatile , но и делать здесь нечего - результат сравнения нигде не используется.
if (!(PIND & (1<<PIND1)))
{
for ( i = 0; i<<200; i++);//задержка для движения вперед -
Вот здесь - i<<200 - понимаю, что опечатка - но ! даже если написать i<200, то i - у вас, во первых не static или volatile, во вторых - signed - макс значение, которое может принимать + 127.
Давать лучше смысловые имена - в данном случае нагляднее было бы
#define BUTTON 1
Дальше пошли, вот идет проверка условия и что ?
if (!(PIND & (1<<PIND1))); //проверка условия
Почему здесь точка с запятой ? Выбросить выражение, как ничего не делающее, компилятор не может, потому что PIND - volatile , но и делать здесь нечего - результат сравнения нигде не используется.
if (!(PIND & (1<<PIND1)))
{
for ( i = 0; i<<200; i++);//задержка для движения вперед -
Вот здесь - i<<200 - понимаю, что опечатка - но ! даже если написать i<200, то i - у вас, во первых не static или volatile, во вторых - signed - макс значение, которое может принимать + 127.
- Сообщения: 25
- Зарегистрирован: Вт окт 09, 2012 14:09:39
Ребят два вопроса - опять про кнопки и частоту :
вот две функции
Такой код работает, а вот проверка на одновременное нажатие двух кнопок :
Правильно ?
И второй вопрос:
Есть такой код:
Timer_Create - Данная функция создает новый таймер. FiredTimer - Событие таймера «интервал истек». Timer_Start - Данная функция запускает таймер.
Вопрос вот в чем, почему то не работают правильно записи вида
TIMER_INTERVAL = TIMER_INTERVAL * 1.4;
Timer_Start (timer,TIMER_CYCLIC_MODE,MS(TIME_INTERVAL);
После двух-трех увеличений таймер ломается. Хотя если заменять в Timer_Start (timer,TIMER_CYCLIC_MODE,MS(TIME_INTERVAL); TIME_INTERVAL на число к примеру намного больше числа 125 - 2000. То все работает. Вполне возможно это из-за типа uint8_t. Но мне нужно как-то сделать, подскажите пожалуйста в чем может быть проблема.
вот две функции
Код: Выделить всё
// обработчик события "кнопка нажата"
EVENT ButtonsPressed(uint8_t Buttons)
{
if(Buttons&1)
//действие1
else if(Buttons&2)
//действие2
}
// обработчик события "кнопка отпущена"
EVENT ButtonsReleased(uint8_t Buttons)
{
if(Buttons&1)
//действие1
else if(Buttons&2)
//действие2
}
Код: Выделить всё
if((Buttons&1) && (Buttons&2))
И второй вопрос:
Есть такой код:
Код: Выделить всё
volatile uint8_t TIME_INTERVAL = 125;
timer = Timer_Create(FiredTimer,NULL);
TIMER_INTERVAL = TIMER_INTERVAL * 1.4;
Timer_Start (timer,TIMER_CYCLIC_MODE,MS(TIME_INTERVAL);
Вопрос вот в чем, почему то не работают правильно записи вида
TIMER_INTERVAL = TIMER_INTERVAL * 1.4;
Timer_Start (timer,TIMER_CYCLIC_MODE,MS(TIME_INTERVAL);
После двух-трех увеличений таймер ломается. Хотя если заменять в Timer_Start (timer,TIMER_CYCLIC_MODE,MS(TIME_INTERVAL); TIME_INTERVAL на число к примеру намного больше числа 125 - 2000. То все работает. Вполне возможно это из-за типа uint8_t. Но мне нужно как-то сделать, подскажите пожалуйста в чем может быть проблема.
Проверка на одновременное нажатие похоже написана корректно, однако ИМХО лучше писать так:
Просто ваша запись меня немного сбила с толку сначала. Еще можно макросы объявить, что-то типа , и писать это вместо чисел.
PS. Вы можете сделать свой код более понятным для других, если не будете именовать переменные (да и функции в том числе) прописными буквами. Обычно идентификатор, написанный в верхнем регистре принимается за константу (перечисления) или макрос.
Код: Выделить всё
if((Buttons & 0x1) && (Buttons & 0x2))
Код: Выделить всё
#define BUTTON_1 (0x1)Ну так замените на uint32_t, что вам мешает? По логике явное переполнение, но с таким куском кода сложно сказать. Что в таймере "ломается"? Погоняйте код в отладчике.drac0Sha писал(а):Вполне возможно это из-за типа uint8_t. Но мне нужно как-то сделать, подскажите пожалуйста в чем может быть проблема.
PS. Вы можете сделать свой код более понятным для других, если не будете именовать переменные (да и функции в том числе) прописными буквами. Обычно идентификатор, написанный в верхнем регистре принимается за константу (перечисления) или макрос.
- Сообщения: 882
- Зарегистрирован: Ср фев 22, 2012 01:25:21
Интересно, если я создаю текстовый массив в PROGMEM, он разместится в памяти непрерывно и в такой же последовательности?
Подумал, для уверенности в структуру запихать, как то так:
Да не тут то было, в PROGMEM не хочет в структуру оформлять.....
Вопрос к знающим: как сделать так, чтобы массив в PROGMEM расположился непрерывно, и именно в такой последовательности, как я написал?
Или это итак подразумевается, как само собой разумеющееся?
Спойлер
Код: Выделить всё
//ТИТУЛЬНЫЕ НАДПИСИ "0123456789abcdef0123456789abcdef"
unsigned char TitlePage [] PROGMEM= " многоканальный терморегистратор"; //приветственное сообщение
unsigned char TitleMenu [] PROGMEM= " меню изменения\x13настроек!"; //заголовок меню настроек
unsigned char ExitNoSave [] PROGMEM= " выход без\x13сохранения"; //выход без сохранения
unsigned char ExitSave [] PROGMEM= " изменения\x13сохранены!"; //выход с сохранением
//МЕНЮ ОСНОВНОЕ "0123456789abcdef0123456789abcdef"
unsigned char MenuBase [] PROGMEM= " "; //строка первого термодатчика
unsigned char Time [] PROGMEM= " "; //строка второго термодатчика
unsigned char Time [] PROGMEM= "время:"; //время
unsigned char Date [] PROGMEM= "дата:"; //дата
unsigned char Alarm [] PROGMEM= "будильник:"; //будильник
unsigned char SetupBase [] PROGMEM= "сист. настройки"; //установки
//МЕНЮ ВЫБОРА НАСТРОЕК "0123456789abcdef0123456789abcdef"
unsigned char SetupAlarm [] PROGMEM= "будильник"; //настройка будильника
unsigned char SetupSens [] PROGMEM= "настройка часов"; //программирование сенсоров
unsigned char SetupTime [] PROGMEM= "повтор тревоги"; //настройка часов
unsigned char SetupTReg [] PROGMEM= "период рег-ции"; //программирование времени регистрации
unsigned char SetupTRpt [] PROGMEM= "термо датчики"; //программирование времени повтора тревоги
//прочие надписи "0123456789abcdef0123456789abcdef"
unsigned char On [] PROGMEM= "вкл"; //включено
unsigned char Off [] PROGMEM= "выкл"; //выключено
unsigned char SensName [] PROGMEM= "сенсор_"; //имя по умолчанию для термодатчиков (8 символов)
unsigned char Error [] PROGMEM= "ошибка"; //ошибка чтения
Спойлер
Код: Выделить всё
struct {
//ТИТУЛЬНЫЕ НАДПИСИ "0123456789abcdef0123456789abcdef"
unsigned char TitlePage [] PROGMEM= " многоканальный терморегистратор"; //приветственное сообщение
unsigned char TitleMenu [] PROGMEM= " меню изменения\x13настроек!"; //заголовок меню настроек
unsigned char ExitNoSave [] PROGMEM= " выход без\x13сохранения"; //выход без сохранения
unsigned char ExitSave [] PROGMEM= " изменения\x13сохранены!"; //выход с сохранением
//МЕНЮ ОСНОВНОЕ "0123456789abcdef0123456789abcdef"
unsigned char MenuBase [] PROGMEM= " "; //строка первого термодатчика
unsigned char Time [] PROGMEM= " "; //строка второго термодатчика
unsigned char Time [] PROGMEM= "время:"; //время
unsigned char Date [] PROGMEM= "дата:"; //дата
unsigned char Alarm [] PROGMEM= "будильник:"; //будильник
unsigned char SetupBase [] PROGMEM= "сист. настройки"; //установки
//МЕНЮ ВЫБОРА НАСТРОЕК "0123456789abcdef0123456789abcdef"
unsigned char SetupAlarm [] PROGMEM= "будильник"; //настройка будильника
unsigned char SetupSens [] PROGMEM= "настройка часов"; //программирование сенсоров
unsigned char SetupTime [] PROGMEM= "повтор тревоги"; //настройка часов
unsigned char SetupTReg [] PROGMEM= "период рег-ции"; //программирование времени регистрации
unsigned char SetupTRpt [] PROGMEM= "термо датчики"; //программирование времени повтора тревоги
//прочие надписи "0123456789abcdef0123456789abcdef"
unsigned char On [] PROGMEM= "вкл"; //включено
unsigned char Off [] PROGMEM= "выкл"; //выключено
unsigned char SensName [] PROGMEM= "сенсор_"; //имя по умолчанию для термодатчиков (8 символов)
unsigned char Error [] PROGMEM= "ошибка"; //ошибка чтения
} Txt; Вопрос к знающим: как сделать так, чтобы массив в PROGMEM расположился непрерывно, и именно в такой последовательности, как я написал?
Или это итак подразумевается, как само собой разумеющееся?
А зачем это нужно?
все равно константы именованные, а если нужно пролистывание в этом списке, то можно массив указателей сделать на эти данные и тогда точно все на месте будет.
все равно константы именованные, а если нужно пролистывание в этом списке, то можно массив указателей сделать на эти данные и тогда точно все на месте будет.
- Сообщения: 882
- Зарегистрирован: Ср фев 22, 2012 01:25:21
Просто хочу сообразить функцию обработки менюшек. Т.е. функция должна по номеру сообщения, найти его и вывести на дисплей. Нужную строку можно будет найти отсчитывая попадающиеся нулевые символы. Вот тут и надо чтобы ничего лишнего не попадалось посреди массива, и массив был расположен именно в той последовательности.
Если массив указателей на строки соображать, это уже не так гибко будет.
Если массив указателей на строки соображать, это уже не так гибко будет.
shads,
почему не гибко? Потом искать по массиву нулевые символы - это что гибкость ?
PS Компилятор положит данные, как ему удобно. Никаких обещаний насчёт "последовательно", "ничего лишнего" никто не даёт.
unsigned char string_1 [] PROGMEM= "String2";
unsigned char string_2 [] PROGMEM= "String3";
unsigned char string_3 [] PROGMEM= "String4";
unsigned char string_4 [] PROGMEM= "String5";
unsigned char string_6 [] PROGMEM= "String6";
/* -- .... -- */
PROGMEM const unsigned char *string_table[] =
{
string_0,
string_1,
string_2,
string_3,
string_4,
string_5 };
/* и где нужно использовать 4-ю строку из массива, использовать string_table[3], что ещё проще? */
почему не гибко? Потом искать по массиву нулевые символы - это что гибкость ?
PS Компилятор положит данные, как ему удобно. Никаких обещаний насчёт "последовательно", "ничего лишнего" никто не даёт.
Спойлер
unsigned char string_0 [] PROGMEM= "String1";unsigned char string_1 [] PROGMEM= "String2";
unsigned char string_2 [] PROGMEM= "String3";
unsigned char string_3 [] PROGMEM= "String4";
unsigned char string_4 [] PROGMEM= "String5";
unsigned char string_6 [] PROGMEM= "String6";
/* -- .... -- */
PROGMEM const unsigned char *string_table[] =
{
string_0,
string_1,
string_2,
string_3,
string_4,
string_5 };
/* и где нужно использовать 4-ю строку из массива, использовать string_table[3], что ещё проще? */
In theory, theory and practice are the same. In practice, they're not.
- Сообщения: 882
- Зарегистрирован: Ср фев 22, 2012 01:25:21
Ну..... не знаю как для вас, а для меня гибкость.... пока что попробовал, все работает по моей задумке..... в функцию передаю начало списка менюшки, и номер нужной строки, в результате на дисплее появляется эта и следующая строки.....Tolmi писал(а):shads, почему не гибко? Потом искать по массиву нулевые символы - это что гибкость ?![]()
Код: Выделить всё
//ФУНКЦИЯ ВЫВОДА НА ДИСПЛЕЙ СТРОК МЕНЮ
//АРГУМЕНТ1 - указатель на первый пункт тематического текстового массива меню в PROGMEM
//АРГУМЕНТ2 - порядковый номер строки меню, помещаемой на первой строке дисплея
void MenuListToBuf (unsigned char* pMenuList, unsigned char NumLine)
{
while (1){
if (! NumLine--){ //если NumLine == 0, начать вывод в буфер дисплея
LCDStringProgMemToBuf (pMenuList, 1);//вывести в буфер дисплея (позиция 1), строку с места pMenuList
while (pgm_read_byte (pMenuList++)){}//находим начало следующей строки
LCDStringProgMemToBuf (pMenuList, 17);//вывести в буфер дисплея (позиция 17), строку с места pMenuList
return;
}
while (pgm_read_byte (pMenuList++)){}//найти начало следующей строки
}
} Вот..... это сомнение бы как то устранить.....Tolmi писал(а):PS Компилятор положит данные, как ему удобно. Никаких обещаний насчёт "последовательно", "ничего лишнего" никто не даёт.
Хотя пока что, компилятор все последовательно распологает.....


