Список форумов ModLabs.net ModLabs.net
Порtал tехногенных эkспериментов
 
FAQ  •  Правила  •  Поиск  •  Пользователи  •  Группы  •  Регистрация
Профиль  •  Войти и проверить личные сообщения  •  Вход


Микроконтроллеры начинающим

 
новая тема ответить    Список форумов ModLabs.net -> Схемотехника и электроника
Автор Сообщение
Day
Junior Member



Зарегистрирован: 14.09.2006
Сообщения: 14

Сообщение24.01.2007 17:40  Микроконтроллеры начинающим профиль цитировать

суть проблемы: к МК 90S2313 подключен 7ми сегментный цифровой индикатор через сдвиговый регистр 74HC164, дабы не занимать лишние лапы.
цифра выводится на индикатор следующим образом:
выставляем на CLK ноль, подаем 1 или 0 (смотря что нужно) на вход DATA,выставляем на CLK единицу
и так восемь раз.
и здесь напрашивается цикл
Так вот никак не могу додуматься как выводить цифры в цикле (на Си, компилятор CodeVision)
listener
Member



Зарегистрирован: 08.05.2003
Сообщения: 618
Откуда: Лужки :-)

Сообщение25.01.2007 04:49   профиль цитировать

Например, так:
Код:

for (i = 0; i < 8; i++) {
  CLK = 0; 
  DATA = (number&(1 << i)) ? 0 : 1;
  CLK = 1;
}


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

Есть и более оптимальные варианты (сдвинуть число вправо и взять младший бит, двигать маску и т.д.)

А еще есть такая вещь, как 74HC595 - он напрямую к SPI цепляется.

_________________
Assimilate, don't comlain
Day
Junior Member



Зарегистрирован: 14.09.2006
Сообщения: 14

Сообщение25.01.2007 11:59   профиль цитировать

вот про эту строчку можно по подробнее:
Код:
DATA = (number&(1 << i)) ? 0 : 1;


что она делает, что такое "number", "? 0 : 1;"-таких конструкций еще не встречал
listener
Member



Зарегистрирован: 08.05.2003
Сообщения: 618
Откуда: Лужки :-)

Сообщение26.01.2007 01:38   профиль цитировать

number - битовое значение, которое нужно вывести (в данном случае - восьмибитная маска, каждый бит в которой соответствует своему светодиоду).

1 << i - единица, сдвинутая на i бит влево (т.е., грубо говоря, получается двоичное число, где после 1 идет i нулей)

condition ? trueValue : falseValue - оператор, возвращающий trueValue если условие выполняется (применительно к C: condition - выражение, имеющее ненулевое значение), или falseValue, если условие не выполняется.

Т.е., выражение a = cond ? b : c; эквивалентно if (cond) a = b; else a = c; (только гораздо компактнее записывается).

Т.е., сдвигом (<<) мы получаем битовую маску - число с одной единицей, которая последовательно сдвигается в цикле справа налево. Затем мы делаем "AND" с состояниями светодиодов. Если в этом значении для i-того светодиода стоит 1, то условие выполняется и в DATA записывается "1", иначе - "0".

_________________
Assimilate, don't comlain
Day
Junior Member



Зарегистрирован: 14.09.2006
Сообщения: 14

Сообщение26.01.2007 11:46   профиль цитировать

додумался пока только до этого
Код:
#include <90s2313.h>
#include <delay.h>

//знакогенератор пишем в EEPROM дабы не занимать регистры
flash unsigned char zg7[10]={0xDB,0x48,0xE3,0xEA,0x78,0xBA,0xBB,0xC8,0xFB,0xFA};
unsigned char cnt, buf;

void main(void) {
PORTD=0x70; DDRD=0x60;   //  настройка портов.  динамическая индикация пока не нужна
PORTB=0x07; DDRB=0xFF;   //  поэтому сразу даем GND на нужный катод
buf = zg7[3]; //Записываем нужное число из знакогенератора в переменную buf для отображения

 for (cnt=0;cnt<8;cnt++) {     
   PORTD.6=0; //даем 0 на CLK
   if (buf & (1<<7)) {PORTD.5=1;} //проверяем флаг сдвига если установлен, в DATA пишем 1
   else {PORTD.5=0;} //иначе пишем 0 в DATA     
   PORTD.6=1; //даем 1 на CLK
   buf = buf << 1; // делаем логический сдвиг значения из знакогенератора
  } //for
} //main


какие ошибки?

и еще: подскажите про BCD (двоично-десятичная кодировку) - где почитать, что эт такое и т.п.
PS Большое спасибо за ответы
listener
Member



Зарегистрирован: 08.05.2003
Сообщения: 618
Откуда: Лужки :-)

Сообщение28.01.2007 14:17   профиль цитировать

Day
Второй сдвиг лишний. Т.е. биты выводятся не все, а через один.
В таком виде правильнее будет так:
Код:

for (cnt=0;cnt<8;cnt++) {     
   PORTD.6=0; //даем 0 на CLK
   PORTD.5 = buf&1; // выводим в DATA младший бит
   buf >>= 1; // сдвигаем buf на бит вправо
   PORTD.6=1; //даем 1 на CLK
} //for


BCD - форма записи, когда в байте хранится число от 0 до 99 - т.е. в каждых 4х битах - цифра от 0 до 9. (В младших 4х битах - единицы, в старших - десятки) Используется как раз для вывода на всякие числовые индикаторы.

http://en.wikipedia.org/wiki/Binary-coded_decimal

_________________
Assimilate, don't comlain
Day
Junior Member



Зарегистрирован: 14.09.2006
Сообщения: 14

Сообщение31.01.2007 11:16   профиль цитировать

выкладываю то что получилось.

Код:
#include <90s2313.h>
#include <delay.h>
#include <BCD.h>

// МАКРОСЫ
#define vbit_(n)        (1<<n)  //вес бита по номеру
#define bits(p,b)    (p |= (1<<b)) // устанавливает бит b в регистре p
#define bitc(p,b)    (p &= (~(1<<b))) // очищает бит b в регистре p
#define checkbit(p,b)    (p & (1<<b)) // проверка бита b в регистре p
#define invertbit(xbyte, xbit)   (xbyte^=(1<<xbit)) // инвертировать бит X в байте Y

#define IND_DATA    5               
#define IND_CLK         6
#define IND_KEYS      4             
#define RELAY             4

//знакогенератор пишем в EEPROM дабы не занимать RAM, записаны цифры от 0 до 9
flash unsigned char zg7[10]={0xDB,0x48,0xE3,0xEA,0x78,0xBA,0xBB,0xC8,0xFB,0xFA};
unsigned char cnt, buf, sec;
unsigned char bin2bcd(unsigned char n);

interrupt [TIM1_OVF] void timer1_ovf_isr(void) //описываем прерывание
{
TCNT1H = 0x98;   TCNT1L = 0x94; // снова устанавливаем временной интервал  т.е. с какого значения таймер начинает считать
// выполняемый код
if (sec==59){sec=0;} else sec++;}

void main(void) {
PORTD=0x70; DDRD=0x60;   //  настройка портов.  динамическая индикация пока не нужна
PORTB=0x0f; DDRB=0xFF;   //  поэтому сразу даем GND на нужный катод

 //устанавливаем начальные параметры счетчика
 TCCR1A = 0b00000000;   TCCR1B = 0b00000100; /*  устанавливаем частоту клоков CR/256, те
 при кварце 10Мгц, CR/256 и начале отсчета от 0x9894 прерывания будут происходить
 через примерно 1сек*/
 TCNT1H = 0x98;   TCNT1L = 0x94; /* устанавливаем начальный временной интервал   
 т.е. с какого значения таймер начинает считать
 в данном примере начинаем считать с 0x00ff */
 OCR1H  = 255;   OCR1L  = 250; /*устанавливаем регистр совпадения
 те при насчете таймером такого же значения должно произойти прерывание*/
 TIMSK  = 0b10000000;   /* разрешаем прерывание от таймера/счетчика 1
 по переполнению (бит7)  и/или совпадению (бит6)
 в данном конкретном примере только по переполнению*/ 
 #asm ("SEI")     // ГЛОБАЛЬНО разрешаем прерывания

while (1){

              buf=zg7[(bin2bcd(sec) & 0x0f)]; //получаем единицы sec
              for (cnt=0;cnt<8;cnt++) {
              buf = buf << 1; // делаем логический сдвиг значения из знакогенератора
              bitc(PORTD,IND_DATA);
              if (SREG&0x01) {bits(PORTD,IND_DATA);} //проверяем флаг сдвига, если установлен, в DATA пишем 1
              bitc(PORTD,IND_CLK); //даем 0 на CLK
              bits(PORTD,IND_CLK); //даем 1 на CLK
              } //for
              PORTB.3=0;
              delay_ms(1);
              PORTB.3=1;
             
              buf=zg7[((bin2bcd(sec)>>4) & 0x0f)]; //получаем десятки sec         
              for (cnt=0;cnt<8;cnt++) {
              buf = buf << 1; // делаем логический сдвиг значения из знакогенератора
              bitc(PORTD,IND_DATA);
              if (SREG&0x01) {bits(PORTD,IND_DATA);} //проверяем флаг сдвига, если установлен, в DATA пишем 1
              bitc(PORTD,IND_CLK); //даем 0 на CLK
              bits(PORTD,IND_CLK); //даем 1 на CLK
              } //for
              PORTB.2=0;
              delay_ms(1);
              PORTB.2=1;
                               
  }//while
} //main


Ваши замечания господа!
PS Приветствуются камни большие и маленькие
Показать сообщения:   
новая тема ответить    Список форумов ModLabs.net -> Схемотехника и электроника Часовой пояс: GMT + 4
Страница 1 из 1

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы можете вкладывать файлы
Вы можете скачивать файлы


Powered by phpBB © 2001, 2005 phpBB Group

File Attachment © by Meik Sievertsen
Rambler's Top100