Форум Микро-Чип

Форум Микро-Чип (http://www.microchip.su/index.php)
-   Вопросы начинающих (http://www.microchip.su/forumdisplay.php?f=14)
-   -   Подскажите по указателям (http://www.microchip.su/showthread.php?t=18332)

alex_new_2030 30.05.2018 17:50

Подскажите по указателям
 
Здравствуйте!
вызываю допустим функцию
Код:

SSD1306_Out8("Пример");
сама функция имеет цикл
Код:

void SSD1306_Out8(const char *texto){
                while( *texto ){
                        SSD1306_Chr( *texto++);
                };

}

мне надо что бы цикл по константе прошел два раза. Делаю так:
Код:

void SSD1306_Out8(const char *texto){
        for (ii=0;ii<=1;ii++){
                while( *texto ){
                        SSD1306_Chr( *texto++);
                };
        };
}

Но второй раз по строке цикл while не пробегает. Нужно как-то начать цикл по строке с начала. Но как это указать ни как не соображу :(
Подскажите пожалуйста как начать цикл while сначала строки?

besogon 30.05.2018 18:58

Re: Подскажите по указателям
 
Код:

#define MAX_PRINT_LENGTH        20
...
void SSD1306_Out8(const char *texto){
        const char* restrict data;

        for (uf ii=0;ii<=1; ++ii){
                data = texto;
                for(uf lim = MAX_PRINT_LENGTH; (*data) && (lim); --lim){
                        SSD1306_Chr( *data++);
                };
        };
}


alex_new_2030 30.05.2018 19:20

Re: Подскажите по указателям
 
Спасибо! натолкнуло на такое решение:
Код:

void SSD1306_Out8(const char *texto){
        const char *data;

        data = texto;
        for (uf ii=0;ii<=1; ++ii){
                while(*texto){
                        SSD1306_Chr( *texto++);
                };
                texto=data;
        };
}

Работает.

besogon 30.05.2018 19:25

Re: Подскажите по указателям
 
alex_new_2030
почитайте про указатели. в интернете есть множество достойных материалов.

не работаете со строками, как будто бы они всегда нуль-терминированные.
редко когда имеет смысл работать со строками бесконечной длины - старайтесь ограничивать длину.

на ssd1306 Вы больше 20 букв не выведите - ну ограничьте 20 буквами метод Ваш.

alex_new_2030 30.05.2018 19:33

Re: Подскажите по указателям
 
Спасибо за совет.

pasha_zv 31.05.2018 11:35

Re: Подскажите по указателям
 
Цитата:

Сообщение от alex_new_2030 (Сообщение 237343)
Здравствуйте!
вызываю допустим функцию
Код:

SSD1306_Out8("Пример");
сама функция имеет цикл
Код:

void SSD1306_Out8(const char *texto){
                while( *texto ){
                        SSD1306_Chr( *texto++);};
}


а не правильнее будет писать так:

void SSD1306_Out8(const rom char *texto)

besogon 31.05.2018 11:46

Re: Подскажите по указателям
 
pasha_zv
квалификатор const для данных, на которые указывает указатель означает, что мы не собираемся модифицировать данные через этот указатель.

rom это нестандартный квалификатор си-подобных компиляторов, который является атрибутом хранения.

иначе говоря, мне не понятно, почему вдруг строка не может оказаться в RAM и зачем использовать нестандартные квалификаторы хранения для этой функции вообще?

alex_new_2030 31.05.2018 11:59

Re: Подскажите по указателям
 
а если я в функцию передаю не только константу "пример", но и массив-строку.
Код:

SSD1306_Out8(&stroka[0]);
В принципе все работает, но как правильно делать?

DimaS 31.05.2018 12:34

Re: Подскажите по указателям
 
Цитата:

Сообщение от alex_new_2030 (Сообщение 237366)
а если я в функцию передаю не только константу "пример", но и массив-строку.
Код:

SSD1306_Out8(&stroka[0]);
В принципе все работает, но как правильно делать?


&stroka[0] и просто stroka - это одно и то-же.

pal1222@yandex.ru 31.05.2018 15:28

Re: Подскажите по указателям
 
Цитата:

Сообщение от alex_new_2030 (Сообщение 237347)
Спасибо! натолкнуло на такое решение:
Код:

void SSD1306_Out8(const char *texto){
        const char *data;

        data = texto;
        for (uf ii=0;ii<=1; ++ii){
                while(*texto){
                        SSD1306_Chr( *texto++);
                };
                texto=data;
        };
}

Работает.

Код:

void SSD1306_Out8(const char *texto){
        for (uf ii=0;ii<=1; ++ii) for(uf i=0; texto[i]; SSD1306_Chr(texto[i++]));
}


alex_new_2030 31.05.2018 15:50

Re: Подскажите по указателям
 
А что такое uf в описании цикла for? хайтеч ругается на uf
В устройстве проверить не могу сейчас. Но думаю заработает. Спасибо!

besogon 31.05.2018 16:01

Re: Подскажите по указателям
 
alex_new_2030
переопределенный тип, короткое имя для беззнакового типа, быстрого для данной архитектуры.

пример для pic32mx что я использую в своем arch.h, что подключаю к тому, чтобы писать код.
Код:

/**
 * short names for types
 * only for gcc compilier
 */
typedef unsigned char u8;
typedef __signed char s8;
typedef unsigned short int u16;
typedef short int s16;
typedef unsigned int u32;
typedef int s32;
__extension__
typedef unsigned long long int u64;
__extension__
typedef long long int s64;
typedef unsigned int uf;
typedef int sf;

понятное дело что Вы можете переопределить свои имена типов или использовать те, что у Вас есть или использовать stdint.h

вообще говоря используя переопределенные типы меньше проблем с переносимостью кода.

pal1222@yandex.ru 31.05.2018 16:44

Re: Подскажите по указателям
 
Цитата:

Сообщение от alex_new_2030 (Сообщение 237369)
А что такое uf в описании цикла for? хайтеч ругается на uf
В устройстве проверить не могу сейчас. Но думаю заработает. Спасибо!

Не знаю, с besogon - а скопипастил :o

maagalex 12.05.2019 15:35

Re: Подскажите по указателям
 
Опять мне понадобились указатели..и возникла проблема..
Нужно за минимальное время вызвать одну из 36 функций в зависимости от значения переменной..
В функциях присвоение некоего значения регистру, но есть два вида регистров, младшие и старшие (возможно младшие и старшие 8 бит от 16 битного регистра), так они описаны в библиотеке
PHP код:

       #define PWM_1_COMPARE1_LSB    (*(reg8 *) PWM_1_PWMUDB_sP8_pwmdp_u0__D0_REG)
       #define PWM_1_COMPARE1_LSB_PTR ((reg8 *) PWM_1_PWMUDB_sP8_pwmdp_u0__D0_REG)
       #define PWM_1_COMPARE2_LSB    (*(reg8 *) PWM_1_PWMUDB_sP8_pwmdp_u0__D1_REG)
       #define PWM_1_COMPARE2_LSB_PTR ((reg8 *) PWM_1_PWMUDB_sP8_pwmdp_u0__D1_REG)
       #define PWM_1_COUNTERCAP_LSB   (*(reg8 *) PWM_1_PWMUDB_sP8_pwmdp_u0__A1_REG)
       #define PWM_1_COUNTERCAP_LSB_PTR ((reg8 *) PWM_1_PWMUDB_sP8_pwmdp_u0__A1_REG)
       #define PWM_1_COUNTER_LSB     (*(reg8 *) PWM_1_PWMUDB_sP8_pwmdp_u0__A0_REG)
       #define PWM_1_COUNTER_LSB_PTR  ((reg8 *) PWM_1_PWMUDB_sP8_pwmdp_u0__A0_REG)
       #define PWM_1_CAPTURE_LSB     (*(reg8 *) PWM_1_PWMUDB_sP8_pwmdp_u0__F1_REG)
       #define PWM_1_CAPTURE_LSB_PTR  ((reg8 *) PWM_1_PWMUDB_sP8_pwmdp_u0__F1_REG) 

Я хотел было вызывать одну из функций через SWITCH-CASE но в этой конструкции контроллер пробежит по всем CASE для проверки а не сразу перепрыгнет на нужную, а у меня нет на это времени..

Задал указатель
PHP код:

reg8   *pwm[36]=
{
   & 
PWM_1_COMPARE1_LSB,
    
PWM_1_COMPARE1_LSB_PTR,
   & 
PWM_2_COMPARE1_LSB,
    
PWM_2_COMPARE1_LSB_PTR,
   & 
PWM_3_COMPARE1_LSB,
    
PWM_3_COMPARE1_LSB_PTR,
  & 
PWM_4_COMPARE1_LSB,
    
PWM_4_COMPARE1_LSB_PTR,
  & 
PWM_5_COMPARE1_LSB,
    
PWM_5_COMPARE1_LSB_PTR,
  & 
PWM_6_COMPARE1_LSB,
    
PWM_6_COMPARE1_LSB_PTR,
  & 
PWM_7_COMPARE1_LSB,
    
PWM_7_COMPARE1_LSB_PTR,
  & 
PWM_8_COMPARE1_LSB,
    
PWM_8_COMPARE1_LSB_PTR,
  & 
PWM_9_COMPARE1_LSB,
    
PWM_9_COMPARE1_LSB_PTR,
  & 
PWM_10_COMPARE1_LSB,
    
PWM_10_COMPARE1_LSB_PTR,
  & 
PWM_11_COMPARE1_LSB,
    
PWM_11_COMPARE1_LSB_PTR,
  & 
PWM_12_COMPARE1_LSB,
    
PWM_12_COMPARE1_LSB_PTR,
  & 
PWM_13_COMPARE1_LSB,
    
PWM_13_COMPARE1_LSB_PTR,
  & 
PWM_14_COMPARE1_LSB,
    
PWM_14_COMPARE1_LSB_PTR,
  & 
PWM_15_COMPARE1_LSB,
    
PWM_15_COMPARE1_LSB_PTR,
  & 
PWM_16_COMPARE1_LSB,
    
PWM_16_COMPARE1_LSB_PTR,
  & 
PWM_17_COMPARE1_LSB,
    
PWM_17_COMPARE1_LSB_PTR,
  & 
PWM_18_COMPARE1_LSB,
    
PWM_18_COMPARE1_LSB_PTR
}; 

зачем амперсанд сам не знаю-но без него компилятор ругается..

Задаю значения так
PHP код:

    if(DMADDR[1]==dmxcount) *pwm[1]= readData;
    if(
DMADDR[2]==dmxcount) *pwm[2]=readData;
    if(
DMADDR[3]==dmxcount) *pwm[3]=readData

В итоге где амперсанд те каналы работают, а где нет не работают..
Попробовал амперсанд поставить везде-ошибка компиляции:rolleyes:

DimaS 12.05.2019 21:13

Re: Подскажите по указателям
 
Цитата:

Сообщение от maagalex (Сообщение 240617)
через SWITCH-CASE но в этой конструкции контроллер пробежит по всем CASE для проверки а не сразу перепрыгнет на нужную,


Смени компилятор на нормальный.

besogon 12.05.2019 21:17

Re: Подскажите по указателям
 
maagalex
ознакомившись с Вашей проблемой предполагаю, что Вы что-то делаете очень сильно не так, как надо.

если Вы сформулируете задачу, то скорее всего Вам смогут подсказать, что Вам делать.

maagalex 12.05.2019 21:33

Re: Подскажите по указателям
 
Цитата:

Сообщение от DimaS (Сообщение 240618)
Смени компилятор на нормальный.

Компилятор ARM GCC 5.4 с оптимизацией по скорости,
конструкцию SWITCH-CASE специально испытывал, и как и предполагал она ооочень медленная, буквально с 3 строками условий сбои ,а с 18 строками вообще все тормозит..

По задаче..вроде как описал..я принимаю пакеты DMX и раскидываю байты по ШИМ ам..Так вот проблема в том что ШИМы двухканальные, у каждого есть два регистра для двух значений ,а мне нужно просто одной командой забросить одно значение в один регистр, а сделать это можно только через указатели..
Помогайте, а то сами будите смотреть Евровидение по тв с мерцающими декорациями :D

bzx 12.05.2019 21:39

Re: Подскажите по указателям
 
Цитата:

Сообщение от maagalex (Сообщение 240617)
В итоге где амперсанд те каналы работают, а где нет не работают..
Попробовал амперсанд поставить везде-ошибка компиляции:rolleyes:

Следует правильно объявить массив указателей на функцию, а потом правильно вызвать. Как-то так:
Код:

reg8 (*actions[36]) (reg8) = {
// список твоих функций

};

for( i = 1; i <= 36 ; i++ ) {
        if( DMADDR[1] == dmxcount )
                ( *pwm[1] )( readData );
}


ampersant 12.05.2019 21:52

Re: Подскажите по указателям
 
Цитата:

Сообщение от maagalex (Сообщение 240620)
Компилятор ARM GCC 5.4 с оптимизацией по скорости,
конструкцию SWITCH-CASE специально испытывал, и как и предполагал она ооочень медленная, буквально с 3 строками условий сбои ,а с 18 строками вообще все тормозит..

По задаче..вроде как описал..я принимаю пакеты DMX и раскидываю байты по ШИМ ам..Так вот проблема в том что ШИМы двухканальные, у каждого есть два регистра для двух значений ,а мне нужно просто одной командой забросить одно значение в один регистр, а сделать это можно только через указатели..
Помогайте, а то сами будите смотреть Евровидение по тв с мерцающими декорациями :D

Смешно. Уже не успел. Могу прикрыть, вот так сделать, правда для меня одноразово: https://wik-end.com/news/obschestvo/...tvo_9411.html? можно даже по всей стране. Мерцать ничего не будет. Это шутка.

besogon 12.05.2019 21:57

Re: Подскажите по указателям
 
Вы принимаете как-то какую-то команду, синтаксический анализ которой дает Вам на выходе пару - номер ШИМ, значение скважности?

если да, то я бы сделал это следующим образом:
1) определил структуру ШИМ модуля.
2) сделал массив указателей на ШИМ модули.
3) указатель на нужный ШИМ это тогда начало листа со смещением номера ШИМ.
4) модифицировал нужные регистры выбранного ШИМ исходя из скважности.

На мой взгляд это простой способ решения Вашей проблемы.
gcc компилятор собирает нормальный код.

maagalex 13.05.2019 01:38

Re: Подскажите по указателям
 
Цитата:

Сообщение от besogon (Сообщение 240623)
Вы принимаете как-то какую-то команду, синтаксический анализ которой дает Вам на выходе пару - номер ШИМ, значение скважности?

Нет..значения я принимаю по последовательному порту, и с приемом кажого значения я попадаю в прерывание по UART и мне нужно принятое значение поместить в регистр ШИМ модуля..
Проблема в том что этих регистров много и они не в массиве чтобы просто а[b]=x , а модифицируются вызовом функций..
То есть нужно как то создать массив указателей чтобы уже через них присваивать значения тем регистрам, я это сделал но получилось только с регистрами с двумя звездочками, а там где одна либо компилятор ругается, либо компилируется но при работе не меняется содержание регистра..
PHP код:

       #define PWM_1_COMPARE1_LSB    (*(reg8 *) PWM_1_PWMUDB_sP8_pwmdp_u0__D0_REG) 
       #define PWM_1_COMPARE1_LSB_PTR ((reg8 *) PWM_1_PWMUDB_sP8_pwmdp_u0__D0_REG) 

Пробовал делать указатели на сами функции, тоже была какая то ошибка что функции не того вида какого должны быть чтобы на них ссылаться через указатели..

BarsTmb 13.05.2019 06:17

Re: Подскажите по указателям
 
Вы где-то недопоняли с дефайнами… Первая строка - макрос для доступа к регистру. Вторая - указатель на тот же регистр (о чем ненавязчиво напоминает _PTR в имени).
Амперсандом Вы опять же делаете из регистра указатель. У вас инициализируется массив указателей, причем по две соседние строки одним и тем же.

besogon 13.05.2019 09:24

Re: Подскажите по указателям
 
maagalex
и они не в массиве чтобы просто а[b]=x , а модифицируются вызовом функций.. - у Вас на шине адреса расположены регистры управления конкретным модулем ШИМ. таких одинаковых модулей на шине 18, как я понял из Ваших слов.

функция это Ваша конкретная реализация какого-то действия. это не в контроллере - это у Вас в голове. gcc не предоставляет библиотеки для всей этой ерунды - она предоставляет интерфейс для работы с конкретным ядром и в общем-то всё.

maagalex 13.05.2019 11:09

Re: Подскажите по указателям
 
Цитата:

Сообщение от BarsTmb (Сообщение 240625)
Вы где-то недопоняли с дефайнами… Первая строка - макрос для доступа к регистру. Вторая - указатель на тот же регистр (о чем ненавязчиво напоминает _PTR в имени).
Амперсандом Вы опять же делаете из регистра указатель. У вас инициализируется массив указателей, причем по две соседние строки одним и тем же.

Я вижу что регистр тот же в обеих строках, но в одной период задается первому каналу ШИМ, а во второй второму (там по два ШИМ канала в каждом модуле) ..Возможно модуль 16-битный, а ШИМ 8 битные и такими дефайнами как то меняется младший и старший байты 16 битного регистра?..

Цитата:

Сообщение от besogon (Сообщение 240626)
maagalex
и они не в массиве чтобы просто а[b]=x , а модифицируются вызовом функций.. - у Вас на шине адреса расположены регистры управления конкретным модулем ШИМ. таких одинаковых модулей на шине 18, как я понял из Ваших слов.

функция это Ваша конкретная реализация какого-то действия. это не в контроллере - это у Вас в голове. gcc не предоставляет библиотеки для всей этой ерунды - она предоставляет интерфейс для работы с конкретным ядром и в общем-то всё.

Ну мне же удалось поменять каждый сторой регистр через указатели, и поиском по проекту я вышел на тело функции, эти дефайны и в конечном счете адрес того регистра в памяти..Вопрос только как их модифицировать через указатель все?..
Подсказку от bzx еще не проверял, попробую сегодня..

besogon 13.05.2019 11:19

Re: Подскажите по указателям
 
maagalex
я вышел на тело функции, эти дефайны и в конечном счете адрес того регистра в памяти - в данном случае Вам нужен datasheet. в нем должна быть раскладка памяти и описание работы модуля.


Часовой пояс GMT +3, время: 15:00.

Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd. Перевод: zCarot