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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> ATtiny2313 прием по SPI 4 байт
WreWolf
сообщение Sep 19 2009, 10:15
Сообщение #1


Участник
*

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



на ATtiny2313
Необходимо принять 4 байта
обьединить по 2
PWM_S = первые 2 байта
Serv_S= вторые 2 байта

И вывести PWM на 1 ножку если первые 2 байта больше 127 или на 2 ножку если меньше.
ширина PWM пропорциональна значеию |X-127|.

Код
        If PWM_S >= 127 Then
            PWM1 = Math.Abs(TextBox1.Text - 127)
            PWM2 = Disable
        Else
            PWM2= Math.Abs(TextBox1.Text - 127)
            PWM1 = Disable
        End If
        //PWM1 и PWM2 соответственно ширина 1 и 2 PWM


а вторые 2 байта нужны для выдачи на 3 ножку сигнала(управление сервоприводом)
частота 50Гц
ширина импульса от 0.9мкс до 2.1 пропорционально полученному значению

п.с.
можно ли это реализовать на ATtiny26
Go to the top of the page
 
+Quote Post
Ledmaster
сообщение Sep 19 2009, 14:00
Сообщение #2


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

Группа: Свой
Сообщений: 142
Регистрация: 18-02-08
Из: Челябинск
Пользователь №: 35 141



Вопрос навстречу, а зачем принимать по два байта, если из описания следует, что значения переменных ( по крайней мере, PWM_S) явно укладываются в один байт?
Реализовать можно на чем угодно, особенно при наличии одного таймера с двумя выходами PWM и второго универсального таймера.
Первая часть даже проще, чем Вы написали:
Код
    if ( PWM_S > 127)
    {
          PWM1 = PWM_S - 127; PWM2 = 0;
    }
    else
   {
        PWM1 = 0;  PWM2 = 127 - PWM_S;
   ]

Во второй части и вовсе достаточно установить таймер в режим одиночного импульса и запускать в соответствии с принятым значением Serv_S.
Период следования можно задавать программной задержкой, поскольку точности от него не требуется никакой.
Причина редактирования: Ненужное цитирование.
Go to the top of the page
 
+Quote Post
WreWolf
сообщение Sep 21 2009, 07:28
Сообщение #3


Участник
*

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



Т.е. нужно принимать 2 слова. А мне необходимо принять 1 слово и его обработать.
Go to the top of the page
 
+Quote Post
Ledmaster
сообщение Sep 22 2009, 03:41
Сообщение #4


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

Группа: Свой
Сообщений: 142
Регистрация: 18-02-08
Из: Челябинск
Пользователь №: 35 141



Цитата(WreWolf @ Sep 21 2009, 13:28) *
Т.е. нужно принимать 2 слова. А мне необходимо принять 1 слово и его обработать.

Цитата
Необходимо принять 4 байта
обьединить по 2
PWM_S = первые 2 байта
Serv_S= вторые 2 байта


Что из этого истина?
Go to the top of the page
 
+Quote Post
WreWolf
сообщение Sep 22 2009, 10:51
Сообщение #5


Участник
*

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



принять 4 байта
например: 0xAC7F
PWM_S = 0xAC
Serv_S=0x7F
Go to the top of the page
 
+Quote Post
zltigo
сообщение Sep 22 2009, 11:26
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(WreWolf @ Sep 22 2009, 12:51) *
принять 4 байта
например: 0xAC7F

Печально, но 0xAC7F, это ДВА байта. Придется Вам начать задавать вопросы с еще более низкого уровня sad.gif


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
WreWolf
сообщение Sep 23 2009, 05:16
Сообщение #7


Участник
*

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



действительно (
но в принципе суть в том
что бы так разделить входноо сообщение.
*pwm=0xAC7F;
*pwm_s=*(pwm+1);

можно ли так?
и как взыть по 1 байту?
тип даных byte?
byte pwm=*pwm;
byte pwm_s=*pwm_s;
Go to the top of the page
 
+Quote Post
Ledmaster
сообщение Sep 23 2009, 14:30
Сообщение #8


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

Группа: Свой
Сообщений: 142
Регистрация: 18-02-08
Из: Челябинск
Пользователь №: 35 141



Цитата(WreWolf @ Sep 23 2009, 11:16) *
суть в том что бы так разделить входноо сообщение.
*pwm=0xAC7F;
*pwm_s=*(pwm+1);

Суть в том, что SPI регистр в ATtiny2313 (как впрочем и во множестве других микроконтроллеров) имеет длину 8 бит и делить ничего не нужно!
Вы, кажется, пытаетесь эмулировать работу микроконтроллера программой на PC, а надо бы начать с изучения его архитектуры.
Go to the top of the page
 
+Quote Post
WreWolf
сообщение Sep 23 2009, 17:07
Сообщение #9


Участник
*

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



Ну не совсем так.
Пишется программа которая через LPT порт сможеть передать джанные значения в тиньку.
Т.е. вы имеете в виду просто получить 2 байта.
как это реализовать программно?
требуется ли задержка при передаче с компьютера(м\у) байтами?

возможно ли выполнить 2 команды которые выполнят прием данных(если прием выполнен в виде в отдельной функции)
Go to the top of the page
 
+Quote Post
Ledmaster
сообщение Sep 24 2009, 03:18
Сообщение #10


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

Группа: Свой
Сообщений: 142
Регистрация: 18-02-08
Из: Челябинск
Пользователь №: 35 141



Цитата(WreWolf @ Sep 23 2009, 23:07) *
Пишется программа которая через LPT порт сможеть передать джанные значения в тиньку.

Вы умеете управлять линиями LPT? Приведите фрагмент кода для передачи одного байта.
Go to the top of the page
 
+Quote Post
WreWolf
сообщение Sep 24 2009, 10:17
Сообщение #11


Участник
*

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



Ну этим занимаю не я. Этим занимается другой человек.
Я занимаюсь приемным устройством.
логика такая

клок в 0
ждем
цикл по колву бит
установил данные
ждем
клок в 1
ждем
клок в 0
возврат цикла


Возможно ли использование данного кода
CODE

#include <avr\io.h>
#include <avr\io2313.h>

//Function
void USIinit(void);
ISR (USI_OVERFLOW_vect);

int main(void)
{
USInit();
unsigned char pwm=ISR();
unsigned char pwm_s=ISR();
}

/* F-я Инициализация UPI*/
void USIinit(void)
{
DDRB = (1<<USI_PIN_DO);
PORTB |= (1<<USI_PIN_DI) | (1<<USI_PIN_SCK);
USICR = (1<<USIOIE) | (1<<USIWM0) | (1<<USICS1);
}

/*Прием 1байт данных UPI*/
ISR (USI_OVERFLOW_vect)
{
int usi_in_buf[8];
int gBuf_ind_in=0;
USISR |= (1<<USIOIF);

usi_in_buf[gBuf_ind_in] = USIDR;
gBuf_ind_in++;
return usi_in_buf;
}


И вот то что я нашел еще
как переписать на си.
SPI Slave Operation Example
The following code demonstrates how to use the USI module as a SPI Slave:
CODE

init:
ldi r16,(1<<USIWM0)|(1<<USICS1)
out USICR,r16
...
SlaveSPITransfer:
out USIDR,r16
ldi r16,(1<<USIOIF)
out USISR,r16
SlaveSPITransfer_loop:
sbis USISR,USIOIF
rjmp SlaveSPITransfer_loop
in r16,USIDR
ret




Как переделать это под вывод шим на 2 пина порта D

CODE
#include "iom16.h"

unsigned char pwm = 1;
unsigned char inc = 1; // inc = 0 - уменьшать, inc = 1 - увеличивать яркость

void timer2_init()
{
OCR2 = 1; //ШИМ почти выключена
// Быстрая ШИМ, переключать OC2 (PD7), увеличение таймера каждые 64 такта
TCCR2 |= (1 << WGM20) | ( 1 << WGM21) | (1 << COM21) | (1 << CS22);
}

void timer1_init()
{
OCR1A = 43200; //Прерывание 32 раза в секунду
TCCR1A = 0;
// СТС режим, увеличение таймера каждые 8 тактов
TCCR1B |= (1 << WGM12) | (1 << CS11);
// Прерывание по совпадению А таймера1
TIMSK |= (1 << OCIE1A);
SREG |= (1 << 7); //Разрешить прерывания
}

void io_init() //Инициализация портов ввода-вывода
{
DDRD = (1 << PD7)|(1 << PD6); //додумался пока только до этого
PORTD = 0;
}

void main ()
{
timer2_init();
timer1_init();
io_init();
while(1)
{
}
}

// Заставляет лампу плавно загораться и гаснуть раз в 8 секунд
#pragma vector = TIMER1_COMPA_vect
__interrupt void PWM_change()
{
if (inc == 1)
{
if (pwm < 254)
{
pwm++; // Увеличиваем яркость лампы, пока не достигнем максимума
OCR2 = pwm;
}
else
{
inc = 0;
}
}
else
{
if (pwm > 1)
{
pwm--; // Уменьшаем яркость лампы, пока не остигнем минимума
OCR2 = pwm;
}
else
{
inc = 1;
}
}
}
Go to the top of the page
 
+Quote Post
XVR
сообщение Sep 25 2009, 07:05
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Совет первый - выкинуть обрывки кода, найденные непонятно на какой помойке
Совет второй - внимательно прочесть datasheet на используемый камень и понять какими аппаратными блоками в нем можно реализовать то, что вы хотите (и в каком режиме)
Совет третий - потом разобраться, как эта аппаратура должна взаимодействовать друг с другом (и в частности что нужно обрабатывать в прерываниях, а что нет)
И только ПОТОМ начинать писать программы
Go to the top of the page
 
+Quote Post
WreWolf
сообщение Sep 25 2009, 11:17
Сообщение #13


Участник
*

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



1) Обрывки кода выкинуты
2) Даташит прочитан.
3) В прерываниях ясности нет.(но в принципе можно на отдельную ножку кинуть прерывание и использовать ее как CS)


Вот то что было сгенерировано из CVAVR Wissard и чтения даташита
CODE

#include <avr/power.h>
#include <avr/eeprom.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define SPI_MOSI PINB5
#define SPI_MISO PINB6
#define SPI_SCK PINB7
#define DDR_SPI DDRB


#define F_CPU 8000000UL // 8 MHz


void SPI_SlaveInit(void)

{
// Set MOSI, SCK and SS as output, all others input
DDR_SPI |= (1<<SPI_MISO) ;

// Enable USI for SPI, External Clk, SPI mode 0
USICR |= (1<<USIWM0) | (1<<USICS1);
}

uint8_t SPI_SlaveReceive(void)
{
while(!(USISR & (1<<USIOIF)));
return USIDR;
}


void SPI_SlaveTransmit(uint8_t ByteOfData)
{
USIDR = ByteOfData;
while(!(USISR & (1<<USIOIF)));
}

void pwm_io_init() //Инициализация портов ввода-вывода PWM для DC мотора
{
DDRB |= (1 << PINB1)|(1 << PINB2)|(1 << PINB3)|(1 << PINB4);
PORTB = 0;
}

int main(void)
{
uint8_t ByteOfData1;
uint8_t PWM;
uint8_t PWM_S;
SPI_SlaveInit() ;
_delay_us(10) ;

while (1)
{
ByteOfData1 = SPI_SlaveReceive();

//Здесть псать обработку полученных данных
}
}


Сообщение отредактировал WreWolf - Sep 25 2009, 11:21
Go to the top of the page
 
+Quote Post
XVR
сообщение Sep 25 2009, 13:17
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Выглядит нормально.
Теперь по поводу PWM (я так понял их у вас аж 3 штуки). Я не смотрел, есть ли у tiny2313 аппаратный PWM, но если и есть, то явно не 3 канала sad.gif
Т.е. какие то из них придется формировать програмно (и лучше всего в прерывании от таймера).
Go to the top of the page
 
+Quote Post
WreWolf
сообщение Sep 25 2009, 16:59
Сообщение #15


Участник
*

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



Нет у меня всего 2 PWM
1 для управления мотором
2 для управления сервоприводом

Т.е. вы имеете в виду сделать прерывание по срабатыванию 1 PWM и програмно дергать 4 ножки вслед за сигналом PWM

у 2313 есть аппарытный 2-х канальный PWM

а как быть с сигналом управления сервоприводом?
это PWM с частотой 50Гц
Go to the top of the page
 
+Quote Post

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

 


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


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