Теперь в нашем онлайн-магазине доступна уникальная книга «BEAM-робототехника. От азов до создания практических устройств», идеально подходящая как для кружков робототехники, так и для самообучения дома. Вы можете приобрести её по привлекательной цене в 699 рублей. Дополнительная информация о книге доступна на нашем сайте. Также в ассортименте нашего онлайн-магазина представлены готовые наборы для сборки роботов, с помощью которых ваш ребенок сможет легко собрать своего первого робота, следуя нашим подробным инструкциям. Перейти в магазин


[ Раскрыть online-чат / Закрыть ] · [ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 3 из 4
  • «
  • 1
  • 2
  • 3
  • 4
  • »
Модератор форума: nightmare, Huntswarrior, Aleks_Crow  
Форум » Программирование микроконтроллеров AVR, PIC » Вопросы по програмированию » МК - Моторчик - Фотопрерыватель (*icon-0*)
МК - Моторчик - Фотопрерыватель
Отправлено 20.10.2011 - 18:451
Участник
8 сообщений
Мужчина
Имеется:
- средство разработки TE-Mini168 (ATmega168)
- драйвер L293D
- щелевой фотопрерыватель BITR9707 (DINT-5200)
- программатор KIT BM9010 USB
- электродвигатель F280-23100 9.0V (моторчик, на конце прикреплена типа шторка вида X, для датчика)
- AVR Studio 5.0
- MathLab
- Proteus 7 Professional

Необходимо:
- все это дело собрать
- написать прошивку: входные данные - для оборотов моторчика, выходные данные - данные с датчика
- соединить с MathLab: нужно в зависимости от получаемых данных с датчика, управлять оборотами двигателя

P.S.: Пока что в ISIS запускал простейшую прошивку, написанную мною (впервые этим заниматься начал). Но чувствую что сам не справлюсь, особенно с MathLab. Как связать с MathLab вообще не понял.

Не до конца еще собран, т.к. пока что на стадии написания прошивки, а ее работу проверяю в эмуляторе ISIS. Сейчас вот пытаюсь разобраться с ШИМ сигналом от МК к драйверу. Кто-нибудь может помочь с кодом?





ISIS.zip (38.4 Kb) · AVR.zip (13.2 Kb)
Профиль Личное сообщение Дом. страница icq Skype
0
Отправлено 23.11.2011 - 15:4631
Участник
16 сообщений
Мужчина
nightmare когда читал на сайтах и форумах про UART, наткнулся на ссылку для генерации кода (AVR/Си) =)
Там выбрал свой МК (ATmega168) и галочкой включил usarts, поставил Baudrate=9600, на что он выдал:

Code
#include <avr/io.h>
#include <avr/interrupt.h>
#define RAMSTART 0x0100
#define RAMSIZE (RAMEND-RAMSTART+1)
#define nop() asm volatile ("nop")
#define sleep() asm volatile ("nop")

unsigned char usart0_read()
{
    while (!(UCSRA & (1<<RXC))) ;
    return UDR;
}
void usart0_write(unsigned char data)
{
    while (!(UCSRA & (1<<UDRE))) ;
    UDR = data;
}

int main()
{
   // usart '0'
   // settings: 9600 8-n-1
   // real baud = 9615
   // error = 0.15624999999999112%
   UCSRA = 0;
   UCSRB = (1<<RXEN)|(1<<TXEN);
   UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
   UBRRH = 0;
   UBRRL = 103;

   // --- main loop ---
   sei();
   for (;;) sleep(); // ... add your application code here
   return 0;
}


Профиль Личное сообщение Дом. страница icq Skype
0
Отправлено 23.11.2011 - 18:0032
Начальная группа
1798 сообщений
Мужчина
Похоже, лишнего правда нагенерило немного.


Профиль Личное сообщение Дом. страница icq Skype
38
Отправлено 23.11.2011 - 19:5633
Участник
16 сообщений
Мужчина
Quote (nightmare)
Похоже, лишнего правда нагенерило немного.

на все случаи использования мб) либо мне стоило изменить еще какие-то параметры...


Профиль Личное сообщение Дом. страница icq Skype
0
Отправлено 23.11.2011 - 21:4734
Начальная группа
1798 сообщений
Мужчина
Не пробовали еще байты через UART отправлять?


Профиль Личное сообщение Дом. страница icq Skype
38
Отправлено 27.11.2011 - 22:3535
Участник
16 сообщений
Мужчина
Неа, из того что я понял, разбирая примеры и читая в инете про UART, вот:

Рассчитываем UBBR = XTAL / (16 * baudrate) - 1 = 10000000 / (16 * 9600) - 1 = 64,104166666
XTAL - рабочая тактовая частота контроллера
rate - выбрал 9600, вродь норм самый
умножаем на 16, а не на 8 в формуле, тк не включаем ускорение - U2X

Поехали, после библиотек пишем:
Code
#define buffer_MAX 16    // длина буфера
char buffer[buffer_MAX] = "0123456789ABCDEF";  //  то что в буфере
uint8_t buffer_index=0;

// Использовать будем буфер допустим, далее пишем:

ISR (USART_UDRE_vect)   // прерывание по опустошению буфера
{
buffer_index++;   // увеличиваем индекс
if(buffer_index == buffer_MAX)   //  проверка на то, ввели ли весь индекс
     {
     UCSRB &=~(1<<UDRIE);    // UDRIE - сигнализирует о том, готов ли UDR к приему нового байту, тут проверка на это
     }
     else     
     {
     UDR = buffer[buffer_index];    // когда что-то читаем с UDR - мы берем данные с пк, когда записываем в него, UDR отправляет, как в данном случае
     }
}

int main(void)
{
#define baudrate 9600L
#define bauddivider (F_CPU/(16*baudrate)-1)
#define HI(x) ((x)>>8)
#define LO(x) ((x)& 0xFF)

// Инициализация стандартна:

// UBRRL:UBRRH - скорость
UBRRL = LO(bauddivider);    //  т.к. расчитали ранее, то можно записать тут просто = 64;     
UBRRH = HI(bauddivider);     //  а тут = 0;
UCSRA = 0;    // завершение приема и передачи, ставим - 0, тк нам этого не над
UCSRB = 1<<RXEN|1<<TXEN|0<<RXCIE|0<<TXCIE;   //  выставляем флаги: RXEN и TXEN - разрешают прием и передачу, RXC и TXC - флаги завершения передачи и прием
UCSRC = 1<<URSEL|1<<UCSZ0|1<<UCSZ1;       

     // и в конце, после всех настроек (ну типа свои еще какие-то):

sei();    // разрешаем прерывания.

buffer_index=0;  // сбрасываем индекс
UDR = buffer[0];  // отправляем первый байт
UCSRB|=(1<<UDRIE);    // Разрешаем прерывание UDRE

while(1)     
     {
            // тут свое...
     }
}
     

А для своего не могу понять что и как отправлять, принимать тоже... А примеры эти понял вроде...

Добавлено (27.11.2011, 21:34)
---------------------------------------------

Пользуясь кодами и т.д. с инета, у меня либо Proteus ISIS зависал, либо ШИМ переставал работать нормально... В итоге в даташите нашел как более правильно настроить и теперь вроде как все нормально... Написал в коде "эхо", чтобы набрал в терминале чтот, а он тебе в обратку... В Proteus ISIS нашел Virtual Terminal, подключил его RXD и TXD ножки, но что-либо писать в терминал не выходит.. Поэтому даже не знаю как мне проверить... Думал сначала проверю работает ли вообще, патом буду отправлять данные с оптопары и принимать данные для управления ШИМом...

Вот код:
Code
#define F_CPU 1000000UL //частота мк
#include <avr/io.h> // общая библиотека
#include <avr/iom168.h> // atmega168
#include <util/delay.h> // для паузы: _delay_ms(1);
#include <avr/interrupt.h> //Библиотека прерываний

//Перечисляем прототипы функций
void USART_Init(unsigned int ubrr); //Функция инициализации модуля USART
unsigned char USART_Receive(void); //Функция приема данных по протоколу USART
void USART_Transmit(unsigned char data); //Функция передачи данных по протоколу USART

unsigned int counter = 0;

#define IN1 PB0
#define IN2 PB3
#define LED PD4

ISR(INT0_vect)
{
counter++; // счетчик оборотов
if(counter == 250)
{
PORTB &= ~(1<<IN1); // стоп
PORTD |= (1<<LED); // после остановки загорается лампочка
}
}

int main(void)
{
// "0" на ножку PD0 - обороты увеличиваются, на ножку PD1 - обороты уменьшаются
unsigned int i=0;

// порты ввода-вывода:
PORTB = 0x00;
DDRB = (1 << PB1)|(1<<PB0)|(1<<PB3);
PORTD = (1 << PD0)|(1 << PD1);
DDRD = (1<<PD4);

// ШИМ, режим FAST PWM:
TCCR1A = (1 << COM1A1)|(0 << COM1A0)|(1 << WGM11)|(0 << WGM10);
TCCR1B = (1 << WGM13)|(1 << WGM12)|(0 << CS12)|(0 << CS11)|(1 << CS10);
TCNT1 = 0x00; // начальная установка счетчика
ICR1 = 0xFF; // задаем период ШИМ = 255
OCR1A = 0x00; // начальный коэффициент заполнения ШИМ

//Прерывание INT0
EICRA = (1<<ISC00);
EIMSK = (1<<INT0);

PORTB |= (1<<IN1);

USART_Init (64); // Рассчитываем UBBR = XTAL / (16 * baudrate) - 1 = 10000000 / (16 * 9600) - 1 = 64,104166666

sei();
// основной цикл:
while(1)
{
USART_Transmit (USART_Receive()); //Отправка принятого символа назад
if ( (PIND & ( 1 << PD0 )) == 0) //если кнопка "больше" нажата
{
if (i < 254)
{
i++;
OCR1A = i;
_delay_ms(10);
}
}

if (( PIND & (1 << PD1)) == 0) //если кнопка "меньше" нажата
{
if (i > 0)
{
i--;
OCR1A = i;
_delay_ms(10);
}
}
}
}

void USART_Init(unsigned int ubrr)
{
UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char)ubrr;
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}

unsigned char USART_Receive( void )
{
while ( !(UCSR0A & (1<<RXC0)) );
return UDR0;
}

void USART_Transmit( unsigned char data )
{
while ( !( UCSR0A & (1<<UDRE0)) );
UDR0 = data;
}

Добавлено (27.11.2011, 22:35)
---------------------------------------------
В одной книжке нашел, там обороты вот так вычисляют:

Code
unsigned int PreviousTime;
unsigned int CurrentTime, T;

INTERRUPT(SIG_INPUT_CAPTURE1)
{
// вычисляем текушее значение времени замера
CurrentTime=(256*ICR1H)+ICR1L;  
// проверяем, было ли переполнение значения
// если нет, то определяем период Т со времени предыдущего замера
if (CurrentTime>PreviousTime) T = CurrentTime - PreviousTime;
// если было переполнение, то определяем период Т с коррекцией
else T = 0xFFFF - CurrentTime + PreviousTime;
// сохраняем в буфер buffer форматированную строку, содержащую
// значение скорости вращения вала двигателя // нужно подключить библиотеку <string.g>
// spintf(buffer, "%06u",(unsigned long)60E6 / (unsigned long)T);

// насколько я понял все хранится в T. ее и нужно переправить...
// либо отформатировать T и отправлять значение хранящееся в buffer...

PreviousTime = CurrentTime; // делаем текущий замер "предыдущим"
}


Профиль Личное сообщение Дом. страница icq Skype
0
Отправлено 27.11.2011 - 23:1636
Начальная группа
1798 сообщений
Мужчина
Quote
#define F_CPU 1000000UL //частота мк

Quote
USART_Init (64); // Рассчитываем UBBR = XTAL / (16 * baudrate) - 1 = 10000000 / (16 * 9600) - 1 = 64,104166666

Так какая всё таки частота? 1 Мгц или 10 Мгц?
Прототипы функций не влом лепить?))


Профиль Личное сообщение Дом. страница icq Skype
38
Отправлено 27.11.2011 - 23:4737
Участник
16 сообщений
Мужчина
Quote (nightmare)
Так какая всё таки частота? 1 Мгц или 10 Мгц?
Прототипы функций не влом лепить?))

ой, точно =) пересчитаю все для 8 Мгц наверное =)
не) пусть будут прототипы))


Профиль Личное сообщение Дом. страница icq Skype
0
Отправлено 27.11.2011 - 23:5638
Начальная группа
1798 сообщений
Мужчина
Проверил в протеусе - для 8Мгц работает.
Code

#define F_CPU 8000000UL //частота мк
#define BAUD 9600
#define MYUBRR F_CPU/16/BAUD-1

  #include <avr/io.h> // общая библиотека
  #include <avr/iom168.h> // atmega168
  #include <util/delay.h> // для паузы: _delay_ms(1);
  #include <avr/interrupt.h> //Библиотека прерываний
   
  //Перечисляем прототипы функций
  void USART_Init(unsigned int ubrr); //Функция инициализации модуля USART
  unsigned char USART_Receive(void); //Функция приема данных по протоколу USART
  void USART_Transmit(unsigned char data); //Функция передачи данных по протоколу USART
   
  unsigned int counter = 0;
   
  #define IN1 PB0
  #define IN2 PB3
  #define LED PD4
   
  ISR(INT0_vect)
  {
  counter++; // счетчик оборотов
  if(counter == 250)
  {
  PORTB &= ~(1<<IN1); // стоп
  PORTD |= (1<<LED); // после остановки загорается лампочка
  }
  }
   
void _USART_Init( unsigned int ubrr)
{
/*Set baud rate */
UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char)ubrr;
//Enable receiver and transmitter */
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
/* Set frame format: 8data, 2stop bit */
UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}
   
  int main(void)
  {
  // "0" на ножку PD0 - обороты увеличиваются, на ножку PD1 - обороты уменьшаются
  unsigned int i=0;
   
  // порты ввода-вывода:
  PORTB = 0x00;
  DDRB = (1 << PB1)|(1<<PB0)|(1<<PB3);
  PORTD = (1 << PD0)|(1 << PD1);
  DDRD = (1<<PD4);
   
  // ШИМ, режим FAST PWM:
  TCCR1A = (1 << COM1A1)|(0 << COM1A0)|(1 << WGM11)|(0 << WGM10);
  TCCR1B = (1 << WGM13)|(1 << WGM12)|(0 << CS12)|(0 << CS11)|(1 << CS10);
  TCNT1 = 0x00; // начальная установка счетчика
  ICR1 = 0xFF; // задаем период ШИМ = 255
  OCR1A = 0x00; // начальный коэффициент заполнения ШИМ
   
  //Прерывание INT0
  EICRA = (1<<ISC00);
  EIMSK = (1<<INT0);
  PORTB |= (1<<IN1);
   
  USART_Init (MYUBRR);  
   
  sei();
  // основной цикл:
  while(1)
  {
  USART_Transmit (USART_Receive()); //Отправка принятого символа назад
   
  if ( (PIND & ( 1 << PD0 )) == 0) //если кнопка "больше" нажата
  {
   if (i < 254)
   {
    i++;
    OCR1A = i;
    _delay_ms(10);
   }
  }
   
  if (( PIND & (1 << PD1)) == 0) //если кнопка "меньше" нажата
  {
   if (i > 0)
   {
    i--;
    OCR1A = i;
    _delay_ms(10);
   }
  }
   
  }
   
  }
   
  void USART_Init(unsigned int ubrr)
  {
  UBRR0H = (unsigned char)(ubrr>>8);
  UBRR0L = (unsigned char)ubrr;
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);
  UCSR0C = (1<<USBS0)|(3<<UCSZ00);
  }
   
  unsigned char USART_Receive( void )
  {
  while ( !(UCSR0A & (1<<RXC0)) );
  return UDR0;
  }
   
  void USART_Transmit( unsigned char data )
  {
  while ( !( UCSR0A & (1<<UDRE0)) );
  UDR0 = data;
  }


Профиль Личное сообщение Дом. страница icq Skype
38
Отправлено 28.11.2011 - 00:0639
Участник
16 сообщений
Мужчина
Quote (nightmare)
Проверил в протеусе - для 8Мгц работает.

с такой частотой или и uart тоже работает? surprised


Профиль Личное сообщение Дом. страница icq Skype
0
Отправлено 28.11.2011 - 00:3140
БЛОГГЕР
340 сообщений
Мужчина
Если ошибусь, поправте пожалуйста, но UART лучше работает когда частота передачи кратна тактовой частоте МК (сейчас даже источник не скажу, от куда вычитал)


Профиль Личное сообщение Дом. страница icq Skype
16
Отправлено 28.11.2011 - 10:0141
Начальная группа
1798 сообщений
Мужчина
Quote
с такой частотой или и uart тоже работает?

UART тоже работает.
Терминал нужно крест накрест подключать. RX к TX, TX к RX.


Профиль Личное сообщение Дом. страница icq Skype
38
Отправлено 28.11.2011 - 20:1142
Участник
16 сообщений
Мужчина
Quote (nightmare)
UART тоже работает.
Терминал нужно крест накрест подключать. RX к TX, TX к RX.

Здорово, что работает) Пробовал, видимо настройка МК в Proteus не правильная у меня.. или фьюзов... или в AVR Studio при создании hex файла мне тож фьюзы менять нужно было...
Кстати, у TE-MINI168 свой кварц вродь как же есть) на 16 вродь) и по 22 пкф конденсаторы... Надеюсь что это так и фьюзы не нужно будет настраивать, страшно заблокировать мк...

Код в итоге вот такой будет наверное, но проблема возникла с ICR1H.. он используется в ШИМе и для нахождения частоты оборотов через оптопару.. И он один, хотя в даташите и пишут ICRnH, будто бы можно другой еще взять =( Находил другие примеры, коды для тахометров и частометров, но там опять тот же ICR1...
Code

          #define F_CPU 8000000UL //частота мк
          #define BAUD 9600
          #define MYUBRR F_CPU/16/BAUD-1
          #include <avr/io.h> // общая библиотека
          #include <avr/iom168.h> // atmega168
          #include <util/delay.h> // для паузы: _delay_ms(1);
          #include <avr/interrupt.h> //Библиотека прерываний
                    
          //Перечисляем прототипы функций
          void USART_Init(unsigned int ubrr); //Функция инициализации модуля USART
          unsigned char USART_Receive(void); //Функция приема данных по протоколу USART
          void USART_Transmit(unsigned char data); //Функция передачи данных по протоколу USART
                    
          unsigned int counter = 0;
                    
          #define IN1 PB0
          #define IN2 PB3

unsigned int PreviousTime, CurrentTime, T, X;
INTERRUPT(SIG_INPUT_CAPTURE1)
{
// вычисляем текушее значение времени замера
CurrentTime=(256*ICR1H)+ICR1L;         
// проверяем, было ли переполнение значения
// если нет, то определяем период Т со времени предыдущего замера
if (CurrentTime>PreviousTime) T = CurrentTime - PreviousTime;
// если было переполнение, то определяем период Т с коррекцией
else T = 0xFFFF - CurrentTime + PreviousTime;
// по идее все хранится в T. ее и нужно переправить.
PreviousTime = CurrentTime; // делаем текущий замер "предыдущим"
}
                    
         void _USART_Init( unsigned int ubrr)
         {
         /*Set baud rate */
         UBRR0H = (unsigned char)(ubrr>>8);
         UBRR0L = (unsigned char)ubrr;
         //Enable receiver and transmitter */
         UCSR0B = (1<<RXEN0)|(1<<TXEN0);
         /* Set frame format: 8data, 2stop bit */
         UCSR0C = (1<<USBS0)|(3<<UCSZ00);
         }
                    
          int main(void)
          {
          // порты ввода-вывода:
          PORTB = 0x00;
          DDRB = (1 << PB1)|(1<<PB0)|(1<<PB3);

          // ШИМ, режим FAST PWM:
          TCCR1A = (1 << COM1A1)|(0 << COM1A0)|(1 << WGM11)|(0 << WGM10);
          TCCR1B = (1 << WGM13)|(1 << WGM12)|(0 << CS12)|(0 << CS11)|(1 << CS10);
          TCNT1 = 0x00; // начальная установка счетчика
          ICR1 = 0xFF; // задаем период ШИМ = 255
          OCR1A = 0x00; // начальный коэффициент заполнения ШИМ
                    
          //Прерывание INT0
          EICRA = (1<<ISC00);
          EIMSK = (1<<INT0);
          PORTB |= (1<<IN1);
                    
          USART_Init (MYUBRR);          
                    
          sei();
          // основной цикл:
          while(1)
         {
         X=USART_Receive();
         if ((X>0) & (X<254))
         {
          OCR1A = X;
          USART_Transmit (T);
         }
         }
          }
                  
                  
          void USART_Init(unsigned int ubrr)
          {
          UBRR0H = (unsigned char)(ubrr>>8);
          UBRR0L = (unsigned char)ubrr;
          UCSR0B = (1<<RXEN0)|(1<<TXEN0);
          UCSR0C = (1<<USBS0)|(3<<UCSZ00);
          }         
                 
          unsigned char USART_Receive( void )
          {
          while ( !(UCSR0A & (1<<RXC0)) );
          return UDR0;
          }
                    
          void USART_Transmit( unsigned char data )
          {
          while ( !( UCSR0A & (1<<UDRE0)) );
          UDR0 = data;
          }


Сделал бы как Вы писали, но так и не разобрался, в комментариях все написал...
Code

ISR(INT0_vect)          
         {   // нужен ICP (в него сбрасывается содержимое регистра TCNTx, в нем хранится текущее число тиков таймера) и таймер тикает дальше до переполнения
             // Теория: сохраняем в temp=ICP, на следующем импульсе считаем разницу d=ICP-temp
             // зная частоту, с которой тикает таймер, можно подсчитать время одного тика t   (вот этот момент не ясен...)
             // Можно подсчитать частоту как f=1/T (об/сек), а период T=d*t
             // temp,f,T,d,t    как    unsigned int    объявить?
         }


Купил резисторы по 150 Ом, по мощности самые слабые... Вот так собираюсь соединять (ой, на рисунке нарисовал как 100 случайно):

ножку PB0 как вход еще наверное надо в коде описать..


Профиль Личное сообщение Дом. страница icq Skype
0
Отправлено 28.11.2011 - 21:0043
Начальная группа
1798 сообщений
Мужчина
Ага, как вход. Можно еще как вход с подтяжкой внутренним резистором к плюсу, тогда можно попробовать убрать резистор на 100 Ом и подключить фототранзистор к минусу питания и PB0.
Как время будет - напишу программу, всё равно собрался частотомер делать, а там период аналогичным способом измерять.


Профиль Личное сообщение Дом. страница icq Skype
38
Отправлено 28.11.2011 - 21:4744
Участник
16 сообщений
Мужчина
кстати забыл в коде еще и выходы на драйвер L293D написать... PD0 и PD1 не буду использовать, как ранее, там все таки TXD и RXD...


Профиль Личное сообщение Дом. страница icq Skype
0
Отправлено 04.12.2011 - 20:2845
Участник
16 сообщений
Мужчина
Надеюсь, что конечный код:

Code

     #define F_CPU 8000000UL //частота мк
     #define BAUD 9600
     #define MYUBRR F_CPU/16/BAUD-1
     #include <avr/io.h> // общая библиотека
     #include <avr/iom168.h> // atmega168
     #include <util/delay.h> // для паузы: _delay_ms(1);
     #include <avr/interrupt.h> //Библиотека прерываний
          
     //Перечисляем прототипы функций
     void USART_Init(unsigned int ubrr); //Функция инициализации модуля USART
     unsigned char USART_Receive(void); //Функция приема данных по протоколу USART
     void USART_Transmit(unsigned char data); //Функция передачи данных по протоколу USART
          
     unsigned int counter = 0;
          
     #define IN1 PB2
     #define IN2 PB3
     #define LED PD4
        
unsigned int PreviousTime, CurrentTime, T, X;
ISR(SIG_INPUT_CAPTURE1)
{
// вычисляем текушее значение времени замера
CurrentTime=(256*ICR1H)+ICR1L;    
// проверяем, было ли переполнение значения
// если нет, то определяем период Т со времени предыдущего замера
if (CurrentTime>PreviousTime) T = CurrentTime - PreviousTime;
// если было переполнение, то определяем период Т с коррекцией
else T = 0xFFFF - CurrentTime + PreviousTime;
// по идее все хранится в T. ее и нужно переправить.
PreviousTime = CurrentTime; // делаем текущий замер "предыдущим"
}
       
          
    void _USART_Init( unsigned int ubrr)
    {
    /*Set baud rate */
    UBRR0H = (unsigned char)(ubrr>>8);
    UBRR0L = (unsigned char)ubrr;
    //Enable receiver and transmitter */
    UCSR0B = (1<<RXEN0)|(1<<TXEN0);
    /* Set frame format: 8data, 2stop bit */
    UCSR0C = (1<<USBS0)|(3<<UCSZ00);
    }
          
     int main(void)
     {
     unsigned int i=0;
          
     // порты ввода-вывода:
     PORTB = 0x00;
     DDRB = (1 << PB1)|(1<<PB2)|(1<<PB3);
     PORTD = (1 << PD0)|(1 << PD1);
     DDRD = (1<<PD4);
          
     // ШИМ, режим FAST PWM:
     TCCR1A = (1 << COM1A1)|(0 << COM1A0)|(1 << WGM11)|(0 << WGM10);
     TCCR1B = (1 << WGM13)|(1 << WGM12)|(0 << CS12)|(0 << CS11)|(1 << CS10);
     TCNT1 = 0x00; // начальная установка счетчика
     ICR1 = 0xFF; // задаем период ШИМ = 255
     OCR1A = 0x00; // начальный коэффициент заполнения ШИМ
          
     PORTB |= (1<<IN1);
   
     TIMSK1 = (1<<ICIE1);
          
     USART_Init (MYUBRR);     
          
     sei();

     while(1)
    {
    X=USART_Receive();
    if ((X>0) & (X<254))
    {
     OCR1A = X;
     USART_Transmit (T); USART_Transmit(T>>8);
    }
    }
     }
          
     void USART_Init(unsigned int ubrr)
     {
     UBRR0H = (unsigned char)(ubrr>>8);
     UBRR0L = (unsigned char)ubrr;
     UCSR0B = (1<<RXEN0)|(1<<TXEN0);
     UCSR0C = (1<<USBS0)|(3<<UCSZ00);
     }
          
     unsigned char USART_Receive( void )
     {
     while ( !(UCSR0A & (1<<RXC0)) );
     return UDR0;
     }
          
     void USART_Transmit( unsigned char data )
     {
     while ( !( UCSR0A & (1<<UDRE0)) );
     UDR0 = data;
     }




motor.rar (68.4 Kb)
Профиль Личное сообщение Дом. страница icq Skype
0
Форум » Программирование микроконтроллеров AVR, PIC » Вопросы по програмированию » МК - Моторчик - Фотопрерыватель (*icon-0*)
  • Страница 3 из 4
  • «
  • 1
  • 2
  • 3
  • 4
  • »
Поиск: