Перевод числа в массив бит
Перевод числа в массив бит
Всем привет!
подскажите, как из числа получить последовательность бит для пересылки в сдвиговый регистр.
С самой пересылкой проблем нет.
Но вот с переводом самого числа в последовательность бит - проблема. Ничего не приходит в голову.
Набор констант не подходит.
Нужно именно конвертировать в биты
Пишу в MikroC.
подскажите, как из числа получить последовательность бит для пересылки в сдвиговый регистр.
С самой пересылкой проблем нет.
Но вот с переводом самого числа в последовательность бит - проблема. Ничего не приходит в голову.
Набор констант не подходит.
Нужно именно конвертировать в биты
Пишу в MikroC.
- Реклама
- КРАМ
- Друг Кота
- Сообщения: 25292
- Зарегистрирован: Чт янв 10, 2008 22:01:02
- Откуда: Московская область, Фрязино
Re: Перевод числа в массив бит
Физически в большинстве машин биты не адресуются.
В сдвиговые регистры КОНТРОЛЛЕРА пересылаются БАЙТЫ или СЛОВА, в зависимости от разрядности машины и потребности.
Сам сдвиговый регистр и есть АППАРАТНЫЙ преобразователь слова/байта в последовательность бит.
Таким преобразователем на борту контроллеров является ЛЮБОЙ последовательный интерфейс.
UART, SPI, IIC
Можно организовать ПРОГРАММНЫЙ последовательный вывод в любой бит порта посредством маскирования этого бита в этом порту.
Тогда используется операция СДВИГА.
Сдвиг - маска с содержимым порта - вывод в порт.
Но на самом деле выводится ЦЕЛОЕ СЛОВО ИЛИ БАЙТ.
Просто остальные биты сохраняются прежними.
В сдвиговые регистры КОНТРОЛЛЕРА пересылаются БАЙТЫ или СЛОВА, в зависимости от разрядности машины и потребности.
Сам сдвиговый регистр и есть АППАРАТНЫЙ преобразователь слова/байта в последовательность бит.
Таким преобразователем на борту контроллеров является ЛЮБОЙ последовательный интерфейс.
UART, SPI, IIC
Можно организовать ПРОГРАММНЫЙ последовательный вывод в любой бит порта посредством маскирования этого бита в этом порту.
Тогда используется операция СДВИГА.
Сдвиг - маска с содержимым порта - вывод в порт.
Но на самом деле выводится ЦЕЛОЕ СЛОВО ИЛИ БАЙТ.
Просто остальные биты сохраняются прежними.
Re: Перевод числа в массив бит
пример кода можно?
В регистр мне надо поместит 4.
А вообще я имел в виду регистр сдвига. В моем конкретном случае это 74HC164
В регистр мне надо поместит 4.
А вообще я имел в виду регистр сдвига. В моем конкретном случае это 74HC164
- КРАМ
- Друг Кота
- Сообщения: 25292
- Зарегистрирован: Чт янв 10, 2008 22:01:02
- Откуда: Московская область, Фрязино
Re: Перевод числа в массив бит
Вы постарайтесь перечитать написанное...
Код пишется под железо.
Каким образом внешний регистр соединен с МК?
Код пишется под железо.
Каким образом внешний регистр соединен с МК?
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Перевод числа в массив бит
Число в регистрах МК итак хранится в виде последовательности бит, читайте его побитно и будет Вам счастье.как из числа получить последовательность бит
- Реклама
- Леонид Иванович
- Друг Кота
- Сообщения: 4779
- Зарегистрирован: Сб апр 02, 2011 12:40:46
- Откуда: Минск
- Контактная информация:
Re: Перевод числа в массив бит
vksam писал(а):пример кода можно?
Код: Выделить всё
void Wr_Reg(char d)
{
for(char i = 0; i < 8; i++)
{
Port_SCLK_0; //SCLK = 0
if(d & 0x80) Port_SDATA_1; //вывод данных
else Port_SDATA_0;
d = d << 1; //следующий бит
Port_SCLK_1; //SCLK = 1
}
}
Код: Выделить всё
#define Port_SCLK_0 (PORTB &= ~SCLK)- blackx
- Говорящий с текстолитом
- Сообщения: 1518
- Зарегистрирован: Пт дек 28, 2012 21:56:46
- Откуда: St. Petersburg
Re: Перевод числа в массив бит
Ну или к аппаратному SPI подключить регистр, тогда вообще проблем не будет 
К слову, если в примере от Леонид Иванович требуется биты слать "ногами вперед" (сначала мдалшие), то нужно вместо 0x80 написать просто 0x1, и сдвиг поменять на правый (>>).
К слову, если в примере от Леонид Иванович требуется биты слать "ногами вперед" (сначала мдалшие), то нужно вместо 0x80 написать просто 0x1, и сдвиг поменять на правый (>>).
only pure true norwegian blackx 
Re: Перевод числа в массив бит
спасибо, буду пробовать.
Про сдвиги я как-то не подумал... обошелся банальным делением.
Программированием контроллеров не занимался... вот решил первую программу написать для регулятора Никитина.
Про сдвиги я как-то не подумал... обошелся банальным делением.
Программированием контроллеров не занимался... вот решил первую программу написать для регулятора Никитина.
Последний раз редактировалось vksam Чт июл 25, 2013 11:30:21, всего редактировалось 1 раз.
Re: Перевод числа в массив бит
Да, такой код по элегантней будет!Леонид Иванович писал(а):Макросы управления портами Port_SCLK_0 и другие имеют вид типаКод: Выделить всё
void Wr_Reg(char d) { for(char i = 0; i < 8; i++) { Port_SCLK_0; //SCLK = 0 if(d & 0x80) Port_SDATA_1; //вывод данных else Port_SDATA_0; d = d << 1; //следующий бит Port_SCLK_1; //SCLK = 1 } }
Код: Выделить всё
#define Port_SCLK_0 (PORTB &= ~SCLK)
Спасибо!
Re: Перевод числа в массив бит
И раз уж пошел такой разговор 
Думаю прикрутить к регулятору инфракрасный приемник. Нашел на просторах интернета вот такой код
На сколько он работоспособен в плане логики?
Думаю прикрутить к регулятору инфракрасный приемник. Нашел на просторах интернета вот такой код
Спойлер
Код: Выделить всё
volatile char allow=0,i=0,holdr=0b00000000,took[15],toggl=2,intru=0;
void interrupt()//ISR when interrupt occurs
{
if(INTCON.INT0IF==1)
{
INTCON=0X0;delay_us(1000);//disable the interrupt and delay of 1000us
for(i=0;i<13;i++)//taking input
{
took[i]=portb.f0;
delay_us(1778);
}allow=1;//allow flag to 1, indicating that we have received all data
}
}
void main()
{
unsigned char j;
TRISB=0XFF;TRISC=0X0;//portb input and portc output
portc=0;
delay_ms(2000);//stabilize the device
INTCON=0b10010000;//enable the interrupt int0
INTCON2.INTEDG0=0;//for falling edge
while(1)
{
while(allow==0);//when allow flag is 0 then be in this loop for ever.
if(took[1]!=toggl)//check the T bit i.e toggle bit with previous one.
{
if(toggl==2)toggl=took[1];
//check the fist line of code,we assigned toggl as 2,
//if toggl==2 then take real T bit into it
j=5;
for(i=7;i<13;i++)//convert array to variable for
easy comparison with command
{
took[i]=took[i]<<j ;
holdr=holdr|took[i];took[i]=0;
j--;
}
if(holdr==1)portc.f1=~portc.f1;//comparing
if(holdr==2)portc.f2=~portc.f2;
if(holdr==4)portc.f3=~portc.f3;
if(holdr==5)portc.f4=~portc.f4;
if(holdr==6)portc.f5=~portc.f5;
}
holdr=0;allow=0;
portc.f7=1;delay_ms(200);portc.f7=0;
INTCON=0b10010000;
INTCON2.INTEDG0=0;
}
} - Леонид Иванович
- Друг Кота
- Сообщения: 4779
- Зарегистрирован: Сб апр 02, 2011 12:40:46
- Откуда: Минск
- Контактная информация:
Re: Перевод числа в массив бит
Если речь о декодере RC-5, то могу предложить свой:
Спойлер
Код: Выделить всё
//----------------------------------------------------------------------------
//Декодер RC-5
//----------------------------------------------------------------------------
//Декодер использует два прерывания: внешнее от фотоприемника и
//прерывание по переполнению таймера 0.
//После того, как обнаружен стартовый бит (переход из единицы
//в ноль на входе прерывания), в обработчике внешнего прерывания
//разрешается прерывание таймера 0 и загружается интервал до первой
//выборки T_SAMPLE. В прерывании таймера 0 делаются выборки для
//каждной половинки бита. Подсчет выборок ведется в переменной SampCnt.
//Количество выборок задается константой SAMPLE_COUNT.
//Логический уровень для каждой половинки бита вычисляется по
//мажоритарному принципу. Для этого вычисляется сумма выборок
//в переменной SampVal. Если на входе обнаруживается ВЫСОКИЙ уровень,
//то к этой переменной добавляется единица, если НИЗКИЙ - вычитается.
//Значение суммы не может быть равно нулю, так как общее количество
//выборок всегда задается нечетным. По первой половине текущего бита
//принимается решение о значении принятого бита. Для проверки
//корректности кода Манчестер этот уровень сравнивается со значением
//второй половины предыдущего бита, которое сохраняется в переменной
//PreVal. Если значения совпадают, была ошибка, и прием начинается
//с начала. То же самое происходит, если очередной переход на входе
//не обнаружен через время T_SAMPLE * 2 после последней выборки
//(ошибка таймаута). Принятые биты вдвигаются в переменную Rc5Code.
//Подсчет принятых битов осуществляется в переменной BitCounter.
//Когда принято RC5_LENGTH битов, прием завершен, номер системы
//копируется в переменную SysVar, а код команды - в переменную ComVar.
//Декодер поддерживает Extended RC-5 Code, второй стартовый бит
//интерпретируется как бит F (Field). Бит F представляет собой
//инвертированный дополнительный (старший) бит кода команды,
//в результате количество команд удваивается.
//----------------------------------------------------------------------------
#include "Main.h"
#include "RC5.h"
//----------------------------- Константы: -----------------------------------
#define PRE 64 //предделитель таймера 0
#define RC5_SLOT 1778 //длительность слота RC-5, мкс
#define RC5_LENGTH 14 //количество принимаемых битов
#define SAMPLE_COUNT 3 //количество выборок (должно быть нечетным)
#define T_SAMPLE_US (RC5_SLOT / ((SAMPLE_COUNT + 1) * 2))
#define T_SAMPLE (T_SAMPLE_US * F_CLK / PRE + 0.5)
//----------------------------- Переменные: ----------------------------------
static char SampCnt; //счетчик выборок
static signed char SampVal; //величина, полученная суммой выборок
static bool PreVal; //значение педыдущего полу-интервала
static int RC5Code; //принятый код
static char BitCounter; //счетчик принятых битов
static char SysVar; //номер системы
static char ComVar; //код команды
//-------------------------- Прототипы функций: ------------------------------
#pragma vector = INT0_vect
__interrupt void EdgeIR(void); //прерывание по сигналу фотоприемника
#pragma vector = TIMER0_OVF_vect
__interrupt void TimerIR(void); //прерывание таймера 0
//----------------- Инициализация модуля декодера RC-5: ----------------------
void RC5_Init(void)
{
BitCounter = RC5_LENGTH; //инициализация счетчика битов
PreVal = 1; //перед стартовым битом была единица
SysVar = 0xFF; //неиспользуемый код системы
ComVar = 0xFF; //неиспользуемый код команды
TCCR0 = (1<<CS00) | (1<<CS01); //прескалер CK/64 для таймера 0
MCUCR = (1<<ISC01); //INT0 по спаду
GIFR = (1<<INTF0); //очистка отложенных прерываний
GICR |= (1<<INT0); //разрешение INT0
}
//------------- Обработчик прерывания по сигналу фотоприемника: --------------
#pragma vector = INT0_vect
__interrupt void EdgeIR(void)
{
Port_LED_1;
GICR &= ~(1<<INT0); //запрещение INT0
TCNT0 = 256 - T_SAMPLE; //интервал до первой выборки
TIFR = (1<<TOV0); //очистка отложенных прерываний
TIMSK |= (1<<TOIE0); //разрешение прерываний таймера 0
SampCnt = SAMPLE_COUNT * 2; //общее количесто выборок
SampVal = 0; //очистка принятого значения
}
//------------------ Обработчик прерывания таймера 0: ------------------------
#pragma vector = TIMER0_OVF_vect
__interrupt void TimerIR(void)
{
if(SampCnt) //проверка таймаута
{
if(Pin_RC5) SampVal++; //если на входе единица, инкремент суммы,
else SampVal--; //иначе декремент суммы
if(--SampCnt) //декремент количества выборок
{
if(SampCnt != SAMPLE_COUNT)
{
TCNT0 = 256 - T_SAMPLE; //продолжаем опрашивать
return;
}
else //первая половина интервала закончилась:
{
TCNT0 = 256 - T_SAMPLE * 2; //загрузка интервала между сериями выборок
bool Val = (SampVal > 0); //оценка бита
if(Val != PreVal) //проверка корректности кода Манчестер
{
RC5Code <<= 1; //сдвиг принятого кода
if(!Val) RC5Code |= 1; //первая половина = 0, бит = 1
SampVal = 0; //очистка счетчика выборок
return;
}
}
}
else //вторая половина интервала закончилась:
{
TCNT0 = 256 - T_SAMPLE * 2; //загрузка интервала таймаута
PreVal = (SampVal > 0); //оценка второй половины бита
if(PreVal) //обнаружена единица,
MCUCR &= ~(1<<ISC00); //INT0 по спаду,
else MCUCR |= (1<<ISC00); //иначе INT0 по фронту
GICR |= (1<<INT0); //разрешение INT0
if(--BitCounter) //декремент счетчика битов
return; //переход к приему следующего бита
SysVar = (RC5Code >> 6) & 0x3F; //номер системы
ComVar = RC5Code & 0x3F; //код команды
if(!(RC5Code & 0x1000)) //добавление бита F
ComVar |= 0x40;
}
}
BitCounter = RC5_LENGTH; //загрузка счетчика битов
PreVal = 1; //перед стартовым битом была единица
TIMSK &= ~(1<<TOIE0); //запрещение прерываний таймера 0
MCUCR &= ~(1<<ISC00); //INT0 по спаду
GICR |= (1<<INT0); //разрешение INT0
Port_LED_0;
}
//------------------------- Чтение номера системы: ---------------------------
char RC5_GetSys(void)
{
return(SysVar);
}
//-------------------------- Чтение кода команды: ----------------------------
char RC5_GetCom(void)
{
return(ComVar);
}
//----------------------------------------------------------------------------
Re: Перевод числа в массив бит
Это под AVR?
Мне бы под PIC
Мне бы под PIC
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Перевод числа в массив бит
Разницы особой нет. Код будет отличаться только работой с таймером и внешним прерыванием. Перевести этот код под свой компилятор и МК проблем не составит, тем более, что код отлично прокомментирован.Мне бы под PIC
Re: Перевод числа в массив бит
Угу. Буду пробовать "курить матчасть"Аlex писал(а):Разницы особой нет. Код будет отличаться только работой с таймером и внешним прерыванием. Перевести этот код под свой компилятор и МК проблем не составит, тем более, что код отлично прокомментирован.Мне бы под PIC
Re: Перевод числа в массив бит
Дошло дело до макетной сборки.
И появился очередной глупый вопрос.
Если использую порт A для вывода в сдвиговый регистр - на выходе ничего. Не работает. Хотя протеус моделирует
Но если использовать порт В - все хорошо. На индикаторе получаю то что нужно.
В чем может быть причина?
И появился очередной глупый вопрос.
Если использую порт A для вывода в сдвиговый регистр - на выходе ничего. Не работает. Хотя протеус моделирует
Но если использовать порт В - все хорошо. На индикаторе получаю то что нужно.
В чем может быть причина?
Спойлер
Код: Выделить всё
#define RESET RA2_bit
#define Clock RA1_bit
#define DATA RA0_bit
int vl = 127;
void write_data( char val){
unsigned short n = val;
unsigned short i = 7;
for(i = 0; i < 8; i++)
{
Clock = 0; //SCLK = 0
if(n & 0x80) DATA = 1; //
else DATA = 0;
n = n << 1; //
Clock = 1; //SCLK = 1
}
}
void tick(){
Delay_ms(1);
}
void print( int val){
short s,d;
short segment;
bit isNegative;
segment = 1;
if( val < 0){
isNegative = 1;
}else{
isNegative = 0;
}
val = abs(val);
RESET = 1;
write_data(1);
write_data(128);
tick();
RESET = 0;
RESET = 1;
write_data(2);
write_data(128);
tick();
RESET = 0;
}
void main()
{
PORTA = 0;
PORTB = 0;
TRISA = 0b00000000;
TRISB = 0b00000000;
DATA = 0;
while(1){
print(vl);
}
}
- Вложения
-
- Безымянный.jpg
- (63.74 КБ) 649 скачиваний
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Перевод числа в массив бит
Если один порт рабтает, а другой нет, значит нужно курить даташит на предмет разницы этих портов. Благо даташиты у микрочипа отличные. А лень и метод тыка ни к чему хорошему не приведут. Нужно читать, читать и ещё раз читать....
ЗЫ: А протеус не есть инструмент для проверки правильного написания программ. Нельзя ему на столько доверять. Удостовериться в правильности есть только один способ - проверить на железе.
ЗЫ: А протеус не есть инструмент для проверки правильного написания программ. Нельзя ему на столько доверять. Удостовериться в правильности есть только один способ - проверить на железе.
Re: Перевод числа в массив бит
Ну протеус в данном случае не причем , Mid Range он нормально симулирует.
А PORTA надо сделать цифровым - отключите компараторы . Записать в CMCON 0x07 .
И как ALex верно заметил - читать , читать и читать
А PORTA надо сделать цифровым - отключите компараторы . Записать в CMCON 0x07 .
И как ALex верно заметил - читать , читать и читать
- КРАМ
- Друг Кота
- Сообщения: 25292
- Зарегистрирован: Чт янв 10, 2008 22:01:02
- Откуда: Московская область, Фрязино
Re: Перевод числа в массив бит
ANSEL тоже нужно сбросить...
Re: Перевод числа в массив бит
Сбросит , когда он в 628'ом появится.КРАМ писал(а):ANSEL тоже нужно сбросить...
Может в следующей реинкарнации ...
Кстати PIC16F1827 аналог 628 и стоит в 2 раза дешевле ...
Re: Перевод числа в массив бит
Для последовательного вывода я использую следующий код:
char t;
for(i=0;i<8;i++)
{
PORTB.B0 = t.B7;
t = t<<1;
}
Он минимализирован до безобразия, отсутствуют операторы if и else, что увеличивет скорость передачи.
PS пишу на MikroC
char t;
for(i=0;i<8;i++)
{
PORTB.B0 = t.B7;
t = t<<1;
}
Он минимализирован до безобразия, отсутствуют операторы if и else, что увеличивет скорость передачи.
PS пишу на MikroC


