SerYoga72

MSP430. Грамотная реализация програмного SPI

10 posts in this topic

SerYoga72    0

Приветствую всех.

Подскажите не совсем программисту (или совсем не программисту) как грамотно реализовать программный SPI. МК CC430F5137 + OLED дисплей WEH000802A от Winstar. Данные 10 бит. Аппаратный в контроллере позволяет только 8, выход свой написать. Написал, но мне это не нравиться, знаю что можно намного проще, но не нахожу решения. Да и как то странно с портами в этом контроллере работается, нельзя (или не знаю как) данные напрямую в порт кидать, типа P1.0 = 1; А только BITами оперировать??? Вот что у меня получилось, смеяться разрешается ))

//  Обработчик дисплея
//
// Маразм для програмного SPI
void SCL(uchar b) { if (b==1) (P1OUT |= BIT7); else P1OUT &= ~BIT7; } //Строб
void CSB(uchar b) { if (b==1) (P1OUT |= BIT4); else P1OUT &= ~BIT4; } //Выбор чипа
void SDI(uchar b) { if (b==1) (P1OUT |= BIT6); else P1OUT &= ~BIT6; } //Передаваемые данные
void SDO(uchar b) { if (b==1) (P1OUT |= BIT5); else P1OUT &= ~BIT5; } //Принимаемые данные




// Вывод управляющей команды для дисплея
void WriteCMD(uchar CMD)
{
  uchar i;
  CSB(0);
  SDI(0);                                      
  _delay_cycles(100);
  SCL(0);
  _delay_cycles(100);
  SCL(1);
  SDI(0);                                      
  _delay_cycles(100);
  SCL(0);
  _delay_cycles(100);
  SCL(1);
  _delay_cycles(100);
  for(i=0;i<8;i++)
  {
    uchar t = ((CMD>>(7-i)) & 0x01);  // Как уйти от переменной t ????? 
    SDI(t);
    SCL(0);
    _delay_cycles(100);
    SCL(1);
    _delay_cycles(100);
  }
  CSB(1);
}

/*============================================
Вывод одиночного символа на дисплей
============================================*/
void WriteOneDAT(uchar DAT)
{
  uchar i;;
  CSB(0);
  SDI(1);                                      
  _delay_cycles(100);
  SCL(0);
  _delay_cycles(100);
  SCL(1);
  SDI(0);                                      
  _delay_cycles(100);
  SCL(0);
  _delay_cycles(100);
  SCL(1);
  _delay_cycles(100);
  for(i=0;i<8;i++)
  {
    uchar t =((DAT>>(7-i)) & 0x01);
    SDI(t);
    SCL(0);
    _delay_cycles(100);
    SCL(1);
    _delay_cycles(100);
  }
  CSB(1);
}

Технически разница между Командой и Данными в первом бите SDI и объединить эти две функции наверно не проблема, но я уверен что это можно написать как то грамотнее ...  Как в этом контроллере с портами работать кроме как P1OUT |= BIT1 ??? Нельзя как то типа P1OUT_1 = 1;  ?? Где то в буржуйской литературе мапинг какой то проскакивал, но там я вообще не вьехал про что это, для чего это....

Заранее Всем Благодарен.

 

 

 

 

 

Share this post


Link to post
Share on other sites
ARV    763

Вообще говоря, программный SPI настолько элементарен, что просто не заслуживает какого-либо обсуждения.

// маска последнего выводимого бита
#define LAST_BIT	(1<<10)
// макрос SDI() переделать так, чтобы он возвращал bool-уровень на пине
  
uint16_t spi_io(uint16_t data){
	uint16_t result = 0;
	for(uint16_t mask = 1; mask <= LAST_BIT; mask <<= 1){
		SDO(data & mask);
		SCL(1);
		result |= SDI() ? mask : 0;
		SCL(0);
	}
	return result;
}

Вам лишь надо уточнить, в том ли направлении в моём коде идет сдвиг и в нужном ли режиме устанавливается SCK.

Share this post


Link to post
Share on other sites
SerYoga72    0

Я понимаю, но как я сказал - я совсем не программист, когда то давно писал на ассемблере.  Вот например Ваш код мне сложен для понимания, я его конечно раскурю, я Вам благодарен, но придумать я бы такое не смог.

Еще раз благодарю.

Еще бы кто по работе с портами просветил...

Share this post


Link to post
Share on other sites

Опорное решение: компоненты для защиты RS-485

Компания Bourns анонсировала новую (4-ю) версию демонстрационной платы для тестирования защиты низковольтных слаботочных цепей от токовых перегрузок и импульсных перенапряжений, в частности, для защиты интерфейса RS-485. Мы собрали для вас всю самую интересную информацию по данной теме на одной странице.

Подробнее...

ARV    763
Только что, SerYoga72 сказал:

Еще бы кто по работе с портами просветил...

А что с ними не так?

Share this post


Link to post
Share on other sites
SerYoga72    0

Пример Порт 1 Пин 0

P1OUT |= BIT0 ;  // P1.0 установили в единицу

P1OUT &= ~BIT0; // Установили в ноль

Это хорошо для моргания одним светодиодом, но часто проще сразу записать 1 или 0 в нужный порт, типа

P1.0 = 1;  // Неужели подобное невозможно реализовать в MSP430 ??

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

// Маразм для програмного SPI
void SCL(uchar b) { if (b==1) (P1OUT |= BIT7); else P1OUT &= ~BIT7; } //Строб
void CSB(uchar b) { if (b==1) (P1OUT |= BIT4); else P1OUT &= ~BIT4; } //Выбор чипа
void SDI(uchar b) { if (b==1) (P1OUT |= BIT6); else P1OUT &= ~BIT6; } //Передаваемые данные
void SDO(uchar b) { if (b==1) (P1OUT |= BIT5); else P1OUT &= ~BIT5; } //Принимаемые данные

И кстати, в Вашей версии реализации вот этот кусок почему то не работает: 

	SDO(data & mask);

Еще сильно не думал, но даже если data имеет значения 0xFFFF,   SDO все равно имеет значение 0, всегда ноль....  Даже примерно не могу понять почему...

Я использую CCS.  И кстати булевых переменных тут что то же нет? Обявления типа bool var;  выдает ошибку неопределенный тип.... 

Share this post


Link to post
Share on other sites

Видео вебинара «Уникальный подход MORNSUN к разработке DC/DC-преобразователей. Что на выходе?»

На сайте КОМПЭЛ доступны материалы вебинара, посвященные последнему поколению DC/DC преобразователей с фиксированным входом R3 от MORNSUN. Вы можете посмотреть видеозапись, ознакомиться с презентацией и ответами на вопросы.

Подробнее...

ARV    763
Posted (edited)
41 минуту назад, SerYoga72 сказал:

И кстати, в Вашей версии реализации вот этот кусок почему то не работает

потому что данные data и mask 16-битные, а функцию вы определили с 8-битным параметром. и вообще, я рассчитывал, что SDO будет макросом, которому в общем-то плевать на разрядность...

41 минуту назад, SerYoga72 сказал:

P1.0 = 1;  // Неужели подобное невозможно реализовать в MSP430 ??

Такое вообще нельзя реализовать на языке Си - это вы насмотрелись "кода" на недосишном языке CVAVR. Если сильно-сильно хочется именно подобной записи, то придется попариться со структурами и указателями... Но я вам не буду этого советовать - у вас и так проблем хватает.

41 минуту назад, SerYoga72 сказал:

P1OUT |= BIT0 ;  // P1.0 установили в единицу

P1OUT &= ~BIT0; // Установили в ноль

А вот это самая что ни на есть кошерная запись для Си. Именно так и правильно манипулировать битами.

#define SDO(x)	do{ if(x) P1OUT |= BIT5; else P1OUT &= ~BIT5; } while(0)
#define SDI()	(P1IN & BIT7)
#define SCK(x)  do{ if(x) P1OUT |= BIT6; else P1OUT &= ~BIT6; } while(0)

Как-то так всего-навсего... Я не знаком с вашей платформой, но для SDI по-моему нельзя использовать порт вывода P1OUT... я написал P1IN, хотя не уверен, что это правильно...

Edited by ARV

Share this post


Link to post
Share on other sites
SerYoga72    0

Заставил я это работать )). Благодарю.  Теперь вопрос для повышения общего уровня образованности так сказать, ну если Вы не против.:

Вы предлагаете такую реализацию:

18 часов назад, ARV сказал:

#define SDO(x) do{ if(x) P1OUT |= BIT5; else P1OUT &= ~BIT5; } while(0)

#define SDI() (P1IN & BIT7)

#define SCK(x) do{ if(x) P1OUT |= BIT6; else P1OUT &= ~BIT6; } while(0)

У меня реализовано так:

void SCL(uchar b) { if (b) (P1OUT |= BIT7); else P1OUT &= ~BIT7; } //Строб
void CSB(uchar b) { if (b) (P1OUT |= BIT4); else P1OUT &= ~BIT4; } //Выбор чипа
void SDO(uint b)  { if (b) (P1OUT |= BIT6); else P1OUT &= ~BIT6; } //Передаваемые данные

Чем Ваша реализация лучше? (Вопрос не для спора а для понимания) И для чего цикл do-while ?

По поводу SDI (принимаемых данных) Вы правы, просто я данные пока не собирался принимать и написал на автопилоте P1OUT.

Заранее благодарен.

P.S. Как уменьшить межстрочный интервал в форуме?

Share this post


Link to post
Share on other sites
SerYoga72    0

Я кажется понял, если я использую #define то при компиляции данный код вставляется в место вызова и перехода не происходит, а в моем случае происходит переход в функцию и возврат из нее, то есть так мы экономим процессорные тики, я правильно понял?

А для чего do-while ?

Share this post


Link to post
Share on other sites
ARV    763

Да, макросы повышают быстродействие, ведь требования к SPI обычно "чем быстрее, тем лучше". А do-while - это кошерная перестраховка на всякий случай. Во многих случаях можно и без этого, и данный случай как раз такой, просто делаю по привычке. Обычно do-while актуально для  макросов, состоящих из нескольких операторов, и в данном случае не дает никаких преимуществ, т.к. оператор один.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Similar Content

    • By mine1
      Наткнулся на библиотеку hal_xxx.c от TI для MSP430.
      Ни как не могу найти, где взять взять полное семейство этих библиотек. Поделитесь ссылочной  
      hal_UCS.c
    • By Isaev_ivan
      Доброго времени суток всем!
      Недавно возникла потребность передачи данных из микроконтроллера в ПК. Написал код на ассемблере, опираясь на Code_examples от TI, и то, что получилось, приведено ниже:
      #include "msp430F1232.h"
      RSEG CSTACK
      DS16 0
      RSEG CODE
      ;---------------------------------------------------------------------
      ; Установка тактирования от кварца
      ;---------------------------------------------------------------------
      RESET mov #SFE(CSTACK),SP
      mov #WDTPW+WDTHOLD,&WDTCTL ;OSTANOVKA WDT
      BIC #OSCOFF, SR ; tAKTIROVANIE OT KVARCA
      BIS.B #XTS, BCSCTL1
      L1 BIC.B #OFIFG, &IFG1
      MOV #0FFh, R15
      L2 DEC R15
      JNZ L2
      BIT.B #OFIFG, &IFG1
      JNZ L1
      BIS.B #SELM_3, &BCSCTL2
      ;--------------------------------------------------------------------
      ; Инициализация USART
      ;--------------------------------------------------------------------
      mov.b #200,R7
      bis.b #SWRST,&UCTL0;
      bis.b #030h,&P3SEL; P3.4,5 - USART
      bis.b #UTXE0+URXE0,&ME2; Включение передачи и приема
      bis.b #CHAR, &UCTL0; Формат данных 8-разрядный
      mov.b #SSEL0, &UTCTL0; UCLK=ACLK
      mov.b #0100b,&UBR00; 5MHz/19200 = 260.4 = 100000100b
      mov.b #0001b,&UBR10;
      mov.b #0000, &UMCTL0; Без модуляции
      bic.b #SWRST,&UCTL0; Сброс USART не включен
      bis.b #URXIE0+UTXIE0,&IE2
      bis.b #UTXIFG0,&IFG2; Флаг гтовности к прерыванию
      Loop bis.w #LPM3+GIE,SR
      nop
      jmp Loop
      ;-------------------------------------------------------------------
      USART0TX_ISR;
      ;-------------------------------------------------------------------
      mov.b R7, &TXBUF0;
      reti
      ;--------------------------------------------------------------------
      ; Векторы прерываний
      ;--------------------------------------------------------------------
      COMMON INTVEC
      ORG RESET_VECTOR
      DW RESET
      ORG USART0TX_VECTOR
      DW USART0TX_ISR
      END.
      Из программы видно, что я просто хочу передать содержимое R7 в ПК. Трудность заключается в том, что это значение передается не всегда. Запускаю программу, которая считывает информацию с com порта (программа работает 100% правильно), она в тестовый файл записывает значение 200(правильное значение). В следующий раз, после перезапуска программы, в текстовый файл она записывает величину 14. Потом снова 200. И я не пойму, что с ней происходит! Кто знает, отзовитесь пожалуйста
    • By yang
      I am Chinese student, now studying in St. Petersburg. I'm here one year, so i am not very good in Russian,written in English. I would like to know some new friends like programming and design, I want to participate in some professional game in Russia or complete some projects with my friends. If you need, I can help you buy some cheap things in China.If you have spare time or want to learn Chinese, hope you can help me learn the Russian language.This is part of my profile.




    • Guest Duck
      By Guest Duck
      Стоит изучать MSP430?
      Как я понимаю cortex-m он превосходит только энергоэффективностью? Или уже нет?
    • By tim-ua
      Я совсем новичок в МК, столкнулся с проблемой при подключении msp430 к bluetooth модулю. Модуль раньше работал на ардуине но с этой платой ни как не заводится.
      Подключить модуль к планшету получается (в терминале на планшете приходят обратно вводимые символы если замкнуть на модуле RX и TX). Но как дальше его подключить к msp430 я не понял. Пробовал так: P1.1 -> TX, p1.2 -> RX , пробовал менять комбинацию перемычек SW uart \ HW uart.
      Прошивка:

      void setup() { Serial.begin(9600); } void loop() { Serial.println("Test"); delay(100); }
      Возможно ли их вообще подключить?

  • Сообщения

    • У меня паранойи нет совершенно, я просто делаю правильно, т.е. так, как рекомендует производитель. Ну, допустим, команда запуска преобразования, если дошла, приведет к тому, что в течение 750 мс в тайм-слоте чтения датчик будет возвращать 0. Если это не так - команду датчик не получил. А остальные команды типа записи конфигурационных ячеек могут проверяться последующим чтением, как и рекомендует производитель. А чтение гарантируется при помощи CRC.
    • провел расчет по программе старичка,ему отдельно спасибо , - проверьте - ввел; - полумост- сопротивление канала 0.55(irf740),частота 47кгц (R-10k C 1500p) на выход 12  вольт-6 ампер, выдал на мой трансформатор первичка - 41 двойным проводом 0.3 и вторичка -двойным 0.8 -4+4 витка  ,чет не нашел как распечатать данные с программы. данные транса - проницаемость ввел 2000 ,от куда его спер не помню) заводской - вроде меньше и не должен быть.
    • Нет не грузил. Какое надо сопротивление балласта?
    • Вот, именно, мы и заставляем и судей, и приставов соблюдать ЗАКОН!
      Ведь ни одна судья (а они в основном бабы) не обращает даже толки внимания даже на конституцию, не то, что на ГПК.
      Приставы ходют без доверенностей, хотя им главный судебный пристав РФ даже приказ публиковал!
      Наверное и не даст, лишь потому, что ни они ни суды не существуют по закону РФ.
      Кароче вот вам!  
    •   Так это американцы.  В России ничего нового. Будет меняться как и всё. Если только будет вещание, а если нет тогда да, кладбищенский гранит на века. Даже не я, хочу заметить. накуя мне это надо, мой приемник работает, вчера слушал. В подавлении АМ.  в ваши ошибочные словеса?  Так я сразу показал ваши ошибки. Ну вот и придумай как разжать. Передатчик не откажется от компрессии. Поляков утверждает что динамика диодного ЧД не превышает 20-30дб и только может быть ФАПЧ даст больше. Но меня интересует несинхрон.  Повысить динамику в приемнике позволяет только концепция ЧМ как ШИМ и однобитный ЦАП. Можно и так конечно слушать но не удобно, либо шум ограничителя все забьет либо слабые станции будут приниматься гораздо тише сильных, как и происходит в ламповых приемниках где нет ограничителя. Если разница сильный слабый составит  более 20дб то приема станции вообще не будет. Можно конечно АРУ добавить  и совсем слабое ограничение. Глубокое ограничение вырезает информацию и искажает. То что не вырезано находилось на самой нижней полке  после ограничения оно переместиться на верхнюю и пройдет через ЧМ-детектор с максимальной громкостью. Это искажение. Но часть информации ограничитель уже вырезал безвозвратно. Ламповые приемники потому и звучат привлекательно потому что ограничения в них почти нет.
    • Очень напрасно. Крайне советую выбрать Keil. Весь функционал работает "из коробки" и никаких танцев с бубном не требуется. Еще более рекомендую забыть про бред под названием SPL. Конечно, если нужна стабильная и предсказуемая работа МК...