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

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> call back, обменяемся мнениями
grau
сообщение Feb 18 2008, 08:54
Сообщение #16


Участник
*

Группа: Участник
Сообщений: 49
Регистрация: 3-02-05
Пользователь №: 2 390



Цитата(scout @ Nov 30 2007, 13:48) *
Читал архивы и наткнулся... Стало интересно, прочитал, кое - что взял на вооружение. Но непонятен один момент - как устроен класс "CBitsRO", а конкретно каким образом он осуществляет доступ к регистру с адресом, определяемым параметром шаблона?


Сорри, что долго не отвечал..

Класс CBitsRO является фактически обычным макросом. Его задача обеспечить корректность возращаемого значения. Т.е. прозрачно читаем значение битов по маске и сдвигаем их.


Код
template <unsigned A, unsigned P, unsigned L>
class CBitsRO{
public:
    operator unsigned(){
        return ((*((volatile unsigned*) A))>>P)&((1<<L)-1);
    }
};





Цитата(landrey @ Feb 17 2008, 16:09) *
Код
template <IO_REG &r>
void f(uint8_t mask)


int main(){
    f<PORTB>(0x77);    
    return 0;
}


На это ругается компилятор: Internal Error: [any]: Unexpected exception
Что я неправильно написал?


Для начала считаю необходимым заметить, что приводил пример с классами, а не с функциями, с которыми все немного по-другому. Ну а если конкретнее, то мне всегда казалось, что параметризируется только тип аргумента функции, но никак не внутренние переменные. Иначе как ее вообще объявлять?
Go to the top of the page
 
+Quote Post
SpiritDance
сообщение Feb 19 2008, 11:04
Сообщение #17


Дух погибшего транзистора
****

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



Цитата(Shkn @ Oct 26 2007, 09:14) *
Захотел сделать работу с периферией посредством классов. Но возникло два вопроса: как написать один код для каждого типа периферии, но чтоб он работал независимо от ее количества (к примеру UART0, UART1..) и как потом прерывания обрабатывать. Ответ был найден в параметризации шаблона класса базовым адресом в памяти. что-то вроде template<unsigned Adr> class CUart {..}; Соответственно в нем уже работать только по смещению.

Но тут возник интересный ньюанс: а как делать обработчик прерывания? Ведь его адрес надо записать в контроллер? Сделал так: все наследуются от одного базового сласса с виртуальной функцией Isr. В конструкторе все экземпляры регистрируются в глобальном массиве. Для каждого класса (читай номера устройства) делается статическая функция, которая и регистрируется в контроллере прерываний. А уже она по своему вызову выбирает из массива адрес соответствующего ей экзепляра и дергает его Isr.

Так к чему все это? Казалось бы работает, и не надо трогать.. Но нет! Ведь можно же еще уменьшить текст кода! А именно: сделать эту статическую функцию параметризируемой номером периферии и записать всего один раз template<unsigned N> void IsrExe(){ Array[N]->Isr();} Так вот мой Keil Arm не хочет адрес так описанной функции помещать в котроллер, а под MS VC проверяю - все в порядке.

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


Почитав это можно только спросить и к чему так е-ть себе мозги? smile.gif)


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post
grau
сообщение Feb 20 2008, 06:17
Сообщение #18


Участник
*

Группа: Участник
Сообщений: 49
Регистрация: 3-02-05
Пользователь №: 2 390



Цитата(SpiritDance @ Feb 19 2008, 14:04) *
Почитав это можно только спросить и к чему так е-ть себе мозги? smile.gif)


Как поуказывает практика, у большинства людей мозги чаще ржавеют, чем истираются.
Так что не спи - замерзнешьsmile.gif
Go to the top of the page
 
+Quote Post
landrey
сообщение Feb 23 2008, 12:45
Сообщение #19





Группа: Участник
Сообщений: 14
Регистрация: 10-11-07
Из: Харьков
Пользователь №: 32 220



Цитата(grau @ Feb 18 2008, 11:54) *
Для начала считаю необходимым заметить, что приводил пример с классами, а не с функциями, с которыми все немного по-другому. Ну а если конкретнее, то мне всегда казалось, что параметризируется только тип аргумента функции, но никак не внутренние переменные. Иначе как ее вообще объявлять?


Прошу прощения, я сморозил глупость. Все-таки я вначале расписал класс, потом из-за ошибок компиляции начал поочередно все откидывать, потом по старой русской традиции решил все-таки заглянуть в EVAVR_CompilerReference.pdf. вот что я там нашел (цитирую):
Цитата
Non-type template parameters
It is allowed to have a reference to a memory type as a template parameter, even if
pointers to that memory type are not allowed.
Example
extern int __io x;
template<__io int &y>
void foo()
{
y = 17;
}
void bar()
{
foo<x>();
}

Пробую этот кусок - та же ошибка. Поэтому и в своем посте я изобразил подобное.
Но вот вырезка из моего класса:
Код
typedef uint8_t volatile __tiny IO_REG;

template <IO_REG &UDR, IO_REG &UBRRH, IO_REG &UBRRL>
class CBaseUart  
{

private:

    enum
    {
        DEFAULT_BAUDRATE    = 115200,
    };


public:
    
    CBaseUart(uint32_t baudRate=DEFAULT_BAUDRATE)
    {
        uint16_t tmp_baud = CPU_CLK_Hz / (16 * baudRate) - 1;
        UBRRH = (uint8_t)(tmp_baud >> 8);
        UBRRL = (uint8_t)tmp_baud;
    }
    
    virtual ~CBaseUart();
    
    
    inline void transmit(uint8_t data)
    {
        UDR = data;
    }

};


Вот так я пытаюсь использовать:
Код
int main()
{
    
    CBaseUart <UDR0, UBRR0H, UBRR0L> uart;
    
    uart.transmit(0x55);
    
    return 0;
}

Опять та же ошибка. Обидно
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th July 2025 - 12:39
Рейтинг@Mail.ru


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