Справочник по программировани BASCOM-8051 (М.Л. Кулиш, 2001). Справочник по программированию bascom8051 Краснодар 2001
Скачать 6.61 Mb.
|
===================================== Справочник по программированию «Bascom-8051» == Временные диаграммы, формируемые операторами последовательного ввода Оператор Временная диаграмма Скорость Shiftin, mode 0 ___ ____ ____ ____ ____ ____ ___X____X____X____X____X____ In_Data msb __ _ _ _ _ __ lsb |__| |__| |__| |__| |__| Clk Пиковая 100 Кбод, средняя 80 Кбод Shiftin, mode 1 ___ ____ ____ ____ ____ ____ ___X____X____X____X____X____ In_Data msb __ __ __ __ __ lsb __| |_| |_| |_| |_| |__ Clk Пиковая 100 Кбод, средняя 80 Кбод Shiftin, mode 2 ___ ____ ____ ____ ____ ____ ___X____X____X____X____X____ In_Data lsb __ _ _ _ _ __ msb |__| |__| |__| |__| |__| Clk Пиковая 100 Кбод, средняя 80 Кбод Shiftin, mode 3 ___ ____ ____ ____ ____ ____ ___X____X____X____X____X____ In_Data lsb __ __ __ __ __ msb __| |_| |_| |_| |_| |__ Clk Пиковая 100 Кбод, средняя 80 Кбод Shiftin, mode 4 ___ _____ _____ _____ _____ __ ___X_____X_____X_____X_____X__ Out_Data msb _ _ _ _ lsb _____| |___| |___| |___| |____ Clk External До 100 Кбод, средняя 80 Кбод Shiftin, mode 5 ___ _____ _____ _____ _____ __ ___X_____X_____X_____X_____X__ Out_Data msb_____ ___ ___ ___ ____ lsb |_| |_| |_| |_| Clk External До 100 Кбод, средняя 80 Кбод Shiftin, mode 6 ___ _____ _____ _____ _____ __ ___X_____X_____X_____X_____X__ Out_Data lsb _ _ _ _ msb _____| |___| |___| |___| |____ Clk External До 100 Кбод, средняя 80 Кбод Shiftin, mode 7 ___ _____ _____ _____ _____ __ ___X_____X_____X_____X_____X__ Out_Data lsb_____ ___ ___ ___ ____ msb |_| |_| |_| |_| Clk External До 100 Кбод, средняя 80 Кбод Bascom предлагает также операторы Spiin и Spiout, обеспечивающих подключение устройств с последовательным SPI-интерфейсом. Эти операторы реализуют интерфейс программно и в несколько упрощенном виде (не обеспечивается одновременный вывод и ввод соттветственно). По сути, это те же операторы Shiftin и Shiftout, работающие в режиме 1, но только с добавлением сигнала “выбора кристалла”. Тем не менее, операторами Spiin и Spiout можно успешно пользоваться во многих случаях, т.к. большинство периферийных микросхем используют именно такой режим. Ниже в таблице представлены упрощенные (и укороченные) временные диаграммы на линиях интерфейса при работе операторов Spiin и Spiout. ============================================================================= 22-2 ===================================== Справочник по программированию «Bascom-8051» == Оператор Временная диаграмма Скорость при 12 МГц Spiout _ _ |__________________________| CS ___ _____ _____ _____ _____ __ ___X_____X_____X_____X_____X__ Out_Data msb _ _ _ _ lsb _____| |___| |___| |___| |____ Clk Пиковая 100 Кбод, средняя 80 Кбод Spiin _ __ |_________________________| CS ___ ____ ____ ____ ____ ____ ___X____X____X____X____X____ In_Data msb __ __ __ __ __ lsb __| |_| |_| |_| |_| |__ Clk Пиковая 100 Кбод, средняя 80 Кбод Далее приведены примеры ассемблерного кода, выдаваемого компилятором, при использовании операторов последовательного ввода вывода. Обращаем внимание, что операторы Spiin и Spiout оформлены в виде подпрограмм. Операторы Shftin и Shiftout просто вставляются в исполняемый код, что при многократном их использовании дает соответствующее увеличениие размера получаемого кода. Если размер кода является критичным, а операторы Shftin и Shiftout применяются неоднократно, то рекомендуется встраивать их в специально созданные подпрограммы. ;оператор SPIOUT ;при входе указывают: R0-данные, R7-число байт ;F0=0 - из внутренней памяти, F0=1 - из внешней Spiout: CLR P1.2 ;сигнал выбор кристалла Spio1: ACALL Rdda ;считать байт MOV R2,#08H ;число бит Spio2: RLC A ;выдвинуть старший бит MOV P1.1,C ;в порт вывода SETB P1.3 ;сформировать импульс NOP CLR P1.3 DJNZ R2,Spio2 ;повторить восемь раз ACALL Incinx ;инкремент указателя DJNZ R7,Spio1;повторять, пока все байты не выдвинуты SETB P1.2 ;снять сигнал выбора кристалла RET ;считывание данных Rdda: JB F0,Rda1 MOV A,@R0 RET Rda1: MOVX A,@DPTR RET ;запись данных Wrda: JB F0,Wrd1 MOV @R0,A RET Wrd1: MOVX @DPTR,A RET ;инкремент указателя Incinx: JB F0,Iinx1 ============================================================================= 22-3 ===================================== Справочник по программированию «Bascom-8051» == INC R0 RET Iinx1: INC DPTR RET ;----------------------------- ;оператор SHIFTOUT в режиме 1 Shiftout1: CLR P1.3 ;исходное состояние линии Clk MOV R0,#Dat ;адрес данных MOV R2,#01H ;число байт Sho1_1: MOV A,@R0 MOV R3,#08H Sho1_2: RLC A MOV P1.0,C SETB P1.3 NOP NOP CLR P1.3 NOP NOP DJNZ R3,Sho1_1 DEC R0 DJNZ R2,Sho1_2 ;----------------------------- ;оператор SHIFTIN в режиме 0 Shiftin0: SETB P1.1 MOV R0,#34H MOV R2,#02H INC R0 Shi0_1: MOV R3,#08H Shi0_2: CLR P1.1 NOP NOP MOV C,P1.2 RLC A SETB P1.1 NOP NOP DJNZ R3,Shi0_2 MOV @R0,A DEC R0 DJNZ R2,Shi0_1: ;----------------------------- ;оператор SHIFTIN в режиме 1 Shiftin1: CLR P1.1 MOV R0,#34H MOV R2,#02H INC R0 Shi1_1: MOV R3,#08H Shi1_2: SETB P1.1 NOP NOP MOV C,P1.2 RLC A ============================================================================= 22-4 ===================================== Справочник по программированию «Bascom-8051» == CLR P1.1 NOP NOP DJNZ R3,Shi1_2 MOV @R0,A DEC R0 DJNZ R2,Shi1_1 ;----------------------------- Мы видим, что описанные операторы Bascom не обеспечивают предельно возможную (для процессора 8051) скорость приема и передачи, хотя сегодня, уже трудно представить реальные периферийные устройства, все еще требующие такую низкую скорость. Это сделано намеренно и, как увидим дальше, совершенно правильно, чтобы иметь возможность программно принимать выдвигаемые данные (смотри режим 4 оператора Shiftin), а также передавать данные через оптроны, которые обычно дают задержку от 1 до 10 мкс. Таким образом, принятая скорость передачи является компромиссной и удовлетворяющей наибольшее число пользователей. Для ускорения процесса приема или передачи можно использовать собственные программы, например, такие как, примененные для записи и считывания данных, в программе тестирования АЦП типа AD7711A (смотри выше). Еще быстрее работает программа считывания или записи данных, использующая в качестве линии передачи (и приема) данных порт P0.0, а порты P3.6 и P3.7 соответственно как линии синхронизации при записи и считывании данных. Ниже представлен пример программы записи данных, в которой импульс синхронизации формируется аппаратно применением команды MOVX. Mov A , Data ;загрузим аккумулятор Rl A ;начиная со старшего разряда Movx @DPTR , A ;передадим один бит из аккумулятора Rl A ;повторим восемь раз Movx @DPTR , A Rl A Movx @DPTR , A Rl A Movx @DPTR , A Rl A Movx @DPTR , A Rl A Movx @DPTR , A Rl A Movx @DPTR , A Rl A Movx @DPTR , A Еще быстрее (Fкв / 12) можно записывать или считывать данные, используя аппаратный универсальный последовательный интерфейс микроконтроллера, включенный в режиме 3, но при этом занимаются линии P3.0 и P3.1, что часто недопустимо. Если применять модель процессора AT89S8252, имеющего полноценный многорежимный аппаратный SPI-интерфейс, то можно будет работать с максимальной скоростью Fкв / 4. Bascom не поддерживает своими специальными операторами все эти режимы, поэтому чтобы воспользоваться ими, нужно применять обычные операторы загрузки и чтения регистров процессора. ============================================================================= 22-5 ===================================== Справочник по программированию «Bascom-8051» == 23. Вычисления и преобразования чисел Bascom позволяет производить арифметические вычисления (сложение, вычитание, умножение и деле- ние) над целыми числами (одно-, двух и четырехбайтными) и числами в формате с плавающей точкой. В следую- щей таблице показано расположение байтов переменных в памяти. Расположение в памяти Тип переменной Первый байт (Adr*) Второй байт (Adr+1) Третий байт (Adr+2) Четвертый байт (Adr+3) Однобайтовая пе- ременная (Byte) Байт - - - Двухбайтовая (Word, Integer) Младший байт Старший байт - - Четырехбайтовая (Long) 1-й байт (младший) 2-й байт 3-байт 4-й байт (старший) 1-й байт (младший) 2-й байт 3-байт (старший) Знак В формате с пла- вающей точкой (Single)_ Нормализованная мантасса, принимающая значения от 1 до 2, старший бит мантиссы отбрасывается (только подразумевает- ся наличие всегда равного 1). Примеры кода 00 00 80 3F = 1 чисел в порядке, 00 00 00 40 = 2 расположения в 00 00 80 40 = 4 памяти 00 00 00 41 = 8 00 00 80 41 = 16 00 00 00 42 = 32 00 00 80 42 = 64 00 00 00 43 = 128 00 00 20 C1 = -10 00 00 20 C0 = -2.5 Байт порядка. Вычисляется как 127+p, где p- порядок из вы- ражния: 2^p + Мантисса 0 - плюс 1 - ми- нус * Adr – адрес переменной определенный при компиляции Bascom с целыми двухбайтными числами может выполнять знаковые (с переменными типа Integer и Long) и беззнаковые (с переменными типа Byte и Word) арифметические операции. Арифметические операции с четырехбайтными числами всегда производятся с учетом знака. При целочисленных вычислениях длина результа- та, не может превышать длины исходных числовых переменных. Даже при умножении 8-разрядных чисел резуль- тат будет тоже 8-разрядным. Аналогично для 16-разрядных и 32-разрядных чисел. Смешанные произведения дают результат, равный по длине, более длинной переменной. Главная неприятность этой особенности компилятора заключается в том, что при переполнении (возможном при сложении и особенно умножении) теряются старшие разряды. Эта ошибка не показывается компилятором потому, что считается ошибкой программиста. Чтобы этого не происходило, сложение и умножение при наличии вероятности переполнения нужно выполнять с использова- нием переменных двойной длины, а это значительно увеличивает время операции, или применять быструю ас- семблерную программу с собственной программой сложения и умножения. Ниже приведена одна такая програм- ма. Компилятор может производить много вариантов преобразования чисел в явном (с помощью специаль- ных операторов) или в неявном виде (при выполнении других операции). Преобразование в неявном виде проис- ходит при перезаписи данных или при вычислении значения операндов разного типа. Причем, если преобразова- ние производится при считывании исходных значений (до выполнения назначенной операции), вероятность ошибки невелика, т.к. компилятор выбирает подпрограмму обработки, в зависимости от типа исходных перемен- ных. Если запись результата назначена в регистр, отличающийся по типу, от переменных, применяемых при вы- числениях, то ошибка неизбежна, т.к. компилятор использует имя переменной-приемника уже механически. При наличии ошибки несоответствия длины результата и размера переменной, куда помещается результат, последняя может быть заполнена не полностью или, еще хуже, перекрыта по длине. Эти ошибки также не выявляются и не показываются компилятором. Ошибки подобного рода исключены, при выполнении специальных операций пре- образования, когда компилятор проверяет размерность переменной - приемника данных; Ниже приведена программа, в которой имеются примеры вычисления и преобразования чисел, выполняе- мые компилятором Bascom. '---------------------------------------------------- ============================================================================= 23-1 ===================================== Справочник по программированию «Bascom-8051» == ' Преобразование числовых переменных и вычисления '---------------------------------------------------- $large Dim Cnt As Const 5 'число 5 Dim Bt As Bit 'определим по паре переменных всех типов Dim Byt As Byte , Byt1 As Byte Dim Wrd As Word , Wrd1 As Word Dim Intg As Integer , Intg1 As Integer Dim Lng As Long , Lng1 As Long Dim Sng As Single , Sng1 As Single '---------------------------------------------------- Set Bt 'установить бит '---------------------------------------------------- 'преобразование переменных Byt = Bt 'значение бита помещается в младший разряд Byt = Cnt 'записать число (константу) Wrd = Byt 'в младший байт данные, в старший байт 00 Intg = Wrd 'переместить данные без изменений Intg = Not Intg 'инвертировать Wrd = Intg 'обратно без изменений Sng = Wrd : Print Sng 'преобразовать в плавающую Sng = 65550.0 Sng = Intg : Print Sng 'преобразовать в плавающую Sng = -6.0 '---------------------------------------------------- 'целочисленные вычисления Intg = Intg * 5 : Print Intg 'результат Intg = -30 Intg = Intg / 5 : Print Intg 'рузультат Intg = -6 Intg1 = 1000 Intg = Intg1 / Intg : Print Intg'результат Intg = -166 Intg = Intg * -1 'смена знака. Это медленный вариант Intg = Not Intg : Intg = Intg + 1 'аналогично, но работает намного быстрее Intg = Not Intg : Incr Intg 'тоже работает быстро Lng = Intg 'чтобы получить 32-разр. результат умножения, Lng = Lng * Intg 'хотя бы один из операндов должен быть 32-разр. Lng = 1000000 : Lng = Not Lng 'инверсия для смены знака Incr Lng '-1000001 + 1 = -1000000 Print Lng 'результат Lng = -1000000 Lng = Lng / 1000 'деление на константу Print Lng 'результат Lng = -1000 Wrd = Lng / 1000 'так неправильно, хотя компилятор ошибку не покажет Lng = Lng / 1000 : Wrd = Lng 'а это правильно Intg1 = -10 Lng = Lng / Intg1 'деление на переменную другой размерности Print Lng 'результат Lng = 100 '---------------------------------------------------- 'вычисление с плав. точкой Sng = Sng * Lng 'умножение целого числа на плавающее Print Sng 'результата Sng = -600.0 Sng1 = 0.15 : Sng = Sng * Sng1 'умножение плавающих чисел Print Sng 'результата Sng = -90.0 Sng = Sng / -10 'деление на константу Print Sng 'результата Sng = 9.0 $asm Xrl {Sng+3} , #&h80 'мгновенная смена знака числа с плав. точкой Anl {Sng+3} , #&h7f 'или установка положительной полярности Prl {Sng+3} , #&h80 'или установка отрицательной полярности $end asm '---------------------------------------------------- 'демонстрация неправильного умножения Byt = 10 : Byt1 = 15 : Wrd = &H1234 'назначим числа Wrd = Byt * Byt1 'произведение сразу запишем в двухбайтное число Printhex Wrd 'результат Wrd = 1296h - только в младших разрядах Byt = Byt * Byt1 'проделываем это же иначе, а затем Wrd = Byt 'переписываем с очисткой старших разрядов ============================================================================= 23-2 ===================================== Справочник по программированию «Bascom-8051» == Byt1 = Wrd 'обратно берутся только младшие разряды и Print Byt ; " " ; Byt1 ; " " ; Wrd 'теперь результат везде одинаков = 150 '---------------------------------------------------- ' определим время исполнения арифметических операций Byt = 50 : Byt1 = 10 'назначим числа Byt = Byt + Byt1 'сложение - 11 тактов Byt = 50 : Byt1 = 10 ' числа Byt = Byt - Byt1 'вычитание - 12 тактов Byt = 20 : Byt1 = 10 ' числа Byt = Byt * Byt1 'умножние - 10 тактов Byt = 50 : Byt1 = 10 ' числа Byt = Byt / Byt1 'деление - 10 тактов '---------------------------------------------------- Wrd = 500 : Wrd1 = 100 ' числа Wrd = Wrd + Wrd1 'сложение - 20 тактов Wrd = 500 : Wrd1 = 100 ' числа Wrd = Wrd - Wrd1 'вычитание - 21 такт Wrd = 200 : Wrd1 = 100 ' числа Wrd = Wrd * Wrd1 'умножние - 63 такта Wrd = 500 : Wrd1 = 100 ' числа Wrd = Wrd / Wrd1 'деление - 560 тактов '---------------------------------------------------- Intg = 500 : Intg1 = -100 ' числа Intg = Intg + Intg1 'сложение - 20 тактов Intg = 500 : Intg1 = -100 ' числа Intg = Intg - Intg1 'вычитание - 21 тактов Intg = 200 : Intg1 = -100 ' числа Intg = Intg * Intg1 'умножние - 95 тактов Intg = 500 : Intg1 = -100 ' числа Intg = Intg / Intg1 'деление - 620 тактов '---------------------------------------------------- Lng = -5000 : Lng1 = 1000 ' числа Lng = Lng + Lng1 'сложение - 74 такта Lng = -5000 : Lng1 = 1000 ' числа Lng = Lng - Lng1 'вычитание - 74 такта Lng = -2000 : Lng1 = 1000 ' числа Lng = Lng * Lng1 'умножние - 2500 тактов Lng = -5000 : Lng1 = 1000 ' числа Lng = Lng / Lng1 'деление - 3200 тактов '---------------------------------------------------- Sng = 50 : Sng1 = 10 ' числа Sng = Sng + Sng1 'сложение - 240 тактов Sng = 50 : Sng1 = 10 ' числа Sng = Sng - Sng1 'вычитание - 290 тактов Sng = 20 : Sng1 = 10 ' числа Sng = Sng * Sng1 'умножение - 2000 тактов Sng = 50 : Sng1 = 10 ' числа Sng = Sng / Sng1 'деление - 2300 тактов '---------------------------------------------------- 'определим время исполнения преобразований Byt = 100 : Sng = Byt 'байт в плавающую - 490 тактов 'обратно преобразования не производится Wrd = 10000 : Sng = Wrd 'слово в плавающую -370 тактов Wrd = Sng 'обратно -340 тактов Intg = -1000 : Sng = Intg 'знаковое слово в плав. - 470 тактов Intg = Sng 'обратно - 420 тактов Lng = 1000000 : Sng = Lng 'двойное слово в плав. - 280 тактов Lng = Sng 'обратно - 250 тактов '---------------------------------------------------- End В демонстрационной программе имеются ответы почти на все вопросы применения операций преобразова- ния и использования в вычислениях числовых переменных. Нужно заметить, что измеренные значения произво- дительности операций вычисления и преобразования приблизительны, т.к. зависят от значения преобразуемого ============================================================================= 23-3 |