skef 0 3 марта, 2013 Опубликовано 3 марта, 2013 · Жалоба Hi all! Проблема заключается в том, что компилятор космик устанавливает бит который не нужно устанавлитвать. Пример программы: #include <STM8S105C6.h> #define TEST 2 main() { PB_DDR = 255;//здесь порт настраивается на выход PB_CR1 = 255; PB_ODR = (TEST<<1);// Мы устанавливает "1" на вывод 2 порта В //И она уставливается PB_ODR = (TEST<<0);//Мы устанавливает "0" на вывод 2 порта В //И он устанавливается. А вот тут самое интересное. Которое заключеется в том, что на выводе 1, который в //этой программе не задействован, устанавливается "1" while (1) { _asm("nop");//А тут просто брейкпойнт } } На что отладчик в окне дизассемблер заявляет: 0x80ce <main> 0x35FF5007 MOV 0x5007,#0xff MOV _PB_DDR,#0xff main.c:6 PB_CR1 = 255; 0x80d2 <main+4> 0x35FF5008 MOV 0x5008,#0xff MOV _PB_CR1,#0xff main.c:7 PB_ODR = (TEST<<1); 0x80d6 <main+8> 0x35045005 MOV 0x5005,#0x04 MOV _PB_ODR,#0x04 main.c:8 PB_ODR = (TEST<<0); 0x80da <main+12> 0x35025005 MOV 0x5005,#0x02 MOV _PB_ODR,#0x02 main.c:12 _asm("nop"); 0x80de <main+16> 0x9D NOP NOP 0x80df <main+17> 0x20FD JRT 0x80de JRT 0x80de rupt_vector.c:17 return; То есть компилятор самовольно устанавил бит (номер 2) в регистре периферии (PB_ODR). Это баг компилятора? Или я неправильно понял ситуацию и что-то не так сделал? И можно ли какими-то путями (например, опциями компилятора) гарантировано исключить подобные ситуации? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 6 3 марта, 2013 Опубликовано 3 марта, 2013 · Жалоба Если в Х нужно установить бит с номером N: X = X | (1 << N) или X |= (1 << N) Если - сбросить бит с номером N: X = X & ~(1 << N) или X &= ~(1 << N) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 3 марта, 2013 Опубликовано 3 марта, 2013 · Жалоба Проблема заключается в том, что компилятор космик устанавливает бит который не нужно устанавлитвать.Вот что в таких случаях характерно, так это уверенность пишущего, что он д’Артаньян, а разработчики компилятора сами знаете кто. Чуть что — сразу «баг», «компилятор самовольно». Ну кто же признается, что он книжкой по С он в туалете пользовался, а теперь обосрался, а подтереться нечем сам ошибся. #define TEST 2Все слова TEST в коде тупо заменяются буквой 2 PB_ODR = (TEST<<1);// Мы устанавливает "1" на вывод 2 порта ВЧисло 2 сдвинули влево на один бит и получили число 4. Записали его в порт и получили там нули везде, кроме бита с номером 2. Ура, вывод с номером установился в 1-ку. Случайно совпало (а то у компилятора нашлась бі еще одна бага) так как если бы написали #define TEST 3 то вывод 3 в единичку не установился бы, вместо этого установились бы выводы 2 и 1. PB_ODR = (TEST<<0);//Мы устанавливает "0" на вывод 2 порта ВЧисло 2 сдвинули влево на 0 бит, т.е. оставили число 2. И записали в регистр порта число 2. И получили вполне ожидаемое значение 1 на ножке с номером 1. Это не то, чего ожидали и нужно на форумах спрашивать, как это «обойти», что сделать, чтобы «гарантировано исключить подобные ситуации». Говорю как обойти и как исключить: Перестать верить в то, что ты д’Артаньян, а Билл Гейтс Windows Linux IAR GCC, тьху, Cosmic — кака бяка. Везде сначала искать ошибку себя, нежно любимого и глубоко уважаемого. Читать книжки, как это ни странно звучит. P.S. Пора идти к MBedder-у на курсы по соответствующей лексике. Зла просто не хватает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться