Ср сен 19, 2012 13:30:22
Ср сен 19, 2012 15:22:29
Ср сен 19, 2012 18:27:19
Ср сен 19, 2012 19:38:17
Ср сен 19, 2012 22:40:31
Да хоть так, IMHO, главное чтобы понятно было и можно было разобраться.BOB51 писал(а):Алгоритм согласно правилам, принятым для алгоритмов - ромкбики. квадратики ...строчки описания...
BOB51 писал(а):Кстати, насчет первого поста я так нихрена толком и не понял, чего человеку от нещасного МК надобно было...
А если в прерывании программно генерируется какой-то сигнал на выводе МК, то фронты этого сигнала будут дрожать (jitter) на эти самые 4 такта. Чтобы этого не происходило и используется этот код.Kavka писал(а):перед входом в прерывание микроконтроллер должен завершить выполнение текущей команды. А команды могут выполняться от 1 до 4 тактов (до 5 тактов на МК с памятью 128-256кб).
Ср сен 19, 2012 23:19:57
Чт сен 20, 2012 01:28:27
.org OC1Aaddr
;4 address store
DDS: lds ZL,TCNT1L ;2 TCNT1L = 5..8
ldi ZH,high(JmpTab) ;1
ijmp ;2
.org (PC + 0x100) & 0xFF00 ;align to page
JmpTab: nop ; dummy
nop ; dummy
nop ; dummy
nop ; dummy
nop ; dummy
nop ;0/1 TCNT1L = 5
nop ;0/1 TCNT1L = 6
nop ;0/1 TCNT1L = 7
; TCNT1L = 8
Чт сен 20, 2012 03:37:38
ADC10_ISR:
add.w &ADC10IV, PC ; add offset to PC
reti ; No Interrupt
reti ; ADC10_B overflow
reti ; ADC10_B timing overflow
jmp ADC_hi ; ADC10_B window comparator high
jmp ADC_lo ; ADC10_B window comparator low
jmp ADC_in ; ADC10_B window comparator in
reti ; ADC conversion complete
ADC_fi: clr.w &ADC10IFG ; clear interrupt flags
bic.w #LPM0, 0(SP) ; conversion complete, wake-up CPU
reti
ADC_hi: mov.b #2, &switch ; new state
bis.b #Switch, &event ; set event
mov.w #ADC10LOIE+ADC10INIE+ADC10IFG0, &ADC10IE
jmp ADC_fi
ADC_lo: clr.b &switch ; new state
bis.b #Switch, &event ; set event
mov.w #ADC10HIIE+ADC10INIE+ADC10IFG0, &ADC10IE
jmp ADC_fi
ADC_in: mov.b #1, &switch ; new state
bis.b #Switch, &event ; set event
mov.w #ADC10LOIE+ADC10HIIE+ADC10IFG0, &ADC10IE
jmp ADC_fi
Чт сен 20, 2012 05:46:02
Чт сен 20, 2012 05:51:57
mov A, R0 ; converting to BCD
swap A ; assuming that R1:R0
anl A, #0x0F ; has 3 decimal digits
mov R2, A
mov A, R1
swap A
add A, R2
mov B, #10
div AB
swap A
mov R2, A ; R2 = high(R1:R0/10)
mov A, B
swap A
mov R1, A
mov A, R0
anl A, #0x0F
add A, R1
mov B, #10
div AB
add A, R2
mov bdig3, B ; B = 3rd digit
mov digit3, B
mov B, #10
div AB ; A - 1st digit, B = 2nd digit
mov bdig1, A
mov digit1, A
mov bdig2, B
mov digit2, B
Чт сен 20, 2012 06:08:41
Чт сен 20, 2012 06:15:41
Чт сен 20, 2012 06:33:01
Здорово! Такой вариант быстрее!Леонид Иванович писал(а):У меня выравнивание джиттера прерывания сделано так (mega88):
Чт сен 20, 2012 07:36:37
А что сразу запинывать!? Предлагать свой вариант надо!!!Ser60 писал(а):Очень интересная и полезная тема. Но опасная! Вот выложишь тут, что тебе кажется трюком, а кто-то это давно использует или ему покажется это очевидным и запинают до смерти. Да и для себя самого это будет трюком в первый или во второй раз, потом становится рутиной... Но рискну.
Чт сен 20, 2012 09:49:28
Чт сен 20, 2012 10:20:49
Возможно оно так и есть. Только с небольшим уточнением - если только брать и вставлять интегрировать не разбираясь, то ничему не научишься. И когда кончится то лучшее у других, или просто его не будет для решения нужной задачи, то сам не сможешь решить поставленную задачу. Поэтому остаётся только учиться, постоянно. А учиться можно только тому чего не знаешь и у тех кто знает и умеет. В общем, это уже философия и она выходит за рамки топика этой темы.BOB51 писал(а):так что девиз темы - возьми лучшее от окружающих и интегрируй под свои нужды
Чт сен 20, 2012 12:02:52
Kavka писал(а):Здорово! Такой вариант быстрее!
.org OC1Aaddr
DDS: in XL,TCNT1L ;TCNT1L = 4..7
sbrs XL,0
rjmp PC+1
sbrs XL,1
lpm XL,Z
;tempH:tempM:tempL convert to BCD Dig[0..6]
DisBCD: ldy Dig
clr temp
ldi Cnt,7
clrout: st Y+,temp ;output array clear
dec Cnt
brne clrout
ldi Cnt,24 ;input bits count
ldz Dig
hloop: lsl tempL ;input array shift left
rol tempM
rol tempH
ldy Dig+7
sloop: ld temp,-Y
rol temp
subi temp,-0x06 ;temp+6, C=1
sbrs temp,4
subi temp,0x06 ;temp-6, C=0
andi temp,0x0f
st Y,temp
cpse YL,ZL ;ZH:ZL = Dig+3
rjmp sloop
cpse YH,ZH
rjmp sloop
dec Cnt ;YH:YL = Dig+3
brne hloop
//---------- Преобразование Long2BCD: ----------
//Преобразование двоичного числа в двоично-десятичное:
//x - входное двоичное число (32 бита, без знака)
//buff - выходной массив (10 цифр)
void Long2BCD(unsigned long x, char *buff)
{
for(char i = 0; i < 10; i++)
buff[i] = 0; //очистка выходного буфера
for(char i = 0; i < 32; i++) //цикл по количеству входных бит
{
char c = (x >> 31) & 1; //сохранение переноса
x = x << 1; //сдвиг входного числа
for(char p = 0; p < 10; p++) //цикл по количеству цифр
{
char s = buff[p]; //чтение цифры
s = (s << 1) | c; c = 0; //сдвиг с учетом переноса
if(s > 9) { s += 0x06; c = 1; } //коррекция цифры
s &= 0x0F; //выделение ниббла
buff[p] = s; //сохранение цифры
}
}
}
//---------- Преобразование Int2BCD: ----------
//Преобразование двоичного числа в двоично-десятичное:
//x - входное двоичное число (16 бит, без знака)
//buff - выходной массив (5 цифр)
void Int2BCD(int x, char *buff)
{
for(char i = 0; i < 5; i++)
buff[i] = 0; //очистка выходного буфера
for(char i = 0; i < 16; i++) //цикл по количеству входных бит
{
char c = (x >> 15) & 1; //сохранение переноса
x = x << 1; //сдвиг входного числа
for(char p = 0; p < 5; p++) //цикл по количеству цифр
{
char s = buff[p]; //чтение цифры
s = (s << 1) | c; c = 0; //сдвиг с учетом переноса
if(s > 9) { s += 0x06; c = 1; } //коррекция цифры
s &= 0x0F; //выделение ниббла
buff[p] = s; //сохранение цифры
}
}
}
Чт сен 20, 2012 12:59:13
Так же быстро как с IJMP и просто супер компактно.Леонид Иванович писал(а):
- Код:
.org OC1Aaddr
DDS: in XL,TCNT1L ;TCNT1L = 4..7
sbrs XL,0
rjmp PC+1
sbrs XL,1
lpm XL,Z
Чт сен 20, 2012 13:23:26
ldi tmp, AB
out DDRB, tmp
out UART, tmp
Чт сен 20, 2012 19:27:20
uint8_t msk;
for (msk=0x80; msk; msk=msk >> 1)
{
if (b & msk)
{
PORT|=DS;
}
else
{
PORT&=~DS;
}
}