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

 
 
> Помогите разобраться с таймером и SPI для мега 16
_Надя
сообщение Nov 18 2008, 19:58
Сообщение #1


Участник
*

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



Я по прерыванию таймера Т2 формирую импульсы длительностью 8 мс…. Т.е. через каждые 8мс должно наступать прерывание. К примеру я по 10 прерыванию устанавливаю бит а по 11 сбрасываю его. Импульс же должен получиться 8 мс, а у меня всего 1 мс. В чем может быть причина?
МK тактируется от внутренней RC цепочки частотой 8 мгц. Коэффициент деления для Т2 беру 1024. Получаем 8 000 000/1024=7812,5 1/7812.5=0,000128. Далее для формирования импульса длительностью 8 мс делю 0,008/0,000128=63. Получается, что Т2 до переполнения должен просчитать 63 раза. Записываю в счетный регистр число 255-63=192 или С0. Вот собственно и все. Может я где то в расчетах ошиблась?

Второй вопрос по SPI:
Почему-то у меня на плате выводы SPI MISO, MOSI соединены через резистор 4,7 кОм. Я соединяю их напрямую перемычкой длиной примерно 8 см. У меня такое ощущение что мой SPI срабатывает от помехи. Хочу увидеть какие данные шлют друг другу мк и ничего не могу увидеть. Может причина в настройках?
Если не лень, посмотрите алгоритм, пожалуйста... Ну что я делаю не так?
Для мастер
На выводе SS высокий уровень. Инициализирую SPI:
Включаю SPI, разрешаю прерывания., режим мастер, частота CLK 125 кГц.
На вывод SS Slave подаю 0 в SPDR загружаю данные.
В прерывании считываю принятые данные от Slave вызываю функцию обработки принятых данных.

Для Slave
Инициализирую SPI: Включаю SPI, разрешаю прерывания.
В SPDR загружаю данные.
В прерывании считываю принятые данные от Master вызываю функцию обработки принятых данных.

Заранее благодарю smile.gif
прошу прощения за много бкафф
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
_Надя
сообщение Nov 19 2008, 14:19
Сообщение #2


Участник
*

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



Спасибо всем за помощь smile.gif
Не судите строго - это первая программа, которую я пишу. До этого программированием не занималась. поэтому может что то быть криво косо не красиво, но мне сейчас важно что бы это работало.
с таймером разобралась - все получилось.
С SPI тоже все хорошо. видно что отсылается что принимается. конечно все это с учетом Ваших замечаний.
Теперь возник еще один вопрос, никак не могу понять в чем же дело...
я в пошаговом режиме просматриваю алгоритм - все отлично работает, если переменные val и adc2 имеют значения больше 0х80 - то все корректно работает, если меньше то там где не нужно в статус регистре устанавливаются флаги Н, S, V, C . Дальше идет неверное выполнение программы. я так понимаю, что это связано с отрицательными числами. Везде стараюсь сравнивать переменные одинаковых типов. Правда в этой программе приходится переменный val , adc2 присваивать числа, т.к. на самом деле в эти переменные записывается результат АЦП. Точнее в переменной val хранится результат АЦП а переменная adc2 - в нее пишется принятое по SPI значение. Может кто нибудь подскажет на что обратить внимание? и какие еще косяки бросились Вам в глаза в первом исходнике? Мне сейчас это важно. заранее благодарю smile.gif
Код
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <avr/eeprom.h>
#include <util/delay.h>


// global defines
#define uchar unsigned char
#define ushort unsigned short


// init_ports

#define F_CONTROL   PB0
#define P_OUT          PB1
#define P_OUT1         PB2
#define P_relays     PB3
#define SLED1        PC2
#define SLED2        PC3
#define Zap1        PC4
#define Zap2        PC5
#define SNU         PD7
#define TEST        PD1
#define N_relays    PD0


#define CPU_CLK                8000000
#define STATUS1_ON        PORTC|=_BV(SLED1)
#define STATUS1_OFF        PORTC&=~_BV(SLED1)
#define FCONTROL_ON      PORTB|=_BV(F_CONTROL)
#define FCONTROL_OFF     PORTB&=~_BV(F_CONTROL)
#define POUT_ON          PORTB|=_BV(P_OUT)
#define POUT_OFF        PORTB&=~_BV(P_OUT)
#define POUT1_ON          PORTB|=_BV(P_OUT1)
#define POUT1_OFF        PORTB&=~_BV(P_OUT1)
#define SNU_ON          PORTD|=_BV(SNU)
#define SNU_OFF            PORTD&=~_BV(SNU)


// global variables


volatile signed char val;                   //Максимальное значение в массиве
volatile signed char val8;                 //Переменная для анализа уровня
volatile signed char adc_delta;             //Разница значений между двумя АЦП
volatile signed char adc2;                  //Принятый рез-т АЦП
volatile uchar level;
volatile signed char leveloff;
volatile signed char dop1;
volatile signed char dop2;
volatile signed char n;
volatile signed char t;
uchar eeprom_addr;
uchar adc_addr;

//functions

void analyze_transmit();


//Инициализация портов
void init_pio()      
{ DDRA=0;
  DDRB=0xBF;
  DDRC=0xBF;
  DDRD=0xB3;
  PORTB=0x10;                    // откл.Slave по  выводу SS
  PORTC=0x30;
  PORTD=0x01;
}


// read cfg from eeprom

#define EEA_LEVEL           0
#define EEA_LEVEL_OFF   1

void read_cfg()
{eeprom_addr=0;
  adc_addr=0;
eeprom_write_byte(0,0xBB); //Порог включения
eeprom_write_byte(1,0x74); //Порог выключения
//read
level=eeprom_read_byte(EEA_LEVEL);
leveloff=eeprom_read_byte(EEA_LEVEL_OFF);
}

// analyze_transmit анализ  принятых данных
void analyze_transmit()
{
dop1=0x00;  // Допустимое. значение 5
  dop2=0x01;  // Допустимое значение 0
  val=0x0F;
  adc2=0F;
  adc_delta=val-adc2; // Определение разницы измеренного  и принятого значения АЦП
if (adc_delta>=dop1) val8=adc2; //Если разница положительная используем принятое значение АЦП
if (adc_delta<dop1)
  {adc_delta=adc2-val; // Если отриц.,вычисляем положительную разницу
  val8=val;            // используем измеренное значение
  }

    if (adc_delta>dop2) // Если разница больше допустимого
    { STATUS1_OFF;      //Выкл. индик.
      FCONTROL_OFF;       //Выкл. контр. частоту
      POUT_OFF;           //Выкл. фронт ключ
      //POUT1_ON;           //Вкл. тыл. ключ
    SNU_OFF;
      return;
    }
  
  if(adc_delta<=dop2) {     //Если разница меньше допустимого -  анализ порога    
  if (val8>=level)             //если больше порога                                // Здесь  устанавливаются флаги H,C,N Статус регистр
        { STATUS1_ON;      //Вкл. индик
           FCONTROL_ON;     //Вкл. контр. частоту
          POUT_ON;         //Вкл. Вкл. фронт. кл.
        //POUT1_OFF;       //Выкл. тыл.  ключа
        SNU_ON;          //Вкл. сигнала наличия уровня
       }
     }
  
  else {            // если меньше порога
    if (val8<leveloff)
            {    STATUS1_OFF;  //Выкл. индик.
              FCONTROL_OFF; //Выкл. контр. частоту
              POUT_OFF;     //Выкл. фронт ключ
             //POUT1_ON;    //Вкл. тыл. ключ
              SNU_OFF;      //Выкл. сигнала наличия уровня
           }
   } }



int main(void)
{  
   init_pio();
   read_cfg();
   while (1)
   analyze_transmit();
   }


Сообщение отредактировал _Надя - Nov 19 2008, 14:20
Go to the top of the page
 
+Quote Post



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

 


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


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