Вс сен 08, 2013 17:03:09
Bit 6 – ICES1: Input Capture Edge Select
This bit selects which edge on the Input Capture Pin (ICP1) that is used to trigger a capture
event. When the ICES1 bit is written to zero, a falling (negative) edge is used as trigger, and
when the ICES1 bit is written to one, a rising (positive) edge will trigger the capture.
When a capture is triggered according to the ICES1 setting, the counter value is copied into the
Input Capture Register (ICR1). The event will also set the Input Capture Flag (ICF1), and this
can be used to cause an Input Capture Interrupt, if this interrupt is enabled.
Вс сен 08, 2013 17:11:56
Сб окт 12, 2013 19:36:30
Ср фев 12, 2014 03:18:18
Пт фев 14, 2014 12:18:45
1. считали байт из ПП
2. вызвали процедуру печати символа
3. уменьшили (декремент) счётчик
4. переход к п.1, если не ноль
1. считали байт из ПП
2. скопировали его
3. маскируем его (лог. «И») с 0b00011111
4. вызвали процедуру печати символа
5. проверили копию на наличие ещё одного символа
// если все 3 старшие биты нулевые — второго символа в данном байте нет
// проще всего организовать через сравнение с константой 0b00011111
6. переход к п.10, если второго символа нет
7. иначе переместили старшие 3 бита в младшие
// например, через обмен тетрадами и сдвиг вправо
8. маскировали его (лог. «И») с 0b00000111
9. вызвали процедуру печати символа
10. уменьшили (декремент) счётчик
11. переход к п.1, если не ноль
Сб май 03, 2014 17:44:19
#define DIR_LRTB 0 // LEFT to RIGHT, TOP to BOTTOM
#define DIR_RLTB 1 // RIGHT to LEFT, TOP to BOTTOM
#define DIR_LRBT 2 // LEFT to RIGHT, BOTTOM to TOP
#define DIR_RLBT 3 // RIGHT to LEFT, BOTTOM to TOP
void draw_line(int x0, int y0, int x1, int y1, int c)
{
int x,y,dx,dy,s;
char d=0;
x=x0; y=y0;
if(x0>x1){d|=1;dx=x0-x1;}else{dx=x1-x0;}
if(y0>y1){d|=2;dy=y0-y1;}else{dy=y1-y0;}
switch(d)
{
case DIR_LRTB:
if(dy>dx)
{
for(s=dx;y<=y1;y++)
{
plot(x,y,c);
s+=dx;
if(s>=dy){x++;s-=dy;}
}
} else
{
for(s=dy;x<=x1;x++)
{
plot(x,y,c);
s+=dy;
if(s>=dx){y++;s-=dx;}
}
}
break;
case DIR_RLTB:
if(dy>dx)
{
for(s=dx;y<=y1;y++)
{
plot(x,y,c);
s+=dx;
if(s>=dy){x--;s-=dy;}
}
} else
{
for(s=dy;x>=x0;x--)
{
plot(x,y,c);
s+=dy;
if(s>=dx){y++;s-=dx;}
}
}
break;
case DIR_LRBT:
if(dy>dx)
{
for(s=dx;y>=y0;y--)
{
plot(x,y,c);
s+=dx;
if(s>=dy){x++;s-=dy;}
}
} else
{
for(s=dy;x<=x1;x++)
{
plot(x,y,c);
s+=dy;
if(s>=dx){y--;s-=dx;}
}
}
break;
case DIR_RLBT:
if(dy>dx)
{
for(s=dx;y>=y0;y--)
{
plot(x,y,c);
s+=dx;
if(s>=dy){x--;s-=dy;}
}
} else
{
for(s=dy;x>=x0;x--)
{
plot(x,y,c);
s+=dy;
if(s>=dx){y--;s-=dx;}
}
}
break;
}
}
Сб авг 16, 2014 18:27:47
; {...}
; {делаем что-нибудь}
; {...}
ldi r20, 0x0C ; Инициализация внешнего счётчика
outer_loop:
; {...}
; {содержимое внешнего цикла}
; {...}
ldi r18, 0xE4 ; Инициализация внутреннего счётчика
ldi r19, 0x01 ; То, что не поместилось в байт
inner_loop:
; {...}
; {содержимое внутреннего цикла}
; {...}
dec r18 ; Уменьшаем внутренний счётчик
brne inner_loop
dec r19 ; Тоже внутренний счётчик
brne inner_loop
dec r20 ; Уменьшаем внешний счётчик
brne outer_loop
; {...}
; {делаем ещё что-нибудь}
; {...}
; {...}
; {делаем что-нибудь}
; {...}
ldi r19, 0x0C ; Инициализация внешнего счётчика
outer_loop:
; {...}
; {содержимое внешнего цикла}
; {...}
ldi r18, 0xE4 ; Инициализация внутреннего счётчика
ori r19, 0xE0 ; То, что не поместилось в байт
; Величина, помещаемая в старший полубайт
; вычисляется по формуле y = 0xF - x
; В моём случае x=0x1, поэтому y=0xE
inner_loop:
; {...}
; {содержимое внутреннего цикла}
; {...}
dec r18 ; Уменьшаем внутренний счётчик
brne inner_loop
subi r19, 0xF0 ; Тоже внутренний счётчик
; Выполнение этой команды увеличивает
; старший полубайт регистра r16 на 0x1,
; при этом флаг переноса уставлен, кроме случая,
; когда старший полубайт оказывается равным 0x0
brcs inner_loop
dec r19 ; Уменьшаем внешний счётчик
brne outer_loop
; {...}
; {делаем ещё что-нибудь}
; {...}
; {...}
; {делаем что-нибудь}
; {...}
ldi r19, 0x0C ; Инициализация внешнего счётчика
outer_loop:
; {...}
; {содержимое внешнего цикла}
; {...}
ldi r18, 0xE4 ; Инициализация внутреннего счётчика
ori r19, 0x10 ; То, что не поместилось в байт
inner_loop:
; {...}
; {содержимое внутреннего цикла}
; {...}
dec r18 ; Уменьшаем внутренний счётчик
brne inner_loop
subi r19, 0x10 ; Тоже внутренний счётчик
brcс inner_loop
subi r19, 0xF1 ; Уменьшаем внешний счётчик
brne outer_loop
; {...}
; {делаем ещё что-нибудь}
; {...}
Пн авг 25, 2014 00:38:03
внутренний цикл на чуть более, чем 256 итераций (в моём случае 484 = 0x01E4).
Пн авг 25, 2014 04:23:13
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; STACK HACK FOR AVR ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.include "m8def.inc"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.dseg
.org (RAMEND - 1)
st_ret_h: .byte 1
st_ret_l: .byte 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.cseg
.org 0x0000
rjmp RESET
.org INT_VECTORS_SIZE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RESET: ldi r16, Low(RAMEND)
ldi r17, High(RAMEND)
out SPL, r16
out SPH, r17
rcall TEST
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LX: rjmp LX
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LOOP: rjmp LOOP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TEST: ldi r16, Low(LOOP)
sts st_ret_l, r16
ldi r16, High(LOOP)
sts st_ret_h, r16
ret
Пн авг 25, 2014 07:24:49
Пн авг 25, 2014 08:01:40
Вт авг 26, 2014 10:34:32
ARV писал(а):АЦП отлично может функционировать в качестве дополнительного таймера с фиксированным периодом счета...
Вт авг 26, 2014 10:39:11
:))) можно, но...Gudd-Head писал(а):ARV писал(а):АЦП отлично может функционировать в качестве дополнительного таймера с фиксированным периодом счета...
Хм... А какой-нить УАРТ/И²С/СПИ тоже ведь так можно настроить?
Вт авг 26, 2014 10:50:00
ARV писал(а):...это будет "однократный" таймер, который в обработчике прерываний придется перезапускать
ARV писал(а):...этот "таймер" будет гадить на внешних линиях ввода-вывода
Вт авг 26, 2014 11:13:36
Gudd-Head писал(а):А вот у АЦП, если мультиплексором выбрать такую комбинацию бит, которым ничего не соответствует в ДШ будет нормально работать? И не задействует никакую ногу?
Вт авг 26, 2014 11:23:17
Пт сен 05, 2014 17:08:59
#include <avr\io.h>
#include <util\delay.h>
#include <avr\pgmspace.h>
typedef int(*myFunc)(void);
int func1(void);
int func2(void);
int func3(void);
myFunc fArr[3] = {func1, func2, func3};
//----------
int main()
{
while(1)
{
for(int i = 0; i < 3; i++)
{
fArr[i]();
}
}
}
//----------
int func1(void)
{
PORTB=0x01;
return 0;
}
int func2(void)
{
PORTB=0x02;
return 0;
}
int func3(void)
{
PORTB=0x04;
return 0;
}
;---------- Адреса процедур
HANDLERS:
.dw MPT, RSTCFG, OPNCFG, MENUCFG, LIGHT_CFG, US_OV, STAT_CFG, SENS_CFG, CLR_CFG, MASTERCFG
;---------- конфигурации
CONFIG:
rcall KEYREQ ;Опрос клавиатуры
cpi temp0, _NO_BT ; ничего не нажато (0xFF)
breq CONFIG
cpi temp0, _CLR ;нажата кнопка "Сброс" (0x0F)
breq CFGEND
cpi temp0, _A ; нажаты кнопки от А до Enter (всего 16 кнопок. 0...9, A, B, C, D, Enter, CLR) = (0x00...0x0F)
brsh CFGERR
ldi ZL, Low(HANDLERS*2) ; нажаты кнопки от 0 до 9
ldi ZH, High(HANDLERS*2) ; соответственно, выбран один из пунктов меню. Загружаем адрес начала массива адресов процедур
lsl temp0 ; Из-за типичной для AVR организации памяти, приходится домножать номер процедуры на два простым сдвигом влево.
clr temp1
add ZL, temp0 ;смещаемся до нужного элемента массива
adc ZH, temp1
lpm dx2, Z ; грузим адрес из массива
adiw Z, 0x01
lpm dx3, Z
mov ZL, dx2
mov ZH, dx3
icall ; вызываем процедуру
rjmp CONFIG
CFGERR:
rcall ERR ; индикация ошибки
rjmp CONFIG
;---------- Выход из меню
CFGEND:
rcall INIT
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;----------
MPT:
;процедура номер ноль
ret
;----------
RSTCFG:
;процедура номер раз
ret
;----------
OPNCFG:
;процедура номер два
ret
;----------
MENUCFG:
; процедура номер три
ret
;----------
LIGHT_CFG:
;процедура номер четыре
ret
;----------
US_OV:
;процедура номер пять
ret
;----------
STAT_CFG:
;процедура номер шесть
ret
;----------
SENS_CFG:
;процедура номер семь
ret
;----------
CLR_CFG:
;процедура номер восемь
ret
;----------
MASTERCFG:
;процедура номер девять
ret
Пт сен 05, 2014 17:53:37
Пт сен 05, 2014 20:35:07
void Handle(Command cmd)
{
case Command1: Handle1(); break;
case Command2: Handle2(); break;
case Command3: Handle3(); break;
case Command4: Handle4(); break;
case Command5: Handle5(); break;
case Command6: Handle6(); break;
case Command7: Handle7(); break;
case Command8: Handle8(); break;
case Command9: Handle9(); break;
case CommandA: HandleA(); break;
case CommandB: HandleB(); break;
case CommandC: HandleC(); break;
case CommandD: HandleD(); break;
case CommandE: HandleE(); break;
case CommandF: HandleF(); break;
default: Handle0(); break;
}
Сб сен 06, 2014 22:17:19