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

 
 
5 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> давайте делится удобными дефайнами для stm32f10x
super_puper
сообщение Feb 6 2013, 03:09
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 222
Регистрация: 14-12-12
Из: новосибирск
Пользователь №: 74 845



например я вот такие сделал :
CODE
#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 - Feb 7 2013, 18:53
Причина редактирования: форматирование
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 6 2013, 04:12
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



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

Код
#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);
Go to the top of the page
 
+Quote Post
ISK2010
сообщение Feb 6 2013, 05:19
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 205
Регистрация: 21-09-10
Из: г.Зеленоград
Пользователь №: 59 631



Ну, раз для STM32F1, т.е. для контроллера с ядром Cortex M3, то полезны макросы для побитовой работы с регистрами:
CODE
/*Побитовая адресация:*/
#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;
Но при использовании оптимизации лучше использовать следующее:
CODE
#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 - Feb 7 2013, 18:50
Причина редактирования: форматирование
Go to the top of the page
 
+Quote Post
super_puper
сообщение Feb 7 2013, 02:04
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 222
Регистрация: 14-12-12
Из: новосибирск
Пользователь №: 74 845



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

Сообщение отредактировал super_puper - Feb 7 2013, 02:39
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 7 2013, 06:33
Сообщение #5


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(super_puper @ Feb 7 2013, 06:04) *
я обнаружил что есть готовые стандартные бибилотеки) STM32F10x_StdPeriph_Driver ,изучаю щас их и пытаюсь пользоваться

Совет: если собираетесь что-то написать с плотным использованием этой либы, не отходите далеко от предложенного темплейта проекта, - только в этом случае у Вас не съедет крыша от количества мелких ньюансов, которые надо держать в голове и которые отвлекают от того, что нужно.
Go to the top of the page
 
+Quote Post
super_puper
сообщение Feb 7 2013, 09:14
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 222
Регистрация: 14-12-12
Из: новосибирск
Пользователь №: 74 845



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

Сообщение отредактировал super_puper - Feb 7 2013, 09:14
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 7 2013, 09:38
Сообщение #7


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(super_puper @ Feb 7 2013, 12:14) *
опять решил сам писать

Вот это и есть главная опасность, если Вам уже пора результат какой-то получить, а Вы начинаете с нуля все переписывать. Рискуете свалиться в бесконечную писанину. Кривизна этих либ бесспорна, но сделать лучше таки сложновато с первого захода, если надо получить нечто, работающее на всех STM32.
Как промежуточный вариант - отлаживаю bsp в симуле кейла, затем добавляю несколько wrapper"ов касательно синтаксиса и перехожу в GCC.
Или хватаю пример использования чего-то там (с этой либой, а как жеж) - и пилю своё.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 7 2013, 13:34
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(_Pasha @ Feb 7 2013, 15:38) *
Кривизна этих либ бесспорна, но сделать лучше таки сложновато с первого захода, если надо получить нечто, работающее на всех STM32.
Не соглашусь с Вами. Вполне можно написать свои макросы, гораздо более лёгкие и понятные чем эти библиотеки.
У меня вызовы макросов типа установить/обнулить/проинвертировать/... пин GPIO одинаковы для разных процессоров, что часто позволяет переносить исходники с одного CPU на другой другого производителя с минимальными модификациями (или вообще без оных).
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 7 2013, 14:11
Сообщение #9


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(jcxz @ Feb 7 2013, 16:34) *
У меня вызовы макросов типа установить/обнулить/проинвертировать/... пин 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.gif

Go to the top of the page
 
+Quote Post
super_puper
сообщение Feb 8 2013, 02:27
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 222
Регистрация: 14-12-12
Из: новосибирск
Пользователь №: 74 845



CODE
#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
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^


CODE
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 - Feb 8 2013, 03:47
Go to the top of the page
 
+Quote Post
super_puper
сообщение Feb 8 2013, 03:48
Сообщение #11


Местный
***

Группа: Участник
Сообщений: 222
Регистрация: 14-12-12
Из: новосибирск
Пользователь №: 74 845



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

Сообщение отредактировал super_puper - Feb 8 2013, 03:49
Go to the top of the page
 
+Quote Post
HHIMERA
сообщение Feb 8 2013, 05:29
Сообщение #12


Местный
***

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



Цитата(super_puper @ Feb 8 2013, 06:48) *
никто не написал ещё?

Бросьте фигнёй заниматься... займитесь лучше чем-то полезным...
Go to the top of the page
 
+Quote Post
Lmx2315
сообщение Feb 8 2013, 06:18
Сообщение #13


отэц
*****

Группа: Свой
Сообщений: 1 729
Регистрация: 18-09-05
Из: Москва
Пользователь №: 8 684



QUOTE (super_puper @ Feb 8 2013, 06:48) *
теперь нужно для частот тактирования, выбор источника тактирования , и ПЛЛек писать дефайны или функции
никто не написал ещё?

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

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


--------------------
b4edbc0f854dda469460aa1aa a5ba2bd36cbe9d4bc8f92179f 8f3fec5d9da7f0
SHA-256
Go to the top of the page
 
+Quote Post
Forger
сообщение Feb 8 2013, 06:23
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(super_puper @ Feb 8 2013, 06:27) *
теперь програмка моргания светодиодом выглядет высокоуровневее

Ну, ну... Почитайте этот же код через этак пару месяцев, занявшись в это время другим проектом.
Уверен, что хрен поймете, что это за абстрактные "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. Буду рад, если мои идеи кому-то еще пригодятся sm.gif


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 8 2013, 07:32
Сообщение #15


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Lmx2315 @ Feb 8 2013, 10:18) *
http://electronix.ru/forum/lofiversion/ind...hp/t103011.html

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

Это миф, не умеет оно код генерить. Вижуалти хорошее, иногда полезно для полноты впечатлений. Пользуюсь плагином для клипсы
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 15th June 2024 - 16:04
Рейтинг@Mail.ru


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