' ********************************************************************** ' * File: uk_BAS51_015.BAS * ' * Version: 1.1 * ' * Date: 21.06.10 * ' * Development Tools: Bascom 8051 COMP.,IDE 2.0.14.0 + FLIP 2.4.6 * ' * Cards: GMM 5115 + GMM TST3 * ' * Developed by: GRIFO(r) Italian Technology * ' * via Dell'Artigiano 8/6 * ' * 40016 S. Giorgio di Piano (BO) * ' * Tel. +39 051 892052 Fax. +39 051 893661 * ' * http://www.grifo.com http://www.grifo.it * ' * Author: Gianluca Angelini * ' ********************************************************************** ' Example program 015 of BASCOM 8051 course. ' It generates messages with Morse codes and save/load them into/from internal ' EEPROM. ' The program can perform the following operations: ask for a message and then ' generates it with Morse codes on buzzer, define the generation speed of the ' Morse codes, repeat the generation of the last inserted message, save up to ' 5 messages on EEPROM, load a message from EEPROM and finally it generates the ' 3 special Morse codes dedicated to attention, error and repeat. ' The user interactions happen through a serial console provided of keyboard ' and monitor and it must communicate with a fixed physical protocol at 19200 ' Baud, 8 Bit x chr, 1 Stop bit, No parity. ' This console can be another system capable to support a serial RS 232 ' communication. In order to simplify the use it can be used a PC provided of ' one COMx line, that execute a terminal emulation program as HYPERTERMINAL or ' the homonym modality provided by BASCOM 8051 (see IDE Configuration). ' ' Added instructions: Disable Interrupts, Enable Interrupts, Out, Inp, Incr, ' Or, Chr, Space. ' ' 21/06/10: uk_BAS51_015.BAS - Ver 1.1 - By G.A. ' First version. ' ' '**************************** IDE Configurations ******************************* ' NOTE: in order to coorectly use this demo program, please execute the following ' steps: ' 1) Check the availability of 89C5115.DAT file into the directory where the ' BASCOM 8051 is installed and copy it if not present. ' 2) Into the window "Options | Compiler | Misc" set: ' Register File = 89C5115.DAT ' Byte End(Hex) = A0 ' Size warning = selected at 16384 (=4000H) ' 3) Into the window "Options | Communication" set: ' COM port = the PC line connected to GMM 5115, through GMM TST3 ' Baudrate = 19200 ' Parity = None ' Databits = 8 ' Stopbit = 1 ' Handshake = None ' Emulation = TTY ' Font = Terminal, Normal, 12 points, white colour ' Backcolor = Navy ' Run emulator modal = not selected ' 4) At the end of compilation, after the code is programmed on GMM 5115, select ' RUN mode and open the terminal emulation window of BASCOM 8051 with the ' option: Tools | Terminal emulator (Ctrl+T) and then reset or powen on the ' Mini Module. '************************* Compiler directives ********************************* $regfile "89C5115.DAT" ' Definitions file for used microcontroller $romstart = &H0 ' Code start address on FLASH $iramstart = &H0 ' Data start address on internal RAM $ramstart = &H0 ' Data start address on external RAM $ramsize = &H100 ' External RAM size $crystal = 14745600 ' Microcontroller crystal frequency $large ' Code size > 2K $map ' Generate debug information $baud = 19200 ' Serial communication speed: 19200 Baud ' Other parameters fixed to: 8 bit x chr ' 1 Stop bit ' No parity '******************************* Definitions *********************************** ' The resources used by program are connected as described in following table: ' !!! Note: On GMM TST3 the following jumpers must be properly configured: ' J1 in 2-3 ; J2 in 2-3 ; J3 in 1-2 ; J8 in 2-3 !!! ' ' hardware pin Z1 pin Signal Signal ' resource GMM TST3 GMM 5115 GMM 5115 uP ' Buzzer BZ1 15 9 P4.1 P4.1 ' ' Signal pin COMx pin CN5 pin Z1 pin Signal Signal ' PC DB9 GMM TST3 GMM TST3 GMM 5115 GMM 5115 uP ' TX 3 3 9 3 RxD RS232 P3.0 ' RX 2 2 10 4 TxD RS232 P3.1 ' GND 5 5 20 14 GND - ' This table shows that the connection cable between PC COM line and CN5 of ' GMM TST3 is a normal pin to pin cable or direct. Grifo(r) can supply it by ' requesting the CCR 9+9E code. Pinbz1 Alias P4.1 ' Signal connected to buzzer BZ1 Pinrx Alias P3.0 ' Signal connected to GMM 5115 RxD Pintx Alias P3.1 ' Signal connected to GMM 5115 TxD '************************* Constants declaration ******************************* Const Ee_timeout = 5000 ' Timeout for waiting end of EEPROM write Const Max_msg_ee = 5 ' Maximum number of messages on EEPROM Const Cod_msg_ee = &H5A ' Code that denote message saved on EEPROM '************************* Variables declaration ******************************* Dim Choice As Byte ' Selected operation Dim Mchr As Byte ' Character to generate with Morse Dim Ichr As Byte ' Index for character to generate search Dim Mcod As Byte ' Morse code of character to generate Dim Ncmp As Byte ' Component number of Morse code Dim Icmp As Byte ' Component index of Morse code Dim Mbit As Byte ' Current bit of Morse code Dim Msgstr As String * 40 ' String with message to generate Dim Mdt As Word ' Time unit duration in milliseconds Dim Lstr As Byte ' String with message length Dim Pstr As Byte ' Pointer to string with message Dim Chrstr As String * 1 ' Character of the message to generate Dim Datee As Byte ' Data to write on or read from EEPROM Dim Addee As Word ' EEPROM location address to write or read Dim Hlpb As Byte ' General purpose help variable Dim Tout As Word ' Counter for security timeout Dim Nmsg As Byte ' Message number to read/write from/on EEPROM Dim Msgsaved As Boolean ' Message saved on EEPROM flag '************************ Subroutines declaration ****************************** Declare Sub Del_1unit() ' Generate delay of one Morse time unit Declare Sub Morse_cod() ' Generate a Morse code Declare Sub Morse_chr() ' Generate a character with Morse code Declare Sub Morse_str() ' Generate a message with Morse code Declare Sub Rd_ee() ' Read a byte from internal EEPROM of uP Declare Sub Wr_ee() ' Write a byte on internal EEPROM of uP Declare Sub Read_msg_ee() ' Read a message from EEPROM Declare Sub Write_msg_ee() ' Write a message on EEPROM Declare Sub Show_msg_ee() ' Show the messages saved on EEPROM '****************************** Main program *********************************** Main: Pinrx = 1 ' Initialize signals for serial communication Pintx = 1 ' as digital inputs Pinbz1 = 1 ' Initialize signal connected to BZ1 as digital output, high Mdt = 200 ' Define initial time unit duration to 200 msec Print ' Separate from previous visualization by showing an empty new line Print " Morse generator with EEPROM" Do ' Begin endless loop Print ' Shows menu with available operations Print "M -> Generate message" Print "S -> Define generation speed" Print "L -> Repeat last generated message" Print "P -> Put a message on EEPROM" Print "G -> Get message from EEPROM" Print "A -> Generate attention code" Print "E -> Generate error code" Print "R -> Generate repeat code" Print "Perform the choice by pushing the associated key: "; Choice = Waitkey() ' Wait selection of operation to execute Printbin Choice ' Shows performed choice Print If Choice >= "a" Then ' If choice is lower case Choice = Choice And &HDF ' Convert it in upper case End If Select Case Choice ' Check converted choice Case "M": ' Selected operation is generate message Print "Insert message to generate with Morse (max. 40 characters): " Input Msgstr ' Get and save message to generate Msgstr = Ucase(msgstr) ' Convert message to generare in upper case Call Morse_str() ' Generate inserted message with Morse Case "S": ' Selected operation is define speed Print "Current duration of Morse time unit: " ; Mdt ' Show current value and it ask for the new one Input "Insert new duration (1..1000 msec): " , Mdt Case "L": ' Selected operation is repeat last generated message Call Morse_str() ' Generate last message with Morse Case "P": ' Selected operation is save a message on EEPROM Call Show_msg_ee() ' Show the messages saved on EEPROM Input "Message number to save: " , Nmsg ' Ask and gest the message number to save Print "Insert message to save on EEPROM (40 characters max.): " Input Msgstr ' Get message to save on EEPROM Call Write_msg_ee() ' Save message on EEPROM Case "G": ' Selected operation is read a message from EEPROM Call Show_msg_ee() ' Show the messages saved on EEPROM Input "Message number to read: " , Nmsg ' Ask and gest the message number to read Call Read_msg_ee() ' Read message from EEPROM Case "A": ' Selected operation is generate attention code Mcod = &H12 ' Set binary code for attention Ncmp = 5 ' Set components number for attention Call Morse_cod() ' Generate defined code with Morse Print "Attention code generated" Case "E": ' Selected operation is is generate error code Mcod = &H00 ' Set binary code for error Ncmp = 8 ' Set components number for error Call Morse_cod() ' Generate defined code with Morse Print "Error code generated" Case "R": ' Selected operation is is generate repeat code Mcod = &H00 ' Set 1st part of binary code for repeat Ncmp = 2 ' Set 1st part components number for repeat Call Morse_cod() ' Generate defined code with Morse Call Del_1unit() ' Generate delay of 3 time units Call Del_1unit() Call Del_1unit() Mcod = &H00 ' Set 2nd part of binary code for repeat Ncmp = 2 ' Set 2nd part components number for repeat Call Morse_cod() ' Generate defined code with Morse Print "Repeat code generated" Case Else: ' Selected operation is not valid Printbin &H07 ' Generate an advise BEL on console End Select Loop ' End endless loop End '*************************** End of main program ******************************* '*********************** Subroutines used by program *************************** ' Read a byte from internal EEPROM of uP. ' Input: Addee = variable with EEPROM location address to read ' Output: Datee = variable with data read from EEPROM Sub Rd_ee() Auxr = &H2E ' Deselect ERAM of uP, extend MOVX duration Disable Interrupts ' General interrupts disable Eecon = &H02 ' Select EEPROM of uP, allocated on external data area Datee = Inp(addee) ' Read byte from EEPROM Eecon = &H00 ' Deselect EEPROM of uP Enable Interrupts ' General interrupts re-enable Auxr = &H0C ' Selects ERAM of uP son external data area End Sub ' Write a byte on internal EEPROM of uP, with security timeout ' Input: Addee = variable with EEPROM location address to write ' Datee = variable with data read from EEPROM ' Output: None ' It uses global variables Hlpb, Tout Sub Wr_ee() Auxr = &H2E ' Deselect ERAM of uP, extend MOVX duration Disable Interrupts ' General interrupts disable Eecon = &H02 ' Select EEPROM of uP, allocated on external data area Out Addee , Datee ' Write byte on EEPROM column latch Eecon = &H52 ' Start write operation on internal EEPROM Eecon = &HA2 Eecon = &H00 ' Deselect EEPROM of uP Enable Interrupts ' General interrupts re-enable Auxr = &H0C ' Selects ERAM of uP son external data area Tout = 0 ' Reset timeout counter Do ' Cycle that wait write end with timeout Incr Tout Hlpb = Eecon ' Read and mask EEPROM busy bit Hlpb = Hlpb And &H01 Loop Until Hlpb = 0 Or Tout >= Ee_timeout ' Exit when EEPROM not busy or timeout elapsed End Sub ' It perform a delay of one Morse time unit. This endurance generates the Morse ' code with the speed defined by user. ' Input: None ' Output: None Sub Del_1unit() Waitms Mdt ' Perform delay in milliseconds saved into Mdt variable End Sub ' Generate one character with Morse code by using the passed binary code and ' components number. ' Please remind that in the binary code a bit=0 equals to a point (buzzer ' enabled for 1 time unit) while a bit=1 equals to a line (buzzer enabled for ' 3 time units). Each components is obviously separated from next one by a ' space (buzzer disabled for 1 time unit). ' The codes generation speed is established by a proper variable defined by ' user. ' Input: Mcod = binary Morse code to generate ' Ncmp = components number to generate ' Output: None Sub Morse_cod() For Icmp = 1 To Ncmp ' Loop repeated for the number of components Mbit = Mcod And &H01 ' Obtain less significant bit of code Pinbz1 = 0 ' Enable BZ1 buzzer If Mbit = 0 Then ' If current component is a point Call Del_1unit() ' Generate 1 time unit delay Else ' Current component is a line Call Del_1unit() ' Generate 3 time units delay Call Del_1unit() Call Del_1unit() End If Pinbz1 = 1 ' Disable BZ1 buzzer Call Del_1unit() ' Generate space of 1 time unit Shift Mcod , Right , 1 ' Shift code of one bit right Next Icmp End Sub ' It generates one letter with Morse code by using the table defined in the ' program. The codes generation speed is established by a proper variable ' defined by user. ' Input: Mchr = variable with character to generate ' Output: None Sub Morse_chr() If Mchr >= " " And Mchr <= "`" Then ' If character included in Morse codes table ' Get binary Morse code and number of components associated to character to ' generate from table defined at the end of program Mchr = Mchr - &H20 ' ASCII code of character to generate start from 0 Restore Morse ' Point to start of Morse table For Ichr = 0 To Mchr ' Loop that read the table from the start to character to generate Read Mcod ' Get Morse code of Ichr character from table Read Ncmp ' Get components of Ichr character from table Next Ichr Call Morse_cod() ' Generate code with Morse of character ' Generate space between one character and following one (buzzer disabled ' for 3 time units) Call Del_1unit() ' Generate 3 time units delay Call Del_1unit() Call Del_1unit() Else ' Character not included in table Ncmp = 0 ' Setting for character not generated End If End Sub ' Generate one message with Morse code by using the subroutines previously ' defined and it shows the valid generated charcater on console. The codes ' generation speed is established by a proper variable defined by user. ' Input: Msgstr = string variable with message to generate ' Output: None Sub Morse_str() Print "Generated characters: "; Msgstr = Ucase(msgstr) ' Convert messae to generate in upper case Lstr = Len(msgstr ) ' Obtain legth of string with message For Pstr = 1 To Lstr ' Loop repeated for the characters of message Chrstr = Mid(msgstr , Pstr , 1) ' Get current character of message Mchr = Asc(chrstr) ' Obtain ASCII code ASCII of current character If Mchr <> " " Then ' If character is not a space Call Morse_chr() ' Generate current character with Morse Else ' Generate space between one word and following one (buzzer disabled for ' 7 time units) Call Del_1unit() ' Generate 7 time units delay Call Del_1unit() Call Del_1unit() Call Del_1unit() Call Del_1unit() Call Del_1unit() Call Del_1unit() Ncmp = 7 ' Set component number to show the generated space End If If Ncmp > 0 Then ' If current character was valid and it has been generated Print Chrstr; ' Show generated character on console End If Next Pstr Print ' Separate indications, by showing an empty new line End Sub ' Each message occupies 42 bytes of EEPROM: the first dedicated to a message ' saved indicator, the second dedicated to message length and the following ' 40 bytes dedicated to the maximum 40 characters of the message. ' ' Read a message from EEPROM, by checking if it has been previously saved. ' Input: Nmsg = variable with message number to read ' Output: Msgstr = string variable with read message ' Msgsaved = flag for message saved and thus read Sub Read_msg_ee() Addee = Nmsg * 42 ' Calculate start address of message saved on EEPROM Call Rd_ee() ' Get message saved indicator from EEPROM If Datee = Cod_msg_ee Then ' If message is already saved on EEPROM Incr Addee ' Increase the EEPROM read address Call Rd_ee() ' Get message length from EEPROM Lstr = Datee Msgstr = Space(lstr) ' Arrange string long as message to read For Pstr = 1 To Lstr ' Cycle repeated for characters of message Incr Addee ' Increase the EEPROM read address Call Rd_ee() ' Get ASCII code of current character from EEPROM Chrstr = Chr(datee) ' Obtain character from Ascii code Mid(msgstr , Pstr , 1) = Chrstr ' Save current character of message Next Pstr Msgsaved = 1 ' Message was saved on EEPROM and it has been read Else Msgsaved = 0 ' Message was not saved on EEPROM and it hasn't been read End If End Sub ' Write a message from EEPROM, by adding proper message saved indicator ' Input: Nmsg = variable with message number to write ' Msgstr = string variable with message to write ' Output: None Sub Write_msg_ee() Addee = Nmsg * 42 ' Calculate start address of message saved on EEPROM Datee = Cod_msg_ee ' Write message saved indicator on EEPROM Call Wr_ee() Lstr = Len(msgstr) ' Obtain length of string with message Datee = Lstr ' Write message length on EEPROM Incr Addee ' Increase EEPROM write address Call Wr_ee() For Pstr = 1 To Lstr ' Cycle repeated for characters of message Chrstr = Mid(msgstr , Pstr , 1) ' Get current character of message Datee = Asc(chrstr) ' Obtain ASCII code of current character Incr Addee ' Increase EEPROM write address Call Wr_ee() ' Write current character ASCII code on EEPROM Next Pstr End Sub ' Show on serial console the list of message currently written=saved on EEPROM ' Input: None ' Output: None Sub Show_msg_ee() Print "Message currently saved on EEPROM:" ' Show list head description For Nmsg = 1 To Max_msg_ee Print Nmsg ; " = "; ' Show message number of the list Call Read_msg_ee() ' Read current message of EEPROM list If Msgsaved = 1 Then ' If message saved on EEPROM and read Print Msgstr ' Show read message of the list Else ' Message not saved and not read Print ' Show empty message of the list End If Next Nmsg End Sub '******************* End of subroutines used by program ************************ '************************** Data used by program ******************************* ' Each character is coded by two numbers: the first is the real bits code of ' the components and the second is the components number. The term components ' refers either to points and lines that compose each letters with Morse code, ' as follows: ' - the point equals to a bit at 0; ' - the line equals to a bit at 1; ' - in the code the less significant bit is the first to generate; ' - the characters are ordered with ASCII standard codes, starting from "0"=&H30. ' ' For example the character 1 is coded by: point line line line line ' with bits it becomes: 0 1 1 1 1 ' with inverted generation order it becomes: 1 1 1 1 0 ' that in Hexadecimal HEX is: 1E ' with a components number: 5 ' with BASCOM AVR it becomes: Data &H1E , 5 ' ' For example the character D is coded by: line point point ' with bits it becomes: 1 0 0 ' with inverted generation order it becomes: 0 0 1 ' that in Hexadecimal HEX is: 01 ' with a components number: 3 ' with BASCOM AVR it becomes: Data &H01 , 3 ' Morse: Data &H00 , 0 ' Character =&H20 Data &H00 , 0 ' Character ! Data &H12 , 6 ' Character '' Data &H00 , 0 ' Character # Data &H48 , 7 ' Character $ Data &H00 , 0 ' Character % Data &H00 , 0 ' Character & Data &H1E , 6 ' Character ' Data &H0D , 5 ' Character ( Data &H2D , 6 ' Character ) Data &H00 , 0 ' Character * Data &H0A , 5 ' Character + Data &H33 , 6 ' Character , Data &H21 , 6 ' Character - Data &H2A , 6 ' Character . Data &H09 , 5 ' Character / Data &H1F , 5 ' Character 0=&H30 Data &H1E , 5 ' Character 1 Data &H1C , 5 ' Character 2 Data &H18 , 5 ' Character 3 Data &H10 , 5 ' Character 4 Data &H00 , 5 ' Character 5 Data &H01 , 5 ' Character 6 Data &H03 , 5 ' Character 7 Data &H07 , 5 ' Character 8 Data &H0F , 5 ' Character 9 Data &H07 , 6 ' Character : Data &H15 , 6 ' Character ; Data &H00 , 0 ' Character < Data &H11 , 5 ' Character = Data &H00 , 0 ' Character > Data &H0C , 6 ' Character ? Data &H16 , 6 ' Character @=&H40 Data &H02 , 2 ' Character A Data &H01 , 4 ' Character B Data &H05 , 4 ' Character C Data &H01 , 3 ' Character D Data &H00 , 1 ' Character E Data &H04 , 4 ' Character F Data &H03 , 3 ' Character G Data &H00 , 4 ' Character H Data &H00 , 2 ' Character I Data &H0E , 4 ' Character J Data &H05 , 3 ' Character K Data &H02 , 4 ' Character L Data &H03 , 2 ' Character M Data &H01 , 2 ' Character N Data &H07 , 3 ' Character O Data &H06 , 4 ' Character P=&H50 Data &H0B , 4 ' Character Q Data &H02 , 3 ' Character R Data &H00 , 3 ' Character S Data &H01 , 1 ' Character T Data &H04 , 3 ' Character U Data &H08 , 4 ' Character V Data &H06 , 3 ' Character W Data &H09 , 4 ' Character X Data &H0D , 4 ' Character Y Data &H03 , 4 ' Character Z Data &H00 , 0 ' Character [ Data &H00 , 0 ' Character \ Data &H00 , 0 ' Character ] Data &H00 , 0 ' Character ^ Data &H2C , 6 ' Character _ Data &H00 , 0 ' Character `=&H60 '********************** End of data used by program ****************************