Пост N: 613
Зарегистрирован: 16.03.09
Откуда: Родина, Севастополь
Рейтинг:
1
Отправлено: 12.02.13 14:21. Заголовок: Систематизация кода и оформление программ.
В процессе написания программы зачастую возникают сложности и вопросы по её ПРАВИЛЬНОМУ оформлению. Особенно важно это начинающему, потому как лучше сразу привыкать к правильному и удобному оформлению и написанию, чем потом "переучиваться". Одной из моих настольных книг является пособие Виктора Тимофеева (Tester) "Как правильно оформлять программы на ассемблере для PIC-контроллеров". Очень грамотно, наглядно и доходчиво изложен материал. Но хочется продолжения! Здесь можно задавать свои вопросы, либо делиться наработками, алгоритмами, ПП, примерами.
А ни кто и не спорит. Любая толковая информация, помогающая в освоении предмета изучения и не содержащая ошибок или противоречий, есть благо. Каждый ищет то, что ему легче в понимании и освоении. Потому их и такое количество, а споры что лучше или хуже не утехают. Но теория, как Вы знаете, без практики мертва. И всё надо проверять в "железе". По тому мы здесь и собрались, чтоб не останавливаться на достигнутом, а обмениваться опытом, вопрошать, советовать, искать решения, алгоритмы. Всё для этого есть.
Отправлено: 05.02.13 14:30. Заголовок: Александр пишет: на..
Александр пишет:
цитата:
на самом деле могу сказать от себя что больше мне помог самоучитель 2
Как бы этот самоучитель не сыграл злую шутку... Все что там написано просто противоречит здравому смыслу, в смысле оформления и лирических отступлений. Лично мне очень было сложно даже читать чужие программы. Сейчас мне стало куда проще, даже переход с piс контроллеров на STM32 стал просто детской игрой... По сути пара дней и контроллер был уже запущен, а это основа. Осталось просто изучать работу его модулей, что тоже не составило особых затруднений пока... По сути стоит относится серьезно только к первой части самоучителя, остальное следует принимать только к сведению или как помощь, но ни в коем случае как образец для подражания... Сейчас даже многие птенцы до сих пор не умеют пользоваться файлами с описание стандартных регистров, не пользуются директивой cblock и многим другим. Вы попробуйте из первой части самоучителя подключить #include <p16F84A> и убрать назначение адресов стандартным регистрам специального назначения типа STATUS и увидите что программа даже не скомпилируется... Всему виной нестандартное оформление программы. Даже сейчас еще не все исключенные переучились на стандартное оформление программ, до сих пор используют вместо bsf STATUS,RP0 запись bsа STATUS,5 не смотря на то, что первая запись значительно понятнее...
Пост N: 609
Зарегистрирован: 16.03.09
Откуда: Родина, Севастополь
Рейтинг:
1
Отправлено: 05.02.13 15:21. Заголовок: Алексей пишет: Даже..
Алексей пишет:
цитата:
Даже сейчас еще не все исключенные переучились на стандартное оформление программ, до сих пор используют вместо bsf STATUS,RP0 запись bsа STATUS,5 не смотря на то, что первая запись значительно понятнее...
Наверное bsf STATUS,5. Согласен, лучше привыкать сразу к надлежащему написанию, тем более это и самому полезнее, так как в мозгах фиксируется правильное название бита в регистре, а не его местоположение. Но мне , допустим, иногда яснее использовать именно второй вариант, потому как чаще и быстрее запоминается именно положение бита в регистре, а не его название. Тем более названия бывают очень созвучны и можно ошибиться. Но в любом случае полезно даже для самого себя в коментах фиксировать действие, зачем используется та или иная команда или блок команд. А вот для чего прописывать (назначать) адреса стандартным спец. регистрам, я так и не понял. Что это даёт? При отладке их можно всегда вывести в окне, там и адреса их есть. А подключив инструкцию МК они и так сами определяются. Ни когда не прописывал их. Очень полезная вещь от Tester есть по оформлению программ, иногда перечитываю.
Отправлено: 05.02.13 19:00. Заголовок: не bcf STATUS,5 и b..
не bcf STATUS,5 и bcf STATUS,RP0 это все неправильно по сути. Правильно banksel, для совместимости и переносимости. Хотя по сути, все будет работать. На мой взгляд не страшно. Заморачивать себе голову на этом не надо. Каждый придет к удобному для себя варианту
Пост N: 611
Зарегистрирован: 16.03.09
Откуда: Родина, Севастополь
Рейтинг:
1
Отправлено: 10.02.13 22:05. Заголовок: Кстати, на счёт bank..
Кстати, на счёт banksel. Если необходимо произвести действие над несколькими спец регистрами, как то не удобно перед каждым выбор банка ставить. И потом, после действия над регистром, как знать в каком банке ты находишься? Лично мне ближе принудительный выбор, как то надёжнее. И через силу бит названием прописываю, типа так правильнее, хороший тон. Цифрой быстрее, понятнее и удобнее, ИМХО! Ведь когда инициализируешь МК, удобнее бинарным способом регистры прописывать. Тут и место бита видно, и менять легко.
В том то и дело что нет. Это ты сейчас знаешь каждый номер бита наизусть. А теперь представь что этих битов сотни и разбросаны по десяткам регистров. Когда ты работаешь с PIC12 или PIC16 их немного, и запомнить их можно в принципе. Но вот если у тебя был перерыв в работе? Ну предположим месяц? вспомнишь ли ты все биты по номерам? Очень сомневаюсь. Вот давай к примеру вспомни какой бит отвечает за включение таймера 1 в PIC16F628A. Только по честному, не заглядывая ни в даташит, ни в свои ни в чужие исходники, ни куда либо еще кроме своей памяти... Я допустим напишу просто
bsf T1CON, TMR1ON
Тут даже коментария не нужно, и так прекрасно видно что этой строкой включается тмр1. Или же например надо включить прерывания и разрешить прерывание по INT0. Если написать так
movlw (1<<GIE | 1<<INTE) movwf INTCON
Сразу видно что делаешь этой строкой и без комментариев и без заглядывания в даташит... А теперь попробуй тоже самое написать пользуясь только своей памятью... А потом в ходе отладки программы все это еще и помнить. А представь что программа у тебя сразу не заработала и ты полез проверять правильно ли ты задал маску? Немудрено и ошибиться... А запись здесь расшифровывается очень просто, 1 сдвинуть влево на константу GIE, т.е. 7 раз влево. Вот и получим старший бит под №7 в маске. Знак | всего лишь означает логическую операцию ИЛИ. Таким образом и формируем маску для регистра INTCON. Теперь предположим что в ходе написания программы тебе понадобилось включить еще прерывания по изменению уровня сигнала на порту В и ты не помнишь номер бита... Лезем в даташит ищем нужный номер бита и переставляем в маске нужный битик... Пользуясь константами это можно сделать даже не заглядывая в даташит
movlw (1<<GIE | 1<<INTE | 1<<RBIE) movwf INTCON
Просто добавив еще одну запись 1<<RBIE. Маска формируется автоматически и сразу с первого взгляда видно что она делает. Я сразу смогу сказать что данной маской разрешаются все прерывания, включается прерывание по INT0 и по изменению уровня на порте В... Кстати, для ярых противников Си. Си вообще здесь не при чем, это голый асм... Таким же макаром очень удобно сбрасывать флаги, т.к. не нужно помнить номера битов
bcf INTCON, INTF и bcf INTCON, RBIF
И при первом же беглом просмотре чужой программы видно сразу что мы делаем. Да даже при просмотре своей собственной программы при отладке уже не нужно держать в памяти что делается данными строками. Да, я помню, какой был гемор, когда писал тоже только номера битов. Сколько мозг поломаешь пока отлаживаешь. Как только начал пользоваться константами текст программы стал в разы легче читаться... Даже если в программе мне нужны флаги, ну например 6 штук, я для них стараюсь объявлять символьные имена. Например объявляю регистр Flag а для его же битов объявляю константы
и пишу уже так bcf Flag, fl2 и при отладке программы я уже знаю какой флаг сбросил. А удержать в памяти каждый бит регистра Flag тяжеловато, постоянно путаешься... естественно fl2 определение только условно для примера, в реальности каждому биту даю осмысленные названия, соответствующие смыслу этого флага. Мне лично непонятна такая вот тяга в программе писать сами номера битов вместо стандартных предопределенных для них констант . Сан Саныч, вот смотри когда ты показываешь свои программы с какими то циферками, обозначающих номер бита, лично мне крайне тяжело так посмотреть. Тот же банк переключить... RP0 и RP1 это понятно, а какие биты действительно за это отвечают в регистре STATUS я уже точно и не помню... Поэтому запись STATUS,5 мне вообще ни о чем не говорит... А все это школа КЕА... Надо отвыкать уже. Обязательно нужно пользоваться константами и не заниматься мазохизмом, тем более на асме, где и так хватает забот . Понятнее как раз не цифрой, а стандартной константой, которая уже определена за нас. Нам остается только пользоваться... Насчет быстрее тоже можно поспорить, учитывая время на ползание по даташиту в поисках нужного бита. С удобнее я бы тоже поспорил, особенно при отладке программы, когда видишь только номера битов а не их символьные имена... пока вспомнишь что это за бит такой... мозг сломаешь...
Вся беда в том, что названия битов, регистров, кто за что, пока в голове не задерживаются. Но посидев 2 недели с мплабом и ДШ под подушкой, кое что проясняется. Не знал о таком приёме
movlw (1<<GIE | 1<<INTE | 1<<RBIE) movwf INTCON
Не важна очерёдность? Очень удобно и видно сразу. Всё, буду причёсывать свою новую прогу! Ещё вопрос, константы в каком лучше виде. Мне удобнее в десятичном, типа .120 . К адресам не относится, просто число в регистре. Была здесь хорошая тема "Систематизация кода и оформление программ", так кажется называлась. Но в пылу боя она сгорела! Может возобновить? Довольно часто возникают вопросы и по оформлению, и по алгоритмам, стандартным процедурам и тд. Можно было бы делиться своими наработками в этом вопросе. Я её создам, а там видно будет! Алексей
Отправлено: 12.02.13 14:26. Заголовок: SanSanich пишет: и ..
SanSanich пишет:
цитата:
и мучаюсь в протеусе, ругается гад и всё! Потом углядел, НОЛИК пропустил, мать его!
А ты знаешь сколько я раз на такие грабли наступал? и на подобные... SanSanich пишет:
цитата:
Не важна очерёдность?
Не важна... Сам посуди... эта запись будет абсолютна эквивалентна вот такой (b'10000000' ИЛИ b'00010000' ИЛИ b'00001000') = b'10011000' теперь если заглянешь в дизасм этой строки то увидишь
movlw b'10011000' movwf INTCON
именно это, в какой бы последовательности биты ты не поставил. Т.е. запись маски через константы мало того что наглядно видно что за маска задается, чтобы ошибиться надо еще очень сильно постараться, так еще и абсолютна эквивалентна и не создает лишних команд... SanSanich пишет:
цитата:
Ещё вопрос, константы в каком лучше виде.
Все зависит от задачи, которую преследует константа... В дизасемблере все равно все будет в двоичном виде... Например перекодировку из двоично десятичных чисел в код семисегментного индикатора удобно задавать в двоичном виде, константы в счетчике в десятичном, маски задавать удобно опять в двоичном. в шестнадцатиричном удобно байты в массив укладывать. Вобщем все зависит от задачи. допустим чтобы задать маску когда ты знаешь какие номера битов нужно считать а которые обнулить, например так b'00110101' (Ну или лучше воспользоваться либо стандартными константами, или сразу определить из самому), сразу в двоичном можно задать чтобы не переводить в другую систему, просто смысла нет... но можно и перевести, но тогда если будешь править программу потеряешь наглядность, например при переключении ножек порта... Опять придется переводить и туда и сюда... Если организовываешь счетчик, то естественно зачем мозг ломать другими системами, если сразу знаешь что счетчик должен отсчитать ровно .120 раз? Естетсвенно что константу лучше записать сразу в десятичном виде. Вот еще пример. Ты подключаешь например LCD к контроллеру и работаешь с ним в программе так
bsf PORTA,0 ; Формирование импульса строба на линии Е bcf PORTA,0
А теперь ситуация. Начал разводить печатную плату и все у тебя очень хорошо, красиво получается, НО! линии E и А0 у тебя пересекаются и никак не разводятся по другому. Решение простое, как дважды два, поменять местами эти две ножки на плате... В программе их тоже надо перекинуть. Хорошо если у тебя формирование строба только в одном месте и надо только подправить эти две команды, а также формирование А0, а вот его уже точно будет больше! и ты начинаешь шерстить всю программу чтобы подменить, и можешь сделать еще кучу ошибок... Поэтому лично я поступаю так
#define E PORTA,RA0 #define A0 PORTA,RA1
А в программе просто пишешь уже
bsf E bcf E
и так же с А0... Теперь тебе достаточно поменять их местами в шапке, а все остальное сделает компилятор. Для задания направления работы этих самых ножек поступаю точно таким же образом.
Пост N: 615
Зарегистрирован: 16.03.09
Откуда: Родина, Севастополь
Рейтинг:
1
Отправлено: 12.02.13 16:15. Заголовок: Не удержался, уж бол..
Не удержался, уж больно мне нравится пример оформления программы у В. Тимофеева. При желании можно воспользоваться готовыми блоками, адаптируя их под свои нужды.
;******************************************************************************* ; voltmetr.asm ; ; Одноканальный вольтметр 0..Vdd с выводом на 3х позиционный 7-сегментный индикатор. ; ; RA0 - аналоговый вход ; RC5, RC6, RC7 - общие катоды сегментов ; portb - управление сегментами ; ; Программа является примером, поясняющим правила оформления, описанных в статье: ; "MPASM: как правильно оформлять программы на ассемблере для PIC-контроллеров" ; ; Автор: В.Тимофеев, testerplus@mail.ru, osa@pic24.ru ; ; История: 13.11.2010 - Файл создан ; ;*******************************************************************************
;******************************************************************************* ; ; КОНСТАНТЫ ПОЛЬЗОВАТЕЛЯ (могут меняться в зависимости от режима) ; ;*******************************************************************************
F_OSC equ .4000000 ; Тактовая частота (Гц) F_ADC equ .1000 ; Частота измерений ADC ; Для отображения на индикаторе производится ; осреднение по 128 выборкам
;------------------------------------------------------------------------------- ; Параметры входного сигнала ;------------------------------------------------------------------------------- V_REF equ .5000 ; Задаем напряжение опоры (мВ) ADC_RESOLUTION equ .10 ; Разрешение АЦП AVERAGE_CONST equ .16-ADC_RESOLUTION ; Константа осреднения будет зависеть от ; разрядности АЦП с тем, чтобы сумма ; измерений четко уложилась в два байта
TRISB_CONST equ b'00000000' ; Все выходы PORTB_CONST equ b'11111111' ; Управление сегментами
SEG_A equ (1<<0) ; Назначение сегментов в индикаторах SEG_B equ (1<<1) ; SEG_C equ (1<<2) ; A SEG_D equ (1<<3) ; F B SEG_E equ (1<<4) ; G SEG_F equ (1<<5) ; E C SEG_G equ (1<<6) ; D H SEG_H equ (1<<7) ;
TRISC_CONST equ b'00000000' ; Все выходы PORTC_CONST equ b'00000000'
; Проверка, что получили константу, соответствующую разрядности TMR8 (не более 8 бит) #if TMR0_CONST >= 256 error Неправильно выбрана константа TMR0_PRS_CONTS! Следует увеличить ее значение! #endif
CBLOCK 0x20 output_text :3 ; Текстовое представление напряжения cur_digit ; Текущая цифра для отображения
work_data :3 ; Для преобразования из единиц АЦП в милливольты adc_average_data :2 ; Результат АЦП adc_average_counter ; Счетчик измерений при усреднении (см. ADC_AVERAGE)
product :3 ; Переменные для подпрограммы умножения multiplier :2
divider ; Переменная для подпрограммы деления со сдвигом
div_result ; Переменные для bin2dec преобразования
btfss adc_average_counter, AVERAGE_CONST ; Пропускаем измерение, если основная программа ; еще не обработала данные bsf adcon0, GO ; Запускаем следующее преобразование
bcf PIN_DIGIT_0 ; Сначала гасим все три индикатора bcf PIN_DIGIT_1 ; bcf PIN_DIGIT_2 ; clrf portb ; ;----------------------------------------------------------------------- movf cur_digit, w ; Включаем один из сегментов btfsc status, Z ; bsf PIN_DIGIT_0 ; btfsc cur_digit, 0 ; bsf PIN_DIGIT_1 ; btfsc cur_digit, 1 ; bsf PIN_DIGIT_2 ; ;----------------------------------------------------------------------- addlw output_text ; Зажигаем нужные сегменты movwf fsr ; fsr = адрес цифры для вывода movf indf, w ; movwf portb ; ;----------------------------------------------------------------------- incf cur_digit, f ; Берем следующую позицию (0,1,2,0,1,2,0,...) movf cur_digit, w ; xorlw 0x3 btfsc status, Z ; clrf cur_digit ;
banksel pie1 ; Пропускаем, если прерывание запрещено btfss pie1, ADIE ; или не завершено goto ADIF_Skip ; banksel pir1 ; btfss pir1, ADIF ; goto ADIF_Skip ; ;----------------------------------------------------------------------- bcf pir1, ADIF ;----------------------------------------------------------------------- ; Условия сброса сторожевого таймера: ; 1. Прерываня T0IF и ADIF возникают и ; обрабатываются не реже, чем раз в 18 мс clrwdt ; 2. Основная программа периодически получает ; управление (т.к. adc_average_counter обнуляется) ; Следовательно, если попали в эту точку, значит, ; программа работает в штатном режиме ;-------------------------------;
banksel adresl ; Выполняем сложение: movf adresl, w ; adc_average_data = adc_average_data + ADRES banksel adresh ; addwf adc_average_data, f ; movf adresh, w ; btfsc status, c ; incf adresh, w ; addwf adc_average_data+1, f ; incf adc_average_counter, f ; Увеличиваем счетчик выборок btfss adc_average_counter, AVERAGE_CONST ; Собрали ли нужное количество выборок? goto ADIF_Skip ; Еще нет.
movf adc_average_data, w ; Если собрали, то переносим данные в рабочую movwf work_data ; переменную: work_data = adc_average_data movf adc_average_data+1, w ; movwf work_data+1 ; clrf work_data+2 ;
clrf adc_average_data ; Готовим переменную к сбору следующих выборок clrf adc_average_data + 1 ;----------------------------------------------------------------------- ADIF_Skip: clrf status
;------------------------------------------------------------------------------- Int_Exit: movf fsr_temp, w movwf fsr movf pclath_temp, w movwf pclath movf status_temp, w movfw status swapf wreg_temp, f swapf wreg_temp, w retfie
;******************************************************************************* ; ; ОСНОВНОЙ ЦИКЛ ; ;*******************************************************************************
clrf adc_average_counter
clrf adc_average_data ; Сумма для осреднения изначально = 0 clrf adc_average_data +1 ; clrf adc_average_data +2 ;
;----------------------------------------------------------------------- ; Сейчас в рабочей переменной word_data сумма последних ; (1<<AVERAGE_CONST) измерений ;-----------------------------------------------------------------------
movlw AVERAGE_CONST lcall DivideShift
;----------------------------------------------------------------------- ; Переводим из единиц АЦП в милливольты: ; work_data = work_data * V_REF/(1<<ADC_RES) ;----------------------------------------------------------------------- call MultiplyVRef ; Умножить work_data на V_REF movlw ADC_RESOLUTION lcall DivideShift ; Делить work_data на (1<<ADC_RESOLUTION)
call Bin2Dec ; Перевести work_data в массив десятичных чисел
lgoto Main
;******************************************************************************* ; ; ФУНКЦИИ ; ;*******************************************************************************
;******************************************************************************* ; MultiplyVRef ;------------------------------------------------------------------------------- ; Функция выполняет перемножение: work_data = work_data * (V_REF/10) ; Т.к. используются только 3 значащие цифры, то единицы мВ не нужны, ; поэтому пересчет ведется в измерении 10мВ ; ; Использует переменные: ; multiplier[2] - второй множитель ; product[3] - произведение ; На выходе: ; work_data = product ;------------------------------------------------------------------------------- MultiplyVRef: clrf product ; Обнуляем произведение clrf product+1 ; clrf product+2 ; clrf product+3 ;
;----------------------------------------------------------------------- MV_Loop: btfss multiplier, 0 ; Если очередной бит goto MV_SkipSumm ; второго множителя установлен,
movf work_data, w ; то выполняем сложение двух 3-байтовых addwf product, f ; чисел movf work_data+1, w ; btfsc status, C ; incfsz work_data+1, w ; addwf product +1, f ; movf work_data+2, w ; btfsc status, C ; incfsz work_data+2, w ; addwf product +2, f ;
MV_SkipSumm:
bcf status, C ; Увеличиваем вес слагаемого rlf work_data, f ; rlf work_data+1, f ; rlf work_data+2, f ;
bcf status, C ; Берем следующий разряд rrf multiplier+1, f ; rrf multiplier, f ;
movf multiplier, w ; Прекращаем вычисления, когда заканчиваются iorwf multiplier+1, w ; биты во втором множителе btfss status, Z ; goto MV_Loop ; ;-----------------------------------------------------------------------
movf product, w ; Копируем произведение в рабочую переменную movwf work_data ; movf product+1, w ; movwf work_data+1 ; movf product+2, w ; movwf work_data+2 ;
return ; MultiplyVRef
;******************************************************************************* ; DivideShift ;------------------------------------------------------------------------------- ; Функция выполняет деление work_data на(1<<WREG) по правилам целочисленного деления: ; ; X/Y -> (X + Y/2) / Y ; ; Использует перемнные: ; divider - счетчик цикла сдвигов ; На входе: ; work_data - делимое ; WREG - степень делителя (1 << WREG) ; На выходе: ; work_data ; ;------------------------------------------------------------------------------- DivideShift: movwf divider DS_Loop: bcf status, C ; Выполняем нужное количество сдвигов, rrf work_data+2, f ; т.е. эквивалент деления на (1 << divider) rrf work_data+1, f rrf work_data+0, f decfsz divider, f goto DS_Loop
;----------------------------------------------------------------------- ; На данный момент CARRY=1, если остаток больше половины делителя ; в этом случае нужно прибавить к частному "1" ;-----------------------------------------------------------------------
btfsc status, C incfsz work_data+0, f return incfsz work_data+1, f return incf work_data+2, f return
; DivideShift
;******************************************************************************* ; Bin2Dec ;------------------------------------------------------------------------------- ; Функция переводит переменную work_data в массив комбинаций для вывода на ; 7-сегментный индиктор ; ; На выходе: ; output_text ;------------------------------------------------------------------------------- Bin2Dec:
; Дополняем таблицу до 16 значений, чтобы предотвратить ; улет неизвестно куда при неправильном значении wreg на входе retlw 0 retlw 0 retlw 0 retlw 0 retlw 0 retlw 0
;******************************************************************************* ; ; Конец программы Voltmetr.asm ; ;*******************************************************************************
ADC_RESOLUTION equ .10 ; Разрешение АЦП AVERAGE_CONST equ .16-ADC_RESOLUTION ; Константа осреднения будет зависеть от ; разрядности АЦП с тем, чтобы сумма ; измерений четко уложилась в два байта adc_average_counter ; Счетчик измерений при усреднении (см. ADC_AVERAGE) ADCON1_PCFG_CONST equ b'1110' ; RA0 - аналоговый, остальные - цифровые
Вот, просто взял из шапки. Т.е. в программе вместо символьных имен констант будет поставлены их значения, присвоенные в шапке... А adc_average_counter это просто регистр общего назначения...
Отправлено: 13.02.13 18:10. Заголовок: SanSanich пишет: А ..
SanSanich пишет:
цитата:
А вот как у тебя, типа
movlw (1<<GIE | 1<<INTE) movwf INTCON
не получается.
Ты уверен что правильно все делаешь? Я специально попробовал, думал может чего с синтаксисом, все норма, работает... константа пишется в регистр... Код выложи на чем пробуешь... У меня мплаб 8,63. SanSanich пишет:
цитата:
banksel или вначале и в конце блока STATUS, RP0
в принципе можно и так и так, но лучше banksel. Это просто встроенный макрос, который соответственно раскладывается на
bsf STATUS,RP0 bcf STATUS,RP1
комбинации bsf и bcf могут меняться в зависимости от банка, но обязательно будут присутствовать эти две команды. Макросу вообще все равно какой выбран текущий банк. Хоть вторая команда при переходе из 0 банка в принципе лишняя, но при применении banksel все равно она будет присутствовать. Естественно банк будет выбран до тех пор, пока ты его снова не переключишь в программе...
Пост N: 619
Зарегистрирован: 16.03.09
Откуда: Родина, Севастополь
Рейтинг:
1
Отправлено: 13.02.13 18:34. Заголовок: Алексей пишет: Есте..
Алексей пишет:
цитата:
Естественно банк будет выбран до тех пор, пока ты его снова не переключишь в программе...
Т.е. если я находясь в 0 банке обратился в другой к регистру через banksel, и не вернулся после этого обратно, продолжая работать с регистрами 0 банка, будет ошибка? Это что ж к каждому регистру надо через banksel обращаться? Вот на счёт Алексей пишет:
цитата:
Код выложи на чем пробуешь...
Init clrf STATUS clrf GPIO ; Инициализация защелок GPIO на выход movlw B'00000111' ; Компаратор выключен movwf CMCON ; Регистр компаратора bsf STATUS,5 movlw B'00000101' ; Каналы GP2,GP0(5,7 нога)- выход, остальные – цифровые входы movwf TRISIO movlw B'00110001' ; AD clock internal rc, выбор АЦП0 (7 нога) movwf ANSEL movlw B'00000000' ; Подтягивающие резисторы выключены movwf WPU movlw B'01001111' ; WDT 1:256, по переднему фронту,INTEDG(OPTION_REG<6>) movwf OPTION_REG movlw B'10010000' ; Разрешить все не маскированные прерывания, на входе GP2/INT movwf INTCON bcf STATUS,5 movlw B'10000001' ; Правое выравнивание, Vdd, AN0,АЦП включен movwf ADCON0
Бинарные надо заменить, если не трудно, смени парочку а я проверю. Я взял твой пример и вставил, лаб заругался на синтаксис. MPLAB IDE Version 8.30.00.00
Release build of project `D:\!PROJECT\!SANICH\Heater_12F675\Heater_12F675.mcp' started. Language tool versions: MPASMWIN.exe v5.48, mplink.exe v4.46, mplib.exe v4.46 Wed Feb 13 20:52:13 2013 ---------------------------------------------------------------------- Clean: Deleting intermediary and output files. Clean: Done. Executing: "C:\Program Files (x86)\Microchip\MPASM Suite\MPASMWIN.exe" /q /p12F675 "Heater_12F675.asm" /l"Heater_12F675.lst" /e"Heater_12F675.err" /o"Heater_12F675.o" Message[312] D:\!PROJECT\!SANICH\HEATER_12F675\HEATER_12F675.ASM 62 : Page or Bank selection not needed for this device. No code generated. Error[113] D:\!PROJECT\!SANICH\HEATER_12F675\HEATER_12F675.ASM 140 : Symbol not previously defined (TRIS2) Error[113] D:\!PROJECT\!SANICH\HEATER_12F675\HEATER_12F675.ASM 140 : Symbol not previously defined (TRIS0) Halting build on first failure as requested. ---------------------------------------------------------------------- Release build of project `D:\!PROJECT\!SANICH\Heater_12F675\Heater_12F675.mcp' failed. Language tool versions: MPASMWIN.exe v5.48, mplink.exe v4.46, mplib.exe v4.46 Wed Feb 13 20:52:14 2013 ---------------------------------------------------------------------- BUILD FAILED
Причём по разному пробовал, и в ручную вводил, и с ДШ копировал, не принимает.
Отправлено: 13.02.13 22:30. Заголовок: Ты подключал файл #i..
Ты подключал файл #include <P12F675.INC>? если да то все должно работать. В любом случае надо смотреть этот файл. Сейчас посмотрел эти константы объявлены так
Все даты в формате GMT
3 час. Хитов сегодня: 8
Права: смайлы да, картинки да, шрифты нет, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет