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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> сделать задержку при включении
shide_3
сообщение Oct 3 2012, 20:06
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 314
Регистрация: 27-04-10
Пользователь №: 56 923



добрый вечер! в МК я совсем новичок. есть 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
Go to the top of the page
 
+Quote Post
d7d1cd
сообщение Oct 4 2012, 02:54
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 442
Регистрация: 26-11-10
Пользователь №: 61 199



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

while(TBR != 32768); //ждем 5 секунд
Go to the top of the page
 
+Quote Post
chernenko
сообщение Oct 4 2012, 04:26
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 170
Регистрация: 8-02-06
Из: Москва
Пользователь №: 14 116



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

А вас компилятор за это сильно не ругал?
Go to the top of the page
 
+Quote Post
shide_3
сообщение Oct 4 2012, 05:29
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 314
Регистрация: 27-04-10
Пользователь №: 56 923



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

пока нет, я еще не компилировал. просто сомневаюсь в том что код будет делать то что нужно.хорошо бы просимулировать, только как в ИАР это сделать

Сообщение отредактировал shide_3 - Oct 4 2012, 05:31
Go to the top of the page
 
+Quote Post
E.V.G.
сообщение Oct 4 2012, 05:45
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 34
Регистрация: 31-01-10
Из: Арзамас
Пользователь №: 55 175



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;
// когда таймер досчитает - возникнет прерывание
// здесь можно перепрограммировать таймер на другой режим работы
// или установить флаг, который проверяется в главном цикле программы
}

Сообщение отредактировал E.V.G. - Oct 4 2012, 05:53
Go to the top of the page
 
+Quote Post
shide_3
сообщение Oct 4 2012, 06:12
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 314
Регистрация: 27-04-10
Пользователь №: 56 923



Цитата(E.V.G. @ Oct 4 2012, 08:45) *
P4OUT &= ~BIT1; P4DIR |= BIT1; P4SEL |= BIT1;

а нужно ли вначале инициализировать порт, ведь тогда нога переключится когда он досчитает до 40960?
Go to the top of the page
 
+Quote Post
E.V.G.
сообщение Oct 5 2012, 04:18
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 34
Регистрация: 31-01-10
Из: Арзамас
Пользователь №: 55 175



Вывод сигнала на ногу сделан только для того, чтобы вы могли проконтролировать период. Для формирования временного интервала операции с портом и 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
Go to the top of the page
 
+Quote Post
shide_3
сообщение Oct 5 2012, 10:21
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 314
Регистрация: 27-04-10
Пользователь №: 56 923



Спасибо!
если можно-еще один вопросик. разбираюсь в чужом коде (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?

премного благодарен
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 9 2012, 18:29
Сообщение #9


Гуру
******

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



Цитата(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.
Go to the top of the page
 
+Quote Post
shide_3
сообщение Oct 10 2012, 07:25
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 314
Регистрация: 27-04-10
Пользователь №: 56 923



Цитата(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? поправьте пожалуйста если я заблуждаюсь
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 10 2012, 11:11
Сообщение #11


Гуру
******

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



Цитата(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-и битной переменной будет давать неверный результат.
Go to the top of the page
 
+Quote Post
shide_3
сообщение Oct 10 2012, 12:03
Сообщение #12


Местный
***

Группа: Участник
Сообщений: 314
Регистрация: 27-04-10
Пользователь №: 56 923



Цитата(rezident @ Oct 10 2012, 14:11) *
Адрес буфера TempBuf типа unsigned char "насильно" приводится к адресу внешней переменной типа tNV_Data

но то же самое можно сказать и про переменную d , поскольку static tNV_Data *d
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 10 2012, 14:14
Сообщение #13


Гуру
******

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



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

Дык d изначально, при его декларации определен как указатель на тип tNV_Data. У массива переменных TempBuf тип другой - unsigned char. Поэтому компилятор должен выдавать как минимум предупреждение при формальной проверке соответствия типов.
Go to the top of the page
 
+Quote Post
shide_3
сообщение Oct 15 2012, 06:18
Сообщение #14


Местный
***

Группа: Участник
Сообщений: 314
Регистрация: 27-04-10
Пользователь №: 56 923



спасибо Вам за поучительные ответы.
но запись d= (tNV_Data *)TempBuf; для меня не понятна, грамотнее наверное было бы написать &TempBuf = &NV_Data; d = &TempBuf; а то какой то бред получается.. или просто d = &NV_Data
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 15 2012, 10:15
Сообщение #15


Гуру
******

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



Цитата(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). Я об этом уже писал ранее.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 27th July 2025 - 20:28
Рейтинг@Mail.ru


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