На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
    > МК-51 массив
      Подскажите, как написать программу на асм 51, обрабатывающую массив хранящийся во внешней памяти.
        Цитата hawk1 @
        Подскажите, как написать программу на асм 51, обрабатывающую массив хранящийся во внешней памяти.

        Внешняя память чего? Программ или данных? Обработка массива в чем заключается? Сортировка/изменение по маске/еще чего то там? :D
          Внешняя память данных я так понял. Обработка - суммирование и поиск минимального элемента, но мне хотя бы понять как объявить массив и обратиться к его элементу.
            Цитата hawk1 @
            но мне хотя бы понять как объявить массив и обратиться к его элементу.

            На чем писать собрался?

            Добавлено
            Цитата hawk1 @
            на асм 51,

            За вопрос извиняюсь. :D В DPTR заносишь адрес первого элемента массива. В любой регистр (назовем его Rx) количество элементов массива. И гонишь итерацию:
            ExpandedWrap disabled
              cikle  MOVX A, @DPTR   ;пересылаем очередной байт массива в аккумулятор
              ....................   ;что то с ним делаем
                     INC DPTR     ;увеличиваем указатель на элемент массива
                     DJNZ Rx, cikle  ;цикл, пока не пройдем все элементы массива

            Если элементов более 255 байт - то создаешь вложенный цикл.
            Сообщение отредактировано: medved_68 -
              Это понятно. А объявить массив как?
                Цитата hawk1 @
                А объявить массив как?

                Если я правильно тебя понял - то через директиву DB резервируешь память.
                  А пример можно?
                    Цитата hawk1 @
                    А пример можно?

                    :blink: А чем тебе пост 4 не понравился? Мнемоника по другому не напишется... Тем более, что тебе:
                    Цитата hawk1 @
                    Это понятно.
                    :D
                      Дело в том, что размер массива, который нужно обработать, 1500. Как его инициализировать?
                        Цитата hawk1 @
                        Дело в том, что размер массива, который нужно обработать, 1500. Как его инициализировать?

                        1500 чего? Что ты подразумеваешь под инициализацией? Начальные установки каждого элемента во внешней памяти? Или...?
                          1500 элементов. Инициализация - то есть присвоение значения каждому элементу
                            Цитата hawk1 @
                            Инициализация - то есть присвоение значения каждому элементу

                            Эти значения должны быть вызваны откуда то или можно прямо в прошивке писать их в виде констант?
                              Не сказано.
                                Цитата hawk1 @
                                Не сказано.

                                Ну тогда в чем проблема? Есть два варианта:
                                1. Ты загружаешь константу в аккумулятор и выплевываешь ее в нужную ячейку внешней памяти.
                                Примерно так:
                                ExpandedWrap disabled
                                      MOV   A,#XX    ;где ХХ это необходимая байтовая константа
                                      MOVX  @DPTR,A  ;загружаем этот байт во внешнюю память по необходимому адресу.
                                      INC   DPTR     ;увеличиваем указатель на элемент массива
                                Недостаток - весьма большой объем программного кода.

                                2. При помощи директивы DB ты заносишь в участок памяти программ свой массив. Далее, в цикле ты извлекаешь из памяти программ байты этого массива в аккумулятор и заносишь их во внешнюю память данных.
                                Примерно так:
                                ExpandedWrap disabled
                                  NABLE    DB   #02
                                           DB   #04
                                           DB   #FF   ;Это твои данные, которые должны находится в массиве при первоначальной инициализации
                                  ............
                                  ............
                                  ............
                                  ; где то в программе в секции начальной инициализации
                                           MOV   DPTR,NABLE   ;Инициализируем указатель началом массива
                                           XRL   A,A          ;обнуляем аккумулятор
                                           MOV   R0,DPL       ;Сохраняем младшую часть указателя в РОН
                                           MOV   R1,DPH       ;Сохраняем старшую часть указателя в РОН
                                           MOV   R2,A         ;Сохраняем смещение относительно начала массива
                                           MOV   DPTR,#XXXX   ;загружаем адрес начала массива во внешней памяти данных
                                           MOV   R3,DPL       ;Сохраняем младшую часть указателя в РОН
                                           MOV   R4,DPH       ;Сохраняем старшую часть указателя в РОН
                                  ;Далее простой расчет - у тебя количество элементов 1500, регистр может максимум 256 отсчетов, ;следовательно 1500/256 = 5. Т.е. Один регистр совершит полный оборот в цикле от нуля до нуля, а ;второй ;просчитает эти циклы. Т.е. получим 256*5 = 1280 элементов мы инициализируем за это цикл. Для оставшихся ;220 сделаем еще один, но с одним счетчиком, в который будет загружено значение 220 = DC        
                                           XRL   R5,R5         ;Обнуляем внутренний счетчик циклов
                                           MOV   R6,05         ;Загружаем внешний
                                  ;Ну и собственно сам цикл инициализации:
                                  CIKLE    MOV   DPL,R0       ;Восстанавливаем младшую часть указателя
                                           MOV   DPH,R1       ;Восстанавливаем старшую часть указателя
                                           MOV   A,R2         ;Восстанавливаем смещение относительно начала массива
                                           MOVC  A,@A+DPTR    ;Вытаскиваем из памяти программ байт для массива
                                           MOV   DPL,R3       ;Восстанавливаем младшую часть указателя на внешнюю память
                                           MOV   DPH,R4       ;Восстанавливаем старшую часть указателя на внешнюю память
                                           MOVX  @DPTR,A      ;Заносим байт во внешнюю память данных
                                           INC   DPTR         ;Увеличиваем указатель на внешнюю память программ
                                           MOV   R3,DPL       ;Сохраняем младшую часть указателя в РОН
                                           MOV   R4,DPH       ;Сохраняем старшую часть указателя в РОН
                                           INC   R2           ;Увеличиваем указатель на массив
                                           DJNZ  R5,CIKLE     ;Закрываем внутренний цикл
                                  ;По окончании внутреннего цикла необходимо снова переинициализировать указатели на память программ, скорректировав указатель DPTR на 256 байт, которые мы уже извлекли из памяти программ.
                                           MOV   DPH,R1       ;Восстанавливаем старшую часть указателя
                                           INC   DPH
                                           MOV   R1,DPH       ;Сохраняем старшую часть указателя в РОН
                                  ;Увеличение на 1 старшей части и даст нам в итоге 100, т.е +256.
                                           XRL   R2,R2        ;Обнуляем смещение относительно начала блока
                                           DJNZ  R6,CIRLE     ;И заряжаем следующую итерацию на 256 байт.

                                Как то так. Таким образом ты проинициализируешь свой массив данных, расположенный во внешней памяти данных, значениями, которые ты занесешь в ПЗУ контроллера при прошивке его памяти программ. :D
                                  Нет у 51-го команды
                                  ExpandedWrap disabled
                                    XRL REG, REG
                                  Так что
                                  ExpandedWrap disabled
                                    mov R5, #0

                                  Ну и всё можно упихать в один цикл, если аккуратно счётчики инициализировать.

                                  hawk1, вопрос нескромный: внешняя память — она действительно внешняя, или микроконтроллер толстый с большой «внутренней внешней»?
                                  Потому как если она действительно внешняя, висит на портах P2,P0 то можно через MOVX @Ri, A писать в любое место, используя порт P2 как регистр страницы.
                                  И тогда совсем коротко:
                                  ExpandedWrap disabled
                                    INIT_DATA:
                                        DB ...
                                        DB ...
                                     
                                    XRAM_ARRAY_LEN equ 1500
                                     
                                        mov DPTR, #INIT_DATA
                                        mov R0, #low  (XRAM_ARRAY)
                                        mov P2, #high (XRAM_ARRAY)
                                        ; Инициализируем 16-битный счётчик цикла, но хитрым образом
                                        mov R2, #low  (XRAM_ARRAY_LEN)
                                        mov R3, #high (XRAM_ARRAY_LEN+255)
                                     
                                    loop:
                                        clr A
                                        movc    A,@A+DPTR
                                        movx    @R0, A
                                        inc DPTR
                                        inc R0
                                        ; если после инкремента R0 стал 0, то нарастить страницу в порту P2
                                        cjne    R0, #0, no_inc_P2
                                        inc P2
                                    no_inc_P2:
                                        djnz R2, loop
                                        djnz R3, loop
                                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                  0 пользователей:


                                  Рейтинг@Mail.ru
                                  [ Script execution time: 0,0678 ]   [ 15 queries used ]   [ Generated: 3.05.24, 02:49 GMT ]