Все установил ну не фига не получается
Загружаю программу порты PB0-PB6 работают в режиме выхода. Подаю сигнал на PD6 и PB0-PB6 начинают работать в состоянии входа.
YS Не хочу я биение.
Я просто не знаю эээээ. Ну вот как реализовать сигнал с телефона программно, по аналогии с кнопкой ( с фиксацией). Т.е пришел сигнал вкл, пришел опять выключил и т.д. А режим будет один. Хотя было бы прикольно если бы он генерировался как то или менялся со временем, ну пока надо одно сделать, во я губу раскатал.
Хотелось бы дополнить схему датчиком освещенности, чтобы днем не горел.
Вот как я рассуждаю:
Устанавливаем в состояния входа PD5, PBx в состоянии выхода
Ну а дальше прошу подсказаньку у вас. Как сделать фиксированный сигнал?
Блин не могу догнать, как делать то что вы сказали((( Понимаю, что это как то просто но не могу написать( Наверное я дерево)
Вот смотрите, первое, что нужно сделать создать переменную, потом назначить порт на который будет падать сигнал входом. Затем сохраняем, состояние порта в переменную, а вот дальше ступор. Начал писать условие, if...else ну это потом дошло что это то же самое что и кратковременное нажатие, только, рулим логикой через переменную. Как сделать фиксированный сигнал? Скажите пожалуйста.
Я хочу хотя вкл выкл сердце по звонку. А потом можно и все другое городить.
Код на асме. Я писал на асме, потому что вообще не понимаю кода на С в случае МК. Хотя обычный "компьютерный" С я понимаю на ура.
Видимо, напрямую связываю код и железку в голове, чего не происходит в случае использования Ц.
Пример кода для включения/выключения лампы по прерыванию
.include "2313def.inc"
;Константа нужна в процедурах Delay
.equ d250us = 8 ;7@10MHz with 7 nops at Delay() ;;;;; 8 - у меня был кварц на 4Мгц если правильно помню .
.equ STACKTOP = RAMEND - 100
;Описание использования регистров общего назначения (РОН)
.def SAVE_SREG = r0 ; в данном коде не используется.
.def AReg = r16 ; working reg, like the 68HC11 A register
.def BReg = r17 ; working reg, like the 68HC11 B register
.def DelayVal = r18 ; РОН, используемый в процедурах программной задержки
;ОПИСАНИЕ ИСПОЛЬЗОВАНИЯ ПОРТА B
.equ PB_TRIAC = 0 ; PORTB bit used for triac optocouple managing (ножка 0 управляет оптопарой триака)
;Настройка векторов прерываний. В коде по нужным смещениям будут нужные команды.
;(допустима одна команда - либо rjmp METKA или reti если не надо обрабатывать)
.cseg
.org $000 ;Reset Vector
rjmp Reset
; Пока ничего не используем. Я откомментировал большой кусок кода и дописал туда примерчик ловли из UART слова
; RING которое кидает модем телефона при входящем звонке. Но пока писал, а писал в редакторе, сессия устарела.
; я как бы помнил об этом и собирался скопипастить перед отправкой, но случайно задел кнопку предпросмотр и ... всё под хвост ... =)
; не знаю, стоит ли повторять подвиг c кодом про UART =)) .
;Interrupt vectors
.org INT0addr ;External Interrupt0 Vector ; прерывание будет, будет включено, но кода в нем не будет.
; Оно будет просто прерывать sleep в main_loop.
reti
.org INT1addr ;External Interrupt1 Vector
reti
.org ICP1addr ;Input Capture1 Interrupt Vector
reti
.org OC1addr ;Output Compare1 Interrupt Vector Address
reti
.org OVF1addr ;Overflow1 Interrupt Vector
reti
.org OVF0addr ;Overflow0 Interrupt Vector
reti
.org URXCaddr ;UART Receive Complete Interrupt Vector
reti
.org UDREaddr ;UART Data Register Empty Interrupt Vector
reti
.org UTXCaddr ;UART Transmit Complete Interrupt Vector
reti ;rjmp transmit_complete
.org ACIaddr ;Analog Comparator Interrupt Vector
reti
Reset: ; сюда попадем после включения контроллера.
ldi AReg, low(STACKTOP)
out SPL, AReg ;set low byte for stack pointer. Общая фича.
rcall Setup ;set up, Serial I/O, timers, etc
main_loop: ;основной цикл работы контроллера
; Вот кусок кода, который реализует переключение в противоположное состояние:
sbic PORTB, PB_TRIAC ;sbic - skip if bit is clear ; пропустить следующую операцию если бит в порту = 0.
rjmp write0 ; в порту 1, пропуска не было, пойдем писать в порт 0.
write1:
sbi PORTB, PB_TRIAC ; в порту 0, ставим 1
rjmp writeDone
write0:
cbi PORTB, PB_TRIAC ; в порту 1, ставим 0
writeDone:
; наверное тут надо поставить какую-то задержку, на сколько-то долго, чтобы просто так не срабатывать по кругу
; Допустим, ждем 10 cек защитного интервала.
ldi BReg,10
ldi AReg,250
wait_loop1:
rcall delay_ms ; 4 вызова по AReg = 4 * 250 мсек = 1 сек
rcall delay_ms
rcall delay_ms
rcall delay_ms
; для визуализации процесса можно сделать здесь мигание вспомогательным светодиодом, типа так:
; одну из rcall delay_ms обрамить командами вкл/выкл другой ножки порта В
; sbi PORTB, PB_INFO
; rcall delay_ms
; cbi PORTB, PB_INFO
dec BReg
brne wait_loop1 ; ждем, пока dec не выставит флаг что BReg == 0.
; Тогда мы выйдем из цикла и будем снова спать в sleep до следующего прерывания.
sleep; ;не забыть выставить таймера/прерывания чтобы хоть иногда просыпаться.
;Т.е. ждем нового прерывания
rjmp main_loop ;wait here until something interesting happens
Setup:
; режим sleep, просто IDLE, прерывания по спаду (возможно, вам надо по нарастанию =) )
; Флаги смотрятся в даташите. Вообще всё смотрится в даташите =)
ldi AReg, (1<<ISC11)|(0<<ISC10)|(1<<ISC01)|(0<<ISC00); // (1<<SE)
out MCUCR, AReg
ldi AReg, (1<<INT1)|(1<<INT0) ; Разрешаем прерывания INTO INT1
out GIMSK,Areg ; Вам в принципе достаточно любого одного.
ser AReg ; Порт В - все ноги на выход
out DDRB,AReg
clr AReg ; Очистим AReg в нули, т.е. все линии PORTB тоже будут в нуль.
;ldi AReg, (1<<PB_TRIAC) ; Или наоборот, поставим туда единичку в нужную позицию, одно из двух
out PORTB, AReg ; Запишем в порт значение из регистра. Вся запись в порты делается через регистр(AFAIK).
;; DEBUG ; после включения - можно просто мигнуть для проверки.
ldi Areg,250
sbi PORTB, PB_TRIAC ; sb - set bit . Включим бит.
rcall delay_ms ; подождем немного (250 мс)
cbi PORTB, PB_TRIAC ; cb - clear bit . Очистим бит обратно
;; /DEBUG
sei ; разрешаем прерывания
reti
;**************
;* Процедуры программной задержки
;**************
;**********************************************
;* Delay time in us based on CLK/8 *
;* DelayVal holds the delay value. *
;* 11clk + (255 - DelayVal) * 4clk *
;**********************************************
;; 13 clk + (255 - DelayVal)* 10clk ( с учетом закомментированного nop)
Delay: ;вызов функции через rcall занимает 3 clk
push DelayVal ;2clk
Delay0:
inc DelayVal ; 1
; nop ; 1
; nop ; 1 250u = 7@10MHz, these nops must be uncommented
; nop ; 1
; nop ; 1
; nop ; 1
; nop ; 1
nop ; 1
brne Delay0 ;1/2 по прямой 1 clk - jmp 2 clk
pop DelayVal ;2
ret
Delay1ms:
ldi DelayVal, d250us ;1 clk
rcall Delay ;3 clk
rcall Delay
rcall Delay
rcall Delay
ret
Delay_ms:
push AReg
Dms0:
rcall Delay1ms
dec Areg
brne Dms0
pop AReg
ret
Понимаю, что это как то просто но не могу написать( Наверное я дерево)
Я не вижу смысла писать конкретно этот пример (т.к. конкретный вид зависит от алгоритма). Скажите, как оно должно мигать при приходе сигнала, и я напишу код. Это займет минут десять. А потом Вы его изучите и спросите, чего нясно.
Во вложении Ваша разводка с пронумерованными для ясности транзисторами. Опишите порядок включения и задержки между ними.
Пара уточнений:
МК ATtiny2313?
Ко входу "телефон" подключается выход звонка? Тогда кроме этого рекомендую диод + конденсатор + резистор, можно навесом.
#pragma offtopic
Закон симметрии, чо. У кого есть девушка - тот не умеет писать под МК, кто умеет писать под МК, у того нет девушки...
Да на асме жестко писать.
Спасибо за помощь.
Вот собственно что я хочу
С моторчика телефона поступает сигнал, на порт PD5
Поступил сигал, начинаем выполнять программу
Сердечко будет состоять из спиралей (модулей)
-Каждый модуль это выход всего их 7 от PB1 до PB7 (ну или Q1-Q7)
Каждый модуль должен включаться поочередно с задержкой 2сек
Программа должна выполняться пока не поступит новый сигнал (звонок)
Так же было рационально использовать фоторезистор, если день то офф (т.е это одно из условий выполнения) Ну как я понимаю такую вещь надо подключать к АЦП
Спасибо
Эк Вас напугали. На самом деле все не так страшно. Но применять тут асм я смысла не вижу.
С моторчика телефона поступает сигнал, на порт PD5
Тогда используйте ту схему, что я нарисовал выше.
Каждый модуль должен включаться поочередно с задержкой 2сек
А потом выключаться? Или нет? Т.е., Q1 on->Q2 on->Q3 on->Q4 on->Q5 on->Q6 on->Q7 on->все горят до сигнала выкл., или Q1 on->Q2 on->Q3 on->Q4 on->Q5 on->Q6 on->Q7 on->Q1 off->Q2 off->Q3 off->Q4 off->Q5 off->Q6 off->Q7 off->начинаем сначала, и до сигнала выкл?
Так же было рационально использовать фоторезистор, если день то офф (т.е это одно из условий выполнения) Ну как я понимаю такую вещь надо подключать к АЦП
Фоторезистор - каменный век. Рациональнее фотодиод или фототранзистор. АЦП нужен только если хотим программно менять порог переключения. А так можно сделать и в железе.
Разница между теорией и практикой на практике гораздо больше, чем в теории.
ОК, ща напишу каркас программы с эффектом, упомянутым выше. Алгоритм переклчения потом можно будет скорректировать, главное, теперь я понял, чего надо в смысле логики работы.
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Логика следующая: программа проверяет PD5. Когда на этой ножке появляется лог. 1, программа для верности ждет, пока оная пропадет, и только тогда включает/выключает основную часть (изначально все выключено). Т.е., у телефона лучше всего отключить сигнал звонка, а на SMS поставить сигнал покороче. Соответственно, управлять SMS-кой.
Основная часть просто раз в секунду копирует значение из массива effect_data в PORTB до тех пор, пока не встретит конец массива, потом все повторяется с начала. Поскольку PB0 не используется, я оставил значение 0x01 как маркер конца массива. Так что записывайте в массив то, что нравится, и наслаждайтесь (сейчас там простой бегущий огонек).
Можно было бы написать и оптимальнее, но я решил сместить акцент в сторону понятности, чтобы у Вас был шанс самостоятельно разобраться в коде.
Код расчитан на настройки тактирования МК по-умолчанию (1МГц), ибо заставлять Вас разбираться с фьюз-битами было бы бесчеловечно.
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdint.h>
#define SEQ_END 0x01
volatile uint8_t run_allowed=0;
//This array contains effect stages
//modify to your own needs
const uint8_t effect_data[] PROGMEM = {
0x02,0x04,0x08,0x10,0x20,0x40,0x80,SEQ_END
};
ISR (TIMER1_COMPA_vect)
{
static uint8_t i=0;
uint8_t v;
TCNT1=0;
if (run_allowed)
{
v=pgm_read_byte(&(effect_data[i]));
if (v!=SEQ_END)
{
PORTB=v;
i++;
}
else
i=0;
}
else
{
i=0;
PORTB=0;
}
}
void main(void)
{
TCNT1=0; //Initial timer value is zero
OCR1A=0x3D09; //This will give 1Hz interrupt @ 1MHz clock
//(default for ATtiny2313)
TIMSK=(1<<OCIE1A); //Interrupt on compare A match
TCCR1B=(1<<CS11) | (1<<CS10); //Starting timer at F_CPU/64
DDRD&=~(1<<PD5); //PD5 is on/off signal input from phone
DDRB=0xFF; //PORTB drives outputs, so all pins to output mode
sei();
while (1)
{
if (PIND & (1<<PD5)) //Wow, call/SMS!
{
while (PIND & (1<<PD5)); //Waiting for signal end to prevent surprises
run_allowed=!run_allowed; //Switching all thing ON/OFF
}
}
}
Разница между теорией и практикой на практике гораздо больше, чем в теории.