Не байт, а бит. Из-за этого и сложность.Аlex писал(а):Я так понял, count у Вас - кол-во передаваемых байт (т.б., грубо говоря, размер массива).
Тогда зачем эти все замудренные вычисления и лишние циклы с переменными и указателями ?
Сдвиговые регистры, нужна подсказка
А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
- Реклама
А почему тогда читаете из массива побайтно ?U235 писал(а):Не байт, а бит.
В таком случае, если count будет отличен от 8, у Вас будут передаваться из каждого байта не все биты.Код: Выделить всё
temp=*pdata; // Берём очередной байт
Вы берёте байт, затем передаёте кол-во бит, равное переменной j, в которую Вы пишите число count (кол-во бит).
Вот исправленный вариант. Но Alex прав - он всё равно излишне сложный, ведь число светодиодов как правило кратно восьми.
Код: Выделить всё
void send_data (unsigned char pdata[], unsigned char count)
{
unsigned char i, j, temp;
j=0;
for (i=count; i != 0;)
{
if (i > 7) j=8;
else j=i ;
i-=j;
temp=*pdata;
while (j)
{
if (t & 0x01) PORTD.0=1;
else PORTD.0=0;
# asm("nop");
PORTD.1=(CLK);
# asm("nop");
PORTD.1=~(CLK);
# asm("nop");
temp>>=1;
j--;
}
pdata++;
}
PORTD.2=(Latch);
# asm("nop");
PORTD.2=~(Latch);
}А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
По этому, может быть, лучше тогда передавать кол-во байт ? ИМХО, будет логичнее.число светодиодов как правило кратно восьми
Как то примерно так:
Код: Выделить всё
void send_data (unsigned char *pdata, unsigned char count){
while(count--){
char i;
temp = pdata[count];
for(i=0;i<8;i++){
if (temp & 0x80) PORTD.0 = 1;
else PORTD.0 = 0;
temp << =1;
PORTD.1=1;
# asm("nop");
PORTD.1=0;
# asm("nop");
}
}
PORTD.2=1;
# asm("nop");
PORTD.2=0;
}
Извините конечно, но попробывать сейчас не могу. Сразу дам еще информацию для размышления.
А если я захочу зажечь еще один светодиод и гнать его тоже, например через 2 не светящихся. Это будет уже возможно или надо еще подумать над кодом?
P.s. Попробую все это часа через 2. Заранее спасибо!
А если я захочу зажечь еще один светодиод и гнать его тоже, например через 2 не светящихся. Это будет уже возможно или надо еще подумать над кодом?
P.s. Попробую все это часа через 2. Заранее спасибо!
- Реклама
Сделайте пару функций - устанавливать и сбрасывать бит по его номеру в массиве.
А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
Заполняйте массив, как душе угодно, и выводите его наружу.А если я захочу зажечь еще один светодиод и гнать его тоже, например через 2 не светящихся.
Что-то я попробывал и опять ничего толком не вышло... (((
А можете просто попробывать объяснить весь этот чудодейственный код словами, понятными ))) Я сообразить что-то не могу
А можете просто попробывать объяснить весь этот чудодейственный код словами, понятными ))) Я сообразить что-то не могу
Что конкретно Вы пробовали и что не получилось ? Покажите...
То, что мы приводили выше, - это функции вывода массива на внешние регистры.
Заполняйте массив данными с необходимой периодичностью и , с помощью этой ф-ии, выводите его.
В Вашем случае, размер массива должен быть = 4. Если будете использовать мой код, то в параметр pdata передавайте указатель на массив (он же - его имя), а в count - число 4. Ну и проверьте соответствие ПИНов и устанавливаемые им значения, я писал от балды...
То, что мы приводили выше, - это функции вывода массива на внешние регистры.
Заполняйте массив данными с необходимой периодичностью и , с помощью этой ф-ии, выводите его.
В Вашем случае, размер массива должен быть = 4. Если будете использовать мой код, то в параметр pdata передавайте указатель на массив (он же - его имя), а в count - число 4. Ну и проверьте соответствие ПИНов и устанавливаемые им значения, я писал от балды...
Переработал код в такой вид. Да, пробывал и код Аlexа, работает. Это как раз из его сделано.
Вопрос такой теперь стал: Как вывести две переменных? Чтобы в начале например горел светодиод и в конце?
В этом коде сейчас включается 80 светодиод и 73. Я хочу зажечь 73 и 20. Как?
Вопрос такой теперь стал: Как вывести две переменных? Чтобы в начале например горел светодиод и в конце?
В этом коде сейчас включается 80 светодиод и 73. Я хочу зажечь 73 и 20. Как?
Код: Выделить всё
void send_data (){
char i;
temp = pdata;
for(i=0;i<80;i++){
if (temp & 0x80) PORTD.0 = 1;
else PORTD.0 = 0;
temp<<=1;
PORTD.1=1;
# asm("nop");
PORTD.1=0;
# asm("nop");
}
PORTD.2=1;
# asm("nop");
PORTD.2=0;
}
void main(void)
pdata=0b10000001;
while (1){
if (!PINB.0) {
send_data();
}
{Код: Выделить всё
#define DATA_PIN PORTD.0
#define CLK_PIN PORTD.1
#define LATCH_PIN PORTD.2
unsigned char buf[8];
/*****************************************************************/
void send_data (unsigned char *pdata, unsigned char count){
while(count--){
unsigned char i;
unsigned char temp = pdata[count];
for(i=0;i<8;i++){
if (temp & 0x80) DATA_PIN = 1;
else CLK_PIN = 0;
temp<<=1;
CLK_PIN=1;
Nop();
CLK_PIN=0;
Nop();
}
}
LATCH_PIN=1;
Nop();
LATCH_PIN=0;
}
/*****************************************************************/
Код: Выделить всё
buf[0] = 0b10000000; // 1-ый регистр
buf[1] = 0b00000000; // 2-ой регистр
buf[2] = 0b00000010; // 3-ий регистр
buf[3] = 0b01000000; // 4-ый регистр
buf[4] = 0b00000000; // 5-ый регистр
buf[5] = 0b00001000; // 6-ой регистр
buf[6] = 0b01000000; // 7-ой регистр
buf[7] = 0b00000000; // 8-ой регистр
send_data(buf, 8);
Если включать и выключать побитно, то можно сделать так:
Код: Выделить всё
#define SET_BIT(bit_num) (buf[(bit_num)/8] | (1<<(bit_num%8)))
#define CLR_BIT(bit_num) (buf[(bit_num)/8] & ~(1<<(bit_num%8)))
.....
.....
.....
SET_BIT(25); // Включить 25-ый светодиод.
CLR_BIT(50); // Выключить 50-ый светодиод.
- Сообщения: 7518
- Зарегистрирован: Вс мар 29, 2009 22:09:05
Господи, как все страшно.
Если стоит задача произвольной загрузки 64 бит, тут уже надо делать чуток сложнее.
***
Первое - эффективный код загрузки одного байта:
Второе - макросы установки бита в буфере.
Надо 64 бита? Заводим массив на 8 байт.
Ну и вперед...
Если задача только такая - достаточно один раз записать единицу, а потом только дергать SH_CP/ST_CP регистров. Если они соединены последовательно, единица будет двигаться сама.Как заставить один светодиод зажигаться по очереди на всех 64 светодиодах?
Если стоит задача произвольной загрузки 64 бит, тут уже надо делать чуток сложнее.
***
Первое - эффективный код загрузки одного байта:
Код: Выделить всё
void ShiftData(uint8_t b)
{
uint8_t mask;
for (mask=0x80; mask; mask=(mask >> 1))
{
REG_PORT&=~REG_SHCP;
if (b & mask)
{
REG_PORT|=REG_DSER;
}
else
{
REG_PORT&=~REG_DSER;
}
REG_PORT|=REG_SHCP;
}
}
void SetData(void)
{
REG_PORT&=~REG_STCP;
REG_PORT|=REG_STCP;
}
Код: Выделить всё
#define set_bit_by_num(BUF,BIT) ((BUF)[(BIT) / 8]|=(1<<((BIT) % 8)))
#define clear_bit_by_num(BUF,BIT) ((BUF)[(BIT) / 8]&=~(1<<((BIT) % 8)))
Код: Выделить всё
uint8_t led_buffer[8];
void RefreshBuffer(void)
{
uint8_t i;
for (i=0; i<8; i++)
{
ShiftData(led_buffer[i]);
}
SetData();
}
Код: Выделить всё
uint8_t i=0;
while (1)
{
set_bit_by_num(led_buffer,i);
RefreshBuffer();
_delay_ms(100);
clear_bit_by_num(led_buffer,i);
RefreshBuffer();
_delay_ms(100);
i++;
if (i>7)
i=0;
}
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Пока всем спасибо за подсказки. Последние два кода Alexa меня порадовали. Я их пытаюсь доработать для себя. Будут вопросы - я отпишусь, пока все ясно!
P.s Так же спасибо всем, кто подсказывал!
P.s Так же спасибо всем, кто подсказывал!
я так понял все получилось? нужно решение?
Придумать бы, ЧТО создавать, остальное - дело техники


