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

 
 
> Работа с отдельными битами под AVR Studio под С, Нужна консультация по чтению/записи отдельных бит в регистры AtMega
Master_MW
сообщение Mar 5 2009, 11:24
Сообщение #1


Местный
***

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



Доброго времени суток , коллеги. Проблема в следующем. Пересмотрев достаточное количество материалов по программированию AVR на С, я так и не нашел ответа на сл. вопрос: как прочитать/изменить отдельный бит информации регистра? Для установления одного бита в лог. 1 есть библиотечная директива _BV(и та не везде работает). А как быть с чтением отдельных бит и установкой в ноль? На ассемблере ни для AVR, ни для PIC таких проблем не возникает.


--------------------
Отсуствие единых стандартов всегда будет мучать человечество.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 12)
MrYuran
сообщение Mar 5 2009, 11:38
Сообщение #2


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



byte |= (1<<bit) // - установка бита bit
byte &= ~(1<<bit) // - сброс бита bit

Есть куча различных макросов на эту тему

1<<bit можно заменить любой маской


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Mar 5 2009, 11:42
Сообщение #3


;
******

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



Тоже в свое время "многа думаль". Додумался вот до чего:

1. Структуры и объединения с битовыми полями  smile.gif это не я додумался, конечно

Код
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) тоже частенько встречаются.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 5 2009, 11:58
Сообщение #4


Гуру
******

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



Цитата(Master_MW @ Mar 5 2009, 13:24) *
Для установления одного бита в лог. 1 есть библиотечная директива _BV(и та не везде работает).
Приведите пример не работы.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Mar 5 2009, 12:09
Сообщение #5


;
******

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



Кстати, _BV() породили, а  _nBV(val) в смысле ~(1<<val) не захотели sad.gif Зажали понятие.
Go to the top of the page
 
+Quote Post
VladimirYU
сообщение Mar 5 2009, 12:22
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 426
Регистрация: 5-04-07
Из: Санкт-Петербург
Пользователь №: 26 782



Цитата(Master_MW @ Mar 5 2009, 14:24) *
Доброго времени суток , коллеги. Проблема в следующем. Пересмотрев достаточное количество материалов по программированию AVR на С, я так и не нашел ответа на сл. вопрос: как прочитать/изменить отдельный бит информации регистра? Для установления одного бита в лог. 1 есть библиотечная директива _BV(и та не везде работает). А как быть с чтением отдельных бит и установкой в ноль? На ассемблере ни для AVR, ни для PIC таких проблем не возникает.

Посмотрите на сахаре, эта тема вроде до сих пор обсуждается.
[url="http://caxapa.ru"]
Go to the top of the page
 
+Quote Post
mdmitry
сообщение Mar 5 2009, 12:39
Сообщение #7


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



Эта тема активно обсуждалась на форуме AVR в прошлом году. Спрашивающему поиск в помощь.
Присоединяюсь к реплике Сергея Борща. Может не был #define _BV определен или файл (avr/sfr_defs.h) подключен? Это не библиотечная функция.


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
Master_MW
сообщение Mar 5 2009, 20:08
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 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, а теперь необходимы некоторые вычисл. мощности, которые проще сделать на МК, нежели на ПЛИС...


--------------------
Отсуствие единых стандартов всегда будет мучать человечество.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 5 2009, 21:01
Сообщение #9


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Mar 5 2009, 21:04
Сообщение #10


;
******

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



Цитата(Master_MW @ Mar 5 2009, 23:08) *
INTERRUPT(SIG_OWERFLOW1)
для корректной работы нужно использовать
ISR(TIMER0_OVF_vect){

Имена SIG_xxxxx не рекомендуются к дальнейшему применению. (см. понятие "Deprecated features")
Упс, опередили.
Go to the top of the page
 
+Quote Post
Master_MW
сообщение Mar 5 2009, 21:27
Сообщение #11


Местный
***

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



Цитата
Это несколько странно - этот файл включен в avr/io.h, поэтому должен подключаться автоматически при подключении avr/io.h. А без подключения avr/io.h компилятор не знает что такое PORTB и PORTB1. Становится совсем непонятно, как же у вас _BV() не работало.


Согласен... Хотя я, наверное, неправильно выразился, - компилятор не понимает, что такое PORTB1, например, либо имя бита, выставл. общее разрешение прерываний... Но ладно, полученной информации вполне достаточно, чтобы во всем оставшимся разобраться самому. Думаю, если у вас остались вопросы, то можно договориться , о том, что я могу выслать по электронной почте проект, - так будет проще ... Полагаю, так на свой вопрос вы ответите гораздо быстрее, если возникнет желание - пишите в личку.


--------------------
Отсуствие единых стандартов всегда будет мучать человечество.
Go to the top of the page
 
+Quote Post
Legotron
сообщение Mar 25 2009, 14:34
Сообщение #12


инопланетянин
***

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



У меня есть вот такой вопрос:

Как вы(обращение ко всем) работает с некоторой периферией у которой регистры устанавливаются по различным протоколам (USART, SPI, I2C) и имеют признаки only R/ only W/ RW, default-состояния отличные от 0?
Я встречал подходы с использованием массива shadow-регистров, но мне не понравился тот пример по изящности исполнения.
Если не жалко покажите свои наработки smile.gif
Go to the top of the page
 
+Quote Post
SysRq
сообщение Mar 26 2009, 08:28
Сообщение #13


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Цитата(Legotron @ Mar 25 2009, 17:34) *
У меня есть вот такой вопрос...

С флагом UDRE в регистре состояния USART, который в 1 при старте, ничего никогда не делал. Разрешу прерывания по UDRE или проверю сам флаг при отправке данных и всё.
А вот с only R байтом "флагов" (на самом деле светодиоды управлялись) приходилось действительно использовать дополнительно байт, работать с ним, и периодически или по необходимости записывать его содержимое в тот only R байт.
Go to the top of the page
 
+Quote Post

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

 


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


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