|
74HC595, Помогите с пониманием |
|
|
|
May 12 2007, 15:24
|

Местный
  
Группа: Свой
Сообщений: 293
Регистрация: 14-03-06
Пользователь №: 15 254

|
Народ подскажите как должен выглядеть код чтобы можно было зажеч второй св.диод на 1 регистре и 3 на втором. привожу код который написал для работы с одним регистром Код void sr_w(unsigned char ch ) { unsigned char counter = 8;
ISP_ST_CP = 0; ISP_SH_CP = 0; while (counter--) { ISP_SH_CP = 0; if ( ch & 0x80 ) ISP_DS = 1; else ISP_DS = 0; #asm("nop") ISP_SH_CP = 1; ch <<= 1; }
ISP_ST_CP = 1; } Зарание всем благодарен.
|
|
|
|
|
May 12 2007, 15:52
|
Местный
  
Группа: Свой
Сообщений: 256
Регистрация: 6-03-06
Из: Украина, г. Винница
Пользователь №: 15 017

|
Вроде все правильно, только ISP_ST_CP = 1; вынеси за функцию ISP_ST_CP = 0; sr_w(4); sr_w(2); ISP_ST_CP = 1; Ну и комбинацию Код if ( ch & 0x80 ) ISP_DS = 1; else ISP_DS = 0; можно попроще написать: ISP_DS = ch & 0x80;
Сообщение отредактировал Александр Куличок - May 12 2007, 15:53
|
|
|
|
|
May 12 2007, 15:59
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Александр Куличок @ May 12 2007, 17:52)  можно попроще написать: ISP_DS = ch & 0x80; Но это же будет уже не то.. Чтобы сохранить алгоритм надо писать или так: ISP_DS = (ch & 0x80) ? 1 : 0; или так ISP_DS = (ch & 0x80) != 0;
|
|
|
|
|
May 12 2007, 16:04
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Цитата только ISP_ST_CP = 1; вынеси за функцию  просмотрел похожие имена, хотя и без вынесения практически незаметно будет Цитата можно попроще написать:ISP_DS = ch & 0x80; Тогда уж ISP_DS = !!(ch & 0x80); Интересно, а где у TamTam пины разбросаны? А то, вероятно где-то должно быть что-то типа 1<<ISP_DS и для других выходов то же
--------------------
aka Vit
|
|
|
|
|
May 12 2007, 16:06
|

Местный
  
Группа: Свой
Сообщений: 293
Регистрация: 14-03-06
Пользователь №: 15 254

|
Народ сори затупил, Вопрос должен звучать так Есть у меня код которы при Код SR_W(255); Выставляет высокий уровень на все 8 бит здвигового регистра; Как мне модифицировать выше указанную процедуру чтобы высокое состояние при Код SR_W(258) Выставилось еще и на первые 2 бита второго сдвигового регистра Надеюсь что теперь корекно мысль сформулировал
Эскизы прикрепленных изображений
|
|
|
|
|
May 12 2007, 16:12
|
Местный
  
Группа: Свой
Сообщений: 256
Регистрация: 6-03-06
Из: Украина, г. Винница
Пользователь №: 15 017

|
Если быстро, тогда так: Код void sr_w(unsigned int ch ) { unsigned char counter = 16;
ISP_ST_CP = 0; ISP_SH_CP = 0; while (counter--) { ISP_SH_CP = 0; if ( ch & 0x8000 ) ISP_DS = 1; else ISP_DS = 0; #asm("nop") ISP_SH_CP = 1; ch <<= 1; }
ISP_ST_CP = 1; }
Сообщение отредактировал Александр Куличок - May 12 2007, 16:35
|
|
|
|
|
May 12 2007, 16:41
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Похоже, TamTam хочет, чтобы если число меньше или равно 255, то все светилось в "первом" регистре, а всё, что больше - во "втором", т.е. что-то типа sr_w(258-255); sr_w(255); Цитата не вижу смысла логичекое выражение дважды инвертировать ch & 0x80 - это побитовое И, т.е. результат будет равен 0 или 0x80. Т.е. Вы просто ошиблись. Логическое выражение же возвращает в Си 0 или 1, т.е. если число не 0, то даст 1. Получается, чтобы получить именно 1, нужно дважды проинвертировать и всё. А варианты с Цитата Чтобы сохранить алгоритм надо писать , можете использовать, но это не то, что Вы до того написали, и никак не может отвергнуть за неправильностью мою поправку.
--------------------
aka Vit
|
|
|
|
|
May 12 2007, 16:44
|

Местный
  
Группа: Свой
Сообщений: 293
Регистрация: 14-03-06
Пользователь №: 15 254

|
Цитата(sensor_ua @ May 12 2007, 19:41)  Похоже, TamTam хочет, чтобы если число меньше или равно 255, то все светилось в "первом" регистре, а всё, что больше - во "втором", т.е. что-то типа sr_w(258-255); sr_w(255); ch & 0x80 - это побитовое И, т.е. результат будет равен 0 или 0x80. Т.е. Вы просто ошиблись. Логическое выражение же возвращает в Си 0 или 1, т.е. если число не 0, то даст 1. Получается, чтобы получить именно 1, нужно дважды проинвертировать и всё. А варианты с , можете использовать, но это не то, что Вы до того написали, и никак не может отвергнуть за неправильностью мою поправку. Нет не так, я хочу удлиннить потр чтобы он стал не 8 а 16 битный.
|
|
|
|
|
May 12 2007, 16:59
|
Местный
  
Группа: Свой
Сообщений: 256
Регистрация: 6-03-06
Из: Украина, г. Винница
Пользователь №: 15 017

|
Цитата(sensor_ua @ May 12 2007, 19:41)  ch & 0x80 - это побитовое И, т.е. результат будет равен 0 или 0x80. Т.е. Вы просто ошиблись. Полностью согласен, ступил немного. Правда, ошибку заметил раньше Вашего указания и уже успел подкорректировать свой пост. Цитата unsigned int i = 258;//0x0102 sr_w((unsigned char)(i>>8));//0x01 sr_w((unsigned char)(i));//0x02 можно и так. Но ISP_ST_CP = 1; все равно вынеси за функцию, так как это строб на перезапись из сдвигового регистра на выход ИМС. Если не вынести, данные 2-го регистра будут подсвечивать на 1-м.
|
|
|
|
|
May 12 2007, 17:27
|
Местный
  
Группа: Свой
Сообщений: 256
Регистрация: 6-03-06
Из: Украина, г. Винница
Пользователь №: 15 017

|
Цитата(TamTam @ May 12 2007, 20:08)  Чето я так и неврубился как должна выглядеть процедура. Вариант 1: Смотри выше мой пост (там, где counter=16 и тип переменной ch - unsigned int) Процедуру вызываем так: sr_w(258); Только для того, чтобы засвеить все диоды, нужно писать sr_w(0х3FF); Вариант 2: Код void sr_w(unsigned char ch ) { unsigned char counter = 8;
// ISP_ST_CP = 0; - убрали, но можно и оставить ISP_SH_CP = 0; while (counter--) { ISP_SH_CP = 0; if ( ch & 0x80 ) ISP_DS = 1; else ISP_DS = 0; #asm("nop") ISP_SH_CP = 1; ch <<= 1; }
// ISP_ST_CP = 1; - убрали } и вызывать unsigned int i = 258; //0x0102 ISP_ST_CP = 0; sr_w((unsigned char)(i>>8));//0x01 sr_w((unsigned char)(i));//0x02 ISP_ST_CP = 1; // после этой команды новые данные появляются на выходе.
Сообщение отредактировал Александр Куличок - May 12 2007, 17:32
|
|
|
|
|
May 12 2007, 17:40
|

Местный
  
Группа: Свой
Сообщений: 293
Регистрация: 14-03-06
Пользователь №: 15 254

|
Цитата(Александр Куличок @ May 12 2007, 20:27)  Вариант 1: Смотри выше мой пост (там, где counter=16 и тип переменной ch - unsigned int) Процедуру вызываем так: sr_w(258); Только для того, чтобы засвеить все диоды, нужно писать sr_w(0х3FF); Вариант 2: Код void sr_w(unsigned char ch ) { unsigned char counter = 8;
// ISP_ST_CP = 0; - убрали, но можно и оставить ISP_SH_CP = 0; while (counter--) { ISP_SH_CP = 0; if ( ch & 0x80 ) ISP_DS = 1; else ISP_DS = 0; #asm("nop") ISP_SH_CP = 1; ch <<= 1; }
// ISP_ST_CP = 1; - убрали } и вызывать unsigned int i = 258; //0x0102 ISP_ST_CP = 0; sr_w((unsigned char)(i>>8));//0x01 sr_w((unsigned char)(i));//0x02 ISP_ST_CP = 1; // после этой команды новые данные появляются на выходе. Все равно не получается светятся два диода 2 на 1 регистре и 1 на второмю Есть два варианта глюк Протеуса или хз
|
|
|
|
|
May 12 2007, 17:41
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Цитата ISP_ST_CP = 1; все равно вынеси за функцию, так как это строб на перезапись из сдвигового регистра на выход ИМС. Если не вынести, данные 2-го регистра будут подсвечивать на 1-м. По хорошему именно так и надо, но если не поправить, то, если только проц не на единицах Герц работает, то не будет заметно на глаз и как было.
--------------------
aka Vit
|
|
|
|
|
May 12 2007, 17:44
|
Местный
  
Группа: Свой
Сообщений: 256
Регистрация: 6-03-06
Из: Украина, г. Винница
Пользователь №: 15 017

|
Цитата Все равно не получается светятся два диода 2 на 1 регистре и 1 на второмю Есть два варианта глюк Протеуса или хз Какой вариант используеш? Какие значения передаеш в процедуры? Ножки настроены на выход?
Сообщение отредактировал Александр Куличок - May 12 2007, 17:44
|
|
|
|
|
May 12 2007, 17:52
|

Местный
  
Группа: Свой
Сообщений: 293
Регистрация: 14-03-06
Пользователь №: 15 254

|
Цитата(Александр Куличок @ May 12 2007, 20:44)  Какой вариант используеш? Какие значения передаеш в процедуры? Ножки настроены на выход? Пробывал оба варианта. Привожу полный листинг. Вроде все сконфигурено правильно. Код /***************************************************** This program was produced by the CodeWizardAVR V1.25.3 Professional Automatic Program Generator © Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.com
Project : Version : Date : 12.05.2007 Author : F4CG Company : F4CG Comments:
Chip type : AT90S2313 Clock frequency : 11,059200 MHz Memory model : Tiny External SRAM size : 0 Data Stack size : 32 *****************************************************/
#include <90s2313.h>
#define ISP_DS PORTB.1 // SR_DATA #define ISP_SH_CP PORTB.0 // SR_CLK #define ISP_ST_CP PORTB.2 // SR_LATCH #define ISP_MR PORTB.3 // MR
unsigned int i = 258; //0x0102
// Declare your global variables here
void sr_w(unsigned char ch );
void sr_w(unsigned char ch ) { unsigned char counter = 8;
// SR_LATCH = LOW; // SR_CLK = LOW; // ISP_ST_CP = 0; ISP_SH_CP = 0; while (counter--) { // SR_CLK = LOW; ISP_SH_CP = 0; if ( ch & 0x80 ) // SR_DATA = HIGH ISP_DS = 1; else // SR_DATA = LOW; ISP_DS = 0; #asm("nop") // SR_CLK = HIGH; ISP_SH_CP = 1; ch <<= 1; // ñäâèã âëåâî } // SR_LATCH = HIGH; // çàù¸ëêíåì // ISP_ST_CP = 1; // ISP_MR = 1; } void main(void) { // Declare your local variables here
// Input/Output Ports initialization // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=Out Func1=Out Func0=Out // State7=T State6=T State5=T State4=T State3=0 State2=0 State1=0 State0=0 PORTB=0x00; DDRB=0x0F;
// Port D initialization // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTD=0x00; DDRD=0x00;
// Timer/Counter 0 initialization // Clock source: System Clock // Clock value: Timer 0 Stopped TCCR0=0x00; TCNT0=0x00;
// Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer 1 Stopped // Mode: Normal top=FFFFh // OC1 output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; OCR1H=0x00; OCR1L=0x00;
// External Interrupt(s) initialization // INT0: Off // INT1: Off GIMSK=0x00; MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x00;
// Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80;
sr_w(258);
ISP_ST_CP = 0; sr_w((unsigned char)(i>>8));//0x01 sr_w((unsigned char)(i));//0x02 ISP_ST_CP = 1; // ïîñëå ýòîé êîìàíäû íîâûå äàííûå ïîÿâëÿþòñÿ íà âûõîäå.
while (1) { // Place your code here
}; }
|
|
|
|
|
May 12 2007, 18:13
|
Местный
  
Группа: Свой
Сообщений: 256
Регистрация: 6-03-06
Из: Украина, г. Винница
Пользователь №: 15 017

|
Цитата светятся два диода 2 на 1 регистре и 1 на второмю Значит программа правильно работает. Мы ведь пишем во второй регистр r_w((unsigned char)(i>>8));// 0x01=0b0000_0001 - то есть должен гореть 1 диод (по схеме 2-й снизу) и в 1-й регистр - sr_w((unsigned char)(i));// 0x02 =0b0000_0010 - еще 1 диод(2-й сверху). Уточни, что ты конкретно хочешь получить на выходе в зависимости от входных данных? Данная программа и схема выводит на выходы НС595 16-битное значение "i" в двоичном коде. (младший байт - на верхний регистр и старший на нижний). Для того, чтобы засветить все светодиоды, нужно переменной "i" присвоить значение i = 0x3FF (т.е в двоичном коде 0b_0000_0011_1111_1111 или в десятичном 1023). Кстати, для данной схемы 1й вариант (где в процедуру передается беззнаковое 16-битное) предпочтительней, так как в основной программе не нужно заботиться о подаче строба перезаписи.
Сообщение отредактировал Александр Куличок - May 12 2007, 18:31
|
|
|
|
|
May 13 2007, 07:52
|
Местный
  
Группа: Свой
Сообщений: 256
Регистрация: 6-03-06
Из: Украина, г. Винница
Пользователь №: 15 017

|
Цитата(TamTam @ May 12 2007, 23:47)  Родился еще один вопрос, можноли при помощи этойже микрухи выполнить опрос кнопок ? Если на контроллере есть лишние ноги, то кнопки лучше к нему прицепить. Код попроще получится. И если это будет реальный девайс, то не забудь про защиту от дребезга.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|