|
|
  |
Работа с отдельными битами под AVR Studio под С, Нужна консультация по чтению/записи отдельных бит в регистры AtMega |
|
|
|
Mar 5 2009, 11:42
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Тоже в свое время "многа думаль". Додумался вот до чего: 1. Структуры и объединения с битовыми полями  это не я додумался, конечно Код typedef struct { unsigned flag1:1; unsigned flag2:1; } flagset_t; union Tflags { flagset_t bits; uint8_t byte; } flags;
// получается flags.byte =0; flags.bits.flag1 = 0; Обратите внимание, что биты выделяются от младшего к старшему 2. Это все конечно хорошо, но до тех пор, пока у нас нет обращения к периферии. Поскольку работа с битовыми полями в описании потрохов МК не прижилась, нет смысла упорствовать, сочинять типы для "красоты текста" и для портов лучше применять _BV и иже с ними. Лично меня не плющит написАть (1<<bit_name) ЗЫ (bit_mask << bit_mask_offset) тоже частенько встречаются.
|
|
|
|
|
Mar 5 2009, 12:22
|
Местный
  
Группа: Свой
Сообщений: 426
Регистрация: 5-04-07
Из: Санкт-Петербург
Пользователь №: 26 782

|
Цитата(Master_MW @ Mar 5 2009, 14:24)  Доброго времени суток , коллеги. Проблема в следующем. Пересмотрев достаточное количество материалов по программированию AVR на С, я так и не нашел ответа на сл. вопрос: как прочитать/изменить отдельный бит информации регистра? Для установления одного бита в лог. 1 есть библиотечная директива _BV(и та не везде работает). А как быть с чтением отдельных бит и установкой в ноль? На ассемблере ни для AVR, ни для PIC таких проблем не возникает. Посмотрите на сахаре, эта тема вроде до сих пор обсуждается. [url="http://caxapa.ru"]
|
|
|
|
|
Mar 5 2009, 20:08
|

Местный
  
Группа: Свой
Сообщений: 202
Регистрация: 18-12-08
Из: Беларусь, Минск
Пользователь №: 42 590

|
Сергей Борщ, Так, например, не хочет работать PORTB=_BV(PORTB1); mdmitry, Сергей Борщ,Насчёт _BV mdmitry оказался прав, хотя в книге Ю.А. Шпака указано что _BV() библиотечный макрос (Ю.А. Шпак. Программирование на языке С для AVR и PIC микроконтроллеров, стр. 165). Проблема решилась с подключением файла avr/sfr_defs.h В тамошнем примере код до функции отработки прерывания следующий: CODE #include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h>
#if defined(__AVR_AT90S2313__) # define OC1 PB3 # define OCR OCR1 # define DDROC DDRB #elif defined(__AVR_AT90S2333__) || defined(__AVR_AT90S4433__) # define OC1 PB1 # define DDROC DDRB # define OCR OCR1 #elif defined(__AVR_AT90S4414__) || defined(__AVR_AT90S8515__) || \ defined(__AVR_AT90S4434__) || defined(__AVR_AT90S8535__) || \ defined(__AVR_ATmega163__) # define OC1 PD5 # define DDROC DDRD # define OCR OCR1A #endif
#if defined(COM11) # define XCOM11 COM11 #elif defined(COM1A1) # define XCOM11 COM1A1 #endif
enum { UP, DOWN };
unsigned int pwm; unsigned char direction; ; К слову, вектор прерывания там тоже нерабочий , вместо INTERRUPT(SIG_OWERFLOW1) для корректной работы нужно использовать ISR(TIMER0_OVF_vect){ OCR0++; if(OCR0==255) OCR0=0;} Это простенький, реально заработавший в железе пример. Тем не менее, ситуация достаточно прояснилась , - спасибо всем за помощь. Дело в том , что раньше я писал все свои проекты управления на VHDL, а теперь необходимы некоторые вычисл. мощности, которые проще сделать на МК, нежели на ПЛИС...
--------------------
Отсуствие единых стандартов всегда будет мучать человечество.
|
|
|
|
|
Mar 5 2009, 21:01
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Master_MW @ Mar 5 2009, 22:08)  Так, например, не хочет работать PORTB=_BV(PORTB1); Ммм... поясните пожалуйста термин "не хочет работать". Это выражение должно записать число 0x02 в PORTB. Затерев при этом предыдущее значение всех 8 битов. Цитата(Master_MW @ Mar 5 2009, 22:08)  в книге Ю.А. Шпака указано что _BV() библиотечный макрос В этом со Шпаком можно согласиться. Это действительно макрос (он объявлен через #define), а не директива, как вы написали в первом сообщении, и он действительно часть библиотеки (avr-libc). Цитата(Master_MW @ Mar 5 2009, 22:08)  Проблема решилась с подключением файла avr/sfr_defs.h Это несколько странно - этот файл включен в avr/io.h, поэтому должен подключаться автоматически при подключении avr/io.h. А без подключения avr/io.h компилятор не знает что такое PORTB и PORTB1. Становится совсем непонятно, как же у вас _BV() не работало. Цитата(Master_MW @ Mar 5 2009, 22:08)  для корректной работы нужно использовать
ISR(TIMER0_OVF_vect) Помню из детства: "однако, за время пути собака могла подрасти". Время идет, компилятор развивается. Книга была написана давно, примеры в ней относятся к компилятору версии 2005-2006 года (если память не изменяет).
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Mar 5 2009, 21:27
|

Местный
  
Группа: Свой
Сообщений: 202
Регистрация: 18-12-08
Из: Беларусь, Минск
Пользователь №: 42 590

|
Цитата Это несколько странно - этот файл включен в avr/io.h, поэтому должен подключаться автоматически при подключении avr/io.h. А без подключения avr/io.h компилятор не знает что такое PORTB и PORTB1. Становится совсем непонятно, как же у вас _BV() не работало. Согласен... Хотя я, наверное, неправильно выразился, - компилятор не понимает, что такое PORTB1, например, либо имя бита, выставл. общее разрешение прерываний... Но ладно, полученной информации вполне достаточно, чтобы во всем оставшимся разобраться самому. Думаю, если у вас остались вопросы, то можно договориться , о том, что я могу выслать по электронной почте проект, - так будет проще ... Полагаю, так на свой вопрос вы ответите гораздо быстрее, если возникнет желание - пишите в личку.
--------------------
Отсуствие единых стандартов всегда будет мучать человечество.
|
|
|
|
|
Mar 25 2009, 14:34
|

инопланетянин
  
Группа: Свой
Сообщений: 236
Регистрация: 24-12-06
Из: Питер
Пользователь №: 23 832

|
У меня есть вот такой вопрос: Как вы(обращение ко всем) работает с некоторой периферией у которой регистры устанавливаются по различным протоколам (USART, SPI, I2C) и имеют признаки only R/ only W/ RW, default-состояния отличные от 0? Я встречал подходы с использованием массива shadow-регистров, но мне не понравился тот пример по изящности исполнения. Если не жалко покажите свои наработки
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|