|
|
  |
Умножение + перекодировка на AVR, не могу понять |
|
|
|
Aug 26 2008, 07:47
|

Местный
  
Группа: Свой
Сообщений: 253
Регистрация: 28-12-07
Из: Украина г. Первомайск
Пользователь №: 33 716

|
Всем привет , не могу никак понять как написать подпрограмму перекодировки значения для LM7001 Пример такой значение 0x0F 0xA0 умножаем на 25 DEC or 0x19 HEX clr tmp2 ldi tmp, 0x19 // загружаем константу add_25: // add r22, 0xA0 // умножаем на 25 DEC / 19 HEX adc r23 , 0x0F // adc r24, tmp2 // dec tmp // brne add_25 // После умножения получаем число трех байтовое r24 = 0x01 r23 = 0x86 r22 = 0xА0 как мне из него сделать десятичное число 100 000 ? потом после этого мне каждый символ нужно вывести на ЖКИ 44780 , в ASCII , это уже допишу сам . Буду рад пинку в нужном направлении .
|
|
|
|
|
Aug 26 2008, 07:53
|
Местный
  
Группа: Свой
Сообщений: 374
Регистрация: 6-09-05
Из: Тирасполь, Приднестровье
Пользователь №: 8 294

|
Цитата(Павлик @ Aug 26 2008, 10:47)  Всем привет , не могу никак понять как написать подпрограмму перекодировки значения для LM7001 Пример такой значение 0x0F 0xA0 умножаем на 25 DEC or 0x19 HEX clr tmp2 ldi tmp, 0x19 // загружаем константу add_25: // add r22, 0xA0 // умножаем на 25 DEC / 19 HEX adc r23 , 0x0F // adc r24, tmp2 // dec tmp // brne add_25 // После умножения получаем число трех байтовое r24 = 0x01 r23 = 0x86 r22 = 0xА0 как мне из него сделать десятичное число 100 000 ? потом после этого мне каждый символ нужно вывести на ЖКИ 44780 , в ASCII , это уже допишу сам . Буду рад пинку в нужном направлении .  теперь от этих 3 байт отними 100000 столько раз сколько сможешь, дальше 10000, потом 1000, 100,10.Остануться единицы. Из всего этого сформируй десятичное число
|
|
|
|
|
Aug 26 2008, 08:17
|

Местный
  
Группа: Свой
Сообщений: 253
Регистрация: 28-12-07
Из: Украина г. Первомайск
Пользователь №: 33 716

|
clr tmp2 ldi tmp, 0x19 // загружаем константу add_25: // add r22, 0xA0 // умножаем на 25 DEC / 19 HEX adc r23 , 0x0F // adc r24, tmp2 // dec tmp // brne add_25 // // registers // 28 27 26 // 1 55 CC = 87.500 // 1 86 A0 = 100.000 // 1 A5 E0 = 108.000 ldi r26, 0xA0 // отнимаем 100 000 ldi r27, 0x86 ldi r28, 0x01 rcall dec_char mov dig_1,loop // сохраняем результат первой цыфры ldi r26, 0x10 // отнимаем 10 000 ldi r27, 0x27 clr r28 rcall dec_char mov dig_2,loop // сохраняем результат второй цыфры ldi r26, 0xE8 // отнимаем 1 000 ldi r27, 0x03 rcall dec_char mov dig_3,loop // сохраняем результат третьей цыфры ldi r26, 0x64 // отнимаем 100 clr r27 rcall dec_char mov dig_4,loop // сохраняем результат четвертой цыфры ldi r26, 0x0A // отнимаем 10 clr r27 rcall dec_char mov dig_5,loop // сохраняем результат пятой цыфры // Перекодировка HEX -> DEC dec_char: // ldi loop,-1 // загружаем значение и отнимаем от него 1 char_no: sub r22, r26 // sbc r23, r27 // sbc r24, r28 // dec loop // brsh char_no // перейти если больше без знака ret // пробую так , не выходит , может я не так заганяю значение в loop ? Сколько раз нужно отнять значение 100 000 ? потому что если отнимать его 256 раз проц затухает примерно на 1 секунду  .
|
|
|
|
|
Aug 26 2008, 11:23
|
Участник

Группа: Свой
Сообщений: 68
Регистрация: 29-12-06
Из: Омск
Пользователь №: 23 999

|
100 000 в данном случае десятичное  Без деления не обойтись. Стандартные процедуры деления есть в аппноутах AVR. Берешь число, делишь на 100тыщ, к результату + #30 и на индикатор готовый символ. Остаток деления делишь на 10 тыщ, и то же самое.... Повторить с 1000, 100, 10, и остаток от деления на 10 - тоже туда же. Чтобы умножить число, совсем не нужно 25 раз складывать его с собой  аппаратное умножение есть почти во всех мегах. http://atmel.com/dyn/products/app_notes.asp?family_id=607Смотри апноты AVR200...AVR204
|
|
|
|
|
Aug 26 2008, 11:55
|
Местный
  
Группа: Участник
Сообщений: 246
Регистрация: 4-12-06
Пользователь №: 23 101

|
Цитата(Syberian @ Aug 26 2008, 15:23)  Без деления не обойтись. Стандартные процедуры деления есть в аппноутах AVR. Зачем же путать начинающего? Конечно, легко и приятно написать a=b/100000; (Догадались? следующая строка будет a=b%100000;) Но потом надо посмотреть, во что это превращается на ассемблере. Тут и поможет вычитание. Сравните код, станет всё ясно. Для 6-разрядного десятичного числа максимальное количество вычитаний - всего 45; при этом тысячи вычитаются из 2-х байт, а десятки - из одного. Цитата(Syberian @ Aug 26 2008, 15:23)  Чтобы умножить число, совсем не нужно 25 раз складывать его с собой  аппаратное умножение есть почти во всех мегах. Смотри апноты AVR200...AVR204 Это да!
Сообщение отредактировал Maik-vs - Aug 26 2008, 11:58
|
|
|
|
|
Sep 29 2008, 15:53
|
Частый гость
 
Группа: Участник
Сообщений: 148
Регистрация: 27-04-06
Пользователь №: 16 558

|
Цитата(Павлик @ Aug 31 2008, 20:13)  "Спасибо всем за участие , чесно говоря украл готовый исходник , и переписал его немного под себя , все работает как мне было и нужно . А где украл там ещё нету случаем? Тоже надо бы, а то начинаю писать, получается строк больше чем на асме! Хочется то что б и нули незначащие пробелами заменялись, и переменная long.
|
|
|
|
|
Sep 30 2008, 09:20
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(Коляй @ Sep 29 2008, 14:53)  А где украл там ещё нету случаем? Тоже надо бы, а то начинаю писать, получается строк больше чем на асме! Хочется то что б и нули незначащие пробелами заменялись, и переменная long. Как-то так можно Код unsigned char LCDOut[7]={15,32,19,19,30,0,0}; // набор символов по включению const unsigned long step[7]={1000000,100000,10000,1000,100,10,1}; void long2LCD( unsigned long m) { unsigned long temp,val; char i,atemp; val=m; for (i=0; i<6; i++) { temp=step[i]; atemp=0x30; while(val >= temp) { atemp++; val-=temp; } LCDOut[i]=atemp; } LCDOut[6]=val+0x30; }
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|