Форум Микро-Чип
Поиск и заказ электронных компонентов
 

Вернуться   Форум Микро-Чип > Вопросы начинающих

Вопросы начинающих Прежде чем задать вопрос, стоит воспользоваться поиском

Ответ
 
Опции темы Опции просмотра
Старый 30.11.2014, 11:56   #1
oleg-star
Junior Member
 
Регистрация: 28.11.2014
Сообщений: 2
Вес репутации: 100/0
oleg-star will become famous soon enougholeg-star will become famous soon enough
По умолчанию 12F675, работает не так, как запрограммировано

Здравствуйте!
Как начинающий, занимаюсь морганием светодиодов, написал вот такую программку (Product Version: MPLAB X IDE v2.26, System: Linux version 3.0.3-std-def-alt0.M60P.1 running on i386; UTF-8; ru_RU (mplab)
Код:
#include <xc.h>
#include <pic12f675.h>

// CONFIG
#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-Up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // GP3/MCLR pin function select (GP3/MCLR pin function is digital I/O, MCLR internally tied to VDD)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)

#define LED_5 GPIO5
#define LED_4 GPIO4
#define LED_3 GPIO2
#define LED_2 GPIO1
#define LED_1 GPIO0

#define led_on 1
#define led_off 0


volatile unsigned int RTC = 0; //глобальная переменная

void interrupt TMR0_int(void) //прерывание от таймера 0
{
    if (T0IF) //если сработало прерывание от таймера
    {
        T0IF = 0; //сбросить бит прерывания
        RTC++; //RTC увеличить на 1

    }

}

void DELAY(void) //функция "задержка"
{
    unsigned int dlay = 0; //инициализация переменной
    dlay = 256 + RTC; // к RTC прибавляем 256 мс
    while (dlay != RTC); //ждём эти самые 256 мс
}

void INIT(void) //инициализация
{
    T0CS = 0; //Выбор тактового сигнала для TMR0, внутренний тактовый сигнал
    PSA = 0; //предделитель включен перед TMR0
    PS0 = 1; //предделитель, коэффициент деления 1:4
    PS1 = 0; //предделитель, коэффициент деления 1:4
    PS2 = 0; //предделитель, коэффициент деления 1:4
    T0IE = 1; //Разрешение прерывания по переполнению TMR0
    GIE = 1; //Глобальное разрешение прерываний
    TMR0 = 0; //сброс таймера
    TRISIO5 = 0; // канал работает как выход
    TRISIO4 = 0; // канал работает как выход
    TRISIO3 = 1; // канал работает как вход(всегда)
    TRISIO2 = 0; // канал работает как выход
    TRISIO1 = 0; // канал работает как выход
    TRISIO0 = 0; // канал работает как выход
    GPIO5 = 0; //светодиод потушен
    GPIO4 = 0; //светодиод потушен
    GPIO2 = 0; //светодиод потушен
    GPIO1 = 0; //светодиод потушен
    GPIO0 = 0; //светодиод потушен
}


int main(void) {
    INIT();
    while(1)
    {
    LED_5 = led_on;  //включаем 5-й светодиод
    DELAY();         //задержка
    LED_4 = led_on;  //включаем 4-й светодиод
    DELAY();
    LED_3 = led_on;  //и т.д.
    DELAY();
    LED_2 = led_on;
    DELAY();
    LED_1 = led_on;
    DELAY();

    LED_5 = led_off;  //выключаем 5-й светодиод
    DELAY();          //задержка
    LED_4 = led_off;  //выключаем 4-й светодиод
    DELAY();
    LED_3 = led_off;  //и т.д.
    DELAY();
    LED_2 = led_off;
    DELAY();
    LED_1 = led_off;
    DELAY();
    }
}
По теории должны загораться подряд 5 светодиодов, затем выключаться.
Но получается так: загорается 5-й светодиод, затем 4-й, потом 5-й продолжает гореть, 4-й гаснет и включается 3-й и т.д; 5-й горит постоянно, а вот с 4-го по 1-й - это "бегущий огонь". Потом выключается 5-й светодиод и программа просто отрабатывает несколько задержек при выключенных остальных светодиодах.
Пробовал сделать так:
Код:
GPIO5=1;//включаем светодиод
DELAY();
GPIO4=1;//включаем светодиод
...
И так
Код:
asm (" bsf GPIO,0"); //включаем светодиод
DELAYY();
asm (" bsf GPIO,1"); //включаем светодиод
...
И даже так:
Код:
    list      p=12f675       ; list directive to define processor
    #include </1/1.1>        ; это вместо </opt/microchip/mplabx/mpasmx/p12f675.inc>

  __CONFIG  _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_OFF &_INTRC_OSC_NOCLKOUT

;_CP_OFF             - Program Memory code protection is disabled
;_CPD_OFF            - Data memory code protection is disabled
;_BODEN_OFF          - BOD disabled
;_MCLRE_OFF          - GP3/MCLR pin function is digital I/O, MCLR internally tied to VDD
;_WDT_OFF            - WDT disabled
;_PWRTE_OFF          - PWRT disabled
;_INTRC_OSC_NOCLKOUT - INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN


            ; ==ИНИЦИАЛИЗАЦИЯ
            bcf        STATUS,RP0  ; Установить банк 0
            clrf       GPIO        ; Нулим весь порт

            movlw      0x07        ; все каналы - цифровые входы-выходы
            movwf      CMCON

            bsf        STATUS,RP0  ; Установить банк 1
            movlw      b'00000000' ; GP 0,1,2,4,5  на выход
            movwf      TRISIO      ; Но все равно GP3 всегда будет на вход

            movlw      b'00000000' ; Выключить подтяжку(резистор)
            movwf      WPU         ; Подтягивающие резисторы выключены

            movlw      b'00000000' ;
            movwf      T1CON       ; Отключить TMR1

            movlw      b'00000111' ; таймер0 работает от внутреннего генератора,
            movwf      OPTION_REG  ; предделитель 256

            movlw      b'00000000' ;
            movwf      VRCON       ; Отключить источник опорного напряжения
            clrf           INTCON      ; запретить все прерывания

        ; ЗАГРУЗИМ КАЛИБРОВОЧНУЮ КОНСТАНТУ
        call 3FFh              ; калибровочная константа из документации
        movwf      OSCCAL      ; ЗАГРУЗИТЬ КАЛИБРОВОЧНУЮ КОНСТАНТУ

       ;=================

            bcf        STATUS,RP0   ; Установить банк 0
            movlw            0x00   ; обнуляем таймер
            movwf            TMR0
main

   bsf GPIO,0
   call delay
   bsf GPIO,1
   call delay
   bsf GPIO,2
   call delay
   bsf GPIO,4
   call delay
   bsf GPIO,5
   call delay

   bcf GPIO,0
   call delay
   bcf GPIO,1
   call delay
   bcf GPIO,2
   call delay
   bcf GPIO,4
   call delay
   bcf GPIO,5
   call delay

  goto main

;==конец основной проги

delay
   bcf     STATUS,RP0  ; Установить банк 0
   movf       0x00,0
   movwf   TMR0        ; обнуляем таймер
vr
    btfss INTCON,T0IF  ; проверяем переполнение таймера0
    goto        vr
    bcf   INTCON,T0IF  ; устанавливаем в 0 бит переполнения таймера0
    return

;===========================

    end
Но получаю "бегущие огни". Хотя если делать
Код:
        GPIO = 0b0000001; //включаем 1 светодиод
        DELAY();          //задержка
        GPIO = 0b0000011; //включаем 2 светодиода 
и т.д.
то работает как хочу, но надо дёргать каждую ногу отдельно, а не весь порт сразу.
Кто знает - в чём здесь дело?
oleg-star вне форума   Ответить с цитированием
Старый 30.11.2014, 12:36   #2
Guaho
Senior Member
 
Аватар для Guaho
 
Регистрация: 28.06.2013
Возраст: 45
Сообщений: 656
Вес репутации: 1416/36
Guaho has much to be proud ofGuaho has much to be proud ofGuaho has much to be proud ofGuaho has much to be proud ofGuaho has much to be proud ofGuaho has much to be proud ofGuaho has much to be proud ofGuaho has much to be proud ofGuaho has much to be proud ofGuaho has much to be proud of
По умолчанию Re: 12F675, работает не так, как запрограммировано

Не могу не отметить, что вопрос хорошо поставлен, автор молодец! Проблема описана чётко, не приходится включать дар предвидения
По сути вопроса: сделайте переменную, в ней проводите битовые манипуляции, а потом этот байт выводите в порт (кстати, такой вывод можно делать и в прерывании, что повысит удобство работы: в этом случае Вы будете в основном цикле выполнять битовые операции с упомянутым регистром, а вывод будет происходить "сам собой"). Лично я никогда не дёргаю биты портов напрямую во избежание проблем (пресловутое "чтение-модификация-запись").
Guaho вне форума   Ответить с цитированием
Старый 30.11.2014, 13:15   #3
dosikus
Senior Member
 
Аватар для dosikus
 
Регистрация: 05.06.2007
Возраст: 45
Сообщений: 3,603
Вес репутации: 5909/133
dosikus has a reputation beyond reputedosikus has a reputation beyond reputedosikus has a reputation beyond reputedosikus has a reputation beyond reputedosikus has a reputation beyond reputedosikus has a reputation beyond reputedosikus has a reputation beyond reputedosikus has a reputation beyond reputedosikus has a reputation beyond reputedosikus has a reputation beyond reputedosikus has a reputation beyond repute
По умолчанию Re: 12F675, работает не так, как запрограммировано

Цитата:
Сообщение от oleg-star Посмотреть сообщение

movlw 0x07 ; все каналы - цифровые входы-выходы
movwf CMCON
Кроме компаратора есть еще ADC .
Собственно в даташите есть инит GPIO ...


Последний раз редактировалось dosikus; 30.11.2014 в 13:21.
dosikus вне форума   Ответить с цитированием
Старый 30.11.2014, 13:39   #4
petrd
Senior Member
 
Регистрация: 09.02.2008
Адрес: Воронеж
Возраст: 46
Сообщений: 1,672
Вес репутации: 1522/67
petrd has a brilliant futurepetrd has a brilliant futurepetrd has a brilliant futurepetrd has a brilliant futurepetrd has a brilliant futurepetrd has a brilliant futurepetrd has a brilliant futurepetrd has a brilliant futurepetrd has a brilliant futurepetrd has a brilliant futurepetrd has a brilliant future
Отправить сообщение для petrd с помощью ICQ
По умолчанию Re: 12F675, работает не так, как запрограммировано

Цитата:
Сообщение от oleg-star Посмотреть сообщение
работает как хочу, но надо дёргать каждую ногу отдельно, а не весь порт сразу.
Если Вы думаете, что команды BCF и BSF дергают только один бит, то Вы заблуждаетесь, они все равно весь порт дергают, потому как работает чтение - модификация - запись (RMW).
__________________
License MikroC, MikroC PRO and EasyPIC5 by mikroElektronika (the dead mikroICD replaced PICKit2 & PICKit3)
petrd на форуме   Ответить с цитированием
Старый 30.11.2014, 13:52   #5
Miser
Senior Member
 
Регистрация: 06.09.2008
Возраст: 55
Сообщений: 239
Вес репутации: 227/38
Miser has a spectacular aura aboutMiser has a spectacular aura aboutMiser has a spectacular aura about
По умолчанию Re: 12F675, работает не так, как запрограммировано

Если порт правильно нагружен, то никаких проблем с RMW не будет.
Как подключены светодиоды?
Miser вне форума   Ответить с цитированием
Старый 30.11.2014, 14:03   #6
Greg
Super Moderator
 
Регистрация: 25.02.2007
Адрес: Moscow, ODBS
Сообщений: 6,641
Вес репутации: 5137/156
Greg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond repute
По умолчанию Re: 12F675, работает не так, как запрограммировано

Цитата:
Сообщение от Miser Посмотреть сообщение
Если порт правильно нагружен, то никаких проблем с RMW не будет.
при включенном ADC с порта цифрой будут читаться нули.
которые затем и будут записаны обратно.
Greg вне форума   Ответить с цитированием
Старый 30.11.2014, 14:07   #7
Miser
Senior Member
 
Регистрация: 06.09.2008
Возраст: 55
Сообщений: 239
Вес репутации: 227/38
Miser has a spectacular aura aboutMiser has a spectacular aura aboutMiser has a spectacular aura about
По умолчанию Re: 12F675, работает не так, как запрограммировано

Но ведь при этом порт вообще будет ВХОДОМ! Тогда вообще нет смысла подключать к нему светодиод. Или нет?
Miser вне форума   Ответить с цитированием
Старый 30.11.2014, 14:21   #8
Greg
Super Moderator
 
Регистрация: 25.02.2007
Адрес: Moscow, ODBS
Сообщений: 6,641
Вес репутации: 5137/156
Greg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond repute
По умолчанию Re: 12F675, работает не так, как запрограммировано

Цитата:
Сообщение от Miser Посмотреть сообщение
Но ведь при этом порт вообще будет ВХОДОМ! Тогда вообще нет смысла подключать к нему светодиод. Или нет?
порт настроен на выход. при попытке установки единичного бита считывается весь порт (его входы), изменяется (устанавливается) нужный бит, и всё записывается назад. Если выходы были перегружены (ваш вопрос) или на них при чтении был ноль из-за неверной конфигурации, то будет этот самый rmw
Greg вне форума   Ответить с цитированием
Старый 30.11.2014, 14:27   #9
Miser
Senior Member
 
Регистрация: 06.09.2008
Возраст: 55
Сообщений: 239
Вес репутации: 227/38
Miser has a spectacular aura aboutMiser has a spectacular aura aboutMiser has a spectacular aura about
По умолчанию Re: 12F675, работает не так, как запрограммировано

Вот для этого и была фраза: "Если порт ПРАВИЛЬНО нагружен".
Miser вне форума   Ответить с цитированием
Старый 30.11.2014, 14:49   #10
oleg-star
Junior Member
 
Регистрация: 28.11.2014
Сообщений: 2
Вес репутации: 100/0
oleg-star will become famous soon enougholeg-star will become famous soon enough
По умолчанию Re: 12F675, работает не так, как запрограммировано

Спасибо за подсказки, я посчитал что при включении питания достаточно того, что бит ADON устанавливается в 0.
Проблема решена добавлением в секцию INIT вот такого
Код:
... 
   TMR0 = 0; //сброс таймера
    
    ANS0 = 0; // цифровой канал порта ввода/вывода или специальные функции
    ANS1 = 0; // а не АЦП
    ANS2 = 0;
    ANS3 = 0;
    CM0 = 1; //компаратор выключен
    CM1 = 1; //см. стр. 37, документ DS41190A
    CM2 = 1; //

    TRISIO5 = 0; // канал работает как выход
...

Последний раз редактировалось Greg; 30.11.2014 в 14:54.
oleg-star вне форума   Ответить с цитированием
Старый 30.11.2014, 14:53   #11
Greg
Super Moderator
 
Регистрация: 25.02.2007
Адрес: Moscow, ODBS
Сообщений: 6,641
Вес репутации: 5137/156
Greg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond reputeGreg has a reputation beyond repute
По умолчанию Re: 12F675, работает не так, как запрограммировано

Цитата:
Сообщение от Miser Посмотреть сообщение
Вот для этого и была фраза: "Если порт ПРАВИЛЬНО нагружен".
для меня ключевое слово было - "нагружен". Если порт (нога) настроен как вход adc, то даже если к нему вообще электрически ничего не подключено, читаться там будет 0. и соответственно писаться назад.

что забавно, в больших камнях (те же армы) под (проблемой) rmw обычно понимается совершенно другое - т.н. атомарность операции, т.е. чтобы в процессе чтения-записи не произошло прерывание и не изменило переменную.
Greg вне форума   Ответить с цитированием
Старый 30.11.2014, 19:31   #12
Guaho
Senior Member
 
Аватар для Guaho
 
Регистрация: 28.06.2013
Возраст: 45
Сообщений: 656
Вес репутации: 1416/36
Guaho has much to be proud ofGuaho has much to be proud ofGuaho has much to be proud ofGuaho has much to be proud ofGuaho has much to be proud ofGuaho has much to be proud ofGuaho has much to be proud ofGuaho has much to be proud ofGuaho has much to be proud ofGuaho has much to be proud of
По умолчанию Re: 12F675, работает не так, как запрограммировано

Цитата:
Сообщение от oleg-star Посмотреть сообщение
Спасибо за подсказки, я посчитал что при включении питания достаточно того, что бит ADON устанавливается в 0.
Проблема решена добавлением в секцию INIT вот такого...
Сразу хотел написать, чтоб явно указали настройку всей периферии, но посмотрел на значения после сброса бит (ADON устанавливается в 0) - и не написал. В своих проектах всегда инициализирую все модули, дабы не было подобных проблем. Лучше "пере...", чем "недо..."
Guaho вне форума   Ответить с цитированием
Ответ


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Чем/как отлаживать код написаный на Си в WinAVR Yokel Микроконтроллеры других производителей 49 30.09.2014 09:48
H-мост работает не как положено dccharacter Вопросы начинающих 1 21.11.2010 19:12
Макимальная частота прерываний от TMR0 ANH Продукция MICROCHIP 114 05.04.2008 00:50


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


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