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    747

Вообще говоря, программный 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

Старт складской программы по Wi-Fi/ Bluetooth-чипам от Espressif

На склад КОМПЭЛ поступили чипы, модули и отладочные платы от компании Espressif Systems на базе ESP8266 и ESP32. Стоимость всех изделий данной линейки – в 2-3 раза ниже ближайших аналогов, чипы занимают минимальное место на плате, энергоэффективны и универсальны в применении

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

ARV    747
Только что, 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

Вебинар Литиевые ХИТы FANSO или что нужно знать инженеру о батарейках»

20 июня компания Компэл приглашает всех желающих принять участие в вебинаре, посвященном литиевым батарейкам FANSO. На вебинаре будет рассказано о параметрах батареек, их зависимости от режима работы и эксплуатации. Будет дана информация о том, на какие параметры следует обращать внимание, выбирая литиевый ХИТ, и как избежать некоторых проблем.

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

ARV    747
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    747

Да, макросы повышают быстродействие, ведь требования к 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); }
      Возможно ли их вообще подключить?

  • Сообщения

    • Да пожалуй что никакое , из тех,  что применимо в быту. Если только ТС не главный энергетик электростанции )) , и не собирается генерировать энергию в общую сеть. не проще включать по одной ?
    • А что тогда "о чём" - тёрки о щётках на пилотках том, в чём разница шоттки vs трещётки ?  ...всё там нормально, расписано - без изысков, но доступным языком (чуть ли не на пальцах), дабы не перегружать формулами неокрепшие мозги.
    • В тему шариков,мы цветными нитками обматывали дополнительно шарик с клеем,потом жестко ставили,совместно с покрашенным фильтром или лампой,лак с 25вт не сгорал,,,,цапон и разный,цвет с ручек касный классный,зеленый тоже,с синим не очень,а вообще шикардос
    •   Мысль правильная, только токовые клещи явно лишние. До "ныряния" под землю  - на одну фазу вешаем 10 утюгов, на вторую - 5, третью оставляем без нагрузки и, на "вылазе" измеряем напряжение на каждой...
    • вот ЭТО самое интересное. особенно график преобразования ЧМ-сигнала в однобитный ШИМ нарисуйте пожалуйста нам, убогим, по какому графику работает Ваш замечательный преобразователь ещё пепси и чипсов ! the show must go on
    • вздор! Из АМ-детектора никаких сотых долей не выжмешь. Есть только 1 способ -прекратить ток гармонического сигнала через АМ-детектор то есть ПОДАВИТЬ АМ-модуляцию. Прекратить образование гармоник и субгармоник. Но тогда исчезает АМ-детектор что и требуется собсно. Диоды певесести в режим с отсечкой тока, когда их ток станет импульсами. Это ничем не противоречит целям этих писателей про превращение ПЧ в импульсы. Но если у них для АМ-огибающей диод всегда открыт тогда тело перемещается в морг. Всегда открытый диод это пробитый диод. Да, настоящая наука осознает чтобы получить высококачественную ЧМ-демодуляцию надо устранить все что связано с АМ. 1. Режимы диодов сделать импульсными 2. до преобразователя ввести ограничение или стабилизацию амплитуды (АРУ) 3. Подавить ПАМ в ЧМ-демодуляторе Чтобы все это реализовать  нужен отказ от рассмотрения АМ-детектироавания как методики, то есть ОТКАЗ ОТ ДЕДОВСКИХ СХЕМ И ТЕОРИЙ. Но павлик настойчиво отказывается от высокого качества сохраняя АМ-детектирование. Потому и не будет никакого качества ни у него ни у тех кто будет повторять. Подробно опишу процесс превращения в однобитный цифровой демодулятор: Общее напряжение имеет полюсы  9,8мгц и 11,6мгц, благодаря высокой постоянной времени цепи автосмещения за время девиации частоты к к полюсам постоянное смещение не изменяется и ток в импульсах остается постоянным (неизменным) и в результате  ток протекает импульсами от одного полюса к другому, заряжая или разряжая конденсатор памяти. То есть ток либо приносит дополнительный заряд либо уносит лишний. Так образуется управление зарядом для затвора полевого транзистора ОУ. При этом ток стекающий в затвор отсутствует т.к. он весьма низкий, гораздо менее чем обратные токи диодов и не учитывается. На фоне рабочего прямого тока ЧМ-демодулятора, который составляет около 0,3мА Этот ток затвора ОУ (5-50рА) ни в одном процессе не участвует и током нагрузки не является. Демодулятор формально получается преобразователем ШИМ в звуковой сигнал. При ЧМ частота импульсов меняется и это означает модуляцию длительности импульса и паузы-то есть ШИМ. Никого сегодня нельзя удивить такими преобразователями и работают они в цифровых усилителях НЧ,0 блоках питания компов но на низких частотах до 0,5мгц, а моя схема реализует преобразование ШИМ на высокой ПЧ 10,7МГЦ что абсолютно революционно применительно к задаче. Схема поддается некоторой прокачке с подбором величин  сопротивлений и емкостей а также существенная прокачка возможна при замене диодов на более чувствительные, у которых прямая проводимость возникает раньше на ВАХ. Вот это и задача физики- изобрести новые диоды, найти новые полупроводниковые материалы. Как же не прав павлик призывающий НИЧЕГО НЕ ДЕЛАТЬ, диоды не изобретать, схемы не улучшать, новую теорию не постигать и все только лишь повторять как у дедов и это пиплу нравится если у него высокая репутация. Значит пипл такой же, не желает ничего делать для будущего и потому будущее отменяется. Россия приемников не производит и не собирается. Старое советское либо уже развалилось либо на стадии осыпания песка. Отказ от модернизационного производства означает отказ от повышения или хотя бы СОХРАНЕНИЯ ДОХОДНОСТИ то есть любители дедовских теорий будут становится НИЩИМИ, терять зарплату и доходность, уважение, семью и разум. Вот это и есть ДИВЕРСИЯ против будущего России, иногда эта диверсия звучит по другому: все новое это хорошо забытое старое или: все уже украли до нас. Результат: нищенство, глупота, доходы снижаются, производство разрушается. Даже совки были умнее и тырили на западе все что смогут новое чтобы воспроизвести а этим павликам ничего не надо, дедовское д-мо в самый раз. Удивительно, но запад не имеет этой болезни и видит возможность разбогатеть только произведя и продав что-то абсолютно новое.       Срач в этой теме доказывает что разрушение доходности в терминальной стадии и уже пошло разрушение морали, совести, разума.