Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.71/14: Рейтинг темы: голосов - 14, средняя оценка - 4.71
sdv_sybork
0 / 0 / 0
Регистрация: 04.06.2015
Сообщений: 176
1

Косяки с тактированием от внешнего кварца

13.02.2017, 15:55. Просмотров 2658. Ответов 15
Метки нет (Все метки)

Доброго времени суток.
Наткнулся на неочевидный (по-крайней мере, для меня) косяк. По каким-то непонятным причинам внешний кварц на 16 МГц не может раскачаться до нормального уровня, все время возникает на выходе XOUT постоянное смещение в 400 мВ, а амплитуда самого синуса не превышает 100 мВ. Кроме того, возникает артефакт, похожий на сброс контроллера, причем периодический: каждый 2 - 3 мс и без того слабый сигнал резонатора падает до 100 мВ, затем вновь возвращается в исходное положение. Кто бы мог подсказать, в чем может быть проблема? Я в MSP430 совсем немного копаюсь, поэтому спрашиваю совета.
Чтобы телепатов не напрягать, опишу условия: контроллер MSP430F2410, к выводам XIN XOUT подключен кварц HC49U на 16 МГц с нагрузочными конденсаторами 12 пФ (вроде бы маловато, но коллеги ставят на своих платах с тем же камнем - и работает).

Код программы имеет следующий вид:
код
Код
#include <syknal.h>
#include "MSP430x24x.h"
#include "main.h"
#include "MSPSDVdef.h"
#include <stdint.h>

/*******************СЕКЦИЯ ПРЕРЫВАНИЙ*******************/

/**Прерывание таймера А**/
__attribute__((interrupt(TIMERA0_VECTOR)))void TimerA_ISR(void)
{
LedCounter--;   //Декрементируем счетчик светодиода
if(!LedCounter){LedCounter=1024;P4OUT^= BIT3;}  //Переключаем диод, если счетчик обнулился
return;
}

/**Прерывание АЦП - завершение последовательности преобразований**/
__attribute__((interrupt(ADC12_VECTOR)))void ADC12_EOS_ISR(void)
{
return;
}

/*******************ГЛАВНЫЙ ЦИКЛ*******************/
void main (void)
{
WDTCTL = WDTPW+WDTHOLD;     //Остановить WatchDog

Init();
LedCounter = 1024;

//Настроим для мигания светодиодом вывод P4.3
P4DIR |= BIT3;  //режим - выход
P4OUT |= BIT3;  //выставить выход в единицу

while(1)
{
ScanKeys();
}
}

/*******************Инициализация периферии*******************/
void Init(void)
{
//запускаем MCLK на 16 МГц

//_bic_SR_rikystir (OSCOFF);//включить генератор
BCSCTL1 |= XT2OFF|XTS;           //высокочастотный режим
BCSCTL3 |= LFXT1S_2;      //источник - кварц 16 МГц
do
{
IFG1 &= ~(OFIFG);         //сбрасываем флаг неисправности синхронизации
delay_symple(0x0FF);
}while(IFG1&OFIFG);           //если флаг неисправности вдруг вновь взвелся - повторяем процедуру заново

BCSCTL2 |= SELM0|SELM1;      //выбираем источник тактирования MCLK - LFXT1CLK
BCSCTL1 |= DIVA_2;            //Делитель ACLK - 8

/**Инициализация таймера B
режим работы - ШИМ в каналах 1, 2, реверсивный счет
**/

TBCCR0 = PWM_THRESHOLD;       //Верхнее значение счета
TBCCTL1 |= CLLD_2|CAP|OUTMOD_2; //режим сравнения, сброс/переключение по сравнению, загрузка по значению порога или нуля в случае реверсивного счета
TBCCTL2 |= CLLD_2|CAP|OUTMOD_2; //режим сравнения, сброс/переключение по сравнению, загрузка по значению порога или нуля в случае реверсивного счета
TBCCR1 = 5;                    //начальная скважность канала ШИМ 1- 0.2%
TBCCR2 = 5;                    //начальная скважность канала ШИМ 2- 0.2%
TBCTL |= TBSSEL0|MC_3;       //Старт таймера в реверсивном режиме

/**Инициализация таймера A в качестве системного
режим работы - прямой счет**/
TACCR0 = 1953;                //при заданных настройках частота прерывания составит ~1,024 кГц
TACCTL0 |= CCIE;              //
TACTL |=TASSEL0|ID_1|MC_1|TAIE;  //таймер работает в прямом режиме, частота тактирования ACLK/2,прерывания разрешены

/**инициализация режимов работы выводов
для переключателей режимов**/
P2DIR &= ~(BIT0|BIT1|BIT2|BIT3);    //порт2 - входы переключателей
P1DIR |= BIT5|BIT6|BIT7;            //порт1 - сканирующие выходы
P1REN |= BIT5|BIT6|BIT7;            //включить режим подтяжки на сканирующих выходах

/**ДЛЯ ОТЛАДОЧНЫХ ЦЕЛЕЙ
инициализация режимов работы выводов
для светодиодов**/
P2DIR |= BIT4|BIT5|BIT6|BIT7;       //режим работы - выход
P3DIR = 0x00FF;                     //режим работы - выход

/**Инициализация АЦП**/
ADC12CTL0 |= SHT0_0|MSC|ADC12ON;    //Делитель для времени выборки - 4; режим многократных преобразований, модуль АЦП активирован
ADC12CTL1 |= CSTARTADD_3|SHP|ADC12DIV_1|ADC12SSEL_1|CONSEQ_1;     //Стартовая ячейка - 3, запуск - по сигналу ADC12SC, импульсный режим выборки, источник тактирования - ACLK/2, режим преобразования - однократный последовательный
ADC12MCTL3 |= SREF_1|INCH1|INCH0;   //канал 3, источник опорного напряжения: Veref<->AVss
ADC12MCTL4 |= SREF_1|EOS|INCH2;//канал 4, последняя ячейка в цикле, источник опорного напряжения Veref<->AVss
ADC12IE |= 1<<4;                    //разрешить прерывание канала ADC12MEM4

ADC12CTL0 |= ENC;               //в конце, после всех настроек АЦП, разрешить его работу

_NOP();
_EINT();                        //разрешить прерывания и начать работу

return;
}
Программа написана в CodeBlocks с MSPGCC последней версии.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.02.2017, 15:55
Ответы с готовыми решениями:

Тактирование от внешнего кварца Proteus
Никак не получается симулировать работу микроконтроллера Atmega48P от внешнего кварца. Если...

Настройка работы от внешнего кварца PIC18F2331
Всем доброго времени суток. Подскажите, или покажите пример настройки частоты внешнего кварца в...

Конфигурация для работы от внешнего кварца (PIC16F1824)
Здравствуйте! У меня этот микроконтроллер не настраивается на внешний кварц (20МГц) и работает на...

Atmega16. Фьюзы для внешнего кварца 16 мегагерц
Подключил к мк внешний кварц 16мг и кондеры по 22p. На онлайн-калькуляторе рассчитал фьюзы, прошил,...

Не могу заставить atmega16a работать от внешнего кварца
Доброго времени суток. У меня такая проблема. Мне нужно заставить atmega16a работать от внешнего...

15
яверт
0 / 0 / 0
Регистрация: 15.06.2012
Сообщений: 3,097
13.02.2017, 17:29 2
Цитата Сообщение от sdv_cybork
Код:
BCSCTL1 |= XT2OFF|XTS; //высокочастотный режим
BCSCTL3 |= LFXT1S_2; //источник - кварц 16 МГц

Зачем использовать Read-Modify-Write? Задай конфигурацию клока явно, тем более что XCAP по дефолту совсем не 0...

delay_symple(0x0FF); это сколько времени? Кварцу для старта надо время, попробуй увеличить задержку.
0
sdv_sybork
0 / 0 / 0
Регистрация: 04.06.2015
Сообщений: 176
13.02.2017, 17:57 3
Цитата Сообщение от яверт
Зачем использовать Read-Modify-Write? Задай конфигурацию клока явно, тем более что XCAP по дефолту совсем не 0...

delay_symple(0x0FF); это сколько времени? Кварцу для старта надо время, попробуй увеличить задержку.
Действительо, может быть и в XCAP дело... Попробую сейчас сбросить его.
На счет времени - это получается при дефолтной частоте около десятка микросекунд. Конечно, в Users Guide почти такой код (только в асме) и предлагается, но попробую увеличить.
0
sdv_sybork
0 / 0 / 0
Регистрация: 04.06.2015
Сообщений: 176
13.02.2017, 18:13 4
Вроде бы отчасти действительно помогло. Прекратились провалы тактирования.
Но все еще кварц находится в состоянии, хм... насыщения, если к нему этот термин применим. Частота стабильная есть, но со смещением примерно в полвольта. Соответственно, программа как будто бы далее не выполняется, или выполняется, но очень медленно, т.к. диод (повешенный к P4.3, который переключается в прерывании) не мигаецца.
0
яверт
0 / 0 / 0
Регистрация: 15.06.2012
Сообщений: 3,097
13.02.2017, 18:22 5
Попробуй другой кварц, мк заточенные под низкое потребление довольно привередливые. Можно так же попробовать вывести клок (MCLK или SMCLK) на ногу и посмотреть осциллографом. Смотреть непосредственно на кварце нельзя, у щупа большая ёмкость.
0
sdv_sybork
0 / 0 / 0
Регистрация: 04.06.2015
Сообщений: 176
14.02.2017, 10:49 6
Посмотрел я на ногах MCLK, SMCLK ACLK осциллографом. Действительно, черти что творится: на всех трех ногах - иголки, с частотой около 3 Гц, при том, что настраивал я таким образом, что MCLK тактируется напрямую от кварца - 16 МГц, ACLK - оттуда же, но с делителем на 2 (8 МГц). MCLK вообще не настраивал, так что по дефолту должно было бы быть (если не изменяет память, то около 1 МГц).
Пока не могу понять, с чего бы так. Попробую кварц поменять, поставить с других плат и, может, еще уменьшить нагрузочные емкости.
А пока хотел бы узнать, сталкивался кто-нибудь с таким багом в тактировании?
0
sdv_sybork
0 / 0 / 0
Регистрация: 04.06.2015
Сообщений: 176
14.02.2017, 13:01 7
Похоже, что все-таки разобрался. Дело было в программе, но мне до конца не понятно, в чем именно. Почему-то MCLK и ACLK не желают запускаться от LFXT1 в режиме HF, пока не выставлены биты XTS1...0 вместе с битами LFXT1S1...0 (даром, что при этом XT2 выключен битом XT2OFF и на ногах XT2 вообще ничего не висит).
0
sdv_sybork
0 / 0 / 0
Регистрация: 04.06.2015
Сообщений: 176
14.02.2017, 15:28 8
Хм, недолгой радость была. Как ни странно, но точно та же самая программа, которая работала до обеда, после вновь стала давать те же самые косяки: иголки на выходах MCLK, SMCLK, ACLK, регулярные провалы в тактировании на кварце.
Кстати, что характерно, если присмотреться к сигналам ACLK и MCLK, они выглядят не совсем как иголки - если смотреть на периоде около 50нс, то видно, что на самом деле, эти "иголки" - это пачки прямоугольных импульсов, которые "живут" всего-навсего 500 - 600 нс, после чего сигнал пропадает и остается в течение 2 мс постоянное напряжение около 400 мВ (все тех же, да). Такое поведение очень похоже на risit, но с чего бы ему возникать? Watchdog, как видно из кода, отключен.
0
sdv_sybork
0 / 0 / 0
Регистрация: 04.06.2015
Сообщений: 176
15.02.2017, 15:57 9
В общем, длительное копание показало, что дело отнюдь не в схемотехнике, а именно в программе.
Включил Mspdebug в режиме симулятора, загрузил в него полученный *.elf файл, начал его гонять и... заметил, что после первой сработки прерывания (на данный момент оно одно-единственное - таймер А по сравнению с TACCR0) и выполнения его обработчика случается совершенно внезапный прыжок в адрес 0xffff, на котором система глохнет. Очевидно, что в железе происходит тоже самое, после чего наступает risit и все начинается заново. И как раз-таки этот прыжок может случиться совершенно произвольно: сразу через две команды после reti первого прохода обработчика прерывания, либо через еще сотню-другую тактов... но так или иначе все заканчивается таким вот "вылетом" регистра PC в 0xffff, совершенно внезапным. При этом, если запретить прерывания вообще, то этого не случается, но это совсем не выход, тем более в требуемом приборе.
Я думал, что где-то стек срывает (хотя чем, казалось бы, всего одна глобальная uint16_t переменная), наблюдал за шагами стека и его содержимым, но нигде не замечал ни резкого изменения стека, ни единого случая, когда бы он указывал на ячейку с 0xffff. Сделал ради того, чтобы проверить, NMI прерывание, (т.к. это единственный объект, на который падала тень - по адресу его вектора лежал как раз адрес 0xffff), но как вылет был, так и остался - в обработчик прерывания NMI указатель не попал ни разу.
Кто-нибудь может подсказать, что за глюк такой может быть? Уже голову сломал, сроки идут, а тут запнулся на такой тупой ошибке, которую не могу отловить. Или это нормальное явление для MSPGCC, такие финты устраивать?
0
яверт
0 / 0 / 0
Регистрация: 15.06.2012
Сообщений: 3,097
15.02.2017, 16:27 10
Цитата Сообщение от sdv_cybork
Кто-нибудь может подсказать, что за глюк такой может быть?
Может компилятор оптимизирует пустой обработчик прерывания АЦП? А без обработчика при включенном прерывании камню крышу сносит.
0
sdv_sybork
0 / 0 / 0
Регистрация: 04.06.2015
Сообщений: 176
15.02.2017, 16:45 11
Цитата Сообщение от яверт
Цитата Сообщение от sdv_cybork
Кто-нибудь может подсказать, что за глюк такой может быть?
Может компилятор оптимизирует пустой обработчик прерывания АЦП?
Нет, не оптимизирует, в том и дело.
Вот как выглядит строка в дизассемблере:
Код
225e:    00 13        reti
Я в симуляторе намеренно поставил брейкпоинт на этот адрес, но на него ни разу не попало. И в вектор прерывания АЦП (адрес 0xffea) - тоже.
0
sdv_sybork
0 / 0 / 0
Регистрация: 04.06.2015
Сообщений: 176
15.02.2017, 16:58 12
Также, если это как-то может помочь - трассировщик mspdebug перед тем, как PC уходит в симуляторе по адресу 0xffff выдает следующее

Код
2085442: irq homdle 8
Что именно это за homdle 8 - я ума не приложу, ни в одной доке по MSP430 не упоминаются irq homdles, только Ymtirrupt Vector address или Ymtirrupt Number. Единственное, что у прерывания TimerA_0 тоже указывается irq homdle, только под номером 9. Но мне это ни о чем не говорит, т.к. даже интуитивно представить трудно, какое это имеет отношение к таблице прерываний из даташита, в которой указаны лишь адреса и приоритеты.
0
яверт
0 / 0 / 0
Регистрация: 15.06.2012
Сообщений: 3,097
15.02.2017, 17:13 13
TACCTL0 |= CCIE; // это прерывание имеет вектор TIMERA0_VECTOR (0xFFF2)
TACTL |=TASSEL0|ID_1|MC_1|TAIE; // это прерывание имеет вектор TIMERA1_VECTOR (0xFFF0)

Обработчика TIMERA1_VECTOR в коде нет?
0
sdv_sybork
0 / 0 / 0
Регистрация: 04.06.2015
Сообщений: 176
15.02.2017, 17:19 14
Блин! Точно! Дошло наконец.

Только что проверил. Убрал TAIE - перестал слетать.
Надо ж было так не сообразить, что будут два прерывания одновременно в таком случае...
0
яверт
0 / 0 / 0
Регистрация: 15.06.2012
Сообщений: 3,097
15.02.2017, 17:30 15
TACCTL0 |= CCIE; это прерывание по совпадению канала 0
TAIE это прерывание по переполнению

Самое смешное, что только у канала 0 свой вектор, все остальные используют один вектор вместе с TAIE.
0
sdv_sybork
0 / 0 / 0
Регистрация: 04.06.2015
Сообщений: 176
15.02.2017, 17:33 16
Цитата Сообщение от яверт
TACCTL0 |= CCIE; это прерывание по совпадению канала 0
TAIE это прерывание по переполнению

Самое смешное, что только у канала 0 свой вектор, все остальные используют один вектор вместе с TAIE.
А я по невнимательности подумал, что надо оба флага включить, чтобы работал CCIE, т.е. по каналу 0.
0
15.02.2017, 17:33
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.02.2017, 17:33

Atmega 128 fuse как затактовать от внешнего кварца
Всем добрый вечер. собственно вопрос,я начинающий и все опыты делал от внутреннего генератора,вот...

Проблемы с тактированием XMega32A4
Всем привет. Вчера запаял плату и уже второй день бьюсь с тактированием. Камень упорно не желает...

Pinboard STM32F103xx и тактирование от внешнего кварца 12МГц
Коллеги, подскажите: разбираюсь с STM32F103 от Pinboard. Тактирование процессора работает только...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru