Перейти к содержанию
    

давайте делится удобными дефайнами для stm32f10x

например я вот такие сделал :

#define enable_clock(port)	RCC->APB2ENR|=RCC_APB2ENR_IOP##port##EN // включение тактирования порта

#define set_pin(port,bit)	GPIO##port## -> ODR |= GPIO_ODR_ODR##bit // установить на порте 1
#define clear_pin(port,bit)     GPIO##port## -> ODR &= ~ GPIO_ODR_ODR##bit // установить на порте 0 
#define test_pin(port,bit)    	GPIO##port## -> ODR &=  GPIO_ODR_ODR##bit // возвращает истинное состояние на выводе ножки порта

//vvvvvvvvvvv Задаём направление и максимальную частоту работы портов MODE[bit1,bit0] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
#define set_in(port,half,bit)           GPIO##port##->CR##half##&=~(GPIO_CR##half##_MODE##bit##_0);
GPIO##port##->CR##half##|=(GPIO_CR##half##_MODE##bit##_0)
//00: Input mode (reset state) - порт работает на вход, устанавливается по умолчанию после ресета 
#define set_out_10MHz(port,half,bit)    GPIO##port##->CR##half##&=~(GPIO_CR##half##_MODE##bit##_0);
GPIO##port##->CR##half##|=(GPIO_CR##half##_MODE##bit##_1)
//01: Output mode, max speed 10 MHz. 
#define set_out_2MHz(port,half,bit)     GPIO##port##->CR##half##&=~(GPIO_CR##half##_MODE##bit##_1);
GPIO##port##->CR##half##|=(GPIO_CR##half##_MODE##bit##_0) //10: Output mode, max speed 2 MHz.
#define set_out_50MHz(port,half,bit)    GPIO##port##->CR##half##&=~(GPIO_CR##half##_MODE##bit##_1);
GPIO##port##->CR##half##|=(GPIO_CR##half##_MODE##bit##_1) //11: Output mode, max speed 50 MHz.
//если биты портов 0-7 то half=L
//если биты портов 8-15 = то half=H
// в регистре GPIOX_CR(L/H) меняет биты MODEx (режимы работы x ножки порта X)
// Пример использования:
//     set_in(D,L,7); // устанавливает порт D.7 как вход 
//     set_out_10MHz(D,L,7); //устанавливает порт D.7 как выход с максимальной частотой 10 Мгц.
//     set_out_2MHz(D,L,7);
//     set_out_50MHz(D,L,7);
//^^^^^^^^^^^^ Задаём направление и максимальную частоту работы портов ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Изменено пользователем IgorKossak
форматирование

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

хм.... И что-ж тут удобного??? :smile3046:

Во-первых - неудобно, во-вторых - баги в каждом макросе.

Вот вам для примера мои аналогичные макросы, для управления пинами GPIO (NXP). Найдите отличия и поймите где баги: :laughing:

 

#define Pval2(port, pin)   (GPIO[port].PIN >> (pin) & 1)
#define Pclr2(port, pin)   (GPIO[port].CLR = 1U << (pin))
#define Pset2(port, pin)   (GPIO[port].SET = 1U << (pin))
#define Pval(port_pin)     Pval2(port_pin) 
#define Pclr(port_pin)     Pclr2(port_pin) 
#define Pset(port_pin)     Pset2(port_pin) 
#define PORT2(port, pin)       port
#define PIN2(port, pin)          pin
#define PORT(port_pin)         PORT2(port_pin)
#define PIN(port_pin)            PIN2(port_pin)

#define PIN_RF_RST     2, 3  //порт, пин
#define PIN_KEY1         1, 0  
#define PIN_WDI                   1, 9  

//использование:
Pset(PIN_RF_RST);  //установить в '1'
Pclr(PIN_WDI);  //установить в '0'
if (Pval(PIN_KEY1)) { ... }

struct {
  u8 port, pin;
} static const t[] = {{PORT(PIN_WDI), PIN(PIN_WDI)}, ...};

Pset2(t[0].port, t[0].pin);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну, раз для STM32F1, т.е. для контроллера с ядром Cortex M3, то полезны макросы для побитовой работы с регистрами:

/*Побитовая адресация:*/
#define PERIPH_BB_ADDRESS(PeriphAddress,RegisterOffset,NumBit) (((u32)((u32)PeriphAddress+RegisterOffset)-
0x40000000)*32+(NumBit)*4+0x42000000)

#define RELAY5 (Pin)(*((Pin*) PERIPH_BB_ADDRESS(GPIOA,0x0C,2))) /*output PA2*/
#define RELAY6 (Pin)(*((Pin*) PERIPH_BB_ADDRESS(GPIOB,0x0C,2))) /*output PB2*/
#define LEDS_LED1 (Pin)(*((Pin*) PERIPH_BB_ADDRESS(GPIOE,0x0C,5))) /*output PE5*/
#define LEDS_LED2 (Pin)(*((Pin*) PERIPH_BB_ADDRESS(GPIOE,0x0C,4))) /*output PE4*/

/*И по месту просто использовать так:*/
LEDS_LED1 = 1;
RELAY6 =0;

Но при использовании оптимизации лучше использовать следующее:

#define RS485_ADDRESS_FE PERIPH_BB_ADDRESS(RS485_USART,USART_SR,1) /*адрес флага FE*/
#define RS485_ADDRESS_NE PERIPH_BB_ADDRESS(RS485_USART,USART_SR,2) /*адрес флага  NE*/

extern vu32 RS485_FE __attribute__((at(RS485_ADDRESS_FE)));
extern vu32 RS485_NE __attribute__((at(RS485_ADDRESS_NE)));

/*И по месту:*/
if( RS485_FE ) abc = bcd+cda;

Изменено пользователем IgorKossak
форматирование

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Изменено пользователем super_puper

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Совет: если собираетесь что-то написать с плотным использованием этой либы, не отходите далеко от предложенного темплейта проекта, - только в этом случае у Вас не съедет крыша от количества мелких ньюансов, которые надо держать в голове и которые отвлекают от того, что нужно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

опять решил сам писать

Изменено пользователем super_puper

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

опять решил сам писать

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

Как промежуточный вариант - отлаживаю bsp в симуле кейла, затем добавляю несколько wrapper"ов касательно синтаксиса и перехожу в GCC.

Или хватаю пример использования чего-то там (с этой либой, а как жеж) - и пилю своё.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кривизна этих либ бесспорна, но сделать лучше таки сложновато с первого захода, если надо получить нечто, работающее на всех STM32.
Не соглашусь с Вами. Вполне можно написать свои макросы, гораздо более лёгкие и понятные чем эти библиотеки.

У меня вызовы макросов типа установить/обнулить/проинвертировать/... пин GPIO одинаковы для разных процессоров, что часто позволяет переносить исходники с одного CPU на другой другого производителя с минимальными модификациями (или вообще без оных).

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня вызовы макросов типа установить/обнулить/проинвертировать/... пин GPIO одинаковы для разных процессоров, что часто позволяет переносить исходники с одного CPU на другой другого производителя с минимальными модификациями (или вообще без оных).

Вы коснулись хорошей темы, а именно наилучшего API для контроллеров. Его, ессно, не существует, но есть вещи, которые хорошо себя зарекомендовали и на разных платформах. Например вызов инициализации UART в виде

uint_fast8_t async_config(
    const uint_fast8_t    number,  //номер порта
    const uint_fast32_t  baud,      // скорость
    const uint_fast8_t    bits,        // число бит
    const char                 parity,    //'E'-even,  'O'-odd, 'N'-none
    const uint_fast8_t    stops      // 1, 2 для полутора - нет
    );

Но uart - это просто.

Потом, с SPI более менее получается - там где нет аппаратной поддержки, например, DMA, - включается эмуляция оного.

А вот с таймерами - уже засада. Или с АЦП.

 

А дергать пинами - у меня лично такого уровня просто нет. У меня в board.h есть например "включить реле", а set-reset какой-то сферический пин - нету. :laughing:

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

#define uchar unsigned char
// VVVVVVVVVVVVVVVVVVVVV  Работа с портами   VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
#define enable_clock(port)	RCC->APB2ENR|=RCC_APB2ENR_IOP##port##EN // включение тактирования порта
#define pin_on(port,bit)	GPIO##port## -> ODR |= GPIO_ODR_ODR##bit // установить на порте 1
#define pin_off(port,bit)       GPIO##port## -> ODR &= ~ GPIO_ODR_ODR##bit // установить на порте 0 
#define pin_test(port,bit)    	GPIO##port## -> ODR &=  GPIO_ODR_ODR##bit // возвращает истинное состояние на выводе ножки порта

//vvvvvvvvvvv Конфигурируем порты: направление и максимальная частота работы портов vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
#define set_in(port,half,bit)           GPIO##port##->CR##half##&=~(GPIO_CR##half##_MODE##bit##_0); GPIO##port##->CR##half##|=(GPIO_CR##half##_MODE##bit##_0) //00: Input mode (reset state) - порт работает на вход, устанавливается по умолчанию после ресета 
#define set_out_10MHz(port,half,bit)    GPIO##port##->CR##half##&=~(GPIO_CR##half##_MODE##bit##_0); GPIO##port##->CR##half##|=(GPIO_CR##half##_MODE##bit##_1) //01: Output mode, max speed 10 MHz. 
#define set_out_2MHz(port,half,bit)     GPIO##port##->CR##half##&=~(GPIO_CR##half##_MODE##bit##_1); GPIO##port##->CR##half##|=(GPIO_CR##half##_MODE##bit##_0) //10: Output mode, max speed 2 MHz.
#define set_out_50MHz(port,half,bit)    GPIO##port##->CR##half##&=~(GPIO_CR##half##_MODE##bit##_1); GPIO##port##->CR##half##|=(GPIO_CR##half##_MODE##bit##_1) //11: Output mode, max speed 50 MHz.
//если пин порта 0-7 то half=L
//если пин порта 8-15 = то half=H
// в регистре GPIOX_CR(L/H) меняет биты MODEx (режимы работы x ножки порта X)
// Пример использования:
//     set_in(D,L,7); // устанавливает порт D.7 как вход 
//     set_out_10MHz(D,L,7); //устанавливает порт D.x как выход с максимальной частотой 10 Мгц.
//     set_out_2MHz(D,L,7); //устанавливает порт D.x как выход с максимальной частотой 2 Мгц.
//     set_out_50MHz(D,L,7); //устанавливает порт D.x как выход с максимальной частотой 50 Мгц.
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#define pin_config(port,half,pin,b1,b0)     GPIO##port##->CR##half##&=~(GPIO_CR##half##_CNF##pin##_0);GPIO##port##->CR##half##&=~(GPIO_CR##half##_CNF##pin##_1) ; // конфигурация регистра CNF

//vvvvvvvvvvv   меняем настройки портов настроенных на выход, general/alternativ и  push-pull/open-drain vvvvvvvvvvvvvvv
#define general_push_pull(port,half,pin)       pin_config(##port##,##half##,##pin##,0,0)//00: set port as General purpose output push-pull
#define general_open_drain(port,half,pin)      pin_config(##port##,##half##,##pin##,0,1)//01: set port as General purpose output Open-drain
#define alternate_push_pull(port,half,pin)    pin_config(##port##,##half##,##pin##,1,0)//10: set port as Alternate function output Push-pull
#define alternate_open_drain(port,half,pin)   pin_config(##port##,##half##,##pin##,1,1)//11: set port as Alternate function output Open-drain
// пример использования:
//out_general_push_pull(D,L,7);   //set port D, pin7  as General purpose output push-pull 
//out_general_open_drain(D,L,7);  //set port as General purpose output push-pull
//out_alternate_push_pull(D,L,7); //set port as alternate output push-pull
//out_alternate_open_drain(D,L,7);//set port as alternate output push-pull
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^

//vvvvvvvvvvv   меняем настройки портов настроенных на вход vvvvvvvvvvvvvvv
#define input_analog(port,half,pin)          pin_config(##port##,##half##,##pin##,0,0)//00: set port as Analog mode 
#define input_float(port,half,pin)           pin_config(##port##,##half##,##pin##,0,1)//01: set port as Floating input (reset state)
#define input_pull_up_down(port,half,pin)    pin_config(##port##,##half##,##pin##,1,0)//10: set port as Input with pull-up / pull-down
// пример использования:
//input_analog(port,half,pin);// set port as Analog mode           
//input_float(port,half,pin);//  set port as Floating input (reset state)  
//input_pull_up_down(port,half,pin); //set port as Input with pull-up / pull-down
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^

 

enable_clock(D);//включение тактирования порта
 set_out_2MHz(D,L,7);  //устанавливает порт D.x как выход с максимальной частотой 2 Мгц.
 general_push_pull(D,L,7); //set port as General purpose output push-pull

while (1)
{ 

   if (pin_test(D,7))
   {
     pin_off(D,7);
   }
   else
   {
     pin_on(D,7);
   }

   for (d=0; d<1000000; ++d){e ++;};

теперь програмка моргания светодиодом выглядет высокоуровневее

Изменено пользователем super_puper

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

теперь нужно для частот тактирования, выбор источника тактирования , и ПЛЛек писать дефайны или функции

никто не написал ещё?

Изменено пользователем super_puper

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

никто не написал ещё?

Бросьте фигнёй заниматься... займитесь лучше чем-то полезным...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

теперь нужно для частот тактирования, выбор источника тактирования , и ПЛЛек писать дефайны или функции

никто не написал ещё?

http://electronix.ru/forum/lofiversion/ind...hp/t103011.html

 

вот тут посмотрите : STM32 генератор кода

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

теперь програмка моргания светодиодом выглядет высокоуровневее

Ну, ну... Почитайте этот же код через этак пару месяцев, занявшись в это время другим проектом.

Уверен, что хрен поймете, что это за абстрактные "D", 7, что они делают в проге.

Нормальный высокоуровневый код НЕ должен выглядеть, как куча дефайнов поверх других дефайнов. Не это - его цель.

Если уже делаете обертки, то они должны отражать суть программы, ее действия,

а вовсе не суть самой этой обертки - избавиться от чужого говнокода.

 

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

Остальное сделать удобным под все линейки процев, увы, нереально.

По сути, ST-либы реально ускоряют разработку, а в последствии переписать "быстрые" куски кода в обход библиотеки - это уже оптимизация,

которая, зачастую, не так уж и обязательна.

Например, мне приходилось "разворачивать" и оптимизировать код этих либ в обработчиках прерываний CAN, т.к. это реально ускорило работу системы...

 

Чтобы не быть голословным, поделюсь своим вариантом обертки для пинов (STM32L).

 

Базовый класс пина:

class PinBase
{
public:
    PinBase(GPIO_TypeDef * port, UNSIGNED8 pinIndex)  
    { 
        this->port = port;
        this->pinIndex = pinIndex; 
        
        switch ((UNSIGNED32)(this->port))
        {
            case ((UNSIGNED32)GPIOA): RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); break;
            case ((UNSIGNED32)GPIOB): RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); break;
            case ((UNSIGNED32)GPIOC): RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE); break;
            case ((UNSIGNED32)GPIOD): RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE); break; 
            case ((UNSIGNED32)GPIOE): RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE); break;
            case ((UNSIGNED32)GPIOH): RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOH, ENABLE); break;
            default : break;
        }
        
        disablePullUpAndPullDown();
    }

    void setAsInput(void) // MODER = 0
    { 
        port->MODER &= ~(((UNSIGNED32)0x03) << (pinIndex * 2)); 
        port->MODER |= (((UNSIGNED32)0x00) << (pinIndex * 2)); 
    }
    
    void setAsOutput(void) // MODER = 1
    { 
        port->MODER &= ~(((UNSIGNED32)0x03) << (pinIndex * 2)); 
        port->MODER |= (((UNSIGNED32)0x01) << (pinIndex * 2)); 
    }

    typedef UNSIGNED8 AlternativeFunction;
    void setAsAlternative(AlternativeFunction function) // MODER = 2
    { 
        port->MODER &= ~(((UNSIGNED32)0x03) << (pinIndex * 2)); 
        port->MODER |= (((UNSIGNED32)0x02) << (pinIndex * 2));
        if (pinIndex < 8)
        {
            port->AFR[0] &= ~(((UNSIGNED32)0x0F) << (pinIndex * 4)); 
            port->AFR[0] |= (((UNSIGNED32)function & 0x0F) << (pinIndex * 4)); 
        }
        else
        {
            port->AFR[1] &= ~(((UNSIGNED32)0x0F) << ((pinIndex - 8) * 4)); 
            port->AFR[1] |= (((UNSIGNED32)function & 0x0F) << ((pinIndex - 8) * 4)); 
        }
    }
    
    void setAsAnalogInput(void) // MODER = 3
    { 
        disablePullUpAndPullDown();
        port->MODER &= ~(((UNSIGNED32)0x03) << (pinIndex * 2)); 
        port->MODER |= (((UNSIGNED32)0x03) << (pinIndex * 2)); 
    }
    
    void setAsPushPull(void) { port->OTYPER &= ~(1 << pinIndex); } // OTYPER = 0
    void setAsOpenDrain(void) { port->OTYPER |= (1 << pinIndex); } // OTYPER = 1
    
    void setOutputSpeed400kHz(void)     { port->OSPEEDR &= ~(((UNSIGNED32)0x03) << (pinIndex * 2)); port->OSPEEDR |= (((UNSIGNED32)0x00) << (pinIndex * 2)); } // OSPEEDR = 0
    void setOutputSpeed2MHz(void)         { port->OSPEEDR &= ~(((UNSIGNED32)0x03) << (pinIndex * 2)); port->OSPEEDR |= (((UNSIGNED32)0x01) << (pinIndex * 2)); } // OSPEEDR = 1
    void setOutputSpeed10MHz(void)         { port->OSPEEDR &= ~(((UNSIGNED32)0x03) << (pinIndex * 2)); port->OSPEEDR |= (((UNSIGNED32)0x02) << (pinIndex * 2)); } // OSPEEDR = 2
    void setOutputSpeed40MHz(void)         { port->OSPEEDR &= ~(((UNSIGNED32)0x03) << (pinIndex * 2)); port->OSPEEDR |= (((UNSIGNED32)0x03) << (pinIndex * 2)); } // OSPEEDR = 3
        
    void disablePullUpAndPullDown(void)    { port->PUPDR &= ~(((UNSIGNED32)0x03) << (pinIndex * 2)); port->PUPDR |= (((UNSIGNED32)0x00) << (pinIndex * 2)); } // PUPDR = 0
    void enablePullUp(void)                { port->PUPDR &= ~(((UNSIGNED32)0x03) << (pinIndex * 2)); port->PUPDR |= (((UNSIGNED32)0x01) << (pinIndex * 2)); } // PUPDR = 1
    void enablePullDown(void)            { port->PUPDR &= ~(((UNSIGNED32)0x03) << (pinIndex * 2)); port->PUPDR |= (((UNSIGNED32)0x02) << (pinIndex * 2)); } // PUPDR = 2
    
    void lock(void)
    {
        volatile UNSIGNED32 tempRegister = ((UNSIGNED32)1 << pinIndex);
        port->LCKR = tempRegister | (1 << 16);    // Set LCKK bit
        port->LCKR = tempRegister;                 // Reset LCKK bit
        port->LCKR = tempRegister | (1 << 16);    // Set LCKK bit
        tempRegister = port->LCKR;                 // Read LCKK bit
        tempRegister = port->LCKR;                // Read LCKK bit
    }

private:
    volatile GPIO_TypeDef * port;
    volatile UNSIGNED8 pinIndex;
};

 

Шаблон класса пина:

template <UNSIGNED32 PORT_ADDR, UNSIGNED8 PIN_INDEX>
class Pin : public PinBase
{
public:
    Pin(void) : PinBase(((GPIO_TypeDef*)PORT_ADDR), PIN_INDEX) { setToLow(); }

    inline void setToHigh(void)        __attribute__((always_inline)) { ((GPIO_TypeDef*)PORT_ADDR)->BSRRL = (((UNSIGNED32)1) << PIN_INDEX); }
    inline void setToLow(void)        __attribute__((always_inline)) { ((GPIO_TypeDef*)PORT_ADDR)->BSRRH = (((UNSIGNED32)1) << PIN_INDEX); }
    inline bool isHigh(void) const    __attribute__((always_inline)) { return (((((GPIO_TypeDef*)PORT_ADDR)->IDR) & (((UNSIGNED32)1) << PIN_INDEX)) != 0); }
    inline bool isLow(void)    const    __attribute__((always_inline)) { return (((((GPIO_TypeDef*)PORT_ADDR)->IDR) & (((UNSIGNED32)1) << PIN_INDEX)) == 0); }
};

 

Увы, в компиляторе KEIL нельзя в качестве параметров шаблонов использовать указатели, хотя стандарт C++ это вполне допускает.

Поэтому приходится его обманывать:

#define PORTA                                (((UNSIGNED32)GPIOA))
#define PORTB                                (((UNSIGNED32)GPIOB))
#define PORTC                                (((UNSIGNED32)GPIOC))
.....

 

Ну, и пример использования (внешний акселерометр с программным SPI).

H-файл:

// ACCELEROMETER
#define PORT_ACCEL_CS                        (PORTB)
#define PIN_ACCEL_CS                        (15)

#define PORT_ACCEL_SCK                        (PORTB)
#define PIN_ACCEL_SCK                        (14)

#define PORT_ACCEL_MOSI                        (PORTB)
#define PIN_ACCEL_MOSI                        (13)

#define PORT_ACCEL_MISO                        (PORTB)
#define PIN_ACCEL_MISO                        (12)

#define PORT_ACCEL_INT                        (PORTB)
#define PIN_ACCEL_INT                        (11)


.....
.....
....



class Accelerometer : public Singleton<Accelerometer>
{
.....

private:
    Pin<PORT_ACCEL_CS, PIN_ACCEL_CS> pinCS;
    Pin<PORT_ACCEL_SCK, PIN_ACCEL_SCK> pinSCK;
    Pin<PORT_ACCEL_MOSI, PIN_ACCEL_MOSI> pinMOSI;
    Pin<PORT_ACCEL_MISO, PIN_ACCEL_MISO> pinMISO;
    Pin<PORT_ACCEL_INT, PIN_ACCEL_INT> pinINT;
.....
};

 

CPP-файл:

void Accelerometer::initialize(void)
{
....
    pinCS.setAsOutput();
    pinCS.setAsPushPull();
    pinCS.setOutputSpeed10MHz();
    pinCS.setToLow();

....
    
    pinMISO.setAsInput();
    pinMISO.enablePullDown();

    pinINT.setAsInput();
    pinINT.enablePullDown();
....
}

void Accelerometer::writeRegister(UNSIGNED8 address, UNSIGNED8 value)
{
    pinCS.setToLow();
    pinSCK.setToLow();

    for (UNSIGNED8 bit = 8; bit > 0; --bit)
    {
        if ((address & 0x80) != 0)
            pinMOSI.setToHigh();
        else
            pinMOSI.setToLow();
        
        pinSCK.setToHigh();
        address = address << 1;
        pinSCK.setToLow();
    }

    for (UNSIGNED8 bit = 8; bit > 0; --bit)
    {
        if ((value & 0x80) != 0)
            pinMOSI.setToHigh();
        else
            pinMOSI.setToLow();
        
        pinSCK.setToHigh();
        value = value << 1;
        pinSCK.setToLow();
    }

    pinSCK.setToHigh();
    pinCS.setToHigh();
}

 

p.s. Буду рад, если мои идеи кому-то еще пригодятся :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

http://electronix.ru/forum/lofiversion/ind...hp/t103011.html

 

вот тут посмотрите : STM32 генератор кода

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...