И как тогда мне ее, структуру, объявить, если struct pos {unsigned char x, y;}; объявлено неправильно?Siarzhuk писал(а):pos это не переменная, и даже не тип (в С) - а именно что НеизвестнАЯ ИдентификАтыръ.
Програмирование pic на СИ.
- Zhuk72
- Сверлит текстолит когтями
- Сообщения: 1231
- Зарегистрирован: Ср янв 29, 2014 08:41:31
- Откуда: Баку
- Контактная информация:
Re: Програмирование pic на СИ.
Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
- КРАМ
- Друг Кота
- Сообщения: 25184
- Зарегистрирован: Чт янв 10, 2008 22:01:02
- Откуда: Московская область, Фрязино
Re: Програмирование pic на СИ.
Все это зависит от архитектуры контроллера и его системы команд.Siarzhuk писал(а):при оптимизации битовыми полями сегмента данных - страдает сегмент кода (читай производительность), за счёт большего количества операций по доступу к полям. Мало того - в зависимости от позиции битового поля в структуре - размер операций тоже может быть разным. Т.е. если с каким-то полем чаще работаем - можно также сэкономить байтики двигая поле в более выгодную позицию.
Поскольку речь идет о Микрочипе, то битовые элементы структур как раз очень хорошо ложатся на битовые команды. И код получается компактным и быстрым. Правда все зависит от компилятора и уровня оптимизации. При доступе к биту может и маску применить, а может и битовую операцию.
Категоричные заявления о вредности нестандартных типов из-за непереносимости кода не выдерживают никакой критики, потому что различия между платформами столь велики, что переносимыми будут лишь самые общие участки кода, что лишь запутывает программиста и не дает никаких преимуществ и экономии времени.
- Zhuk72
- Сверлит текстолит когтями
- Сообщения: 1231
- Зарегистрирован: Ср янв 29, 2014 08:41:31
- Откуда: Баку
- Контактная информация:
Re: Програмирование pic на СИ.
Вот у КиР написаноZhuk72 писал(а):И как тогда мне ее, структуру, объявить, если struct pos {unsigned char x, y;}; объявлено неправильно?Siarzhuk писал(а):pos это не переменная, и даже не тип (в С) - а именно что НеизвестнАЯ ИдентификАтыръ.
Код: Выделить всё
struct point {
int x;
int у;
} ;Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Програмирование pic на СИ.
лично я в подобных "подозрительных" случаях всегда объявляю пользовательский тип - ни разу сбоев не было!Zhuk72 писал(а):И как тогда мне ее, структуру, объявить, если struct pos {unsigned char x, y;}; объявлено неправильно?
Код: Выделить всё
typedef struct{
unsigned char x, y;
} point_t;
pint_t pos;категорические утверждения о невыдерживнии критики не выдерживают никакой критикиКРАМ писал(а):Категоричные заявления о вредности нестандартных типов из-за непереносимости кода не выдерживают никакой критики
потому что если есть стандарт, то надо максимально соблюдать его требования все время, пока не попал в безвыходную ситуацию. а уж в безвыходной ситуации все средства хороши.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Програмирование pic на СИ.
Третьего дня самолично в RX-GCC наткнулся.ARV писал(а):это на самом деле так? не 1 байт?
Обнаружил это в PIC16F630 с XC8 когда и сам заталкивал в него побольше функционала на фоне исчерпания .data. XC8, правда, был Free версии - а в этом режиме он имеет привычку оптимизировать с прохладцей, саботажем и лёгким вредительством - и если в PRO версии с глобальными bit по другому работает - ну тогда я не прав.Siarzhuk писал(а):скорее всего он задействует для этой цели аппаратные фичи кристалла. про PIC не скажу, а в MCS51 есть особые области ОЗУ с побитовой адресацией
Последний раз редактировалось Siarzhuk Пт ноя 18, 2016 13:38:48, всего редактировалось 1 раз.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- КРАМ
- Друг Кота
- Сообщения: 25184
- Зарегистрирован: Чт янв 10, 2008 22:01:02
- Откуда: Московская область, Фрязино
Re: Програмирование pic на СИ.
Правда это удобство приводит к достаточно громоздкому скомпилированному коду в КАЖДОЙ функции, куда передается указатель на структуру. Потому как до конкретного элемента структуры нужно еще добраться.Аlex писал(а):Ещё, плюс объединений переменных в структуры - обработка в функциях. Можно передавать указатель, как аргумент, вместо кучи переменных.
Есть стандарт языка, но нет стандарта для создаваемого кода. Все средства хороши В ЛЮБОЙ ситуации.ARV писал(а):категорические утверждения о невыдерживнии критики не выдерживают никакой критикиКРАМ писал(а):Категоричные заявления о вредности нестандартных типов из-за непереносимости кода не выдерживают никакой критики
потому что если есть стандарт, то надо максимально соблюдать его требования все время, пока не попал в безвыходную ситуацию. а уж в безвыходной ситуации все средства хороши.
Более того, если программист не применяет эти самые "все средства" всегда, то в "безвыходной ситуации" он оказывается достаточно беспомощным и полученный код действительно не выдержит никакой критики...
- Zhuk72
- Сверлит текстолит когтями
- Сообщения: 1231
- Зарегистрирован: Ср янв 29, 2014 08:41:31
- Откуда: Баку
- Контактная информация:
Re: Програмирование pic на СИ.
Спасибо, получилось!ARV писал(а):лично я в подобных "подозрительных" случаях всегда объявляю пользовательский тип - ни разу сбоев не было!
Именно в ПИКовом проекте объявлял биты, а потом в отладчике наблюдал, как они все оказывались в одном регистре в области общей памяти.ARV писал(а):про PIC не скажу, а в MCS51 есть особые области ОЗУ с побитовой адресацией, и соответствующие однобитовые команды ассемблера. так что и тут речь скорее всего об этом - линкер отдыхает.
Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Re: Програмирование pic на СИ.
Объявлен тип, но не объявлена переменная этого типа.Zhuk72 писал(а):И как тогда мне ее, структуру, объявить, если struct pos {unsigned char x, y;}; объявлено неправильно?
С битовыми полями ещё и на проверке индексов можно экономить:
Код: Выделить всё
#define BIT_SIZE 4
char ringBuffer[1 << SIZE];
struct {
char headIndex : BIT_SIZE;
char tailIndex : BIT_SIZE;
};В map-файл если ешё не заглядывали - тоже, кмк, будет интересно глянуть.Zhuk72 писал(а):а потом в отладчике наблюдал, как они все оказывались в одном регистре в области общей памяти.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- Zhuk72
- Сверлит текстолит когтями
- Сообщения: 1231
- Зарегистрирован: Ср янв 29, 2014 08:41:31
- Откуда: Баку
- Контактная информация:
Re: Програмирование pic на СИ.
Всем спасибо за очень познавательную дискуссию 
Удаляюсь для воплощения.
Удаляюсь для воплощения.
Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
- Zhuk72
- Сверлит текстолит когтями
- Сообщения: 1231
- Зарегистрирован: Ср янв 29, 2014 08:41:31
- Откуда: Баку
- Контактная информация:
Re: Програмирование pic на СИ.
В итоге решил делать так:
Поскольку использовать в подобных конструкциях более, чем 1 бит, только ухудшит конечный код (в асме добавятся маски и сдвиги, как я предполагаю), указанное выше - это просто удобство помнить только одну переменную с именем flag, в которую по необходимости можно добавлять и другие подобные флаги.
Код: Выделить всё
typedef struct {unsigned work: 1;
unsigned btn_start: 1;
unsigned flash: 1;
unsigned b3: 1;
unsigned b4: 1;
unsigned b5: 1;
unsigned b6: 1;
unsigned b7: 1;} bits;
bits flag;
Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Re: Програмирование pic на СИ.
На всякое категоричное утверждение найдётся аргу́́мент.Zhuk72 писал(а):Поскольку использовать в подобных конструкциях более, чем 1 бит, только ухудшит конечный код (в асме добавятся маски и сдвиги, как я предполагаю)
[pedantic mode on]
Если не затруднит - гляньте sizeof(bits) пожалуйста и нам сообщите для общего развития. И да - unsigned это unsigned int, и, припоминаю, явное указание вместо int восьмибитного типа в конкретном случае оптимизации под PIC16F630 сэкономило мне в своё время, таки парочку байтов. Стоит тоже проверить, кмк.
[pedantic mode off]
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- Zhuk72
- Сверлит текстолит когтями
- Сообщения: 1231
- Зарегистрирован: Ср янв 29, 2014 08:41:31
- Откуда: Баку
- Контактная информация:
Re: Програмирование pic на СИ.
1. Я не волшебник, я только учусь (с)Siarzhuk писал(а): [pedantic mode on]
1. Если не затруднит - гляньте sizeof(bits) пожалуйста и нам сообщите для общего развития.
2. И да - unsigned это unsigned int, и, припоминаю, явное указание вместо int восьмибитного типа в конкретном случае оптимизации под PIC16F630 сэкономило мне в своё время, таки парочку байтов. Стоит тоже проверить, кмк.
[pedantic mode off]
Вы только намекните где это можно увидеть, а я сразу же...
2. Вот тут я в сомнениях. Что-то написать там нужно, но что именно, чтоб они все упаковались в один байт - я не знаю. Пока времени не было уточнить.
Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Re: Програмирование pic на СИ.
Битовые поля по-честному укладываются на соответствующие биты - вопрос лишь в том, сколько займёт структура. Можно глянуть в отладчике. Можно прикинуть по map-файлу. Вот например ваши флаги в моём файле:Zhuk72 писал(а):2. Вот тут я в сомнениях. Что-то написать там нужно, но что именно, чтоб они все упаковались в один байт - я не знаю. Пока времени не было уточнить.
Код: Выделить всё
_ep_data_out bssBANK2 0131
_flag bssBANK0 006A <--------- flag (в банке 0)
_hid_rpt01 stringtext 1500
_i2cProtocol dataCOMMON 007B
_idle_rate bssBANK2 0143
_inBuffer dataCOMMON 0079
_inPipes bssBANK2 013D
_main cinit 104B
_notifyChunks bssBANK0 006B <--------- следуюший за flag-ом в банке 0
_outBuffer dataBANK0 006E
Код: Выделить всё
_ep_data_out bssBANK2 0131
_flag bssBANK2 0133 <---------
_hid_rpt01 stringtext 1500
_i2cProtocol dataCOMMON 007B
_idle_rate bssBANK2 0144
_inBuffer dataCOMMON 0079
_inPipes bssBANK2 013E
_main cinit 1048
_notifyChunks bssBANK0 006A
_outBuffer dataBANK0 006E
_outPipes bssBANK2 0120
_pBDTEntryEP0OutCurrent bssBANK1 00EA
_pBDTEntryEP0OutNext bssBANK1 00EB
_pBDTEntryIn bssBANK2 0135 <--------- 134-го в bssBANK2 нету
_pBDTEntryOut bssBANK2 0137
А упаковка относится к структурам, поскольку компилятор порой раскладывает их поля по выровненным (aligned) адресам, для ускорения работы с ними. В итоге размер такой структуры будет больше нежели сумма размеров её элементов. Если вам извне придёт пакет данных без подобных "прорех" - разобрать его простым наложением структуры на указатель будет несколько затруднительно. Поэтому при объявлении нужно явно указывать:
Код: Выделить всё
typedef struct __attribute__ ((packed)) _USB_DEVICE_DESCRIPTOR
{
uint8_t bLength; // Length of this descriptor.
[...]
Код: Выделить всё
bit bit1;
bit bit2;
bit bit3;
bit bit4;
MAIN_RETURN main(void)
{
SYSTEM_Initialize(SYSTEM_STATE_USB_START);
flag.b3 = 1;
bit1 = 0;
bit2 = 1;
bit3 = flag.b7;
bit4 = 0;
if (flag.b6 == 1 && bit1 == bit3 || bit1 != bit2 || bit2 == bit4)
USBDeviceInit();
Код: Выделить всё
__size_ofi1_LED_On (abs) 0000
_active_protocol bssBANK2 0147
_bit1 bitbssCOMMON 03D0 <--------- следим
_bit2 bitnvCOMMON 03C8 <--------- за
_bit3 bitnvCOMMON 03C9 <--------- адреса-
_bit4 bitbssCOMMON 03D1 <--------- ми
_configDescriptor1 stringtext 149C
_controlTransferState bssBANK1 00E8
[...]
Name Link Load Length Selector Space Scale
[...]
bssBANK0 66 66 6 50 1
dataCOMMON 7B 7B 1 70 1
bssCOMMON 76 76 3 70 1
bitbssCOMMON 3D0 7A 2 70 1 8 <--------- размер 2!
bitnvCOMMON 3C8 79 2 70 1 8 <--------- тоже самое.
stringtext 1400 1400 DB 28 0
[...]
PS: Других переменных типа bit кроме здесь показанных в программе нету если что.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- Zhuk72
- Сверлит текстолит когтями
- Сообщения: 1231
- Зарегистрирован: Ср янв 29, 2014 08:41:31
- Откуда: Баку
- Контактная информация:
Re: Програмирование pic на СИ.
Вот мое объявление переменных на данный момент:
А это в мар-файле:
Стало быть за границы одного байта ничего не вылезло 
Код: Выделить всё
typedef struct {unsigned work: 1;
unsigned btn_start: 1;
unsigned flash: 1;
unsigned b3: 1;
unsigned b4: 1;
unsigned b5: 1;
unsigned b6: 1;
unsigned b7: 1;} bits;
bits flag;
unsigned char flash_cnt, flash_pause;
Код: Выделить всё
_flag bssBANK0 0026
_flash_cnt bssBANK0 0027
_flash_pause bssBANK0 0028
Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
-
Пока_без_кота
- Потрогал лапой паяльник
- Сообщения: 359
- Зарегистрирован: Чт авг 08, 2013 01:06:54
Re: Програмирование pic на СИ.
Доброго времени суток. Взялся попробовать С. Ну так, самую малость, просто чтобы понять что я теряю, колупаясь в асме. Хочу значит установить предделитель Таймера0. Пишу:
Гляжу в дизассемблер, вижу результат:
В принципе устраивает (хотя я ручками покороче умею).
Помню, что на асме можно удобно по именам битов устанавливать/сбрасывать. На всякий случай лезу в заголовочный файл на используемый МК, и нахожу там заветные строчки
Отлично, заменяю код на:
получаю в итоге:
Это как понимать ? 
Код: Выделить всё
OPTION = 1<<0;
Код: Выделить всё
01A 3001 MOVLW 0x1
01B 1683 BSF 0x3, 0x5
01C 0081 MOVWF 0x1
Помню, что на асме можно удобно по именам битов устанавливать/сбрасывать. На всякий случай лезу в заголовочный файл на используемый МК, и нахожу там заветные строчки
Код: Выделить всё
/* OPTION bits */
volatile bit RBPU @ (unsigned)&OPTION*8+7;
volatile bit INTEDG @ (unsigned)&OPTION*8+6;
volatile bit T0CS @ (unsigned)&OPTION*8+5;
volatile bit T0SE @ (unsigned)&OPTION*8+4;
volatile bit PSA @ (unsigned)&OPTION*8+3;
volatile bit PS2 @ (unsigned)&OPTION*8+2;
volatile bit PS1 @ (unsigned)&OPTION*8+1;
volatile bit PS0 @ (unsigned)&OPTION*8+0;
Код: Выделить всё
OPTION = 1<<PS0;
Спойлер
Код: Выделить всё
19: OPTION = 1<<PS0;
00D 3001 MOVLW 0x1
00E 008E MOVWF 0xe
00F 3000 MOVLW 0
010 1683 BSF 0x3, 0x5
011 1801 BTFSC 0x1, 0
012 3001 MOVLW 0x1
013 3E01 ADDLW 0x1
014 1283 BCF 0x3, 0x5
015 2818 GOTO 0x18
016 1003 BCF 0x3, 0
017 0D8E RLF 0xe, F
018 3EFF ADDLW 0xff
019 1D03 BTFSS 0x3, 0x2
01A 2816 GOTO 0x16
01B 080E MOVF 0xe, W
01C 1683 BSF 0x3, 0x5
01D 0081 MOVWF 0x1
- Zhuk72
- Сверлит текстолит когтями
- Сообщения: 1231
- Зарегистрирован: Ср янв 29, 2014 08:41:31
- Откуда: Баку
- Контактная информация:
Re: Програмирование pic на СИ.
С чего это так не скажу, а для изменения отдельных бит в регистре всегда пользуюсь маской. Могли бы сделать так:
или для второго случая
Но первый лучше.
Код: Выделить всё
OPTION |= 1;
Код: Выделить всё
PS0 = 1;
Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
- КРАМ
- Друг Кота
- Сообщения: 25184
- Зарегистрирован: Чт янв 10, 2008 22:01:02
- Откуда: Московская область, Фрязино
Re: Програмирование pic на СИ.
А понимать это так, что компилятор при нулевом уровне оптимизации:Пока_без_кота писал(а): Это как понимать ?
1. Сгенерировал ДОСЛОВНЫЙ код. То есть сделал ровно то, что было написано на Си, включая промежуточные действия.
2. Обеспечил атомарность, выполняя п.1
Таким образом, сначала произвел действия с константами справа и лишь потом присвоил результат регистру option_reg.
Как Вам передо мной уже сказали, заставить ДАННЫЙ компилятор выполнить битовую операцию при нулевой оптимизации можно макросом PS0=1.
-
Пока_без_кота
- Потрогал лапой паяльник
- Сообщения: 359
- Зарегистрирован: Чт авг 08, 2013 01:06:54
Re: Програмирование pic на СИ.
Спасибо за ответы.
-
spongebob
- Грызет канифоль
- Сообщения: 289
- Зарегистрирован: Пт мар 20, 2009 12:25:47
- Откуда: Ivanovo
- Контактная информация:
Re: Програмирование pic на СИ.
День добрый!
Подскажите как реализовать такую штуку.
Необходимо создавать "некие таймеры". Их число фиксировано и равно, допустим, 8.
Есть один системный таймер T0. Он считает до 255 и объявляет tick. Дальше по этому tick инкрементируется rtc_timer (может быть long, тут дело не в этом).
Сам "некий таймер" представляет из себя структуру следующих параметров:
-активный
-начало
-продолжительность
-функция окончания
По определенному событию (это не важно) - таймер активируется. "активный" выставляется в 1, в начало записывается текущее значение rtc_timer.
Обработчик таймеров постоянно (каждый цикл) проверяет rtc_timer и начало и продолжительность активных таймеров. как только "начало+продолжительность">=rtc_timer - "активный"=0 и выполняется функция.
Вроде алгоритм понятен, а в структурах я чот туплю.
Подскажите как реализовать такую штуку.
Необходимо создавать "некие таймеры". Их число фиксировано и равно, допустим, 8.
Есть один системный таймер T0. Он считает до 255 и объявляет tick. Дальше по этому tick инкрементируется rtc_timer (может быть long, тут дело не в этом).
Сам "некий таймер" представляет из себя структуру следующих параметров:
-активный
-начало
-продолжительность
-функция окончания
По определенному событию (это не важно) - таймер активируется. "активный" выставляется в 1, в начало записывается текущее значение rtc_timer.
Обработчик таймеров постоянно (каждый цикл) проверяет rtc_timer и начало и продолжительность активных таймеров. как только "начало+продолжительность">=rtc_timer - "активный"=0 и выполняется функция.
Вроде алгоритм понятен, а в структурах я чот туплю.
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Програмирование pic на СИ.
Ну, примерно как то так :
Код: Выделить всё
typedef struct{
unsigned enabled :1;
unsigned start :1; // Тут не понял, что за "начало" такое и зачем оно нужно...
unsigned long time;
void* call_back_func; // Тут, скорее всего будет не так, а указатель на созданный ранее тип каллбека. Это уже тонкости
}Timer;