Продолжение. Начало в № в'2006
Алексей КУЗЬМИНОВ
compmicrosys@mail.ru
Современные программные средства связи
микроконтроллера с компьютером по интерфейсу RS-232
2.2. Подпрограммы передачи и приема байта для компьютера и микроконтроллера, использующие логику нового алгоритма обмена Ниже приведены подпрограммы приема и передачи байта, составленные в соответствии с логикой работы ранее изложенного алгоритма обмена и временной диаграммой, приведенной на рис. 1 (см. КиТ № 7'2006).
Подпрограммы для компьютера приведены на языке Кларион для DOS (Clarion v.3.101, Clarion Software Inc.), а для микроконтроллера — на двух языках: ассемблере (8051 Macro Assembler v.4.02a, 2500 A.D. Software Inc., 1985) и Си (C51, Keil Software Inc. v.6.14.).
Подпрограммы на Clarion v.3.101 имеют следующий вид:
! П/п ввода байта (байт в M1[i] )
INBYTE routine
out(3fbh,Y47h) !Установка TxD !(разрешение передачи)
loop; in(3feh,B); if band(B,2) then break.. Южидание старт-бита !(уст-ки DSR)
do DEL20 !Задержка 20 мкс
out(3fbh,Y07h) !Сброс линии TxD !(запрет передачи)
in(3feh,B) Ючистка регистра 3feh !чтением
loop;in(3fdh,B);if band(B,1) then break.. Южидание конца !прихода байта (бит !«DR»- data ready)
in(3f8h,M1[i]) !Чтение байта данных
! П/п вывода байта (байт в M[i] )
OUTBYTE routine
loop;in(3fdh,B);if band(B,20h);break.. передатчика (transmitter empty). !Ожидание готовности
loop;in(3feh,B);if band(B,20h);break.. Южидание разреш. !передачи (установки DSR)
out(3f8h,M[i]) !Вывод байта
loop;in(3feh,B);if band(B,2);break.. !Ожидание запрета !передачи (сброса DSR)
loop;in(3fdh,B);if band(B,40h);break.. !Ожидание выхода !байта из РС (OK to send).
in(3feh,B) !Очистка регистра 3feh !чтением
Подпрограммы на Си имеют следующий вид. //
// П/ п вывода байта
//-------------------
void outbyte(unsigned char byte) {
while (RXD); // Ожидание разрешения на передачу байта // (от компьютера).
SBUF=byte; // Вывод байта.
while (!RXD); // Ожидание запрета на передачу
// (от компьютера). while (!TI); // Ожидание окончания вывода байта
// микроконтроллером.
TI = 0; // Сброс флага передачи (TI).
}
//------------------------
// П/п ввода байта
//--------
unsigned char inbyte() { unsigned char byte;
TXD=0;
while (RXD); DEL10();
TXD=1;
while(!RI);
byte=SBUF; RI = 0; return(byte);
}
//-------------
// Установка разрешения компьютеру передавать // байт.
// Ожидание старт-бита.
// Задержка длительностью полбайта // (115 200 бод).
// Запрет компьютеру передавать байт.
// Ожидание окончания прихода байта // в микроконтроллер.
// Ввод байта в микроконтроллер.
// Сброс флага приема байта (Ю).
На ассемблере представлены макросы ввода и вывода байта. В связи с тем, что в макросах (макроассемблера 8051 Macro Assembler v.4.02a, 2500 A.D. Software Inc., 1985) запрещено использовать комментарии на русском языке, они приведены на английском. Надеемся, это не вызовет особых затруднений у читателя, поскольку их перевод содержится в вышеприведенных подпрограммах на Кларионе и Си. Макросы на ассемблере приведены ниже.
В качестве микроконтроллера взят один из современных — MSC1210Y5. Этот 4-тактный микроконтроллер занимает промежуточное положение по быстродействию между достаточно скоростными (1-тактными) микроконтроллерами, такими как АЭиС847, С8051Ю67/330Б, 2-тактными, например, Р89ЬРС938, средне-
скоростным 6-тактным — АТ89С51ЕБ2 и стандартным 12-тактным, например, AT89S8252. Для микроконтроллера MSC1210 выбранная 10-микросекундная задержка, с учетом времени его реакции на начало передачи Трн (рис. 1), переключает его линию ТхЭ (т. е. ИхБ компьютера) приблизительно между 4 и 5 битом, т. е. примерно в «середине» принимаемого байта.
При использовании более высокоскоростного микроконтроллера, чем MSC1210, задержку можно немного увеличить (в компьютере, например (см. подпрограмму на Кларионе), установлена задержка в 20 мкс), в противном случае — уменьшить. Необходимо только помнить, что точное значение задержки не так уж и важно. Главное условие, чтобы переключение линии ИхБ с низкого уровня в высокий (рис. 1) осуществлялось не ранее чем спустя 1-2 бита (по времени) после начала старт-бита (чтобы на такой короткий импульс среагировал преобразователь интерфейса), но и не позже чем за 1-2 бита до начала стоп-бита (чтобы передатчик «поймал» запрет передачи).
2.3. Тестовые программы обмена информацией между микроконтроллером и компьютером по интерфейсу Я8-232, использующие логику нового алгоритма
2.3.1. Общие положения Ниже будут приведены реально работающие программы, написанные на языке С51 (для некоторых микроконтроллеров будут приведены программы и на ассемблере — для интересующихся) для микроконтроллеров MSC1210 и Р89ЬРС938/904, и программа для компьютера, написанная на языке С1апоп у.3.101 и работающая в операционной системе БОЯ Для микроконтроллеров АЭиС834/845, АТ89С51ЕБ2/ ИБ2 и С8051Ю67/Р330Б программы будут аналогичные, за исключением инициализации интерфейса Р5-232. Что касается программ для компьютера, работающих в ОС ”^п'98/ХР, то они будут приведены несколько позже, поскольку, с одной стороны, в программах для ОС Win'98/XP за основу будет взята именно программа для DOS, с другой — прежде чем приводить программы для Win'98/XP, необходимо будет объяснить предварительные положения и соображения, без уяснения которых,
; Макрос ввода байта
INBYTE .macro
clr TxD Enable transfer
jb RxD,$ Waiting start-bit
call DEL10 Call delay 10 mks
setb TxD Disable transfer
jnb ri,$ Waiting set flag ri
mov a,sbuf Input byte from buffer
clr ri Clear flag ri
.endm
; Макрос вывода байта
OUTBYTE .macro
jb RxD,$ Waiting enable transfer
mov sbuf,a Output byte in buffer
jnb RxD,$ Waiting disable transfer.WARNING!!!
jnb ti,$ Waiting output last bit (flag ti)
clr ti Clear flag ti
.endm
по мнению автора, понять некоторые моменты программирования в ОС Win'98/XP будет непросто.
Хотя программы для микроконтроллеров и снабжены комментариями, все же автор счел нужным привести краткие пояснения к каждой программе, т. к. в комментариях отражены не все моменты и нюансы работы каждого конкретного микроконтроллера. В основном эти пояснения будут касаться инициализации интерфейса К5-232, таймеров, которые предназначены для генерации скорости обмена, и некоторых других особенностей представляемых микроконтроллеров.
2.3.2. Тестовая программа обмена для микроконтроллера MSC1210 Ниже приведены две тестовых программы для микроконтроллера MSC1210. Первая на Си, вторая — на ассемблере. Программы функционируют при условии сопряжения микроконтроллера MSC1210 с компьютером по схеме рис. 9 и рис. 17 (КиТ № 4’2006 г.). Для функционирования программ совместно с компьютером должна использоваться компьютерная программа, приведенная (далее) в 2.3.4. В качестве генератора скорости обмена используется таймер Т2 и внешний генератор с кварцевым резонатором частотой 11 059 200 Гц. Скорость обмена установлена 115 200 бод.
Программа на Си запоминает принимаемую строку из 75 байт и выводит ее обратно в том же порядке, в котором они поступили в микроконтроллер.
Программа на ассемблере записывает поступившие байты в стек, а затем считывает их оттуда и выводит в компьютер. Поэтому байты выводятся в компьютер в обратном порядке.
Программа на языке Си:
// Программа вывода строки байт для MSC1210,
// скорость обмена 115 200 бод, кварц 11 059 200 Гц.
// см. inrs115.asm
//-------------------------------------------
#include «stdarg.h»
#include «stdio.h» /* для printf */
#include «stdlib.h»
#include «reg1210.h» /* для RS-232 */
//----------------------------------------------------------
// Совмещение «u.l» с «u.bt.lenl» и «u.bt.lenh».
// Переменные u.l (размерностью ushort) и
// u.bt.lenl и u.bt.lenh (обе размерностью byte(unsigned char))
// перераспределяют одно и то же место в памяти микроконтроллера. // Порядок расположения переменных lenh (первая) и lenl (вторая) // в структуре (struct) строго определен и при его нарушении // вся конструкция совмещения не работает!!!
//----------------------------------------------------------
union{
unsigned short l; // Длина сгроки^щ.!»).
struct{
unsigned char lenh; // Ст.байт длины строки(«u.bt.lenh»).
unsigned char lenl; // Мл.байт длины строки(«u.bt.lenl»).
}bt;
unsigned char c,j,a[80]; unsigned short temp_L;
void DEL10(void) { for (j=0;j<10;j++);
}
void initrs(void) { SC0N=0xec;
//Переменная для временного(temp) //хранения длины строки.
// Инициализация // интерфейса
T2CON=Ox34;
RCAP2=-3;
THL2=-3;
// RS-232.
//Уобм.=115200 бод.
RCAP2=-36; //Уобм.=9600 бод. THL2=-36;
void outbyte(unsigned char byte) {
while (RXD);
SBUF=byte; while (!RXD);
while (!TI);
TI = 0;
}
// Ожидание разрешения на передачу // байта (от компьютера).
// Вывод байта.
// Ожидание запрета на передачу // (от компьютера).
// Ожидание окончания вывода // байта микроконтроллером.
// Сброс флага передачи (ТІ).
unsigned char inbyte() { unsigned char byte; TXD=0;
while (RXD);
DEL10();
TXD=1;
while(!RI);
byte=SBUF;
RI = 0; return(byte);
}
// Установка разрешения // компьютеру передавать байт.
// Ожидание старт-бита.
// Задержка длительностью полбайта // (115 200 бод).
// Запрет компьютеру передавать байт. // Ожидание окончания прихода // байта в микроконтроллер.
// Ввод байта в микроконтроллер.
// Сброс флага приема байта (Ю).
/**************************************************/ void main(void)
{
initrs();
P3DDRL=OxO7;
REN=1;
CKCON = 0x03;
START:
u.bt.lenl=inbyte(); u.bt.lenh=inbyte(); temp_L=u.l;
// Установка на прием.
// MOVX=12 cycle stretch(1 мкс).
//Прием мл. байта длины строки. //Прием ст. байта длины строки. //Запоминание длины строки //в переменной temp_L. //Переменная и.1-длина строки (и&оЛ) //заполняется автоматически после //заполнения переменных //и.Ы.1еп1 и и.Ы.1епЪ
for(u.l=0;u.l<temp_L;u.l++){ //Прием из компьютера
a[u.l]=inbyte();
}
REN=0;
//очередного //байта строки.
//Изменение и.1 (например, и.1++) //влечет за собой автоматическое //и соответственное изменение //и.Ы.1еп1 и u.bt.1enh.
//Если и.1 — адрес памяти,
//то и.Ы.1еп1 и u.bt.1enh -//соответственно младший //и старший байты этого адреса.
//Установка Я5-232 на передачу.
for(u.l=0;u.l<temp_L;u.l++){ //Передача в компьютер outbyte(a[u.l]); //очередного
} //байта строки.
REN=1;
//Установка RS-232 на прием.
c=inbyte(); //Если принятый символ=>:
if (c==0x40) goto START; //то продолжение работы, E: //иначе — конец.
goto E;
}
Программа на языке Ассемблер:
Программа приема MK строки символов по RS-232 (с передачей длины строки) и вывода символов из МК в компьютер.
Fra=11 059 200 Гц. Скорость обмена — 115 200 и 9600 бод. Синхронизация — с помощью линий TxD и RxD.
Для проверки использовать программы HELLO.EXE(CLA).
;Макрос ввода байта
; В МАКРОСАХ НЕЛЬЗЯ ИСПОЛЬЗОВАТЬ РУССКИЙ ЯЗЫК ВКОММЕНТАРИЯХ!!!
; Алгоритм ввода байта
clr TxD Enable transfer
jb RxD,$ Waiting start-bit
call DEL10 Call delay 10 mks
setb TxD Disable transfer
jnb ri,$ Waiting set flag ri
mov a,sbuf Input byte from buffer
clr ri Clear flag ri
.endm
Алгоритм вывода байта
OUTBYTE .macro
jb RxD,$ ;Waiting enable transfer
mov sbuf,a ;Output byte in buffer
jnb RxD,$ Waiting disable transfer.WARNING!
jnb ti,$ ;Waiting output last bit (flag ti)
clr ti ;Clear flag ti
.endm
.data
Переменные
T2CON equ 0c8h
RCAP2H equ 0cbh
RCAP2L equ 0cah
CKCON equ 08eh
USEC equ 0fbh
PDCON equ 0f1h
ACLK equ 0f6h
PASEL equ 0f2h
P3DDRL equ 0b3h
.code
.org 0000h ;Вектор прерывания по RST jmp MAIN
.org 0003h ;Вектор прерывания по INTO Reti
.org 001bh ;Вектор прерывания по TF1 Reti
.org 0053h ;Вектор прерывания от TIC Reti
Основная программа
.org 0060h mov sp,#20h
MAIN:
Инициал. посл. порта
mov SCON,#11101100b
8 бит,2 стопа,REN=0(запрет приема ReciveENable=0),
TI=0,RI=0,Vобм определяется Т1 или Т2, ;SM1=SM2=1 режим 3. RB8=TB8=1.
Инициализация таймерa T2 — как таймера.
mov T2CON,#00110100b
TF2=0,EXF2=0,RCLK=1,TCLK=1,]
EXEN2=0,
TR2=1-start,CNT2=0,CAP2=0.
mov RCAP2H,#0ffh
Fобм.=Freq/(32*(65536-
(RCAP2H,RCAP2L)))
65536-RCAP2H,
RCAP2L=65536-65533=3 (253=fch)
mov RCAP2L,#-3 ;mov RCAP2L,#-6 ;mov RCAP2L,#-2 ;mov RCAP2L,#-1 ;mov RCAP2L,#-36
;mov RCAP2L,#-12
Fобм.= 11059200/(32*3)=115200 бод. Fобм.=22118400/(32*6)=115200 бод. Fобм.= 7372800/(32*2)=115200 бод. Fобм.= 3686400/(32*1)=115200 бод. 65536-RCAP2H,RCAP2L=65536-(65536,(256-36))=36 Fобм.= 11059200/(32*36)=9600 бод. Fобм.= 3686400/(32*12)=9600 бод.
mov PC0N,#80h mov CKC0N,#20h mov P3DDRL,#07h
Ввод байт по посл. Порту
setb REN mov dptr,# INBYTE mov r0,a INBYTE mov r1,a
;Разрешение приема.
; Мл. байт длины
; Ст. байт длины
spin: INBYTE ; Байт в a
push a
inc dptr mov a,r1 cjne a,dph,spin mov a,r0 cjne a,dpl,spin
; Вывод байт по посл. порту
clr REN ;Запрет приема.
spout: pop a
OUTBYTE
djnz r0,spout
; Ввод команды продолжения работы
setb REN ;Разрешение приема.
IB: INBYTE
cjne a,#40h,E
jmp START
E: mov 0f2h,#0
jmp $
DEL10: mov b,#10
djnz b,$
ret
.end
2.3.3. Тестовые программы обмена для
микроконтроллеров P89LPC938/904
Ниже приведены две тестовых программы на Си для микроконтроллеров P89LPC938 и P89LPC904 и одна программа на ассемблере для P89LPC904. Программы функционируют при условии сопряжения микроконтроллеров с компьютером по схемам рис. 12, рис. 13, рис. 14 и рис. 17 (КиТ № 4’2006 г.). Для функционирования программ совместно с компьютером должна использоваться компьютерная программа, приведенная в 2.3.4.
В качестве генератора скорости обмена используется внутренний генератор скорости обмена (Baud Rate Generator — BRG) с частотой 7 372 800 Гц. Скорость обмена установлена 115 200 бод.
Программы на Си запоминают принимаемую строку из 75 байт и выводят ее обратно в том же порядке, в котором они поступили в микроконтроллер.
Программа на ассемблере записывает поступившие байты в стек, а затем считывает их оттуда и выводит в компьютер. Поэтому байты выводятся в компьютер в обратном порядке.
Программа на языке Си для P89LPC938:
// Программа вывода строки байт для P89LPC938,
// скорость обмена 115 200 бод, кварца нет,
// частота внутреннего генератора 73 72 800 Гц.
// см. inrs115l.asm
//-------------------------------------------
#include «stdarg.h»
#include «stdio.h» /* для printf */
#include «stdlib.h»
#include «reg935.h» /* для RS-232 */
//----------------------------------------------------------
// Совмещение «u.l» с «u.bt.lenl» и «u.bt.lenh».
// Переменные u.l (размерностью ushort) и
// u.bt.lenl и u.bt.lenh (обе размерностью byte(unsigned char))
// перераспределяют одно ито же место впамяти микроконтроллера. // Порядок расположения переменных lenh (первая) и lenl (вторая) // в структуре (struct) строго определен и при его нарушении // вся конструкция совмещения не работает!!!
//----------------------------------------------------------
union{ unsigned short l; struct{
unsigned char lenh; unsigned char lenl; }bt;
// Длина строки^т^»).
// Ст.байт длины строки («u.bt.lenh»). // Мл.байт длины строки («u.bt.lenl»).
unsigned char c,j,a[80]; unsigned short temp_L;
void DEL10(void) { for (j=0;j<10;j++); //10
}
//Переменная для временного(temp) //хранения длины строки.
void initrs(void) { SSTAT=0x00; P1M1=0x02; P1M2=0x01; SC0N=0x40;
BRGC0N=0x00;
BRGR0=0x30;
BRGR1=0x00;
BRGC0N=0x03;
}
//Стандартный 51-совместимый RS-232. //¡Вместе это означает: !
//¡TxD-push/pull_output, RxD-input.! //RI=TI=RB8=TB8=REN=SM2=SM0/ //FE=0, SM1=1:единсгвенный бит=1.
//0x30=48. Vobm=CCLK/[(BRG1 //*256+BRG0)+16] = //7372800/[(0*256+48)+16] = //7372800/64=115200.
//Разрешение SBRGS и BRGEN.
void outbyte(unsigned char byte) {
while (RXD);
SBUF=byte; while (!RXD);
while (!TI);
TI = 0;
}
// Ожидание разрешения
// на передачу байта (от компьютера).
// Вывод байта.
// Ожидание запрета на передачу // (от компьютера).
// Ожидание окончания вывода // байта микроконтроллером.
// Сброс флага передачи (ТІ).
unsigned char inbyte() { unsigned char byte; TXD=0;
while (RXD); DEL10();
TXD=1;
while(!RI);
byte=SBUF; RI = 0; return(byte);
// Установка разрешения компьютеру // передавать байт.
// Ожидание старт-бита.
// Задержка длительностью полбайта // (115 200 бод).
// Запрет компьютеру передавать байт. // Ожидание окончания прихода // байта в микроконтроллер.
// Ввод байта в микроконтроллер.
// Сброс флага приема байта (Ю).
}
void main(void)
initrs();
REN=1;
START:
u.bt.lenl=inbyte();
u.bt.lenh=inbyte();
temp_L=u.l;
// Установка на прием.
//Прием мл. байта длины строки. //Прием ст. байта длины строки. //Запоминание длины строки //в переменной temp_L. //Переменная и.1-длина строки (ushort) //заполняется автоматически после //заполнения переменных //u.bt.1en1 и и.Ы.1епк
for(u.1=0;u.1<temp_L;u.1++){ //Прием из компьютера а[и.1]=тЬу1:е(); //очередного
} //байта строки.
//Изменение и.1 (например, и.1++) //влечет за собой автоматическое //и соответственное изменение //и.Ы.1еп1 и u.bt.1enh.
//Если и.1 — адрес памяти,
//то u.bt.1en1 и u.bt.1enh -//соответственно младший //и старший байты этого адреса.
REN=0;
//Установка RS-232 на передачу.
for(u.l=0;u.l<temp_L;u.l++){ //Передача в компьютер outbyte(a[u.l]); //очередного
} //байта строки.
REN=1;
//Установка RS-232 на прием.
c=inbyte(); //Если принятый символ=»@»,
if (c==0x40) goto START; //то продолжение работы,
E: //иначе — конец.
goto E;
}
//-----------------------------------------
Программа на языке Си для P89LPC904:
// Программа вывода строки байт для P89LPC904,
// скорость обмена 115200 бод, частота внутреннего // генератора 7372800 Гц.
// см. іп^1151.а«т
//------------------------------------------
#mdude «stdarg.h»
#mdude <^&о.Ь>
#inc1ude <^ШіЬ.Ь>
#inc1ude «reg904.h»
/* для printf */ /* для RS-232 */
//----------------------------------------------------------
// Совмещение «u.l» с «u.bt.lenl» и «u.bt.lenh».
// Переменные u.l (размерностью ushort) и
// u.bt.lenl и u.bt.lenh (обе размерностью byte(unsigned char))
// перераспределяют одно и то же место в памяти микроконтроллера. // Порядок расположения переменных lenh (первая) и lenl (вторая) // в структуре (struct) строго определен и при его нарушении // вся конструктция совмещения не работает!!!
//----------------------------------------------------------
union{
unsigned short l; struct{
unsigned char lenh; unsigned char lenl;
}bt;
// Длина строки^т^»).
// Ст.байт длины строки («u.bt.lenh»). // Мл.байт длины строки («u.bt.lenl»).
//--
unsigned char c,j,a[80]; unsigned short temp_L;
void DEL10(void) { for (j=0;j<10;j++); //10
}
//Переменная для временного (temp) //хранения длины строки.
void initrs(void) { SSTAT=0x00;
P1M1=0x02;
P1M2=0x01;
SCON=0x40;
BRGR0=0x30;
BRGR1=0x00;
BRGCON=0x03;
}
//Стандартный 51-совместимый //RS-232.
//¡Вместе это означает: !
//!TxD-push/pull_output, RxD-input.! //RI=TI=RB8=TB8=REN=SM2= //SM0/FE=0,
/^М1 = 1:единственный бит=1. //0x30=48. Vobm=CCLK/ //[(BRG1*256+BRG0)+16]= //7372800/[(0*256+48)+16] = //7372800/64=115200.
//Разрешение SBRGS и BRGEN.
void outbyte(unsigned char byte) {
while (RXD);
SBUF=byte; while (!RXD);
while (!TI);
TI = 0;
}
// Ожидание разрешения на передачу // байта (от компьютера).
// Вывод байта.
// Ожидание запрета на передачу // (от компьютера).
// Ожидание окончания вывода // байта микроконтроллером.
// Сброс флага передачи (ТІ).
unsigned char inbyte() { unsigned char byte; TXD=0;
while (RXD);
DEL10();
TXD=1;
while(!RI);
byte=SBUF;
RI = 0;
vreturn(byte);
// Установка разрешения компьютеру // передавать байт.
// Ожидание старт-бита.
// Задержка длительностью полбайта // (115 200 бод).
// Запрет компьютеру передавать байт. // Ожидание окончания прихода // байта вмикроконтроллер.
// Ввод байта в микроконтроллер.
// Сброс флага приема байта (Ю).
}
/**************************************************/ void main(void)
{
initrs();
REN=1; // Установка на прием.
START:
u.bt.lenl=inbyte(); //Прием мл. байта длины строки.
u.bt.lenh=inbyte(); //Прием ст. байта длины строки.
temp_L=u.l; //Запоминание длины строки
//в переменной temp_L. //Переменная al-длина строки(ш^Л) //заполняется автоматически после //заполнения переменных //u.bt.lenl и u.bt.lenh.
for(u.l=0;u.l<temp_L;u.l++){ //Прием из компьютера a[u.l]=inbyte(); //очередного
} //байта строки.
//Изменение u.l (например, u.l++) //влечет за собой автоматическое //и соответственное изменение //u.bt.lenl и u.bt.lenh. //Если u.l — адрес памяти, //то u.bt.lenl и u.bt.lenh -//соответственно младший //и старший байты этого адреса.
REN=0; //Установка RS-232 на передачу.
for(u.l=0;u.l<temp_L;u.l++){ //Передача в компьютер outbyte(a[u.l]); //очередного } //байта строки.
REN=1; //Установка RS-232 на прием.
c=inbyte(); if (c==0x40) goto START; E: goto E; } } //Если принятый символ=»@», //то продолжение работы, //иначе — конец.
//
Программа на языке ассемблер для P89LPC904:
Программа для микроконтроллера Р89ЬРС904 приема строки символов по Я5-232 (с передачей длины строки) и вывода символов из МК вкомпьютер. Б(ССЬК)=7372800 Гц. Скорость обмена— 115200 и 9600 бод. Синхронизация — с помощью линий ТХР и ЯхП.
Определение выводов TXD и RXD RS-232 P89LPC904
TXDLPC: .reg p1.0 ;a не p3.0!!!
RXDLPC: .reg pl.l ;ане p3.1!!!
В МАКРОСАХ НЕЛЬЗЯ ИСПОЛЬЗОВАТЬ РУССКИЙ ЯЗЫК В КОММЕНТАРИЯХ!!!!!!
Макрос ввода байта
INBYTE .macro
clr TXDLPC jb RXDLPC,$ call DEL10 setb TXDLPC jnb ri,$ mov a,sbuf clr ri .endm
Макрос вывода байта
OUTBYTE .macro
jb RXDLPC,$ mov sbuf,a jnb RXDLPC,$ jnb ti,$ clr ti .endm
DATA
Enable transfer Waiting start-bit Delay 10 us Disable transfer Waiting set flag ri Input byte from buffer Clear flag ri
Waiting enable transfer Output byte in buffer Waiting disable transfer.WARNING!!! Waiting output last bit (flag ti)
Clear flag ti
Переменные
P1M1
P1M2
BRGCON
BRG0
BRG1
SSTAT
equ 91h equ 92h equ 0bdh equ 0beh equ 0bfh equ 0bah
.CODE
.org 0000h jmp MAIN .org 0003h reti
.org 001bh reti
.org 0053h reti
Вектор прерывания по RST Вектор прерывания по INT0 Вектор прерывания по TF1 вектор прерывания от TIC
; Основная программа
.org 0060h ; mov sp,#20h
org $
mov sp,#20h
Инициализация последовательного порта
SPINIT: mov SSTAT,#00h ;Стандартный З1-совместимый RS-232. mov P1M1,#02h ;1Вместе это означает: I
mov P1M2,#01h ;ITxD-push/pull_output, RxD-input.I mov SCON,#40h ;Все биты SCON,кроме SM1,равны 0, ;SM1=1.
mov BRG0,#30h ;30h=48.Vobm=CCLK/[(BRG1*256+ ;BRG0)+16] = mov BRG1,#00h ;7372800/[(0*256+48)+16] = ;7372800/64=115200. mov BRGCON,#03h;Разрешение SBRGS и BRGEN.
Ввод байт по последовательному порту START: setb RE ;Разрешение приема.
mov dptr,#0 INBYTE mov r0,a INBYTE mov r1,a
INBYTE
push a
inc dptr mov a,r1 cjne a,dph,spin mov a,r0 cjne a,dpl,spin
; Младший байт длины ; Старший байт длины ; Байт в а
Вывод байт по последовательному порту clr REN ;Запрет приема.
pop a OUTBYTE
spout:
djnz r0,spout Ввод команды продолжения работы
;Разрешение приема.
IB:
E:
DEL10:
В качестве алгоритма обмена программа использует приведенный в 2.1 новый алгоритм обмена, разработанный автором.
Ниже приведен текст программы Неііо.сіа, а вслед за ним — текст ее файл-проекта.
Программа Неііо.сіа:
Программа передачи и приема строки из УЗ символов по RS-232
MAP
INCLUDE('GUI.INC')
Определение переменных
C byte
A byte
B byte
S string(75)
BT byte
M byte,dim(75),over(S)
S1 string(75)
M1 byte,dim(75),over(S1)
I ushort
j ushort
k ushort
Y00h byte
Y01h byte
Y02h byte
Y03h byte
Y04h byte
Y07h byte
Y12 byte
Y47h byte
Y80h byte
Y0fh byte
setb REN INBYTE cjne a,#40h,E jmp START
jmp $
mov b,#10 djnz b,$ ret
.end
2.3.4. Тестовая программа обмена для компьютера в ОС DOS
Для функционирования любой из тестовых микроконтроллерных программ, приведенных в 2.3.2 (для MSC1210) и 2.3.3 (для P89LPC938/904), написана компьютерная программа на языке Clarion v3.101 Hello.cla, работающая в операционной системе DOS. Программа инициализирует интерфейс RS-232 компьютера (порт COM1:N,8,1,115200), запускает микроконтроллер, передает в него строку из 75 байт (представляющую собой символы латинского и русского алфавита), принимает эту строку от микроконтроллера и обе строки (для сравнения) выводит на экран монитора. В программу включена (INCLUDE) опция графического интерфейса пользователя (Graphic User Interface). Этот интерфейс позволяет работать в DOS в графическом оконном режиме и поддерживает мышь (аналогично всем программам для ОС Windows).
SCREEN(18,80),PRE(SCR1),CENTER,GRAPHIC,CUA,
COLOR(53)
ROW(1,1) PAINT(1,80),COLOR(55)
ROW(1,2) PAINT(1,78),COLOR(112)
ROW(2,1) PAINT(17,1),COLOR(55)
ROW(2,4) PAINT(16,75),COLOR(48)
ROW(2,80) PAINT(17,1),COLOR(55)
ROW(3,20) PAINT(1,34),COLOR(49)
ROW(9,20) PAINT(1,35),COLOR(49)
ROW(16,32) PAINT(1,42),COLOR(49)
ROW(18,4) PAINT(1,73),COLOR(33)
ROW(1,19) STRING('ТестпортаRS-232 {5}
(COM1:115200,N,8,2)'),COLOR(112) ROW(3,7) STRING('k='),COLOR(48)
ROW(4,20) STRING('Hачало передачи
в микроконтроллер'),COLOR(48) ROW(6,4) STRING('Передаваемая строка:'), COLOR(48)
ROW(10,20) STRING('Hачало приема
из микроконтроллера'),COLOR(48) ROW(12,4) STRING('Принятая строка:'), COLOR(48)
ROW(16,27) STRING('(Esc)'),COLOR(49)
COL(65) STRING('(Enter)'),COLOR(49) ROW(16,53) BUTГON('Продолжшъ'),KEY(2ЗУ),
USE(?Ok),COLOR(112,112,135,112,112) COL(18) BUTTON(' Выход '),KEY(256),
USE(?CANSEL),COLOR(48,48,135,48,48) ROW(7,4) ENTRY(@s75),USE(S), COLOR(112,112,112)
ROW(3,9) ENTRY(@n_3),USE(k), COLOR(112,112,112)
ROW(13,4) ENTRY(@s75),USE(S1), COLOR(112,112,112)
setgraphic(89) !VGA
LOADGUI
setcolor(158)
blank
setcolor
loadsymbols
setmouse(10,15)
open(SCREEN1)
k=0
MAIN:
PROGRAM
spin
МАКРОСЫ
SCREEN1
CODE
Y00h=00h;Y01h=01h;Y02h=02h;Y03h=03h;Y04h=04h;Y07h=07h;
Y0fh=0fh;Y12=12;Y47h=47h;Y80h=80h
do INIT !Инициализация RS-232
OK
k=k+1
DISABLE(?CANSEL)
DISABLE(?Ok)
S='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdifjhigklmnopqrstuvw
xyzАБВГДЕЖЗИКЛМНОПРСТУФХЦЧ'
! Ч-75-й символ
DISPLAY !Вывод на экран исходной строки.
i=1 C=M[1] Запоминание первого элемента строки.
M[1]=75
do OUTBYTE !Передача мл. байта длины (75)
M[1]=0
do OUTBYTE !Передача ст. байта длины (0)
M[1]=C !Восстановление первого символа строки.
loop i=1 to 75
do OUTBYTE
in(3f8h,B) !Холостой ввод — делать ОБЯЗАТЕЛЬНО !!!
!(Для сброса бита DR-data ready).
loop;in(3fdh,B);if band(B,1)=0;break.. !Ожидание сброса бита !«DR»-data ready.
S1=иЮбнуление S1 loop i=1 to 75 do INBYTE
DISPLAY !Вывод на экран принятой строки.
ENABLE(?Ok)
ENABLE(?Cansel)
Loop
Accept
case field() of ?CANSEL DISPLAY close(SCREEN1) goto E of ?Ok Display i=1
M[1]=40h do OUTBYTE goto OK
.!case
.!loop
E blank
out(3fch,Y00h) !Сброс микроконтроллера return
П/п инициализации RS-232
INIT routine
Инициализация СОМ-порта.
Установка скорости обмена.
out(3fch,Y00h) ! Сброс линии DTR (Reset микроконтроллера). out(3fbh,Y80h) ! DLAB=1 для установки делителя. out(3f8h,Y01h) ! Установить мл.б. скор.:Y01h-115200 бодУ12-9600 бод. out(3f9h,Y00h) ! Установить ст.б. скор.=0.
Установка режима.
out(3fbh,Y07h) ! DLAB=0,Режим: 8 бит данных, 2 стота,
! нет пар.,сброс TxD.
Установка запрета прерываний по СОМ-порту.
out(3f9h,Y00h) ! Запрет всех прерываний по порту 3f8h.
! Инициализация микроконтроллера.
out(3fch,Y00h) ! Сброс линии DTR
! (Reset микроконтроллера).00Ь
do DEL100MS
out(3fch,Y01h) ! Установка линии DTR
! (Запуск микроконтроллера).0Ш
do DEL100MS do DEL100MS
in(3f8h,B) ! Холостой ввод — для сброса бита 0(DR)
! в 3fdh (в «0»).
do DEL100MS
П/п ввода байта (байт вМ1[і] )
INBYTE routine
out(3fbh,Y47h)
loop; in(3feh,B); if band(B,2) then break..
do DEL20 out(3fbh,Y07h)
in(3feh,B)
loop;in(3fdh,B);if band(B,1) then break..
in(3f8h,M1[i])
Чтение байта данных
П/п вывода байта (байт в M[i] )
OUTBYTE
loop;in(3fdh,B);if band(B,20h);break..
loop;in(3feh,B);if band(B,20h);break..
out(3f8h,M[i])
!in(3feh,B)
loop;in(3feh,B);if band(B,2);break.. loop;in(3fdh,B);if band(B,40h);break..
in(3feh,B)
Установка TxD (разрешение передачи) Ожидание старт-бита (уст-ки DSR)
Задержка 20 мкс Сброс линии TxD (запрет передачи) Очистка регистра 3feh чтением
Ожидание конца приходя, байта (бит DR»-data ready)
routine
Ожидание готовности передатчика (transmitter empty). Ожидание разрешения !пфедачи (установки DSR) Вывод байта Очистка регистра 3feh чтением
Ожидание запрета передaчи (сброса DSR) Ожидание выхода байта из РС (trasmitter holding register empty.OK to send). Очистка регистра 3feh чтением
DEL100MS routine
T#=CLOCK() ;loop while CL0CK()-T#<10. !Задержка 0.1 сек.
DEL200MS routine
T#=CLOCK() ;loop while CL0CK()-T#<20. !Задержка 0.2 сек.
DEL50 routine loop 15000 times
DEL1400 routine loop j=1 to 1400
DEL20 routine loop 40000 times
Файл-проект Hello.pr:
#system auto exe #model extended
#pragma data(stack_size=>24576,threshold=>4096)
#pragma check(stack=>on,index=>on)
#pragma link_option(map=>off,case=>on)
#compile hello.cla /check(stack=>off,nil_ptr=>off,index=>off) /de-bug(vid=>off,line_num=>off)
#pragma link(%clapfx%dos.lib)
#pragma link(%clapfx%xgui.obj)
#set exports='hello'
#link hello
После запуска программы на экран выводится окно, показанное на рис. 5.
Нажатие кнопки «Продолжить» (мышью или клавишей Enter) приведет к повторному запуску программы; количество запусков отражает переменная k в левом верхнем углу. В данном случае k=146.
Нажатие кнопки «Выход» приведет к выходу из программы.
В следующей части статьи пойдет речь о программировании интерфейса RS-232 в ОС Windows98/XP. ■
Продолжение следует Литература
1. Баррингтон Брюс Б. Как создавался Кларион // Мир ПК. 1993. № 2.
2. Кузьминов А. Ю. Интерфейс RS-232. Связь между компьютером и микроконтроллером. От DOS к Windows98/XP. М.: ДМК-ПРЕСС. 2006 (в печати).
3. Кузьминов А. Ю. Интерфейс RS-232. Связь между компьютером и микроконтроллером. М.: Радио и связь. 2004.
4. Кузьминов А. Ю. Однокристальные микроЭВМ — основа удаленных систем сбора и обработки сигналов, поступающих с датчиков // Электроника и компоненты. 1998. № 2.
5. Кузьминов А. Ю. Новые MCS51 — совместимые микроконтроллеры и их применение в системах сбора информации с датчиков // Контрольно-измерительные приборы и системы. 1997. № 6; 1998. № 7.
6. Кузьминов А. Ю. Удаленные системы сбора информации с датчиков на базе однокристальных микроЭВМ // Автоматизация и производство. 1996. № 3.
7. Кузьминов А. Ю. Универсальная система сбора и обработки данных АСИР-3 // Мир ПК. 1996. № 6.
8. Орлов А. Два звучных слова — Clarion и Delphi // Мир ПК. 1996. № 6.
9. Фролов А. В., Фролов Г. В. Программирование модемов. М.: ДИАЛОГ-МИФИ, 1993.
10. w ww.analog.c om
11. w ww .atmel.c om
12. ww w.maxim-ic.c om
13. ww w.semiconductor-philips.c om
14. w ww.silabs.c om
15. w ww.ti.c om
16. w ww.msdn.microsoft.c om/library
17. ww w.gapdev.c om
18. w ww.sysinternal.c om
Рис. 5. Внешний вид окна программ