Что не так с этим примером мигания dsPIC30F2020?

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

Инструменты :

  • Микроконтроллер: dsPIC30F2020
  • Программист: PICKit 2
  • IDE: MPLAB X IDE v3.60

Вот код:

#include "xc.h"
#include "libpic30.h"
#include "stdio.h"
#include "stdlib.h"
#include "p30F2020.h"

// хтал
# определить _XTAL_FREQ 16000000

// Настройки битов конфигурации DSPIC30F2020
// Операторы конфигурации исходной строки 'C'

// ФБС
#pragma config BWRP = BWRP_OFF ​​// Защита загрузочного сегмента от записи (загрузочный сегмент может быть записан)
#pragma config BSS = NO_BOOT_CODE // Защита программного флэш-кода загрузочного сегмента (без загрузочного сегмента)

// ФГС
#pragma config GWRP = GWRP_OFF ​​// Защита от записи общего сегмента кода (общий сегмент может быть записан)
#pragma config GSS = GSS_OFF // Общая защита кода сегмента (отключено)

// ФОСКЕЛ
#pragma config FNOSC = PRIOSC // Режим генератора (основной генератор (HS, EC))

// ФОСК
#pragma config POSCMD = HS // Первичный источник генератора (режим генератора HS)
#pragma config OSCIOFNC = OSC2_CLKO // Функция вывода OSCI/OSCO (вывод OSCO имеет функцию синхронизации)
#pragma config FRANGE = FRC_HI_RANGE // Выбор диапазона частот (верхний диапазон)
#pragma config FCKSM = CSW_FSCM_OFF // Переключение часов и мониторинг (Sw Disabled, Mon Disabled)

// ФВДТ
#pragma config WDTPS = WDTPOST_PS32768 // Постскейлер сторожевого таймера (1:32,768)
#pragma config FWPSA0 = WDTPRE_PR128 // Предварительный делитель WDT (1:128)
#pragma config WWDTEN = WINDIS_OFF // Окно сторожевого таймера (не оконный режим)
#pragma config FWDTEN = FWDTEN_OFF // Включение сторожевого таймера (отключение)

// ФПОР
#pragma config FPWRT = PWRT_128 // Значение таймера POR (128 мс)

// ФИКР
#pragma config ICS = ICS_PGD // Выбор канала связи (используйте PGC/EMUC и PGD/EMUD)

интервал основной () {
    _ТРИСД0 = 0x00;

    в то время как (1) {
        _RD0 = 0xff;
        __задержка32(150000000);
        _RD0 = 0x00;
        __задержка32(150000000);
    }
    вернуть 0;
}

А вот схема:схема для примера мерцания

Скриншот Пикит 2:

фото комплект 2

Когда я подключаю светодиод к RD0 (вывод 15), светодиод горит все время; он не мигает.

Что может быть не так?

[ОБНОВЛЕНИЕ] Я думаю, что это __delay32()проблема. Есть идеи?

Вау, это одно запутанное множество связей!

Ответы (1)

Похоже, вы используете кварц 16 МГц, но сообщаете компилятору, что ваша частота равна 160 МГц:

#define _XTAL_FREQ 160000000

Кроме того, при частоте 16 МГц каждый тактовый цикл 1 / 16 , 000 , 000 "=" 62,5 н с .

Вы звоните __delay32(150000000);, что равносильно 150000000 62,5 н с "=" 9.37 с . Таким образом, светодиод будет гореть около десяти секунд, а затем выключаться примерно на 10 секунд.

Привет, я изменил часы на 16000000 (16 МГц) и время задержки на 15000000, поэтому оно должно задерживаться примерно на 0,937 секунды, но светодиод все еще горит все время. Есть идеи?
@WildanSNahar Хм. Для устранения неполадок я бы провел быстрый тест и сначала выключил светодиод, а затем включил его . Если он все равно загорается, то это указывает на цепь...
Да, я сделал это. Это работает. Во-первых, во время (1) я изменил начальное условие на 0xffи он загорается, а затем во время (1) я снова изменил на 0x00и он выключился. Так что же тогда не так?
@WildanSNahar Ну, это хорошо! Он проверяет ваше оборудование :) Далее я бы попробовал другую функцию, чтобы сделать задержку. Есть вариант, который __delay_ms()вы можете попробовать. В «Справочном руководстве по библиотекам 16-битных языковых инструментов» говорится, что вы должны сначала определить FCYчастоту кристалла. И это должно быть определено до вашего #include "libpic30.h"заявления. Хм. Интересно, если вы просто переместите свою #define _XTAL_FREQ 16000000строку в самый верх файла, возможно, ваша исходная функция `__delay32() начнет работать...
Я пробовал это. Но это не работает. Как мне написать FCY? И как я могу использовать __delay_ms()вместо __delay32()?
@WildanSNahar В дополнение к #define _XTAL_FREQ 16000000, также добавьте новую строку вверху: #define FCY 16000000. Затем вы можете вызвать __delay_ms() с аргументом, равным количеству миллисекунд. Для задержки в одну секунду позвоните__delay_ms(1000);
Я так и сделал, программа успешно скомпилировалась, но светодиод все равно все время горел. Есть идеи, опять?
Попробуйте отключить WDT (сторожевой таймер). Возможно, срок действия кода истекает, и код повторно сбрасывается.