макет управляющей платы для цифровых сервоприводов на MSP430


итак, это только макет, собирал буквально из того что было под рукой, разве что за двигателем пришлось отдельно съездить в магазин. в итоге эта плата должна управлять тремя двигателями.
почему это сервопривод и почему он цифровой? сервопривод это, как все тут знают, привод с обратной связью.
а цифровой потому что сравнение текущего положения маховика с необходимым производится в цифровом виде.
почему MSP430? честно скажу — просто он мне нравится. и к тому же именно этот контроллер лежал у меня под рукой, да еще Launchpad с дебагером

в качестве датчика угла используется переменный резистор на 10кОм, а показания с него снимаются встроенным АЦП контроллера(в конечной задумке будет внешний АЦП), управление приводом от компьютера по UART.
двигатель управляется через H-мост и ШИМ.
схема получилась очень простая

да, я рисую схемы от руки, так проще думается, да и разводить плату проще. особенно учитывая то, что в данном случае плата повторяет схему

снизу видно переходные контактные площадки на вторую сторону платы — H-мост

уже после травления заметил, что забыл соединить землю контроллера с землей платы на лицевой стороне, но это достаточно просто исправилось

логика работы простая — АЦП снимает показания и сравнивает с, хранящемся в буфере, необходимым значением, затем крутит двигатель в нужную сторону, потом опять сравнивает и так постоянно.
заодно опробовал метод травления плат лимонной кислотой, остался доволен.

ну а механическую часть вырезал на работе из плексигласа лазером, поэтому у шестеренок получился такой ужасный люфт.
вот что получилось в итоге

здесь три провода идут к переменному резистору. если до них дотронуться рукой — пойдут помехи, в конечном изделии думаю использовать кусок USB шнура

здесь два желтых провода к двигателю, а другие два — питание +5В и земля

код прошивки, пояснения в комментариях

#include <msp430g2553.h>

void printf(unsigned int x);
static void puth(unsigned n);
void putc(unsigned char c);

unsigned int need,lastp,rxb;

int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;         // останавливаем ватчдог
  if (CALBC1_1MHZ==0xFF)			// If calibration constant erased
  {
    while(1);                       // do not load, trap CPU!!
  }
  DCOCTL = 0;                       // Select lowest DCOx and MODx settings
  BCSCTL1 = CALBC1_1MHZ;            // Set DCO
  DCOCTL = CALDCO_1MHZ;
  P1SEL = BIT1 + BIT2;              // P1.1 = RXD, P1.2=TXD
  P1SEL2 = BIT1 + BIT2 ;            // P1.1 = RXD, P1.2=TXD
  UCA0CTL1 |= UCSSEL_2;             // SMCLK
  UCA0BR0 = 104;                    // 1MHz 9600
  UCA0BR1 = 0;                      // 1MHz 9600
  UCA0MCTL = UCBRS0;                // Modulation UCBRSx = 1
  UCA0CTL1 &= ~UCSWRST;             // **Initialize USCI state machine**
  IE2 |= UCA0RXIE;                  // Enable USCI_A0 RX interrupt

//безбожно сдутая из примеров кода TI инициализаия уарта


  P3DIR=0x01;//P3.0 - ШИМ
  P3SEL=0x01;//выбор альтернативной функции(TA0.2)

  P2DIR=0x03;//P2.0 и P2.1 - управление H-мостом
  P2OUT=0x00;//двигатель остановлен

  //конфигурация таймера A0
  TA0CCR0 = 0x3000;                // период ШИМ
  TA0CCTL2 = OUTMOD_7;             // вывод TA0.2, тип выхода - выкл/вкл
  TA0CCR2 = 0x1000;                // начало ШИМ
  TA0CTL = TASSEL_2 + MC_1;        // счет до CCR0, тактирование от SMCLK


  //инициализация АЦП
  // в качестве ИОН используем VEref+ и VEref-
  // 16 x ADC10CLKs (выборка за 16 тактов), включаем АЦП.
  ADC10CTL0 = SREF_6 + ADC10SHT_3 + ADC10ON + ADC10IE + MSC;
  // Вход A5, делитель ADC10CLK на 1, циклический одноканальный режим.
  ADC10CTL1 =  INCH_5 + SHS_0 + ADC10SSEL_0 + ADC10DIV_0 + CONSEQ_0;

  ADC10CTL0 |= ENC;     // Разрешаем преобразования.

  need=0x100;//начальное значение угла поворота
  lastp=0;//буфер для запрета повтора вывода данных
  rxb=0;//буфер для ввода данных

  while(1)
  {
	  ADC10CTL0 |= ADC10SC;//начинаем новое преобразование
	  _BIS_SR(CPUOFF+GIE);//убиваем процессор, разрешив прерывания

	  //следующий код выполняется после включения процессора
	  if((ADC10MEM>(need-2))&&(ADC10MEM<(need+2)))//если значение достигнуто
	  {			//учитывается погрешность из за плохой механики
	       	P2OUT=0x00;
	       	if(need!=lastp)//если еще не выводили это значение
	       	{
	  		printf(ADC10MEM);//вывести
	  		lastp=need;//и больше не выводить его
	       	}
	  }
	  else if(ADC10MEM>need)//если считанное значение больше нужного
	  {
	       	P2OUT=0x02;//крутим в одну сторону
	       	TA0CCR2=0xB00+(ADC10MEM-need)*5;
	  }
	  else if(ADC10MEM<need)//если меньше
	  {
	       	P2OUT=0x01;//в другую
	        TA0CCR2=0xB00+(need-ADC10MEM)*5;
	  }
  }
}

static void puth(unsigned n)//вывод 16-ричного символа
{
    static const char hex[16] =
    { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    putc(hex[n & 15]);
}


void printf(unsigned int x)//вывод 16-ричного числа
{
	putc(13);
	putc(10);
	putc('0');
	putc('x');
	char i;
	for(i=0;i<4;i++)
	{
		puth((x&0xF000)>>12);
		x=x<<4;
	}
	putc(13);
	putc(10);
}

void putc(unsigned char c)//вывод символа в UART
{
	while (!(IFG2 & UCA0TXIFG)); // Poll TXIFG to until set
	UCA0TXBUF = c;       // TX -> RXed character

}

//  прерывания по приему чего-то по UART
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)//прием символа из UART по прерыванию
{
  if((UCA0RXBUF>='0')&&(UCA0RXBUF<='9'))//распознавание 16-ричных
  {
	  rxb=rxb<<4;
	  rxb+=UCA0RXBUF-'0';
  }
  if((UCA0RXBUF>='a')&&(UCA0RXBUF<='f'))//символов как цифр входного числа
  {
  	  rxb=rxb<<4;
	  rxb+=UCA0RXBUF-'a'+10;
  }
  if(UCA0RXBUF=='g')//по команде 'g' последние 10 бит входного числа
  {		//присваиваются текущему значению угла поворота
	  need=rxb&0x3FF;
	  rxb=0;
  }
  while (!(IFG2&UCA0TXIFG));                // USCI_A0 TX buffer ready?
  UCA0TXBUF = UCA0RXBUF;//передача принятого символа назад,
  	  	  	  	  	  //для организации терминала в putty
}

#pragma vector = ADC10_VECTOR//прерывание от АЦП по завершении преобразования
__interrupt void adc10_(void)
{
		__bic_SR_register_on_exit(CPUOFF);//включаем процессор
}


видео работы

Комментарии (25)

RSS свернуть / развернуть
Плата огонек конечно =) А видео нет только у меня?
0
  • avatar
  • N1X
  • 08 сентября 2013, 10:20
Видео нет.
+1

ААААААААААААААААААААААААА, что это?!!!
0
Это ужас на крыльях ночи. Само плохое, когда это входит в привычку. Если это макетный, тестовый, черновой или ещё какой не релизный вариант, это не дает право делать через пятую точку. Автору нужно осваивать сапр, а не на бумажках рисовать и разводить с нарушением здравого смысла.
+6
  • avatar
  • Wic
  • 08 сентября 2013, 13:08
причём явно видно, что сначала планировался использоваться автотрассировщик, но его результаты были поправлены ручками.
0
а что плохого в том что бы развести простенькую плату руками? так даже проще, чем любым сапром. вот сложные платы — там да, без них никуда. на работе я рисую в Altium Designer
0
плата — симпатяжка, ага :) но для черновика не пофиг ли?
А исходники есть?
0
Для черновика? Если ОНО вообще не дай Бог заработает и протравится без особых проблем, тогда сойдет. Это же можно глаза сломать, на такое смотреть. А где же чувство прекрасного и хоть намек на перфекционизм?

Что то вроде этого напоминает.
+2
«Оно» уже протравилось, вы не заметили? И даже, говорят, работает, хотя видео невидимо.
0
я, конечно, понимаю, что у каждого свои вкусы. но мне, например, уже протравленная плата эстетически очень даже нравится
0
Хотелось бы посмотреть механическую часть с шестерёнками у которых «ужасный люфт».
0
  • avatar
  • EW1UA
  • 08 сентября 2013, 14:45
Это да… Хотя на лазером можно красивенькие и точные шестереночки сделать, если правильно им зубчики посчитать да нарисовать.
0
С «посчитать и нарисовать» могут быть сложности из-за оплавления оргстекла и необходимости вводить коррекцию.
0
да, лазер то не очень хороший — крепления на вал двигателя и резистора вообще пришлось руками допиливать.
шестеренки то есть где взять, только времени много на это уйдет
но теперь уже надо
0
На первом фото, справа.Люфтуют, надо полагать, вон те прозрачные шестерни.
0
  • avatar
  • Vga
  • 08 сентября 2013, 14:57
Ах да, развернул окно браузера, тогда обнаружил.
0
А мне больше мостик понравился. Я вообще очень люблю наивное искусство.
+1
ну говорю же, собирал из того что под рукой. транзисторов этих у меня навалом, а микросхему моста надо заказывать и ждать
+1
Не, мне их расположение понравилось. Прям Тараканище из книжки Чуковского.
+3
Да, мост бесподобен… Напомнило кофеин? ;)
+1
я так понял вы имеете в виду, что дорожки и компоненты должны быть параллельны и перпендекулярны? а почему? это электрически как-то обосновано? и мы сейчас не береч ВЧ схемы, где своя наука трассировки
+1
делал с аналоговым управлением такое на одном операционнике. На вход можно ШИМ подавать отфильт
0
рованный
0
добавил код, починил видео
+1
да, я рисую схемы от руки, так проще думается, да и разводить плату проще. особенно учитывая то, что в данном случае плата повторяет схему

Так это ж TOPOR!!!
0
  • avatar
  • Sly
  • 10 октября 2014, 16:08
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.