Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: сделать задержку при включении
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
shide_3
добрый вечер! в МК я совсем новичок. есть MSP430F169, он выдает на ногу P4.1 c помощью Таймера В сгенерированный сигнал. требуется задержать появление этого сигнала при включении питания, допустим, На 5 сек. таймер работает от частоты 32768 гц.
хочу сделать это с помощью того же таймера. плз просьба оценить мой код инициализации таймера:

void TimerB_Init (void)
{unsigned int Freq, Phase;

TBCCTL1= OUTMOD_4;//режим-переключение
TBCTL = TBSSEL_2 + MC_1;//SMCLK + Up mode
while !(TBR = 32768); //ждем 5 секунд
TBCTL |= 0x0004; // Очищаем таймер
TBCTL = TBSSEL_2 + MC_1;//SMCLK + Up mode


P4DIR |= 0x0002; P4SEL |= 0x0002; //подключаем ногу
TBCCTL1= OUTMOD_6; // режим переключение/установка

TBCCR0= Freq; TBCCR1= (Freq*Phaze)/ 100;//параметры выходного сигнала}

cильно не ругайтеsm.gif
d7d1cd
Не сильно зная микроконтроллер и его периферию, но достаточно зная С++, могу сказать, что надо писать так:

while(TBR != 32768); //ждем 5 секунд
chernenko
Цитата(shide_3 @ Oct 4 2012, 00:06) *
while !(TBR = 32768); //ждем 5 секунд
cильно не ругайтеsm.gif

А вас компилятор за это сильно не ругал?
shide_3
Цитата(chernenko @ Oct 4 2012, 07:26) *
А вас компилятор за это сильно не ругал?

пока нет, я еще не компилировал. просто сомневаюсь в том что код будет делать то что нужно.хорошо бы просимулировать, только как в ИАР это сделать
E.V.G.
P4OUT &= ~BIT1; P4DIR |= BIT1; P4SEL |= BIT1;

void SETUP_TIMER_B (void)
{ TBCTL |= TBCLR;
// защёлки - не зависимы, длина счётчика - 16 бит, такт ACLK=32768Гц,предделитель /4, (32768 / 4 = 8192 Гц * 5сек = 40960)
TBCTL = TBCLGRP_0+CNTL_0+TBSSEL_1+ID_2;
TBCCTL0 = OUTMOD_4 +CCIE; // режим сравнения, переключать вывод при сранении, сбросить флаг прерывания, разрешить прерывание от TBCCR0 при сравнении
TBCCR0 = 40960-1; // считать до 40959
TBCTL |= MC_1; // начать счёт на увеличение
}

// основной цикл программы
void main (void)
{

}

//--------------------------------------------------
#pragma vector=TIMERB0_VECTOR
__interrupt void Interrupt_TIMERB0 (void)
{ TBR=0;
// когда таймер досчитает - возникнет прерывание
// здесь можно перепрограммировать таймер на другой режим работы
// или установить флаг, который проверяется в главном цикле программы
}
shide_3
Цитата(E.V.G. @ Oct 4 2012, 08:45) *
P4OUT &= ~BIT1; P4DIR |= BIT1; P4SEL |= BIT1;

а нужно ли вначале инициализировать порт, ведь тогда нога переключится когда он досчитает до 40960?
E.V.G.
Вывод сигнала на ногу сделан только для того, чтобы вы могли проконтролировать период. Для формирования временного интервала операции с портом и OUTMOD не нужны. Ещё задержку можно сделать через Watchdog таймер в интервальном режиме или через макрос программным способом

Макрос на форуме преводился ранее.
#define CPU_CLK_Hz 1000000 // частота MCLK в Гц

#ifndef DELAY_H
#define DELAY_H

#define CPU_CLK_kHz (unsigned long)(CPU_CLK_Hz/1000)
#define delay_ns(x) __delay_cycles(x*CPU_CLK_kHz*0.000001)
#define delay_us(x) __delay_cycles(x*(CPU_CLK_Hz/1000000))
#define delay_ms(x) __delay_cycles(x*(CPU_CLK_Hz/1000))
#define delay_s(x) __delay_cycles(x*CPU_CLK_Hz) // это ваш случай. напишите delay_s(5);

#endif


Если делать через Watchdog таймер - посмотрите заготовки в файле msp430x16x.h
shide_3
Спасибо!
если можно-еще один вопросик. разбираюсь в чужом коде (IAR). фрагмент следующий:

__no_init tNV_Data NV_Data @ "INFO";
static tNV_Data *d;
extern unsigned char TempBuf[10];
d= (tNV_Data *)TempBuf;
d->Vref= 100;
Dat.Vref= NV_Data.Vref;

Во-первых, что означает первая строка? Потом, по смыслу вроде как d = & NV_data; но в явном виде этого не написано. И для чего нужен TempBuf,
каким образом он потом переходит в NV_Data?

премного благодарен
rezident
Цитата(shide_3 @ Oct 5 2012, 15:21) *
Во-первых, что означает первая строка?
Это объявление неинициализированной переменной NV_Data типа tNV_Data в сегменте INFO. Причем это Тип tNV_Data это скорее всего структура или массив, нужно смотреть его определение. Причем это константная структура, т.к. декларируется в области Flash (сегмент INFO).
Цитата(shide_3 @ Oct 5 2012, 15:21) *
Потом, по смыслу вроде как d = & NV_data; но в явном виде этого не написано.
Вовсе нет. Адрес буфера TempBuf типа unsigned char "насильно" приводится к адресу внешней переменной типа tNV_Data и этот адрес присваивается указателю d.
Цитата(shide_3 @ Oct 5 2012, 15:21) *
И для чего нужен TempBuf,
Спросите у разработчика sm.gif Скорее всего это какой-нибудь временный буфер для хранения копии структуры NV_Data, которая где-то дальше будет записана (полностью или частично) в NV_Data.
Цитата(shide_3 @ Oct 5 2012, 15:21) *
каким образом он потом переходит в NV_Data?
В приведенном вами фрагменте кода указатель d вовсе не указывает на NV_Data. d->Vref это ссылка на элемент Vref, расположенный по адресу в массиве TempBuf. А вот NV_Data.Vref - да, это уже явно адресованный элемент Vref из переменной (или структуры) NV_Data.
shide_3
Цитата(rezident @ Oct 9 2012, 21:29) *
Спросите у разработчика sm.gif Скорее всего это какой-нибудь временный буфер для хранения копии структуры NV_Data, которая где-то дальше будет записана (полностью или частично) в NV_Data.

В том то и дело, что TempBuf дальше нигде не записывается в NV_Data
Цитата(rezident @ Oct 9 2012, 21:29) *
Вовсе нет. Адрес буфера TempBuf типа unsigned char "насильно" приводится к адресу внешней переменной типа tNV_Data и этот адрес присваивается указателю d.

(tNV_Data *)TempBuf - я бы понял так, что TempBuf- это указатель на tNV_Data, значит, не адрес буфера, а сам буфер приводится к адресу переменной типа tNV_Data? поправьте пожалуйста если я заблуждаюсь
rezident
Цитата(shide_3 @ Oct 10 2012, 12:25) *
В том то и дело, что TempBuf дальше нигде не записывается в NV_Data
Ну может быть и наоборот - TempBuf является модифицируемой копией NV_Data.
Цитата(shide_3 @ Oct 10 2012, 12:25) *
(tNV_Data *)TempBuf - я бы понял так, что TempBuf- это указатель на tNV_Data, значит, не адрес буфера, а сам буфер приводится к адресу переменной типа tNV_Data? поправьте пожалуйста если я заблуждаюсь
Адрес он и есть адрес, а указатель содержит его значение (адреса). TempBuf это адрес начала массива. Приведение типа указателя это формальное требование языка Си. Чтобы компилятор мог далее правильно адресовать все элементы структуры, которые могут иметь разные типы и соответственно разные размерности. В данном случае TempBuf возможно выполняет роль этакой "кучи" (Heap). Вот только тут может приключиться засада из-за неправильного выравнивания элементов структуры. Или точнее из-за отсутствия выравнивания. Байтовый массив вполне может быть расположен линкером по нечетному адресу и тогда обращение к элементу структуры как к 16-и битной переменной будет давать неверный результат.
shide_3
Цитата(rezident @ Oct 10 2012, 14:11) *
Адрес буфера TempBuf типа unsigned char "насильно" приводится к адресу внешней переменной типа tNV_Data

но то же самое можно сказать и про переменную d , поскольку static tNV_Data *d
rezident
Цитата(shide_3 @ Oct 10 2012, 17:03) *
но то же самое можно сказать и про переменную d , поскольку static tNV_Data *d

Дык d изначально, при его декларации определен как указатель на тип tNV_Data. У массива переменных TempBuf тип другой - unsigned char. Поэтому компилятор должен выдавать как минимум предупреждение при формальной проверке соответствия типов.
shide_3
спасибо Вам за поучительные ответы.
но запись d= (tNV_Data *)TempBuf; для меня не понятна, грамотнее наверное было бы написать &TempBuf = &NV_Data; d = &TempBuf; а то какой то бред получается.. или просто d = &NV_Data
rezident
Цитата(shide_3 @ Oct 15 2012, 11:18) *
спасибо Вам за поучительные ответы.
но запись d= (tNV_Data *)TempBuf; для меня не понятна, грамотнее наверное было бы написать &TempBuf = &NV_Data; d = &TempBuf; а то какой то бред получается.. или просто d = &NV_Data

Вы неправильно считаете. NV_Data находится во Flash. а TempBuf находится в SRAM. Поэтому адреса у NV_Data и TempBuf разные. Инициализировать указатель адресом NV_Data при обращении к TempBuf или наоборот - нельзя.
Кстати, при использовании массивов правильная запись будет d=TempBuf; или d=&TempBuf[0]; Но поскольку в данном случае d при декларации объявлен как указатель на тип tNV_Data, то компилятор обязан выдать предупреждение при попытке присвоить ему значение адреса переменной другого типа (unsigned char). Я об этом уже писал ранее.
shide_3
Цитата(rezident @ Oct 15 2012, 13:15) *
Вы неправильно считаете. NV_Data находится во Flash. а TempBuf находится в SRAM. Поэтому адреса у NV_Data и TempBuf разные. Инициализировать указатель адресом NV_Data при обращении к TempBuf или наоборот - нельзя.
Кстати, при использовании массивов правильная запись будет d=TempBuf; или d=&TempBuf[0]; Но поскольку в данном случае d при декларации объявлен как указатель на тип tNV_Data, то компилятор обязан выдать предупреждение при попытке присвоить ему значение адреса переменной другого типа (unsigned char). Я об этом уже писал ранее.

ну а если так - d = &NV_Data ?
rezident
Цитата(shide_3 @ Oct 15 2012, 16:15) *
ну а если так - d = &NV_Data ?

Так - без проблем. Но ведь в вашей программе написано
Код
d= (tNV_Data *)TempBuf;

То бишь указатель инициализируется адресом TempBuf, а вовсе не NV_Data laughing.gif Вы бы для разнообразия привели определение типа tNV_Data, чтобы чуток прояснить ситуацию.
shide_3
Цитата(rezident @ Oct 15 2012, 19:20) *
Вы бы для разнообразия привели определение типа tNV_Data, чтобы чуток прояснить ситуацию.

это структура
rezident
Цитата(shide_3 @ Oct 16 2012, 16:26) *
это структура

У меня и раньше были сильные подозрения, что это структура rolleyes.gif Ну дык и приведите определение этой структуры. Или там какие-то нецензурные имена членов структуры имеются? biggrin.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.