|
сделать задержку при включении |
|
|
|
Oct 3 2012, 20:06
|
Местный
  
Группа: Участник
Сообщений: 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ильно не ругайте
|
|
|
|
|
Oct 4 2012, 04:26
|
Частый гость
 
Группа: Свой
Сообщений: 170
Регистрация: 8-02-06
Из: Москва
Пользователь №: 14 116

|
Цитата(shide_3 @ Oct 4 2012, 00:06)  while !(TBR = 32768); //ждем 5 секунд cильно не ругайте  А вас компилятор за это сильно не ругал?
|
|
|
|
|
Oct 4 2012, 05:29
|
Местный
  
Группа: Участник
Сообщений: 314
Регистрация: 27-04-10
Пользователь №: 56 923

|
Цитата(chernenko @ Oct 4 2012, 07:26)  А вас компилятор за это сильно не ругал? пока нет, я еще не компилировал. просто сомневаюсь в том что код будет делать то что нужно.хорошо бы просимулировать, только как в ИАР это сделать
Сообщение отредактировал shide_3 - Oct 4 2012, 05:31
|
|
|
|
|
Oct 4 2012, 05:45
|
Участник

Группа: Участник
Сообщений: 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
|
|
|
|
|
Oct 4 2012, 06:12
|
Местный
  
Группа: Участник
Сообщений: 314
Регистрация: 27-04-10
Пользователь №: 56 923

|
Цитата(E.V.G. @ Oct 4 2012, 08:45)  P4OUT &= ~BIT1; P4DIR |= BIT1; P4SEL |= BIT1; а нужно ли вначале инициализировать порт, ведь тогда нога переключится когда он досчитает до 40960?
|
|
|
|
|
Oct 5 2012, 04:18
|
Участник

Группа: Участник
Сообщений: 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
|
|
|
|
|
Oct 9 2012, 18:29
|
Гуру
     
Группа: Свой
Сообщений: 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, Спросите у разработчика  Скорее всего это какой-нибудь временный буфер для хранения копии структуры 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.
|
|
|
|
|
Oct 10 2012, 07:25
|
Местный
  
Группа: Участник
Сообщений: 314
Регистрация: 27-04-10
Пользователь №: 56 923

|
Цитата(rezident @ Oct 9 2012, 21:29)  Спросите у разработчика  Скорее всего это какой-нибудь временный буфер для хранения копии структуры 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? поправьте пожалуйста если я заблуждаюсь
|
|
|
|
|
Oct 10 2012, 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-и битной переменной будет давать неверный результат.
|
|
|
|
|
Oct 10 2012, 12:03
|
Местный
  
Группа: Участник
Сообщений: 314
Регистрация: 27-04-10
Пользователь №: 56 923

|
Цитата(rezident @ Oct 10 2012, 14:11)  Адрес буфера TempBuf типа unsigned char "насильно" приводится к адресу внешней переменной типа tNV_Data но то же самое можно сказать и про переменную d , поскольку static tNV_Data *d
|
|
|
|
|
Oct 15 2012, 10: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). Я об этом уже писал ранее.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|