реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> АЦП и Таймер в контроллере MSP430F5438, Не могу кинуть данные в регистр таймера
mzhelezkin
сообщение Feb 1 2010, 14:27
Сообщение #1





Группа: Участник
Сообщений: 14
Регистрация: 15-01-10
Пользователь №: 54 827



Здравствуйте. Подскажите в чем дело. Вот код программы:
CODE
#include "msp430x54x.h"
#include "setup_ustroistva.c"
unsigned char a = 0;
void main(void)
{
WDTCTL = WDTPW+WDTHOLD; // Остановка сторожевого таймера

setup_adc();

setup_tb();

for(;;)
{
ADC12CTL0 |= ADC12SC;
a = ADC12MEM0_L;
TB0CCTL4 = (*((unsigned char*)ADC12MEM0));
}
}


Работаю в IAR Embeddet Workbench v4.20.1. Микроконтроллер MSP430F5438. В функциях setup_adc() и setup_tb() просто настройка АЦП и таймер B. Настроил АЦП на 8 разрядов, соответственно таймер B тоже. Проблема в том, что данные из регистра ADC12MEM0 не могу записать в регистр TB0CCTL4. Пробовал и без указателе, т.е просто
TB0CCTL4 = ADC12MEM0;
Не работает. А в переменную записываеться (выше определена переменная а). Ниже привожу картинку.

Прикрепленное изображение


Вообще мне нужно вывести на наушники голос человека. В качестве ЦАП использую ШИМ. Вот, так сказать и мучаюсь. Новую тему создавать не стал, нашел на этом же форуме обсуждение подобной проблемы. Название темы такое: "ЦАП на ШИМ Atmega, Реализация ЦАП с помощью ШИМ атмеги". Общая идея в принципе понятна. По переполнению таймера счетчика, делаем одну выборку АЦП и кидаем ее сразу в регистр таймера. Но вот закинуть в регистр выборку, что-то не получается.
Go to the top of the page
 
+Quote Post
rezident
сообщение Feb 1 2010, 20:35
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



У вас ... как бы помягче сказать.... какая-то ерунда в представлении о том, как должна работать программа, как работает сам микроконтроллер и вообще о том, как можно оцифровывать и синтезировать с помощью ШИМ звуковые сигналы. Даже не знаю, к чтению каких именно документов вас нужно отправить в первую очередь cranky.gif Может вы сами укажите, что прочитали и чем руководствовались при написании этой "программы"?
Go to the top of the page
 
+Quote Post
mzhelezkin
сообщение Feb 2 2010, 12:16
Сообщение #3





Группа: Участник
Сообщений: 14
Регистрация: 15-01-10
Пользователь №: 54 827



Прошу прощения. В общем-то вы правы. У меня каша в голове. Занимаюсь всем этим с нового года. Прочитал "Семейство микроконтроллеров MSP430x4xx", так же вышеуказанный форум "ЦАП на ШИМ Atmega, Реализация ЦАП с помощью ШИМ атмеги". Понакачал библиотек и примеров с техаса для моей экспериментальной платы
MSP-EXP430F5438.

Ну, наверное и все. Если можете, подскажите еще какую-нибудь литературу, буду очень сильно благодарен.
А на счет моего вопроса с шим. Вчера кое что получилось. Стал выводить звук. Правда очень плохо, со свистом, и речь плохо разборчива. Вот код программы.

CODE
#include "msp430x54x.h"
#include "setup_ustroistva.c"
unsigned char a = 0;
void main(void)
{
WDTCTL = WDTPW+WDTHOLD; // Остановка сторожевого таймера

setup_adc();

setup_tb();

for(;;)
{
ADC12CTL0 |= ADC12SC;
a = ADC12MEM0_L;
TB0CCR4 = a;
while(!(TB0CTL & TBIFG));
}
}


Здесь setup_adc()

CODE
void setup_adc(void)
{
vkl_ustroistv();

ADC12CTL2 = ADC12RES_0;
ADC12CTL0 = ADC12ON + ADC12SHT0_6;
ADC12CTL1 = ADC12SHP + ADC12SSEL_3;
ADC12MCTL0 = ADC12INCH_5;
ADC12IE = 0x0001;
ADC12CTL0 |= ADC12ENC; //Enable

}


И setup_tb

CODE
void setup_tb(void)
{
TBCCR0 =128;
TBCCTL4 = CLLD_1 + OUTMOD_7;

TBCTL = CNTL_3 + TBSSEL_2 + MC_1 + TBIE;

}


В функции vkl_ustroistv() идет просто настройка портов.
Подскажите, что в этой программе нужно добавить ил вообще полностью изменить програаму.
Go to the top of the page
 
+Quote Post
rezident
сообщение Feb 2 2010, 20:40
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Ой-ё-ё! wacko.gif Вынужден констатировать, что вы, mzhelezkin, как минимум слабо разобрались с работой периферийных модулей. Так что читайте MSP430x5xx Family User's Guide до полного просветления. Вам еще повезло, что вы случайно не установили глобальный флаг разрешения прерываний. Иначе вообще бы все рухнуло. laughing.gif
Ну а саму программу следует сначала описать в виде алгоритмов и конечных автоматов. Судя по всему, у вас в голове нет алгоритма, есть только мысль, что оцифровка сигнала заключается в том, чтобы считать слово из АЦП и запихнуть его в какой-то регистр таймера. И при этом все должно автоматически заработать. В этом вы "слегка" ошибаетесь, забывая про "овраги" (гладко было на бумаге, да забыли про овраги).
Во-первых, АЦП не дает результат моментально. Для оцифровки аналогового сигнала требуется определенное время. У вас же в программе считается, что результат готов всегда и моментально. Нужно использовать опрос флага готовности результата АЦП перед тем как его (результат оцифровки) считывать.
Во-вторых, параметры ШИМ нельзя менять в произвольное время, а только по окончании текущего импульса ШИМ. Иначе будет то, что у вас и получается - свист, писк, треск и потусторонние голоса. Для этого в MSP430 существует специально разработанная аппаратура таймера. Изучите ее работу.
В-третьих, нужно обеспечить синхронизацию оцифровки звука и вывода звука, чтобы частота сэмплирования на входе и выходе была одинаковой. В связи с этой проблемой нужно правильно настроить систему тактирования микроконтроллера, чем вы вообще не озаботились. Про теорему Котельникова (Котельникова-Найквиста-Шеннона) что-нибудь слышали? Если нет, то поГуглите. Обязательно!
Про формирование сигналов с помощью таймера, генерирующего сигнал ШИМ, в MSP430 почитайте Using PWM Timer_B as a DAC. Вот в этой книге есть его вариант перевода на русский. Там же, кстати, и про архитектуру MSP430 кое-что разжевано.
Go to the top of the page
 
+Quote Post
mzhelezkin
сообщение Feb 2 2010, 21:23
Сообщение #5





Группа: Участник
Сообщений: 14
Регистрация: 15-01-10
Пользователь №: 54 827



rezident, огромное спасибо за подробный ответ, ваши указания на мои ошибкидумаю помогут. Особо заострю на этом внимание.

И если не сложно проясните ситуацию с частотой дискретизации. Про теорему котельникова я слышал biggrin.gif (частота дискретизации должна быть в два раза больше максимальной частоты сигнала, вроде так). В описании "Семейство микроконтроллеров MSP430x4xx" (это описание есть на русском, поэтому я его читаю, думаю что принципиальных отличий от msp430x5xx нет). Так вот, в этом описании написано, цитирую: "Биты SHT0x регистра ADC12CTL0 определяют число циклов ADC12CLK в периоде выборки для регистров с ADC12MEM0 по ADC12MEM7". И приводится таблица значений этих битов для разного количества циклов. Вопрос, правильно ли я считаю частоту дискретизации? Я установил тактирование от SMCLK (для наглядности, вывел эту частоту на порт и посмотрел на осциллографе, получилось примерно 1 МГц). К примеру, установил число циклов в периоде выборки-хранения = 96. Я нахожу период SMCLK (1/1 МГц = 0.000001 с). Дальше 96*0.000001 с = 0.000096 с. И нахожу частоту дискретизации (я так думаю) 1/0.000096 с = 10416 Гц (скорее всего я не правильно считаю). Так вот, вроде бы условие теоремы Котельниково соблюдается. Или нет. Просто я беру максимальную частоту голоса примерно 4000 Гц.
Go to the top of the page
 
+Quote Post
rezident
сообщение Feb 2 2010, 22:52
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Считаете неправильно, т.к. забыли что кроме времени выборки есть еще и время преобразования равное 13, 11 или 9 тактам ADC12CLK. Результирующая формула для определения времени преобразования ADC12 выглядит как tsample+tconvert. Где tsample для выбранного вами режима (можно и другой способ выборки входного сигнала использовать) определяется значением ADC12SHTx, а tconvert разрядностью АЦП. Нужно отметить, что в применяемом вами кристалле (MSP430F5438) модуль АЦП не ADC12, а ADC12_A. Отличия их в том, что ADC12_A может работать с разной разрядностью преобразования: 12 бит, 10 бит и 8 бит. Следовательно tconvert в зависимости от разрядности может быть 13, 11 и 9 тактов ADC12CLK соответственно. Так что для вашего случая время одного преобразования будет как минимум (96+13)/1МГц=109мкс или интерпретируя по-другому - не более 9174 выборок в секунду (SPS - sample per second). В принципе достаточно, но частота весьма нестандартная. Если вы не собираетесь ваш оцифрованный сигнал куда-либо передавать или применять у себя оцифрованный где-либо сигнал, то можно и такую частоту оставить. Я написал "как минимум" и "не более", потому что следует учитывать время, необходимое на "вычитывание" результата преобразования АЦП и передачу его в модуль ШИМ так, чтобы работа была синхронной.
Теперь вам требуется настроить таймер для работы с такой частотой дискретизации. Если вы выберите 12-разрядный (чтобы соответствовать разрешению АЦП) режим работы Timer_B (он лучше, чем Timer_A приспособлен для генерации ШИМ), то частота тактирования таймера должна быть 9174SPS * 2^12=37,576704МГц. Очевидно, что это очень высокая частота для данного таймера. Так что вам следует уменьшить разрядность ШИМ до, скажем, 10-и бит. Тогда частота тактирования таймера должна получаться 9174SPS * 2^10=9,394176МГц, что вполне допустимо для аппаратуры MSP430.
Вообще-то, если более тщательно изучить аппаратуру MSP430, то можно обнаружить способ полностью синхронной работы таймера, вырабатывающего ШИМ, и модуля ADC, при котором временем tsample и запуском преобразования АЦП управляет этот же самый таймер. Правда при этом следует еще и систему прерываний изучить и задействовать. Ищущий, да обрящет wink.gif
Go to the top of the page
 
+Quote Post
mzhelezkin
сообщение Feb 4 2010, 21:03
Сообщение #7





Группа: Участник
Сообщений: 14
Регистрация: 15-01-10
Пользователь №: 54 827



Здравствуйте. Спасибо еще раз за подробнейший ответ biggrin.gif По вашему совету скачал статью Using PWM Timer_B as a DAC. И нашел эту же статью, но уже в переводе на русский. Вот ссылка http://www.gaw.ru/html.cgi/txt/app/micros/msp430/slaa116.htm

Эта статья и ваши разъяснения очень сильно помогли, спасибо. Но возникли некоторый вопросы. Вот один из них.

У меня ADC и PWM настроены от тактирования от SMCLK. Но частота тактирования этих устройств должна быть разная. Возьмем тот же пример на котором вы мне все объясняли.
Как я говорил частоту SMCLK на осциллографе показывает 1 МГц. Тогда время выборки (96 тактов) плюс время преобразования (9 тактов, я поставил разрядность ADC 8 бит) деленное на SMCLK, получим время одного периода преобразования. Т. е. Т = (96 + 9)/1000000 = 105 мкс. Получим 9523 SPS. И частоту тактирования для PWM F = 9523*2^8 = 2437888 Гц = 2,4 МГц. Вопрос, я могу увеличить частоту SMCLK только с помощью UCS (Unified Clock System). Но тогда измениться частота SMCLK и для ADC. Тогда опять пересчитывать biggrin.gif Единственная мысль которая приходит, это использовать входной делитель для частоты ADC. Правильно ли я думаю. Может подгонка частот делается как-то по-другому.
Еще один вопрос. В MSP430x5xx Family User's Guide на рис. 17-4 показана временная диагарамма работы ADC при выборе импульсного режима. Судя по рисунку, к полному времени преобразования (96 + 1) нужно прибавить еще один такт SMCLK для синхронизации ADC. Нужно ли это делать. В принципе я пробовал и прибавлять его и не прибавлять, разницы не заметил.

Что еще хотел сказать. Получить голос на наушниках у меня получилось. Но опять же с каким-то гулом (как в самолете) biggrin.gif Получается я опять что-то не так сделал. мне кто-то сказал что нужно фильтр на выходе поставить и все. Но дело в том, что когда я зашил контроллер тестовую программу, скачанную с сайта TI, такого шума не было. Может внутри контроллера какие фильтры стоят. В описании, в разделе ADC что-то было такое что входы можно интерпретировать как ФНЧ. Может это и использовалось в программе от TI.

И последнее biggrin.gif Как вы правильно догадались мне нужно передать голос по радиоканалу. Точнее по радиоканалу передаются данные ADC. Радиопередатчик использую CC1101. Получилось организовать радиопередачу (для этого скачал пример с TI). Но не могу различить голос. Т.е. я так думаю, что опять с частотами накосячил. Начинаю пробовать менять SMCLK, естественно вообще ничего не работает. Так как UART использует тоже частоту SMCLK. Как мне синхронизовать это дело, пока еще не понял biggrin.gif

Ну вот, пока все что у меня получилось, спасибо за объяснения еще раз и, если не сложно,, еще раз ответьте на вопросы.
Go to the top of the page
 
+Quote Post
rezident
сообщение Feb 4 2010, 22:41
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Вы правильно догадываетесь об использовании предделителей у каждого периферийного модуля.
Для UART с этим вообще нет особых проблем, если соотношение частоты тактирования и скорости передачи достаточно большое. Ведь предделитель UART 16-и разрядный и дает широкий диапазон перестройки для битовой частоты.
У АЦП период готовности результата можно варьировать совокупностью предделителя и времени сэмплирования. Оптимальное время сэмплирования выбирается, исходя из условий выходного сопротивления источника сигнала. Именно этот момент вы поняли как наличие ФНЧ на входе АЦП. Только это (наличие эквивалента RC на входе АЦП) не полезная функция, а паразитное явление с которым нужно считаться. Время сэмплирования можно увеличивать в большую сторону от оптимального (правда это увеличение влияет на общее энергопотребление МК), но если оно уже выбрано оптимальным, то такой необходимости нет. Вам ведь важно, чтобы период оцифровки входного сигнала совпадал с периодом выдачи оцифрованных сэмплов на устройство воспроизведения. И если АЦП будет оцифровывать быстрее, чем требуется, то это даже неплохо. Выберите частоту дискретизации, например, Fдискр=8кГц или 10кГц или даже 11,025кГц (частота сэпмлирования звука для записи на аудио компакт дисках - 44,1кГц, 44,1кГц/4=11,025кГц). Соответственно, если у вас время оцифровки звука будет меньше, чем 1/Fдискр., то все нормально. Вам ведь главное синхронизировать начало запуска преобразования с этой частотой. Сихронизировать с PWM можно, использовав один из его каналов для генерации сигнала управления SAMPCON ADC12. См. на рисунках в соответствующем разделе User's Guide. Если используете Timer_B, то это будут TB0.0 или TB0.1. Т.е. вместо программного запуска преобразования с помощью бита ADC12SC и использования Sample Timer, используйте сигнал ШИМ от Timer_B с подходящими параметрами длительности для генерации этого самого сигнала (SAMPCON). Для такой работы достаточно скоммутировать эти сигналы внутри. См. описания битов ADC12SHSx в регистре ADC12CTL1. При такой настройке оцифровка звука будет происходить синхронно с периодом генерации ШИМ-сигнала. Т.е. если рассматривать на примере той же самой частоты тактирования 1МГц, то при 8-ми битном ШИМ его будет 256 тактов. Соответственно сигнал PWM длительностью 96 тактов будет отвечать за выборку (tsample) и еще 9 тактов (предполагаю, что режим АЦП тоже 8-ми битный) будет затрачено на преобразование (tconvert). Соответственно на 106 такте PWM результат оцифровки уже будет готов, его можно считать и подготовить для записи в таймер для генерации следующего сэмпла звука. При этом еще 150 тактов АЦП будет просто простаивать.
Ну и неплохо бы все это взаимодействие организовать с использованием прерываний. Но этот этап пока отложите до тех пор, пока не добьетесь нормального воспроизведения внутри МК, без использования связи.
P.S. ну и про фильтр на выходе. Естественно, что фильтр нужен. Я думал, что вы и сами поняли это из чтения Using PWM Timer_B as a DAC. Тот факт, что вы не слышали заметных искажений на примерах TI может быть объяснимо тем, что там синус, а не речь синтезируется.
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
mzhelezkin
сообщение Feb 5 2010, 07:26
Сообщение #9





Группа: Участник
Сообщений: 14
Регистрация: 15-01-10
Пользователь №: 54 827



На счет фильтров biggrin.gif Извините, я в самом начале сказал что использую только микроконтроллер, на самом деле я использую отладочную плату от TI MSP-EXP430F5438. Соответственно там и фильтры и усилители, все стоит. Мне посоветовали в тестовой плате перепаивать конденсатор на фильтре, чтобы не было лишних шумов. Я просто очень сильно удивился, как так, с техассовской программой все нормально работает. Я скачал SLAC227F - MSP-EXP430F5438 Example Software. Но в этой программе сделано так, что голос сначала записывается во флешь память контроллера, а потом уже воспроизводится. И теперь могу сказать, что в этой программе синхронизация с PWM идет как раз с помощью TB0.1. Т.е. так, как вы и написали.

Спасибо, буду пробовать, разбираться. Если что, спрошу еще раз.
Go to the top of the page
 
+Quote Post
mzhelezkin
сообщение Feb 8 2010, 08:43
Сообщение #10





Группа: Участник
Сообщений: 14
Регистрация: 15-01-10
Пользователь №: 54 827



Здравтсвуйте. получилось у меня воспроизвести голос. Частота дискретизации 32,460 кГц, частота SMCLK 8.424 МГц. В настройке АЦП использую предделитель с коэффициентом деления 8.
Теперь стоит задача, передать голос по радиоканалу, с помощью сс1101. У меня получается передавать голос, но он получается металлический, разобрать что говорят можно, но с трудом. Как настроить радиоканал. Частота тактирования UART получается 526,5 кГц. Я вроде все флаги буферов приемника SPI и передатчика использую. Т.е. жду когда они выставятся. Подскажите где копать.
Или может с настройками SPI что-то не так. Спасибо.
Go to the top of the page
 
+Quote Post
stepper88
сообщение Apr 29 2011, 07:45
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 43
Регистрация: 20-02-09
Пользователь №: 45 138



Здравствуйте, господа!
Так получилось, что у меня возникла сходная проблема - решил запускать АЦП с помощью таймера. На MSP430F149 подобное получалось, но аналогичного примера для F54xx найти не удалось. Написал вот такую программку на основе примера 14х:
Код
#include <msp430x54xA.h>

unsigned char log [16];
unsigned char i=0;

void main (void)
{
  P7SEL=0xff;
  REFCTL0 |= REFMSTR+REFVSEL_2+REFON+REFTCOFF;
  WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog
  ADC12CTL1 = ADC12SHS_1 + ADC12SHP + ADC12CONSEQ_2;       // TA trig., rpt conv.
  ADC12MCTL0 = ADC12SREF_1 + ADC12INCH_14;            // Channel A10, Vref+
  ADC12IE = 0x01;                           // Enable ADC12IFG.0
  ADC12CTL0 = ADC12SHT0_8 + ADC12REF2_5V + ADC12REFON + ADC12ON + ADC12ENC; // Config ADC12
  TA1CCTL1 = OUTMOD_4;                       // Toggle on EQU1 (TAR = 0)
  TA1CTL = TASSEL_2 + MC_2;                  // SMCLK, cont-mode
  _EINT();
  for(;;);
}

#pragma vector=ADC12_VECTOR
__interrupt void ADC12ISR (void)
{
  log[i++]=ADC12MEM0;
}

Но почему-то программа при исполнении не заходит в обработчик прерывания. И еще я правильно включил источник опорного напряжения (Vref)?
Заранее спасибо!
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 1st July 2025 - 06:01
Рейтинг@Mail.ru


Страница сгенерированна за 0.01465 секунд с 7
ELECTRONIX ©2004-2016