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

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> DS18b20, Исходный код ARM
aaarrr
сообщение May 28 2009, 09:32
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Нет, из головы. При чем тут IAR?
Go to the top of the page
 
+Quote Post
huntero4ek
сообщение Jun 2 2009, 22:05
Сообщение #17





Группа: Новичок
Сообщений: 11
Регистрация: 24-05-09
Пользователь №: 49 496



Вот написал пару функций для работы с DS18B20
Посмотрите плз, правильно ли они реализованы, в особенности меня интерисует установка "0" или "1" с помощью вкл и выкл подтягивающих резисторов. Может есть какой-нить другой способ?
CODE
#define IN (1<<29)

void writebit0(void){
AT91F_PIO_CfgOpendrain(AT91C_BASE_PIOA, IN);//формируем низкий уровень
_delay_us(60);//по истечении 60us установит флаг DS
while(!DS);
AT91F_PIO_CfgPullup( AT91C_BASE_PIOA, IN);//формируем высокий уровень
}

void writebit1(void){
AT91F_PIO_CfgOpendrain(AT91C_BASE_PIOA, IN);//формируем низкий уровень
_delay_us(3);
while(!DS);
AT91F_PIO_CfgPullup( AT91C_BASE_PIOA, IN);//формируем высокий уровень
_delay_us(58);
while(!DS);
}

void writebyte(unsigned char byte){
unsigned char i;
char b;
for(i=0; i<8; i++){
b = (1 << i);
if (byte&b)
writebit1();
else
writebit0();
}
}

unsigned char readbit(void){
unsigned char i;
AT91F_PIO_CfgOpendrain(AT91C_BASE_PIOA, IN);//формируем низкий уровень
_delay_us(10);
while(!DS);
AT91F_PIO_CfgPullup( AT91C_BASE_PIOA, IN);//формируем высокий уровень
_delay_us(15);
while(!DS);
if ((AT91F_PIO_GetInput(AT91C_BASE_PIOA)& IN)==IN) i=1; else i=0;
_delay_us(35);
while(!DS);
return i;
}

signed char readbyte(void) {
unsigned char i, r, read_byte;
for(i=0, r=1, read_byte=0; i<8; i++){
if (readbit())
read_byte|=r;
r<<=1;
}
return read_byte;
}
Причина редактирования: Уменьшение видимого размера цитаты исходника.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 3 2009, 07:55
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(huntero4ek @ Jun 3 2009, 02:05) *
Может есть какой-нить другой способ?

Логично было бы выставить вывод в "0" (PIO_CODR) и упрвлять направлением через PIO_OER/PIO_ODR, не трогая pull-up, который вообще должен быть внешним.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jun 3 2009, 08:07
Сообщение #19


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(huntero4ek @ Jun 3 2009, 01:05) *
Вот написал пару функций для работы с DS18B20
Код
#define IN            (1<<29) 


cranky.gif  Точно будет работать? Не надо ли (1UL << 29) ???
Go to the top of the page
 
+Quote Post
huntero4ek
сообщение Jun 3 2009, 08:26
Сообщение #20





Группа: Новичок
Сообщений: 11
Регистрация: 24-05-09
Пользователь №: 49 496



Цитата(aaarrr @ Jun 3 2009, 10:55) *
Логично было бы выставить вывод в "0" (PIO_CODR) и упрвлять направлением через PIO_OER/PIO_ODR


Т.е. так:
Код
unsigned char readbit(void){
unsigned char i;

  AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, IN);
  AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, IN);//формируем низкий уровень

  _delay_us(10);
  while(!DS);
   AT91F_PIO_CfgInput( AT91C_BASE_PIOA, IN);//формируем высокий уровень
  _delay_us(15);
  while(!DS);
  if ((AT91F_PIO_GetInput(AT91C_BASE_PIOA)& IN)==IN) i=1; else i=0;
  _delay_us(35);
  while(!DS);
  return i;
}

После установки низкого уровня ведущим (1-15us) надо "освободить шину". Т.е., сконфигурировав ногу на вход, я как бы ее освобождаю (при этом pull-up по-умолчанию включен. На шине установится высокий уровень??
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 3 2009, 08:33
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(huntero4ek @ Jun 3 2009, 12:26) *
Т.е., сконфигурировав ногу на вход, я как бы ее освобождаю (при этом pull-up по-умолчанию включен. На шине установится высокий уровень??

Установится, куда денется.
Go to the top of the page
 
+Quote Post
huntero4ek
сообщение Jun 3 2009, 08:36
Сообщение #22





Группа: Новичок
Сообщений: 11
Регистрация: 24-05-09
Пользователь №: 49 496



Значит подчиненный способен завалить ногу в 0 даже с внутренним pull-up резистором в МК?
Цитата
Сигнал “Чтение” : Ведущий устанавливает низкий уровень в течение 1…15 мкс. После этого подчиненный удерживает шину в низком состоянии, если желает передать лог. 0. Если необходимо передать лог. 1, то он просто освобождает линию.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 3 2009, 09:09
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Естественно.
Go to the top of the page
 
+Quote Post
huntero4ek
сообщение Jun 16 2009, 07:17
Сообщение #24





Группа: Новичок
Сообщений: 11
Регистрация: 24-05-09
Пользователь №: 49 496



Никак не могу побороть проблему с генерацией временных задержек таймером.
Код
#define TC_CLKS_MCK8             0x1

void timer_init ( void )
{
AT91F_TC_Open(AT91C_BASE_TC1,TC_CLKS_MCK8,AT91C_ID_TC1);
AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_TC1, TIMER1_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, timer1_c_irq_handler);
AT91C_BASE_TC1->TC_IER  = AT91C_TC_CPCS;
}

Таким образом,инкримент счетчика будет происходить 48000000/8=6000000 раз/с.
сделал процедурку
Код
void UTIL_DelayTimeInUs(unsigned long time_us)
{
  DelayFlag = 0;
  AT91C_BASE_TC1->TC_RC = 6*time_us; //умножив на шесть, получим 1 инкримент счетчика за 1мкс
//умножив все это на требуемое количество мкс получим прерывание, по истечении заданного кол-ва мкс
  AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG;
  AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_TC1);  
  while(!DelayFlag);
  AT91F_AIC_DisableIt (AT91C_BASE_AIC, AT91C_ID_TC1);
}


void timer1_c_irq_handler(void)
{
  AT91PS_TC TC_pt = AT91C_BASE_TC1;
  unsigned int dummy;
  static unsigned long usCount = 0;
  //* Acknowledge interrupt status
  dummy = TC_pt->TC_SR;
  //* Suppress warning variable "dummy" was set but never used
  dummy = dummy;
  DelayFlag = 1;
  MOV_PWM(); //вызываю требуемую ф-цию
}

Решил прописать вызов MOV_PWM() прямо в обработчике - срабатывает моментально, не дожидаясь окончания заданного интервала ( UTIL_DelayTimeInUs(6000000); задержка должна быть 6с!). если же убрать MOV_PWM из обработчика и прописать
Код
UTIL_DelayTimeInUs(6000000);
MOV_PWM();

то MOV_PWM() вообще не вызывается, подскажите пожалуйста, в чем проблемма.

Сообщение отредактировал huntero4ek - Jun 16 2009, 07:19
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 16 2009, 08:06
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(huntero4ek @ Jun 16 2009, 11:17) *
Решил прописать вызов MOV_PWM() прямо в обработчике - срабатывает моментально, не дожидаясь окончания заданного интервала ( UTIL_DelayTimeInUs(6000000); задержка должна быть 6с!).

Видимо флаг CPCS уже взведен на момент разрешения прерываний

Цитата(huntero4ek @ Jun 16 2009, 11:17) *
если же убрать MOV_PWM из обработчика и прописать
Код
UTIL_DelayTimeInUs(6000000);
MOV_PWM();

то MOV_PWM() вообще не вызывается

Наверное DelayFlag не объявлена как volatile.

Кроме того, дергать SWTRG при запрещенных клоках бесполезно:
Код
  AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_TC1);  
  AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG;
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jun 16 2009, 08:10
Сообщение #26


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(aaarrr @ Jun 16 2009, 11:06) *
Наверное DelayFlag не объявлена как volatile.


dummy тоже надо объявить volatile
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 16 2009, 08:13
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(_Pasha @ Jun 16 2009, 12:10) *
dummy тоже надо объявить volatile

Нет, dummy надо вообще выкинуть за ненадобностью, оставив только:
Код
TC_pt->TC_SR;


В любом случае объявлять его как volatile нет необходимости, так как этот квалификатор уже имеет TC_SR.
Go to the top of the page
 
+Quote Post
huntero4ek
сообщение Jun 17 2009, 19:12
Сообщение #28





Группа: Новичок
Сообщений: 11
Регистрация: 24-05-09
Пользователь №: 49 496



таймеры 16-битные, поэтому переделал ф-цию:
Код
void UTIL_DelayTimeInUs(unsigned long time_us)
{
  DelayFlag = 0;
  AT91C_BASE_TC1->TC_RC = 6; // прерывание должно возникать каждую мкс
  AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_TC1);  
  AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG;  
  while(!DelayFlag);
  AT91F_AIC_DisableIt (AT91C_BASE_AIC, AT91C_ID_TC1);
}

Теперь пробую задавать интервал через глобальную переменную.
Код
void timer1_c_irq_handler(void)
{
  AT91PS_TC TC_pt = AT91C_BASE_TC1;
  unsigned int dummy;
  static unsigned long usCount = 0;

  dummy = TC_pt->TC_SR;
  dummy = dummy;
  
  usCount++;
  if(usCount == 5000000){ //вместо глоб. пер. пишу 5000000 - т.е. DelayFlag должен = 1 черех 5 сек
    DelayFlag = 1;
    usCount = 0;
  }else{
     TC_pt->TC_CCR = AT91C_TC_SWTRG;
  }
  
}

проверяю - срабатывает через 15 сек. Уже не знаю что и думать...
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 17 2009, 19:44
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(huntero4ek @ Jun 17 2009, 23:12) *
прерывание должно возникать каждую мкс

И сколько тактов процессора приходится на одну микросекунду? Бедняга из прерывания не вылезает.
Go to the top of the page
 
+Quote Post
huntero4ek
сообщение Jun 17 2009, 19:48
Сообщение #30





Группа: Новичок
Сообщений: 11
Регистрация: 24-05-09
Пользователь №: 49 496



т.е. формировать задержки порядка 5мкс - с помощью таймера маловероятно? нашел реализованную функцию формирования задержки
Код
void UTIL_WaitTimeInUs(unsigned int mck, unsigned int time_us)
{
    volatile unsigned int i = 0;
    i = (mck / 1000000) * time_us;
    i = i /3;
    UTIL_Loop(i);
}

void UTIL_Loop(unsigned int loop)
{
    while(loop--);    
}

проверял - задержки в 2 раза дольше!
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 19th June 2025 - 02:55
Рейтинг@Mail.ru


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