Index Top Previous Next Version 2.0.8.2 document build 90 MCS Electronics may update this documentation without notice. Products specification and usage may change accordingly. MCS Electronics will not be liable for any miss-information or errors found in this document. All software provided with this product package is provided 'AS IS' without any warranty expressed or implied. MCS Electronics will not be liable for any damages, costs or loss of profits arising from the usage of this product package. No part of this document may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying and recording, for any purpose, without written permission of MCS Electronics. Copyright MCS Electronics v.o.f. All rights reserved. Table of contents Top Previous Next Index Index Keyword Reference Changes About MCS About MCS Custom Design Application Notes Installation Installation Problems and solutions Updates Move to a New PC Installation on multiple computers BASCOM-IDE The BASCOM IDE File New , Open , Close , Save , Save As , Print Preview , Print , Project, Exit , ZIP Edit Undo , Redo , Cut , Copy , Paste , Find , Find Next , Replace , Goto , Toggle Bookmark , Goto Bookmark , Indent Block , Unindent Block , Encrypt Selected Code , Proper Indent , Show Excluded Code , Insert ASCII , Fold All Subs and Functions, Unfold All Code , Show Dead Code View PinOut , PDF , Errors , Tip , Project Files, Code Explorer , Vertical Splitter Program Compile , Syntax Check , Show Result , Simulate , Send to Chip Tools LIB Manager , Terminal Emulator , LCD Designer , Graphic Converter , Batch Compile , PDF Update , Resource Editor , Stack Analyzer, Plugin Manager , Font Editor , Options Compiler , Compiler Chip , Compiler Output , Compiler Communication , Compiler I2C,SPI,1WIRE , Compiler LCD , Communication , Environment , Simulator , Programmer , Printer Window Cascade , Tile, Arrange Icons, Minimize All, Maximize All , Tile Vertically Help About , Index, MCS Forum, Support, Knowledge Base , Credits , Wiki , Update Editor Keys BASCOM Developing Order BASCOM and Memory BASCOM Error codes Reserved Words BASCOM and Hardware Additional Hardware AVR Internal Hardware AVR Internal Hardware TIMER0 AVR Internal Hardware TIMER1 AVR Internal Hardware Watchdog timer AVR Internal Hardware PORT B AVR Internal Hardware PORT D AVR Internal Registers Adding XRAM Adding SRAM 4-port Non Multiplexed Attaching an LCD display Using the UART Using RS485 Using the I2C protocol Using the 1 Wire protocol Using the SPI protocol Using USI Power Up ATXMEGA Statements and Hardware Resources Reference Designs EM4095 RFID Reader Misc Assembly Mnemonics International Resellers Language Fundamentals Mixing BASIC with assembly Supported Programmers BASCOMP, command line compiler ASM Libs and Add-Ons Library Category AVR-DOS AVR-DOS BCCARD BCCARD EXTENDED I2C I2C FM24C16 I2C FM24C64_256 I2C I2C MULTIBUS I2C I2CV2 I2C I2C_TWI-MULTI I2C TWI I2C_USI I2C/USI I2CSLAVE I2C I2C_USI_SLAVE I2C/USI FM25C256 SPI HEXVAL Conversion MCSBYTE Conversion MCSBYTEINT Conversion MODBUS MODBUS LCD4BUSY LCD LCD_RX1602A5 LCD LCD4 LCD LCD4E2 LCD lcd4_anypin_oled_RS0010 LCD GLCD LCD GLCDSED LCD PCF8533 LCD LCD-EPSON LCD GLCDST7565R LCD GLCDSSD1325_96x64 LCD GLCDEADOGMXL240-7-I2C LCD GLCDdSSD1306-I2C LCD FT800 LCD PULSEIN IO PS2 Lib PS2 AT_EMULATOR PS2 PS2MOUSE_EMULATOR PS2 DATETIME DATE TIME EUROTIMEDATE DATE TIME SPISLAVE SPI TCPIP TCPIP M128-1WIRE-PORTF 1WIRE TVOUT VIDEO USB USB RAINBOWBSC WS2812/RAINBOW SERIN SERIAL BASCOM Language Reference -#- #IF , #ELSE , #ENDIF , #AUTOCODE -$- $ASM , $BAUD , $BAUD1 , $BIGSTRINGS, $BGF , $BOOT , $CRYSTAL , $DATA , $DBG , $DEFAULT , $EEPLEAVE , $EEPROM , $EEPROMHEX , $EEPROMSIZE, $EXTERNAL , $HWSTACK , $INC , $INCLUDE , $INITMICRO , $LCD , $LCDRS , $LCDPUTCTRL , $LCDPUTDATA , $LCDVFO , $LIB , $LOADER , $LOADERSIZE , $MAP , $NOCOMPILE , $NOINIT , $NORAMCLEAR , $NORAMPZ , $PROJECTTIME, $PROG , $PROGRAMMER , $REGFILE , $RESOURCE , $ROMSTART $SERIALINPUT, $SERIALINPUT1 , $SERIALINPUT2LCD , $SERIALOUTPUT , $SERIALOUTPUT1 , $SIM , $SWSTACK , $TIMEOUT , $TINY , $WAITSTATE , $XRAMSIZE , $XRAMSTART , $XA , $CRYPT , $NOTRANSFORM , $FILE , $AESKEY , $XTEAKEY , $STACKDUMP , $NOFRAMEPROTECT , $FRAMEPROTECT , $FORCESOFTI2C , $REDUCEIVR , $BOOTVECTOR -1- 1WRESET , 1WREAD , 1WWRITE , 1WSEARCHFIRST , 1WSEARCHNEXT ,1WVERIFY , 1WIRECOUNT -A- ABS , ADR, ADR2 , ACOS , ALIAS , ASC , ASIN , ATN , ATN2 , AESENCRYPT , AESDECRYPT , AND -B- BASE64DEC , BASE64ENC , BAUD , BAUD1-BAUDx, BCD , BIN , BITS , BINVAL , BIN2GRAY , BITWAIT , BYVAL , BOX, BOXFILL , BSAVE , BLOAD , BUFSPACE , BREAK -C- CALL ,CHARPOS, CIRCLE , CHECKFLOAT, CHECKSUM , CHECKSUMXOR, CHR , CLEAR , CLS , CLOCKDIVISION , CLOSE , CLOSESOCKET , CPEEKH , CONFIG , CONFIG ACI , CONFIG ADC , CONFIG ADCx, CONFIG BASE , CONFIG BCCARD , CONFIG CLOCK , CONFIG COM1 , CONFIG COM2 , CONFIG DAC, CONFIG DATE , CONFIG EEPROM , CONFIG PS2EMU , CONFIG ATEMU , CONFIG DMXSLAVE, CONFIG EXTENDED_PORT , CONFIG I2CSLAVE , CONFIG INPUT , CONFIG GRAPHLCD , CONFIG KEYBOARD , CONFIG OSC, CONFIG PRIORITY , CONFIG TIMER0 , CONFIG TIMER1 , CONFIG LCDBUS , CONFIG LCDMODE , CONFIG 1WIRE , CONFIG LCD , CONFIG SERIALOUT , CONFIG SERIALIN , CONFIG SPI , CONFIG SPIx, CONFIG LCDPIN , CONFIG SDA , CONFIG SCL , CONFIG SYSCLOCK , CONFIG DEBOUNCE , CONFIG WATCHDOG , CONFIG X10 , CONFIG XRAM , CONFIG PORT , COUNTER0 AND COUNTER1 , CONFIG TCPIP , CONFIG TCXX , CONFIG TWISLAVE ,CONFIG SINGLE, CONFIG USB, CONST , COS , COSH , CRC8 , CRC16 , CRC32 , CRC16UNI , CRYSTAL , CPEEK , CPEEKH , CURSOR , CONFIG DP , CONFIG VPORT , CONFIG ERROR , CONFIG POWER REDUCTION, CONFIG EVENT_SYSTEM , CONFIG DMA , CONFIG DMACHx , CONFIG SUBMODE , CONFIG POWERMODE , CONFIG XPIN , CONFIG CANBUSMODE, CONFIG CANMOB , CANBAUD, CANRESET, CANCLEARMOB, CANCLEARALLMOBS, CANSEND, CANRECEIVE , CANID, CANSELPAGE, CANGETINTS , CHDIR , CONFIG USI , CONFIG TWIXSLAVE , CMD8 , CMD16 , CMD32 , CONFIG FT800 , CONFIG RAINBOW , CLEARATTR , COMPARE , EDMA , EDMAx , CONFIG INPUTBIN , CONFIG TWI1 , CRCMB , CONFIG MODBUS , CONTINUE , CRC8UNI -D- DATE , DATA , DATE$ , DBG , DEBOUNCE , DECR , DAYOFWEEK , DAYOFYEAR , DriveGetIdentity , DriveWriteSector , DriveReadSector ,DEBUG, DECLARE FUNCTION , DECLARE SUB , DEFXXX , DEFLCDCHAR , DEG2RAD , DELAY , DIM , DISABLE , DISPLAY , DO-LOOP , DTMFOUT , DISKFREE , DIR , DriveReset , DriveInit , DELCHAR , DELCHARS -E- ECHO , ELSE , ENABLE , END , EXIT , EXP , EOF , ENCODER -F- FIX , FORMAT , FOR-NEXT , FOURTHLINE , FRAC , FUSING , FLUSH , FREEFILE , FILEATTR , FILEDATE , FILETIME , FILEDATETIME , FILELEN , FLIP -G- GET , GETADC , GETKBD , GETATKBD , GETRC , GETRC5 , GLCDCMD , GLCDDATA , GOSUB , GOTO , GRAY2BIN , GETDSTIP , GETDSTPORT , GETSOCKET , GETTCPREGS , GETREG , GETATTR -H- HEX , HEXVAL , HIGH , HIGHW , HOME -I- I2CINIT , I2CRECEIVE , I2CSEND , I2CSTART, I2CREPSTART, I2CSTOP,I2CRBYTE,I2CWBYTE , IDLE , IF-THEN-ELSE-END IF , INCR , INITLCD , INKEY , INP , INPUTBIN , INPUTHEX , INPUT , INSTR , INT , ISCHARWAITING , INITFILESYSTEM , IP2STR , INSERTCHAR -K- KILL -L- LCASE , LCD , LCDAT , LCDCMD, LCDDATA, LCDAUTODIM , LEFT , LEN , LINE , LOAD , LOADADR , LOADLABEL , LOADWORDADR , LOCAL , LCDCONTRAST , LOCATE , LOG , LOG10 , LOOKDOWN , LOOKUP , LOC , LOF , LOOKUPSTR , LOW , LOWERLINE , LTRIM , LINE INPUT , LCDFONT -M- MACRO , MAKEBCD , MAKEDEC , MAKEMODBUS , MAKEINT , MID , MAX , MIN , MOD , MKDIR , MANCHESTERDEC, MANCHESTERENC -N- NAME , NBITS , NOT , NOP -O- ON INTERRUPT ,ON VALUE , OPEN , OUT , OR -P- PEEK , POKE , POPALL , POWER mode , POWER , POWERDOWN , POWERSAVE , PRINT , PRINTBIN , PSET , PULSEIN , PS2MOUSEXY , PUT , PULSEOUT , PUSHALL -Q- QUOTE , QSIN , QCOS -R- RAD2DEG , RC5SEND , RC6SEND , READ , READEEPROM , READHITAG , READMAGCARD , REM , REPLACECHARS , RESET , RESTORE , RETURN , RIGHT , RND , ROTATE , ROUND RTRIM , READSIG , RMDIR , RGB8TO16 , RB_ADDCOLOR, RB_ANDCOLOR, RB_ORCOLOR, RB_SUBCOLOR, RB_CLEARSTRIPE , RB_CLEARCOLORS , RB_FILL , RB_FILLCOLORS , RB_FILLSTRIPE , RB_SELECTCHANNEL, RB_SEND, RB_SETCOLOR , RB_SWAPCOLOR , RB_ROTATELEFT, RB_ROTATERIGHT, RB_SHIFTLEFT, RB_SHIFTRIGHT , RB_CHANGEPIN , RB_SETTABLECOLOR , RB_GETCOLOR , RB_LOOKUPCOLOR , RB_COLOR , RB_COPY , REDO -S- SENDSCAN , SENDSCANKBD , SELECT CASE - END SELECT , SET , SETFONT , SERIN , SEROUT , SECOFDAY , SECELAPSED , SYSDAY , SYSSEC , SYSSECELAPSED , SETTCP , SGN , SHIFT , SHIFTCURSOR , SHIFTIN , SHIFTOUT , SHIFTLCD , SHOWPIC , SHOWPICE , SIN , SINH , SONYSEND , SOUND , SPACE , SPC , SPIIN , SPIINIT , SPIMOVE , SPIOUT , SQR , START , STCHECK , STOP , STR , STRING , SUB , SOCKETSTAT , SOCKETCONNECT , SOCKETLISTEN , SEEK , SWAP , SPLIT , SETTCPREGS , SETIPPROTOCOL , SORT , STR2DIGITS ,SETREG , SNTP , SOCKETCLOSE, SOCKETDISCONNECT , SETATTR , SPI1IN , SPI1INIT , SPI1MOVE , SPI1OUT -T- TIME , TCPWRITE , TCPWRITESTR , TCPREAD , TCPCHECKSUM , TAN , TANH , THIRDLINE , TIME$ , TRIM , TOGGLE , TCPREADHEADER -U- UCASE , UPPERLINE , UDPREAD , UDPWRITE , UDPWRITESTR , UDPREADHEADER, URL2IP -V- VAL , VARPTR , VER , VERSION -W- WAIT , WAITKEY , WAITMS , WAITUS , WRITE , WHILE-WEND , WRITEEEPROM , WR8 , WR16 , WR32 -X- X10DETECT , X10SEND , XTEADECODE , XTEAENCODE , XOR Keyword Reference Top Previous Next 1WIRE 1Wire routines allow you to communicate with Dallas 1wire chips. 1WRESET , 1WREAD , 1WWRITE , 1WSEARCHFIRST , 1WSEARCHNEXT ,1WVERIFY , 1WIRECOUNT CAN CONFIG CANBUSMODE, CONFIG CANMOB, CANBAUD, CANRESET, CANCLEARMOB, CANCLEARALLMOBS, CANSEND, CANRECEIVE , CANID, CANSELPAGE, CANGETINTS Conditions and Loops Conditions execute a part of the program depending on a condition being True or False IF-THEN-ELSE-END IF , WHILE-WEND , ELSE , DO-LOOP , SELECT CASE - END SELECT , FOR-NEXT , CONTINUE, REDO Configuration Configuration commands initialize the hardware to the desired state. CONFIG , CONFIG ACI , CONFIG ADC , CONFIG ADCx , CONFIG BCCARD , CONFIG CLOCK , CONFIG COM1 , CONFIG COM2 , CONFIG DAC , CONFIG DATE , CONFIG DMXSLAVE, CONFIG EEPROM ,CONFIG EXTENDED_PORT , CONFIG PS2EMU , CONFIG ATEMU , CONFIG I2CSLAVE , CONFIG INPUT, CONFIG GRAPHLCD , CONFIG KEYBOARD , CONFIG TIMER0 , CONFIG TIMER1 , CONFIG LCDBUS , CONFIG LCDMODE , CONFIG 1WIRE , CONFIG LCD , CONFIG OSC, CONFIG SERIALOUT , CONFIG SERIALIN , CONFIG SPI , CONFIG SPIx, CONFIG SYSCLOCK , CONFIG LCDPIN , CONFIG PRIORITY , CONFIG SDA , CONFIG SCL , CONFIG DEBOUNCE , CONFIG WATCHDOG , CONFIG PORT , COUNTER0 AND COUNTER1 , CONFIG TCPIP , CONFIG TWISLAVE , CONFIG SINGLE , CONFIG X10 , CONFIG XRAM , CONFIG USB , CONFIG DP , CONFIG TCXX , CONFIG VPORT CONFIG ERROR , CONFIG POWER REDUCTION, CONFIG EVENT_SYSTEM , CONFIG DMA , CONFIG DMACHx , CONFIG SUBMODE , CONFIG POWERMODE , CONFIG XPIN , CONFIG FT800 , CONFIG I2CBUS , CONFIG EDMA , CONFIG EDMAx , CONFIG INPUTBIN , CONFIG MODBUS Conversion A conversion routine is a function that converts a number or string from one form to another. BCD , GRAY2BIN , BIN2GRAY , BIN , MAKEBCD , MAKEDEC , MAKEINT , FORMAT , FUSING , BINVAL , CRC8 , CRC16 , CRC16UNI , CRC32 , HIGH , HIGHW , LOW , AESENCRYPT , AESDECRYPT , FLIP , CRCMB , CRC8UNI , MANCHESTERDEC, MANCHESTERENC DateTime Date Time routines can be used to calculate with date and/or times. DATE , TIME , DATE$ , TIME$ , DAYOFWEEK , DAYOFYEAR , SECOFDAY , SECELAPSED , SYSDAY , SYSSEC , SYSSECELAPSED Delay Delay routines delay the program for the specified time. WAIT , WAITMS , WAITUS , DELAY Directives Directives are special instructions for the compiler. They can override a setting from the IDE. $ASM , $BAUD , $BAUD1 , $BIGSTRINGS , $BGF , $BOOT , $CRYSTAL , $DATA , $DBG , $DEFAULT , $EEPLEAVE , $EEPROM , $EEPROMHEX , $EEPROMSIZE, $EXTERNAL , $HWSTACK , $INC , $INCLUDE , $INITMICRO , $LCD , $LCDRS , $LCDPUTCTRL , $LCDPUTDATA , $LCDVFO , $LIB , $LOADER , $LOADERSIZE , $MAP , $NOCOMPILE , $NOINIT , $NORAMCLEAR , $NORAMPZ , $PROJECTTIME, $PROG , $PROGRAMMER , $REGFILE , $RESOURCE , $ROMSTART $SERIALINPUT, $SERIALINPUT1 , $SERIALINPUT2LCD , $SERIALOUTPUT , $SERIALOUTPUT1 , $SIM , $SWSTACK , $TIMEOUT , $TINY , $WAITSTATE , $XRAMSIZE , $XRAMSTART , $XA , $CRYPT , $NOTRANSFORM , $FILE , $AESKEY , $XTEAKEY , $STACKDUMP , $NOFRAMEPROTECT , $FRAMEPROTECT , $FORCESOFTI2C , $BOOTVECTOR , $REDUCEIVR , $TYPECHECK , $NOTYPECHECK File File commands can be used with AVR-DOS, the Disk Operating System for AVR. BSAVE , BLOAD , GET , VER , DISKFREE , DIR , DriveReset , DriveInit , LINE INPUT , INITFILESYSTEM , EOF , WRITE , FLUSH , FREEFILE , FILEATTR , FILEDATE , FILETIME , FILEDATETIME , FILELEN , SEEK , KILL , DriveGetIdentity , DriveWriteSector , DriveReadSector , LOC , LOF , PUT , OPEN , CLOSE , CHDIR , MKDIR , RMDIR , NAME , GETATTR , SETATTR , CLEARATTR Graphical LCD Graphical LCD commands extend the normal text LCD commands. GLCDCMD , GLCDDATA , SETFONT , LINE , PSET , SHOWPIC , SHOWPICE , CIRCLE , BOX , RGB8TO16 I2C I2C commands allow you to communicate with I2C chips with the TWI hardware or with emulated I2C hardware. I2CINIT , I2CRECEIVE , I2CSEND , I2CSTART, I2CREPSTART, I2CSTOP,I2CRBYTE,I2CWBYTE IO I/O commands are related to the I/O pins and ports of the processor chip. ALIAS , BITWAIT , TOGGLE , RESET , SET , SHIFTIN , SHIFTOUT , DEBOUNCE , PULSEIN , PULSEOUT Micro Micro statements are specific to the micro processor chip. IDLE , POWER mode , POWERDOWN , POWERSAVE , ON INTERRUPT , ENABLE , DISABLE , START , END , VERSION , CLOCKDIVISION , CRYSTAL , STOP Memory Memory functions set or read RAM , EEPROM or flash memory. ADR , ADR2 , WRITEEEPROM , CPEEK , CPEEKH , PEEK , POKE , OUT , READEEPROM , DATA , INP , READ , RESTORE , LOOKDOWN , LOOKUP , LOOKUPSTR , LOADADR , LOADLABEL , LOADWORDADR , MEMCOPY , GETREG , SETREG , VARPTR Remote Control Remote control statements send or receive IR commands for remote control. RC5SEND , RC6SEND , GETRC5 , SONYSEND RS-232 RS-232 are serial routines that use the UART or emulate a UART. BAUD , BAUD1, BUFSPACE , CLEAR, ECHO , WAITKEY , ISCHARWAITING , INKEY , INPUTBIN , INPUTHEX , INPUT , PRINT , PRINTBIN , SERIN , SEROUT , SPC , MAKEMODBUS SPI SPI routines communicate according to the SPI protocol with either hardware SPI or software emulated SPI. SPIIN , SPIINIT , SPIMOVE , SPIOUT , SPI1IN , SPI1INIT , SPI1MOVE , SPI1OUT String String routines are used to manipulate strings. ASC , CHARPOS, UCASE , LCASE , TRIM , SPLIT , LTRIM , INSTR , SPACE , STRING , RTRIM , LEFT , LEN , MID , RIGHT , VAL , STR , CHR , CHECKSUM , CHECKSUMXOR, HEX , HEXVAL , QUOTE , REPLACECHARS , STR2DIGITS , DELCHAR, DELCHARS , INSERTCHAR TCP/IP TCP/IP routines can be used with the W3100/IIM7000/IIM7010/W5100/W5200/W5300 modules. BASE64DEC , BASE64ENC , IP2STR , UDPREAD , UDPWRITE , UDPWRITESTR , TCPWRITE , TCPWRITESTR , TCPREAD , GETDSTIP , GETDSTPORT , SOCKETSTAT , SOCKETCONNECT , SOCKETLISTEN , GETSOCKET , SOCKETCLOSE , SETTCP , GETTCPREGS , SETTCPREGS , SETIPPROTOCOL , TCPCHECKSUM , SOCKETDISCONNECT , SNTP , TCPREADHEADER , UDPREADHEADER, URL2IP Text LCD Text LCD routines work with normal text based LCD displays. HOME , CURSOR , UPPERLINE , THIRDLINE , INITLCD , LOWERLINE , LCD , LCDAT , FOURTHLINE , DISPLAY , LCDCONTRAST , LOCATE , SHIFTCURSOR , DEFLCDCHAR , SHIFTLCD , CLS , LCDAUTODIM , LCDCMD, LCDDATA , LCDFONT Trig & Math Trig and Math routines work with numeric variables. ACOS , ASIN , ATN , ATN2 , EXP , RAD2DEG , FRAC , TAN , TANH , COS , COSH , LOG , LOG10 , ROUND , ABS , INT , MAX , MIN , SQR , SGN , POWER , SIN , SINH , FIX , INCR , DECR , DEG2RAD , CHECKFLOAT , MOD , QSIN , QCOS , AND, OR , XOR , NOT Various This section contains all statements that were hard to put into another group CONST , DBG , DECLARE FUNCTION , DEBUG, DECLARE SUB , DEFXXX , DIM , DTMFOUT , EXIT , ENCODER , GETADC , GETKBD , GETATKBD , GETRC , GOSUB , GOTO , LOCAL ,ON VALUE , POPALL , PS2MOUSEXY , PUSHALL , RETURN , RND , ROTATE , SENDSCAN , SENDSCANKBD , SHIFT , SOUND , STCHECK , SUB , SWAP , VARPTR , X10DETECT , X10SEND , READMAGCARD , REM , BITS , BYVAL , CALL , #IF , #ELSE , #ENDIF , READHITAG , SORT , XTEADECODE , XTEAENCODE , BREAK , COMPARE , NOP RAINBOW WS2812 Rainbow or WS2812 LED statements and functions. CONFIG RAINBOW , RB_ADDCOLOR, RB_ANDCOLOR, RB_ORCOLOR, RB_SUBCOLOR, RB_CLEARSTRIPE , RB_CLEARCOLORS , RB_FILL , RB_FILLCOLORS , RB_FILLSTRIPE , RB_SELECTCHANNEL, RB_SEND, RB_SETCOLOR , RB_SWAPCOLOR , RB_ROTATELEFT, RB_ROTATERIGHT, RB_SHIFTLEFT, RB_SHIFTRIGHT , RB_CHANGEPIN , RB_SETTABLECOLOR , RB_GETCOLOR , RB_LOOKUPCOLOR , RB_COLOR , RB_COPY FT800-FT801-FT810 CMD8 , CMD16 , CMD32 , RD8 , RD16 , RD32 , WR8 , WR16 , WR32 XMEGA READSIG , ATXMEGA What is new in 2082 Top Previous Next - rearranging memory order for usb support caused a bug in config clock : the date time bytes are not mapped after each other. Fixed. - START/STOP statements worked on the wrong register for the TINY1634 - i2c_twi_multi lib had a problem in the readbyte function. - SPIMOVE added for Xmega - split screen did not allow copy & paste - USI slave support added for tiny1634 - All DAT files are now stored in a sub folder named DAT. This means you need to copy your DAT file to this folder if you made custom DAT files. - some registers of tcc1 were missing in xmega D3 series - read only files could not be opened anymore. fixed. - On win10 you could get a HID error message. - w5500 tcp lbx : removed RST status bit check since the bit never becomes 0 and hangs the code - url2ip bug fix. one byte of the IP address could get trashed - url2ip added to w5500 - new samples for w5500 wiznet chip - accessing a zero based array inside a sub coulld result in an index error. - simulator did not support writing to xmega portx_CLR _SET and TGL registers - using search in files function could result in 'out of bound' error. - manchesterEnc and manchesterDec functions added for manchester coding/decoding - assigning a byte with a string constant with spaces, resulted in 0, not 32. - VARPTR() function returned &H1000 too much for Xmega ERAM data type. - using getadc() with 2 numeric parameters or constants like : getadc(4,&H20) would not set the right bits. - a new option let you select if the programmer settings are stored with the project or are global - i2csend and i2creceive updated for xmega. after the start/slave address, the status is now checked and does not send data in case of a bus problem. this to prevent a hangup in the twi logic. - printing supports selection of text and page range now. you need to use print preview for this. - OUT instruction did not clear RAMPZ for Xmega with ROM > 64KB and normal SRAM. - PS2MOUSEXY accepts an additional optional parameter for mouse wheel support. Notice that you MUST download an update of the ps2 lib add on - config spi on non xmega did not support the extended mode for HW SPI - config tcpip now supports SPI1 for the SPI bus - windows 10 DEP and ASLR support added. - printbin: when using automatic rs485 and printing a long/dword constant on a chip with extended port register, R23 was trashed. Example : printbin &HABCDEF00 - FLIP() function resulted in an error about $REGS - terminal emulator component is replaced in order to support windows DEP/ASLR. This means that some features from the terminal emulator have changed. - printbin can print a variable amount of bytes now. while ; is used to separate multiple variables, the comma can be used to specify the amount of bytes like : printbin ar(1) , numbytes ; othervar this makes the syntax compatible with the old syntax. We recommend to use the new syntax - terminal emulator custom messages extended to 16 - UPDI programmer added for new AVR processors with UPDI interface. - A table is added to $LOADER with the size of maxwordbit. This constant depends on the number of flash pages. FILE LOCATION With DOS things were simple : all files could go in a folder and sub folder. To make a backup all you had to do was using XCOPY. With Windows things are not so simple : files are located all over the PC. Some folders are write protected and to make a backup is not so simple. A lot of customers are looking for the SAMPLE files. These are put in the documents folder and can be accessed using the File, Open Sample option. In 2082 the preferred folder for installation is C:\MCS\BASCAVR2082 But of course you are free to install in any other folder of your choice. The samples are installed in a sub folder of the application folder too. In the Environment Options of the IDE you can specify which folder you want to use for the sample files. About UPDI The new UPDI processors have a total different architecture compared to normal AVR. In fact the differences are similar to XMEGA. For this reason we refer to these processors as XTINY since they are tiny Xmega processors. Because of the work and support for XMEGA fresh in mind, the actual UPDI compiler/DAT support will be available very soon in a next update as an add on. The TINY816/817 will be the first processor to be supported. What is new in 2081 Top Previous Next - CONTINUE statement added - REDO statement added - NOP is now also a BASCOM BASIC statement - The editor supports jump to implementation : hold CTRL key and hover the mouse over an identifier. When it becomes underlined and blue you can click it with the left mouse key. Use CTRL+BACKSPACE to jump back - when defining a constant named Updateeprom , the eeprom will be updated. which means that the value will only be written when it differs. The value of the constant does not matter. - config timer1 for tiny 25/45/85 set the wrong register bits. - the watchdog is disabled as part of the init procedure. it is now disabled BEFORE the optional call to init_micro and not after as in 2079. - passing string constants with embedded {034} resulted in an extra (unwanted) space. - accessing passed string array in sub without length info, but with constant index failed. - crcmb funtion added to help. (checksum for modbus) - for xmega i2cstop you can define a constant named _TWI_STOP_1 or _TWI_STOP_2 to change the behavior. - makemodbus() function 1, 2 and 4 added to modbus.lib - support for xmega added to getrc - PDF download now also checks/download the BASCOM-AVR manual - PRINTBIN did not accept a constant for the optional channel : printbin #someconst. Fixed. - update from within the application simplified. see help. - printbin raised error while printing multiple variables - simulator did not show proper hex value for single variables. - fusing which uses ftoa uses a table which could be loaded on a page boundary. this could lead to rampz problems. fixed. - crc8UNI added for normal crc8 CCITT - config clock additional option : highESR=1 to enable high ESR mode in xmega with 32 bit RTC - FM24C64_256-XMEGA.lib added for xmega. read the lib notes. - tcpip-w5500.lbx has been updated to support usage from boot space. See $loader - stk500 board. osc can be set from menu - using spimove() inside a sub with a parameter for the count, would load the wrong data. - i2cwbyte would raise an error if a multi dim array was used. - get/put/seek in AVR-DOS used in combination with $bigstrings would fail for numeric data - xmega i2cstop has two new optional mode. See help. - CONFIG SPI has a new option : EXTENDED=1 to have extended data size reading/writing. - support for rgbW leds added (ws2812 with extra white led) - CONFIG USI has a new option to support optional pins. What is new or changed in 2080 Top Previous Next - tiny461 and tiny861 only did set pcie0 when you enable the PCINT because there is just one interrupt in the chip. In 2080, both PCIE0 and PCIE1 are enabled/disabled. - added m48PB, m88PB, 168PB and m328PB dat files. - new Rainbow functions : RB_Color and RB_Copy added by Galahat - simulator did not show maximum values of DWORD correct. - RB_GETCOLOR and RB_LOOKUPCOLOR functions did return false result when index was a variable. - some font problems solved. - simulator could crash for xmega processors. - when using non-mono font like Arial, text selection does not work properly. Use a font like CONSOLAS. - Added option 'Use Monofont' for backwards compatibility - Some new atmel PDF files could not be loaded with the PDF viewer. Viewer is rewritten and requires a new DLL named BASPDF.DLL - getadc() on m640.m1280/m2560 or any other processor with 6 mux bits did not set mux5 bit for getadc(32) and higher. - generic byte compare() function added, based on code and idea from MWS. (Magic White Smoke) - varexist() did not support ALIAS. - XMega64A1-SRAM 4-Port-Sample.bas sample added for setup EBI 4 port on XMega. See also Adding XRAM to XMEGA using EBI - when bascom-avr.xml options file exists in the bascom application folder, that option file will be used. - format is extended to use a variable for the mask. - config xpin did not support alias for the pin. - bufspace() did not support UART 5-8 - INSERTCHAR and DELCHAR use Z pointer which must be cleared for XMEGA. fixed in mcs.lib - programmer did not fetch correct chip from editor when code was not saved. this would give a chip mismatch. - assigning a negative value to a dword did not throw an error. - code explorer can show estimated stack usage. - higher standard baud rates added to terminal emulator - added support for EDMA in xmega8/16/32 E5. See config EDMA - version() function did not append to string but would overwrite existing string data. - right() adds an additional null byte when a numeric constant is used for the number of characters to copy. - new dim option to specify multiple items : dim a,b,c,d as byte failed when using multiple indexed items. - all dat files updated with CONFIG information. - printing values from multi index variables failed : print index(index1,index2) - m1284pdef.dat updated with missing TIFR3 register. - more fonts in various sizes from Adam Siwek. - power() function for doubles did not work correct when assigned to a function - some new atmel PDF files can not be loaded with the PDF viewer. Viewer is rewritten. - SSD1306 i2c oled driver updated for Xmega. - m649A and m649P dat files added. - LCDFONT prm, added. prm selects the font table (0-3) of a text LCD. - CONFIG POWER_REDUCTION set register to 0 in some conditions. Also added LCD and other new Xmega power reduction options. - CONFIG OSC extended with calibration register settings and DFLL. - val() for doubles has a bug for XMega >64KB chips - added flip(byte) function to mirror bits in a byte - xmega128B3 dat file added - readsig also works for normal AVR processors. - inputbin and printbin load 1 element too many with arrays using base 0. - config inputbin added to allow reading packets of up to 64 KB - added support for LCD text OLED RS0010 lcd4_anypin_oled_RS0010.lib - FT81x support added - M324PB dat file added. - I2CINIT enhanced for multiple TWI - I2C_TWI-MULTI.lib added to support multiple TWI busses. - second SPI on m328PB added : INIT1SPI, SPI1OUT, SPI1MOVE, SPI1IN - user donated library I2C DOGS104 driver, SSD1803A included. - URL2IP(url) function added to W5100 to do DNS lookup using google DNS server - when defining a const Updateeprom , the eeprom will be updated. which means that the value will only be written when it differs - BASE64ENC and BASE64DEC can work on byte arrays too. 2017, 2080 release - SGN extended to byte, integer, word, dword and long - LOADLABEL assigns a 24 bit address when used with a DWORD - CTRL+SPACE for code help. What is new in 2078-2079 Top Previous Next Beta version 2079 - Support for WS2812 RGB led : CONFIG RAINBOW. This is the rainbow lib from Galahat, see : http://bascom-forum.de/mediawiki/index.php/Rainbow_Lib - SETATTR and CLEARATTR added to AVR-DOS, by Josef. - shift & rotate left/right did not work for xmega port registers - IDE : improved speed for showing deadcode/unused variables - IDE : stacktrace speed up. big projects made the stacktrace slow. - included FT801 support. See CONFIG FT800. Notice that the INC files have been renamed into FT80x - fixed attiny261,461 and 861 interrupt entries. this chip has only 1 pcint. - added check when $loadersize and $boot are combined. - Dim supports a list ; dim a,b,c,d as byte. It also supports identifiers like %,#,& and ! - Font Editor plugin is replaced by integrated Font Editor: Tools, Font Editor - Sample added for USI Slave lib - fonts contributed by Adam Siwek included. You can find them in the Samples\LCDgraph\Fonts folder. - report can be opened in IDE as text file. - mySmartUSB light programmer support added. - support added for W5500 tcp/ip chip - W5500 socketconnect has a 4-th parameter : nowait. When you make it 1, there is no wait for connection. - $ROMSTART added : $romstart = &H8000 , will let the code start at &H8000. Default is 0. - jtag ice mkII programmer new firmware 7.26 from AVR studio resulted in signoff problem. Workaround implemented. - editor can show unused code in conditional compilation. Edit, Show Excluded Code menu option. - usbasp programmer updated. chosen clock frequency will work. - makemodbus() did not support locals/passed parameters properly. - crc16 can now directly read a range from eeprom memory to calculate a checksum for you. To enable it, just add const CRC16_EEPROM=1 to the beginning of your code. - simulator fix for xmega low IO registers. registers were simulated with a 32 byte offset as in plain AVR. - config lcd has 2 new options : BEFORE and AFTER. with a parameter value of 1 a sub will be called _lcdBefore and _lcdAfter just before the LCD is used. This allows for example to turn off interrupts when executing LCD code. Only text LCD is supported. - getadc() when used on normal AVR with offset parameter, and both parameters numeric will give an error when MUX5 bit must be set. Use getadc() with just the channel parameter. - multi dim arrays, added ERAM byte support, and used registers are saved now. - saving programming buffer as HEX file created wrong HEX files which would not load in AVR Studio. This would occur for chips with multiple segments like xmega128 - Full Kamprog support added. - multi dim arrays had no check on invalid index value (non dimmed) - using a constant float without leading 0 resulted in an error message : var= var + .12344 - INPUT did not support DWORD. - added user definable command buttons to terminal emulator. - using {} in constants was not working as expected : Const Cmd_suffix_ver1 = Asc( "{013}") was not interpreted as 13 but 123 (the { sign) - changed PDF download from HTTP to FTP. This is quicker and better for the load of the server. PORT 211 is used for FTP. So you need to have port 211 open on your firewall. - atxmega128c3 added. - FT800, vertex2ii , the X is clipped. Change call in sub vertex2II into Cmd32 _vertex2ii(___wtmpb , R18 , R17 , R16) - support for EADOGXL240-7 I2C added, see eadogxl240-7.bas. This is a customer sponsored lib. - added support for SSD1306 I2C OLED, see SSD1306-I2C.BAS. - i2c multi bus lib did not clear ERR bit correctly. - when a multi dim array is only used within sub/functions and submode=new is used, an error was raised since the index table was not written at that stage. - multi dim arrays can only be used to read/assign variables. Using them in functions and statements will not work. - str() can have an optional parameter to specify the amount of digits. This works for double, but now also for singles. - MOD for singles changed in fp_trig.lib so it uses the same algorithm as excel/VBA. - FOR..NEXT with WORD data type and STEP with values other than 1 failed : for w=1 to 10 step 2 - when opening a single file in non-project mode, the code explorer does not get updated until you set the cursor on the code. This also resulted in not updating the pinout viewer. - R0-R31 internal variables are now exposed as byte variables. This is simpler than using getreg/setreg. - added option to skip eeprom cell test. This allows to write all FF to the EEPROM whithout erasing the chip. - terminal emulator font color could not be selected from the font dialog. - various programmers : added chip name to info panel when chip does not match. no match will result in a red font, a match will show in green. - added an error message when $hwstack,$swstack and $framesize are missing from the source. Also put back compatibility to 2077 when these directives are not specified. - hovering the indention line will show the begin of the structure in the tool tip (just try it). - Terminal emulator has 8 user definable buttons - SEROUT defaults to CONST SEROUT_EXTPULL=1 to be in Hi-Z mode. In this mode a pull up resistor is required. To use PORT output mode, set the constant to 0 : CONST SEROUT_EXTPULL=0 2.0.7.8.001 public release - changing a bit on a passed array inside a sub/function gave a bit index error. - while moving all single FP code to fp_trig.lib, some double (but WRONG) functions were moved to the top. It causes various problems. - clear buffer did not reset the RST pin in case CTS/RTS was used. - val()/asc2float contained a bug for converting big values not fitting into the mantissa. The exponent was not increased. - asc() can have an additional index parameter : byte=Asc(string|string constant[,index]). Use this instead of asc(mid( - user functions/subs can have a custom color - added support for i2c lcd display RX1602A5. Use : config lcd = 16x2 , chipset = st7032. See sample LCD-RX1602A5.bas - using overlay pointing to a string array resulted in a wrong overlay address. - additional XTEA2.LIB added. This lib complies with the original standard. - Tab order can be changed with drag and drop. - USI master TWI mode added. - when config submode=new was used, the syntax check could give false errors. - mkII programmer would give a warning about chip mismatch when atmel chip ID was the same. - pulsein.lib was missing from distribution. - documented beta switches $NOTYPECHECK, $TYPECHECK and $REDUCEIVR - when using a serial boot loader compiled with an older version, and when calling it from code (not after a reset) you need to reset the u2x flag in ucsrxA. Or you can compile both the bootloader and main code with the new version. When you want the old behaviour, you can remark the u2x constant in the dat file. - FLIP programmer will not erase EEPROM anymore. - use ALT key to select blocks of text in the editor. - hint window location fixed for multi monitors systems. - rgb8to16() function added to convert RGB8 to RGB16. - xmega, config OSC : when using external osc, the oscillator ready test was not working properly. enable the internal osc as a workaround in 2077. fixed in this release. - arduino leonardo can be programmed with myAVR MK2/AVR910. You need to give a manual reset before pressing F4. - attiny87 dat file contained an error : INTADR = 1 ; it was 2 but must be 1 - xmega spi length parameter supported globals only. now it supports locals and parameters as well. - syntax check gave errors when config submode=new was used in some cases. - 1wirecount returned with ERR set, even when sensors were found. - simulator has trace log option to dump all executed lines to a file. - error list content can be copied to clipboard with right mouse popup menu - xmega uarts 5-8 serial buffered output enable the wrong uart. - indention line colors can be customized. - proper indent will not indent comment - getkbd() required change for xmega. (xmega does not use port register for pull up) - added dword support to lookup() - config rnd=16|32 added to support bigger random numbers. - attiny441 stk500 settings changed. attiny441 and attiny841 verified with real chips. some mods made to the dat files. - increased internal constant string storage length to 1024. for cases like : s="some very long constant". previously the max size was 256. - xmegaE5 timers 4/5 support added. - xmegaE timer4/5 OVF bit need a manual reset, writing a 1 to intflags register. it is not cleared automatically. - xm128a1U dat file added - code folding added to editor. Press F11 to fold a sub/function - all project files can be placed in an archive (zip) file. - AVR-DOS, GET and PUT support $bigstrings - $boot extended to support >64KB processors. $boot can be used together with $inc to include a boot loader in your code. - FM25C256 example with BMA.bas sample added which demons xmega ramtron lib with shared bus. - baudX=value added for Xmega. This will change the baud rate on an xmega at run time. - special multi bus i2c added for normal AVR processors. See config i2cbus. - muli dimensional array support added like : dim ar(10,50,3,5,2). - long/dword data types added to SORT statement. - report extended with bit position in memory and length of dimensioned strings - Lookup supports a numeric variable too for the label : novar = LOOKUP( value, label|address). - soft spi supports DATA ORDER LSB and MSB - str() second optional parameter added to help. It specifies number of digits after the DP. Only for doubles. - m324/m164/m644/m1280 config timer0, disconnect option fixed. - settings xml file can be passed as parameter to allow different settings files and versions. - added option to show invisible characters. - added support for DWORD to SWAP - added insertionsort.bas sample - m64C1 and M32C1 dat files added. - History Backup option added : it will create a unique copy of the source file each time you save a file. - code explorer can show INC files under their own branch (options, environment, IDE) - Qsin and Qcos integer trig added. About MCS Electronics Top Previous Next About the Founder Since I was young, I was intrigued by remote control, robots, transmitters, in short, all kinds of electronics. I created countless electronic devices. I designed a lot of PCB's by hand using ink and later using tape. At the ETS(electronic technical school in Amsterdam) we had a Philips main frame with terminals which could be programmed in a simple form of BASIC. When working at Philips in Hilversum i also worked with an industrial computer that could be programmed in BASIC. The Apple II we got later on at the ETS could also be programmed in BASIC. When the ATARI came with the 1040ST and an affordable PCB design tool, I bought my first real computer. I bought the ATARI just for the purpose of PCB design. The netlists had to be manually entered. Only Dot matrix printers where available at that time. And the prints were not really usable. That only changed when laser printers became available. I found out that a nice BASIC interpreter, which was similar to GW-BASIC, was included in the OS(TOS). For some reason, I liked this language. It was easy to master and very intuitive. I made some programs for the PTT(now KPN) that were revolutionary at that time. For hobby purpose i used the 8052AH BASIC programmable processor from Intel. I made a lot of interfaces using PIO, relay, etc. My home was automated in 1986. Because of my work for the PTT i was also able to get caller info, something not available as a service yet. I used the 8052AH to show the caller info on an LCD. The 8052 was great but the UV eeproms had to be erased using UV light. It was slow. I found out, that Atmel made the 89C2051, which was a 20 pin chip with flash memory. I was excited to find out that there was a small micro processor that could be erased/reprogrammed without the need to UV erase the EPROM. In those days, electronic circuits consisted of numerous CMOS and TTL chips. I saw the 89C2051 as an ideal replacement for a lot of CMOS/TTL chips. It would make PCB design much simpler. So the 2051 became a replacement chip. Like a small black box chip. Now one was able to design his own chips! The idea to be able to change the behaviour of an electronic circuit, just by reprogramming it without using a solder iron, intrigued me. Today, it is a common practice, to update firmware, to fix bugs or add features. In 1993, it was not so common, at least not to my knowledge. I initially wrote a complete tool for DOS. I rewrote the tool, when I was reasonably satisfied that Windows 3.1 was stable. The tool was for my own usage. When I discovered that it would be usable to others, I decided to add Help files and a simulator and to sell it for a small fee. In 1995, MCS started to sell BASCOM-LT, a BASIC compiler for Windows 3.1. It was the first Windows application that offered a complete and affordable solution, editor, compiler, simulator and programmer. BASCOM-LT was a 8051 BASIC compiler. The reason it became popular was that it included a lot of functionality that was easy to use from BASIC. Using an LCD display was simple, just a configuration line to define the used pins and voila, a working application in minutes. When you needed a different LCD display, you could simply change the CONFIG line. When a different processor was needed, you only had to change the name of the definition file. No need for a lot of .h files. Another reason for its success, was that we hide much of the complexity for the user. No ASM to deal with, simple statements. Of course free updates and support. Small companies that used the BASIC Stamp also recognized another advantage : There was no need for expensive modules and the code ran much quicker. When Windows 95 became an industry standard, users also wanted a 32 bit version. A big part of BASCOM-LT was rewritten with the additional support for arrays and floating point (single). With the many different 8051 variants, it was impossible to support all the chips. Having device definition �DAT� files, made it easy for the user to configure the 8051 variants. When Atmel launched the AVR chip, the 8051 compiler was rewritten, once again, to support the powerful AVR chips. The result was BASCOM-AVR. The AVR chip has a lot of internal memory. It uses simple linear memory addressing. The best part, is that you can make the chip program itself. No wonder this chip family became so popular. Since the AVR chip is so powerful, we could extend the compiler as well. We could add features, which are almost impossible to add to the 8051. With more and more users, there was no way I could manage everything in my spare time. So in order to guarantee the future of BASCOM, I decided to work full time for MCS. Today, MCS is still a small company, with only 3 employees and a few contract workers. We believe in free updates and support. With the number of (demo) users, it is however not possible to support everybody. You need to realize that reading and answering emails is time consuming. Not to mention to duplicate used hardware. We are unique, in that we even support hardware! For a long time, we are working on a more professional version of the software. We occasionally add new features to the current BASCOM version. Note, that we do not provide details or time frames, for updates or for other features. Or main concern is support for new processors such as the Xmega, and maintenance. In order to migrate to a new version, it is important that you keep your software up to date. This will make migration more simple. Things we find important : · The environment. We reuse all usable packing material like foam, plastic bubbles, when we ship your order. · That everybody can use micro processors. They are like all other chips but you can define their behaviour. · Customer privacy: We keep your name, details and code confidential. We do not sell or share any of your details. · Free updates. They have been free since 1995 but there is no guarantee that they will remain free for ever. The intention is to keep them free. In order to apply for free updates you MUST register your software within 1 year. · Free, but limited, support. Limited only, because we do not have the resources to read/answer all emails. Professional users can get an SLA with guaranteed response time. This is a paid option/service. · Support for new chips. It is important to be able to support newly released chips. · The customer : We simply add what is requested most. It does not matter what, as long as it is requested a lot and it does makes sense and doesn't conflict with other features. · That you have fun with electronics, no matter where you live, no matter which religion you have, no matter how old you are, if you are male or female, purple or white. · That you can use the demo for free. The DEMO has no nag screens. You should purchase the full version if you use it commercial. Please do not use cracked software. Only download from the www.mcselec.com domain. Copies from other sites may contain spy ware, virus or other malware. When we detect a cracked version the compiler generates tiny bugs at random which are hard to detect. We ban all IP numbers of users with a cracked version. Mark Alberts MCS Electronics Custom Designs Top Previous Next MCS does produce hardware to support special options. Like the EM4095 Reference Design or the TCP TWI motherboard and adapter boards. We try to avoid SMD parts. In some cases this is not possible however. For a prototype or small series, through hole components are simple to use. We do this with the hobbyist in mind. So our reference designs use little SMD parts too. You can contact us also for : - custom bascom software - customer ASM drivers - windows software development - electronic or software projects - PCB design (Eagle) Application Notes Top Previous Next When you want to show your application at our web as a reference example on what you can achieve with BASCOM, we like to show it at our web, but of course with your permission. We never publish anything without your explicit permission. AN's are also welcome. When you developed a great AN you want to share with other BASCOM users, just send it and we will make an AN out of it. It is important that the comment in the source is in English. You can also share your code at the MCS Electronics user forum. Installation of BASCOM Top Previous Next After you have downloaded the ZIP file you need to UNZIP the file. On Windows XP, for the DEMO version, you may run the setupdemo.exe file from within the Zipped file. For the full version you should unzip the ZIP file. The commercial version comes with a license file in the form of a DLL. This file is always on the disk where the file SETUP.EXE is located. When explorer does not show this file, you must set the option in explorer to view system files (because a DLL is a system file). For the commercial version the setup file is named SETUP.EXE Some resellers might distribute the DLL file in a zipped file. Or the file might have the extension of a number like "123". In this case you must rename the extension to DLL. Make sure the DLL is in the same directory as the SETUP.EXE file. When you are using the DEMO version you don't need to worry about the license file. When you are installing on a NT machine like NT4 , W2000, XP, Vista, Win7, Win8 or Win10, you need to have Administrator rights. After installing BASCOM you must reboot the computer before you run BASCOM. The installation example will describe how the FULL version installs. This is almost identical to the installation of the DEMO version. Before installing the software : make sure you downloaded from mcselec.com domain. Or that you purchased from an authorized reseller. When in doubt you can always check the executable on your PC using your browser at virustotal.com. In fact it is good practice to check files before you install them. virustotal.com will use 50 or more virus scanners. This will give a good idea about the safety of a file. Run the SETUPDEMO.EXE (or SETUP.EXE) by double clicking on it in explorer. Depending on the windows version and your user rights, windows might give the following message : You need to click the YES button. The following window will appear: (screen shots may differ a bit) Click on the Next button to continue installation. The following license info window will appear: Read the instructions , select 'I accept the agreement' and press the Next button. The following window will be shown : Read the additional information and click the Next button to continue. Now the next screen will appear: You can select the drive and path where you like BASCOM to be installed. You can also accept the default value which is : C:\MCS\BASCAVR2082 or you can install into a folder like : C:\Program Files\MCS Electronics\BASCOM-AVR Microsoft likes software to be installed into the Program Files folder. But this also means that all sub folders must be stored elsewhere since all folders under Program Files are write protected by Windows. Using a user writable folder, all the files can be stored in one location. It is a good idea to install each new version into its own folder. This way, you can use multiple versions at the same time. As of version 2082, the settings file is stored in the application folder too. When you are finished click the Next Button to continue. When the directory exists, because you install a newer version, you will get a warning : In case of this warning, select Yes. Or select NO and select a different folder. You will now see the following window: You can select the folder where the sample files are installed. This can be : c:\usersDocuments\samples or c:\MCS\BASCAVR2082\Samples We recommend to use the second option so all files are placed under the application folder. After you made your choice, click the Next button. You are now presented with an optional component : parallel printer programming support. Nowadays there are plenty serial and USB programmers available. Only select this option when you still use the LPT port for ISP programming. Click the Next button to continue. You will now be presented a choice for the program group name and location. You can choose to create into a new Program Group named 'BASCOM-AVR' , or you can modify the name, or install into an existing Program Group. Press the Next-button after you have made your choice. Now the files will be installed. After the main files are installed, some additional files will be installed. This depends on the distribution. These additional files can be PDF files when the program is distributed on a CD-ROM. When the installation is ready you will see the last screen : You have to reboot your computer when you want to make advantage of the programmers that BASCOM supports. You can also do this at a later stage. The BASCOM-AVR Program folder is created: You can view the "Read me" and "License" files content and you can start BASCOM-AVR. BASCOM supports both HTML Help and old Win help(HLP). The HLP file is not distributed in the setup. You need to use the Update Wiz to download it. But it is advised to use the HTML-Help file. When you used to use the HLP file, and find it missing now, turn on 'Use HTML Help' in Options, Environment, IDE. When the UpdateWiz is not installed, you can download it from the register. The option Help, Update will also download the wiz. Till version 2074 all sample files were placed under the MCS Electronics\BASCOM-AVR folder. Version 2075 places the sample files under the user Documents\MCS Electronics\BASCOM-AVR\Samples folder. While we prefer to keep all files at one location and sub folders, this is not allowed in Windows 7 where the Program Files folder and all it's sub folders are write protected. In version 2082 you can decide where the samples must be installed The BASCOM-AVR application contains a number of folders. \DAT : processor data files. These files contain processor info. When you use $REGFILE, the value should match with one of the files. \LIB : library files. They have the extension LIB or LBX. LBX is a compiled LIB file. A library files contains ASM sub routines. \INC : include files. Notice that these server only the compiler. Do not change or store include files here. Normal include files are stored along with the samples. \PDF : PDF files with the bascom-avr manual and processor files from microchip/atmel. \PINOUT : processor pinout and XML description files \SAMPLES : this depends on the user choice during installation Updates Top Previous Next The update process is simple if you follow all steps. · Go to the main MCS website at http://www.mcselec.com · In the left pane under 'Main Menu' you will find a link named 'Registration/Updates' · Optional you can enter the address yourself : http://register.mcselec.com Notice that the website uses two different accounts : one for the forum/shop and one for the registration/updates. You will see the following screen: · Click the link and select 'Create new account' You need to provide a username, password, email and full name. Company name is optional. When you want to receive notifications when updates are available, select this option. When you filled in the information, click 'Submit Registration'. · After you click submit, you can get various error messages. For example that a username already exists. Press the Back-button in your browser, and correct the problem, then try again · If the registration is successful you will get a message that the registration succeeded. · Now you can login. You will see the following screen : · You need to chose 'Product registration'. · The following screen will be shown: · Select a product from the list. · Enter the serial number It is important that you enter a valid serial number. Do not try to enter serial numbers from cracked versions. When you enter invalid serial numbers, you will loose support and the ability to update. We will also ban your IP number from our web. The valid serial number is shown in the Help, About box. When the product is selected, the serial number is entered and you press 'Register product' you will see the following message : · This does mean that you registered successfully. · MCS Electronics will validate all registrations once in a few days. When the product is validated you will receive an email. After you receive the email, you can login to the register again. When you did not received an email within 1 week, check if the email address was entered correct. If it was correct, send an email to support. At the top you can see which products are registered, and which status they have. When you want to do a FULL SETUP, you need to download the full version. You do not need to uninstall a previous version. You can install an update into the same directory or a new directory. When you uninstall a previous version, it will remove the license file which is not part of the setup.exe So in the event that you do run uninstall first, make a backup of the license dll named bscavrL.DLL The ZIP file you download contains only one setup.exe. You need to run this executable. It is also important that you put the license DLL into the same directory as setup.exe Setup will copy this file to the BASCOM application directory. You can also manual copy this file. The license file is on CD-ROM, diskette, or the media (email) you received it on. It is only supplied once. Without the file, BASCOM will not run. The file is named bscavrL.DLL for BASCOM-AVR When you got the license by email, it was zipped and probably had a different extension. Consult the original installation instructions. The file is only provided once, we can not, and do not provide it again. Please note that LIC files are license files for the Update Wiz, but they are not the BASCOM main licence file. See Installing BASCOM on how to do a full install. IMPORTANT As of version 2080, the Update Wiz is phased out. This means that you need to download and install the full setup.exe The BASCOM-IDE has a new simplified update method. See also Help, UPDATE The following information i kept for usage with older versions. It is also possible to do a partial update. For example to update some DAT files, or to update to a beta which is only available as an update. For partial updates, you need the Update Wiz. When you do not have the Update Wiz, you can download it from the register. Unzip it to the same directory as BASCOM. Or use the Help, Update option from BASCOM-AVR. The Update Wiz uses LIC files which you can download. A LIC file is a text file, it is not the LICENSE DLL ! Store the downloaded LIC file in the same directory as the Update Wiz. When you store the Update Wiz into the same directory as BASCOM, the license DLL already exist there. When you put the Update Wiz and the LIC files into a separate directory, you need to copy the BASCOM license DLL to this directory also. When you run the Update Wiz, it will check for a new version of the updatewiz and will download this if available. It will then run again. When the Update Wiz finds a LIC file, it will check if the update/install location is specified. For new downloaded LIC files, the update wiz does not know the update directory, and will ask for the directory you want to update. This can be any (new) directory, but usually is the BASCOM application directory. After you click Ok, the directory to update is stored in the LIC file. It will not be asked again. When you run the wiz with Help, Update, the lic file will be downloaded each time, and as a result, it will be asked each time you run this option. Click the Next button to start the update. It depends on the downloaded LIC files how many products are found. You will get a similar window : You need to select the product that you want to update. In the sample there are multiple choices. Press the Next-button to continue. The Wiz will compare files on the web with your local files in the specified directory. When it finds packages that are newer, they will be shown in a list. By default they are all selected. You can unselect the packages you do not want to update. Press Next to download the selected packages. During the download you will see the history file. When all packages are downloaded, they will be installed/unzipped. Press the Next-button to install the downloaded files. During the installation you will see the progress. When installation is ready, you need to press the Finish-button. The Wiz can also backup all files it will replace. Use the Setup button on the main screen of the UpdateWiz to change the settings. A full zipped backup will be made. The name of the backup files has the name of the license file with the ZIP extension. You can install multiple versions in different directories. Make sure you read the history.txt file after you have updated. Changes and new features are described in this file. This file is opened automatic the first time you run a new version. IMPORTANT As of version 2080, the Update Wiz is phased out. This means that you need to download and install the full setup.exe The BASCOM-IDE has a new simplified update method. See also Help, UPDATE Move to new PC Top Previous Next When you want to move BASCOM to a new PC. You have a number of options. 1 - Run the installer with admin rights from CD-ROM on your new PC. The setup will copy the license file automatically. 2 - Download the latest version of the setup.exe from https://register.mcselec.com , extract the setup.exe , and run setup.exe with admin rights For the register link above, you need access(an account). This account is not the same as for the shop/forum. You need to create an account if you don't have one. This procedure is explained in the help topic 'Updates' Then, after the installation, copy the license file bscavrL.DLL to the bascom-avr application directory of the new PC. Or let setup.exe do this for you. When you put the license file in the same directory as setup.exe, setup will copy/install the file for you. In general it is always better to install the latest version. Installation on multiple computers Top Previous Next The following applies to the licensed version and the license key. You may install BASCOM on multiple computers. For example on your laptop and your desk PC. There is no limit to the number of PC's you install the software. But you may only use one PC at the same time. Since you can only operate one PC at the same time, this is not a real restriction. When you install on multiple PC's and others work on these PC's at the same time as you, you need multiple licenses! Running BASCOM-AVR Top Previous Next After you have installed BASCOM, you will find a program entry under MCS Electronics\BASCOM-AVR Double-click the BASCOM-AVR icon to run BASCOM. The following window will appear. (If this is your first run, the edit window will be empty.) The most-recently opened file will be loaded automatically. Like most Windows programs, there is a menu and a toolbar. The toolbar can be customized. To do this, place the mouse cursor right beside the 'Help' menu. Then right-click. You can turn on/off the toolbars or you can choose 'Customize'. This will show the following window: You have the option to create new Toolbars or the reset the toolbars to the default. To place a new button on a menu bar, select the 'Commands' TAB. In the example above, the Program Category has been selected and at the right pane, all buttons that belong to the Program-category are shown. You can now select a button and drag & drop it to the Toolbar. To remove a button from the Toolbar, you drag it out of the Toolbar and release the left mouse button. On the Options-TAB you can further customize the Toolbar: To preserve screen space there are no large icons available. Option Description Menus show recent used commands first With this option the IDE will learn the menu options you use. It will show only the most used menu options. The idea is that you can find your option quicker this way. Show full menus after a short delay This option will show the remaining menu options after short delay so you do not need to click another menu option to show all menu options. Reset my usage data This option will reset the data the IDE has collected about your menu choices. Show Tool tips on toolbars This option is on by default and it will show a tool tip when you hold the mouse cursor above a toolbar button Show shortcut keys in Tool tips This option is on by default and it will show the shortcut in the tool tip. For example CTRL+C for the Copy button. The Editor The editor supports syntax highlighting. Code you enter can be reformatted automatically. When you press CTRL+J you can select a template. A template is a small piece of code that can be inserted automatically. When you press CTRL+J you can select a template or you can type the template name and press CTRL+J. If there is only one template starting with that name, the template will be inserted. Otherwise the options are shown. Templates are stored in the file bascavr.tpl When you press SHIFT and move the mouse cursor over a variable, constant or other element you will get a tool tip with info. In the sample above the variable 's' was selected and the tool tip shows that it is a string with a length of 16 bytes in the modules crc8-16-32.bas Intellisense The editor has built in intellisense. It is important that your code contains the $REGFILE directive like : $REGFILE = "M88def.dat". When you press CTRL+SPACE you get a list of statements, sub routines, functions, labels, asm registers, etc. This list depends on the place of the cursor in the code. - At the start of a line you will get a list like : . You can select a value from the list and press enter to insert it into the code. - When you type a letter of some letters like pr Here you can see the position is set to the first item that starts with PR : PRINT - After PRINT when a variable is expected : Here you get functions, variables and constants - After CONFIG Here you get a list of all CONFIG statements. - After CONFIG param (the = sign). Here you get a lost of parameter values. - After GOTO, GOSUB Here you get a list with labels. - After CALL Here you get a lost with sub routines. - Inside $ASM-$END ASM Here you get a list of ASM mnemonics. - After ASM mnemonic Here you get a list of registers. PLEASE NOTICE : - intellisense is considered a beta function in 2079. It is subject to change. - values for CONFIG might not be shown. This is because all these values need to be present in the DAT files. And each processor has specific options. Select Text Selection of text can be done by double clicking the text, by holding SHIFT down and moving the cursor or you can select a block of text by pressing the ALT key and dragging the mouse cursor. TABS When you have loaded multiple files, each file will be shown in a TAB. The active TAB can be closed or dragged to a new position. When a file is modified the TAB caption will be shown in red. SHIFT + MOUSE When you move the mouse cursor to the TAB caption you will see the full path of the loaded file. When you press the SHIFT key and move the mouse cursor you can get information in a tool tip. For example when you hover over an indention line : The tooltip shows info about the structure. So you know that the green line belongs to While Unseen > 0 When we hover over a code element like CH : This time since CH is a variable. the data type is shown. The Reference window will list all referenced variables : When you click an item, the cursor will be changed automatically. Custom Configuration You can load a custom configuration file by specifying the filename as a parameter. This allows you to run different versions of the software with different setting/option files. The configuration file has the XML extension. It can be found by clicking the XML data folder link in the Help, About window. By default bascom uses the file : \Users\\AppData\Roaming\MCS Electronics\bascom-avr.xml When you want to use a custom file we would recommend to store it in the bascom-avr application folder. This way you can run multiple versions of bascom, all with their own settings. When a file named bascom-avr.xml exists in the BASCOM-AVR application folder, this file will be used for the settings. By default this file is stored in the users profile folder. You can find it by clicking Help, About, XML data folder link. When you store this file into the BASCOM application folder, you can use multiple versions with multiple configurations. A suggested setup for working with multiple versions would be : c:\APPS\BASCAVR\2079 : for the 2079 version c:\APPS\BASCAVR\2080 : for the 2080 version Please note that this options is implemented in version 2080 so it will not work in prior versions. File New Top Previous Next This option creates a new window in which you will write your program. The focus is set to the new window. You can have multiple windows open at the same time. Only one window can have the focus. When you execute other functions such as Simulate or Program Chip, BASCOM will use the files that belong to the current active program. This is in most cases the program which has the focus. File new shortcut: , CTRL + N File Open Top Previous Next With this option you can load an existing program from disk. BASCOM saves files in standard ASCII format. Therefore, if you want to load a file that was made with another editor be sure that it is saved as an ASCII file. Most programs allow you to export the file as a DOS or ASCII file. Note that you can specify that BASCOM must reformat the file when it opens it with the Options Environment option. This should only be necessary when loading files made with another editor. File open shortcut : , CTRL+O File Close Top Previous Next Close the current program. The current editor window will be closed. When you have made changes to the program, you will be asked to save the program first. You can then decide to save, cancel, or not to save the changes you have made. File close shortcut : File Save Top Previous Next With this option, you save your current program to disk under the same file name. The file name is visible in the Windows caption of the edit window. If the program was created with the File New option, you will be asked to name the file first. Use the File Save As option to give the file another name. Note that the file is saved as an ASCII file. File save shortcut : , CTRL+S File Save As Top Previous Next With this option, you can save your current program to disk under a different file name. When you want to make some changes to your program, but you do not want to make changes to the current version you can use the "Save As" option. It will leave your program as it was saved, and will create a new file with a new name so you end up with two copies. You then make changes to the new created file. Note that the file is saved as an ASCII file. File save as shortcut : File Print Preview Top Previous Next With this option, you can preview the current program before it is printed. Note that the current program is the program that has the focus. File print preview shortcut : File Print Top Previous Next With this option, you can print the current program. Note that the current program is the program that has the focus. File print shortcut : , CTRL+P File Project Top Previous Next Originally the IDE was not designed to support projects. Each file you open is a project. Most chips were not even suited for big projects. Some projects use a lot of include files. It is a good idea to break up your code in modular tested modules. You can simply include the modules with $include. In order to make working with a project more convenient, a number of Project options have been added. The Project menu can be found under the File menu. The Project menu has 4 sub menu items and a MRU list(most recent used projects). When in project mode, the main project file will be compiled. In normal mode, the active window is considered the project and will be compiled. The same is true for the simulator and programmer. A simple project explorer has been added that will list all project files. The active project will be shown in blue. The relative path is shown. You can add a new file to the active project. By default the INC extension will be selected. It will be good practice to give included files the INC extension. The main project should have the BAS extension. When you click the ADD button, a file selection dialog will appear. You can select multiple files by using the SHIFT and/or CTRL keys. When you add a file to a project, it will be added to the project list. When you double click the file in the list it will be selected. Or when it was not loaded before, it will be loaded from disk. That a file is part of a project collection does not mean that the file will be used or included : you still need to $INCLUDE a file that you want to use in your project. You can also remove a file from the project. This will not remove or delete the file from disk. The file will only be removed from the project collection. Only one file can be the main project. This is the file that will be compiled. The main file is colored in blue. When you updated from a previous version, you need to reset the docking in order to make the Project List window visible. This option you can find under Options, Environment, IDE Project New This option will close all files and the current project and will query for a project file name. The file will have the PRJ extension. Project Open This option will close all open files and let you select an existing project file. A project file has the PRJ extension. The PRJ file contains no code, it only contains data about the project files. All files from the project will be loaded when they were loaded when you closed the project. The position and size will be set exactly as when you closed. Project Save This option will save all project files. It will also save other opened non-project files. Project Close This option will close the active project. This will end the project mode. The project mode is started when you open a PRJ file either with OPEN or by clicking a PRJ file from the MRU menu. When you close bascom and you have the Option 'Auto Load All Files' checked, then like usual, all open files will be saved and when you run bascom again, they will all be opened. This might be confusing since you work in normal mode by default. It is recommended to deactivate the 'Auto Load All Files' when working with projects. In project mode, you can also drag and drop files to the IDE. If they have the BAS or INC extension, they will be added to the project. In normal mode, the file will be opened. File ZIP Top Previous Next This option will put all project files into a ZIP file. The file will be given the ZIP extension and is saved into the same folder as the main file. When your file is named main.bas, the file main.zip will be created. The following files will be included : - all files which are included with $INCLUDE - all files which are included with $INC - all files which are included with $BGF If a file is included in the code but can not be found you will get a warning. This option does take conditional compilation into account. Meaning that : #const a=1 #if a=2 $Include "FT800.inc" $Include "FT800_Functions.inc" #endif The files ft800.inc and ft800_functions.inc are not included since the condition does not match. File Exit Top Previous Next With this option, you can leave BASCOM. If you have made changes to your program, you can save them upon leaving BASCOM. All of the files you have open, at the moment you choose exit, will be remembered. The next time you run BASCOM, they will be opened automatically. File exit shortcut : Edit Undo Top Previous Next With this option, you can undo the last text manipulation. Edit Undo shortcut : , CTRL+Z Edit Redo Top Previous Next With this option, you can redo the last undo. Edit Redo shortcut : , CTRL+SHIFT+Z Edit Cut Top Previous Next With this option, you can cut selected text into the clipboard. Edit cut shortcut : , CTRL+X Edit Copy Top Previous Next With this option, you can copy selected text into the clipboard. Edit copy shortcut : , CTRL+C Edit Paste Top Previous Next With this option, you can paste text from the clipboard starting at the current cursor position. Edit paste shortcut : , CTRL+V Edit Find Top Previous Next With this option, you can search for text in your program. Text at the current cursor position will automatically be placed in the find dialog box. All text you search for is saved so the next time you search, you can retrieve the search phrase from a list. To clear the history, right click the mouse above the 'Text to Find' label and select 'Clear History' from the popup menu. The following options available: Option Description Case Sensitive When selected, the case must match. Searching for PRINT will not find pRint. With this option turned off, Print will find print, PRINT, PRinT, etc. Whole words only When selected, only whole words are considered. A whole word is a word that is surrounded by spaces, or that is at the start of a line. Looking for PRINT will find : "Print test" and "print" and "print print". But not "printer" Regular expressions You can use a regular expression to find a match. ^ A circumflex at the start of the string matches the start of a line. $ A dollar sign at the end of the expression matches the end of a line. . A period matches any character. * An asterisk after a string matches any number of occurrences of that string followed by any characters, including zero characters. For example, bo* matches bot, bo and boo but not b. + A plus sign after a string matches any number of occurrences of that string followed by any characters except zero characters. For example, bo+ matches boo, and booo, but not bo or be. [ ] Characters in brackets match any one character that appears in the brackets, but no others. For example [bot] matches b, o, or t. [^] A circumflex at the start of the string in brackets means NOT. Hence, [^bot] matches any characters except b, o, or t. [-] A hyphen within the brackets signifies a range of characters. For example, [b-o] matches any character from b through o. \ A backslash before a wildcard character tells the Code editor to treat that character literally, not as a wildcard. For example, \^ matches ^ and does not look for the start of a line. Forward This is the search direction. By default it will search forward. Specifies the size of the software stack. Backward This is the search direction. You can use backwards in case you pressed F3 too many times and want to go back to the previous found text. Global All the text of the current editor will be searched. Selected text Only the selected text will be searched. From cursor Search from the current cursor position to the end of the code. Entire scope Search from the current cursor position to the end, then search till the start of the cursor position. This will search the entire text. Find in Files The Find in Files option can be used to search for text in files. Option Description Case Sensitive When selected, the case must match. Searching for PRINT will not find pRint. With this option turned off, Print will find print, PRINT, PRinT, etc. Whole words only When selected, only whole words are considered. A whole word is a word that is surrounded by spaces, or that is at the start of a line. Looking for PRINT will find : "Print test" and "print" and "print print". But not "printer" Regular expressions You can use a regular expression to find a match. ^ A circumflex at the start of the string matches the start of a line. $ A dollar sign at the end of the expression matches the end of a line. . A period matches any character. * An asterisk after a string matches any number of occurrences of that string followed by any characters, including zero characters. For example, bo* matches bot, bo and boo but not b. + A plus sign after a string matches any number of occurrences of that string followed by any characters except zero characters. For example, bo+ matches boo, and booo, but not bo or be. [ ] Characters in brackets match any one character that appears in the brackets, but no others. For example [bot] matches b, o, or t. [^] A circumflex at the start of the string in brackets means NOT. Hence, [^bot] matches any characters except b, o, or t. [-] A hyphen within the brackets signifies a range of characters. For example, [b-o] matches any character from b through o. \ A backslash before a wildcard character tells the Code editor to treat that character literally, not as a wildcard. For example, \^ matches ^ and does not look for the start of a line. Search all project files This option will search through all project files. Files considered are $INCLUDE files. Nested $include files are not considered. Search all open files This option will search though all open files. This are loaded files visible in the TABS Search in directories You can specify a custom folder to search for the text. Search in current file This option will restrict the search to the current file. Edit Find shortcut : , CTRL+F Edit Find Next Top Previous Next With this option, you can search again for the last specified search item. Edit Find Next shortcut : , F3 Edit Replace Top Previous Next With this option, you can replace selected text in your program. Edit Replace shortcut : , CTRL+R Edit Goto Top Previous Next With this option, you can immediately go to a specified line number. Edit go to line shortcut : ,CTRL+G Edit Toggle Bookmark Top Previous Next With this option, you can set/reset a bookmark, so you can jump in your code with the Edit Go to Bookmark option. Shortcut : CTRL+K + x where x can be 1-8 Bookmarks are stored in a file named .BM Edit Goto Bookmark Top Previous Next With this option, you can jump to a bookmark. There can be up to 8 bookmarks. Shortcut : CTRL+Q+ x where x can be 1-8 Bookmarks are stored in a file named .BM Edit Indent Block Top Previous Next With this option, you can indent a selected block of text. Edit Indent Block shortcut : , CTRL+SHIFT+I Edit Unindent Block Top Previous Next With this option, you can unindent a block. Edit Unindent Block shortcut : , CTRL+SHIFT+U Edit Remark Block Top Previous Next With this option, you can Remark or Unremark a selected block of text. While you can use '( and ') to remark a block of code, you might prefer the old BASIC way using just one ' . When a remark is found, it will be removed. When there is no remark, it will insert a remark. Edit Insert ASCII Top Previous Next This option will show a pop up window from which you can select an ASCII character. In BASCOM you can embed ASCII characters by using brackets embedded with the ASCII code like : {065} For example : Dim S As String : S="AB{067}" This is the same as S="AAA" The pop up lists shows all ASCII values and when you click the OK-button, the brackets are added. Edit Fold All Subs and Functions Top Previous Next When Code folding is enabled in Options, Environment, IDE, Editor, this options will fold/collapse all sub procedures and functions. Other structures that can be folded with F11 remain unaltered. Using SHIFT+F11 or CTRL+ENTER, you can fold/unfold the current block. Consider this example : Both the Sub and For/Next can be folded but the Fold All Subs and Functions option, will only fold the sub : See Also Edit Unfold All Code Edit Unfold All Code Top Previous Next This option will unfold all folded code so all code becomes visible. See Also Edit Fold All Subs and Functions Edit Encrypt Selected Code Top Previous Next This add on option allows you to encrypt portions of your code. Because the encryption can not be undone, you will get this warning: If you chose YES, the selected code will be encrypted and will result in lines like : $CRYPT 6288E522B4A1429A6F16D639BFB7405B $CRYPT 7ABCF89E7F817EB166E03AFF2EB64C4B $CRYPT 645C88E996A87BF94D34726AA1B1BCCC $CRYPT 9405555D91FA3B51DEEC4C2186F09ED1 $CRYPT 6D4790DA2ADFF09DE0DA97C594C1B074 Only the compiler can decrypt and process these lines. There is no way you can change the $CRYPT lines back into source code ! So make a backup of your code before you use this option. Typically, it will only be used on finished projects. If the encrypted code contains errors, you will get error messages pointing to the $CRYPT lines. This option is not available/enabled by default. You need to buy a license that will unlock this option. Our sales requires your BASCOM serial number too. Edit Proper Indent Top Previous Next This option will properly indent your code. Indention is used to make code better readable. Every structure will be indented. And nested will increase indenting. This code : For C = 0 To 100 B = A(c) Print "Read " ; C ; ":" ; B ; "/" ; Hex(b) Waitms 4 Next Will be transformed into : For C = 0 To 100 B = A(c) Print "Read " ; C ; ":" ; B ; "/" ; Hex(b) Waitms 4 Next And this is a sample with nesting : Do Input "Data to write ? (0-255)" , D Print "Reading content of EEPROM (via ERAM Byte)" For C = 0 To 100 B = A(c) Print "Read " ; C ; ":" ; B ; "/" ; Hex(b) Waitms 4 Next Loop When indenting does not work you need to check your code for mistakes. For example for endif instead of End If. Proper indenting is also required for proper drawing of indention. Edit Show Excluded Code 2080 NEW Top Previous Next This option turns on/off marking of excluded code. Excluded code is code that is not compiled as part of the project because conditional compilation parameters exclude the code. Excluded code is shown in Italic and gray. For example when using an XMEGA processor, the _XMEGA constant will be set to 1. When the option is turned off, it will show normal like : #if _xmega print "XMEGA" #else print "NORMAL" #endif When then option is turned on, the editor will show it like : #if _xmega print "XMEGA" #else print "NORMAL" #endif When you have a lot of conditional code it is hard to see which code is executed. When you turn the option on, it is much easier to see. See this example: See Also #IF, #ELSEIF . #ELSE , Show Dead Code Edit Show Dead Code 2080 NEW Top Previous Next This option turns on/off marking of 'dead' code. Dead code is code that does not do a thing and could be removed. Dead code is shown in Italic and gray. Dead code is similar to Excluded code with the difference that excluded code is not compiled while dead code is compiled. Dead code is a new feature in 2080 and intended to show you which variables or code are not used. You can decide if the code is really dead, and need to be removed, or not. Since this is a new feature, you should take care before deleting 'dead code' The example above demonstrates a few dead code elements: - the local dead as byte, is not used in the code - the function result is assigned twice without that the result is used, this does not make sense - the GOTO skips over some code which is never used (print) See Also Edit Show Excluded Code View PinOut Top Previous Next The Pin Out viewer is a dock able window that shows the case of the active chip. The active chip is determined by the value of $REGFILE. When you move the mouse cursor over a pin, you will see that the pin will be colored red. At the bottom of the window, a pin description is show. In the sample above you will see that each line has a different color. This means that the pin has multiple alternative functions. The first blue colored function is as generic IO pin. The second green colored function is RESET pin. The third black colored function is PIN change interrupt. A pin can have one or more functions. Some functions can be used together. When you move the mouse cursor away, the pin will be colored blue to indicate that you viewed this pin. For example, when you need to look at it again. You can also search for a pin description. Enter some text and return. Here is an example when you search the VCC pin : When pins are found that have the search phrase in the description, the pin will be colored blue. By clicking 'Clear Pin HL' you can clear all colored pins. Some chips might have multiple cases. You can select the case from the package list. When you change from package, all pin colors will be cleared. When you double click a pin, the pin will be colored green. Another double click will color it red/blue. When a pin is green, it will not be colored red/blue. The green color serves as a kind of bookmark. The only exception is the search function. It will make bookmarked green pins, blue too. Use the right mouse to access a popup menu. This menu allows you to zoom the image to a bigger or smaller size. Double click the chip to show the chip data. When you want to search for a chip, click the 'Chip Search' button. It will show the following window: You can provide criteria such as 2 UARTS. All criteria are OR-ed together. This means that when one of the criteria is met, the chip will be included in the list. Only chips supported by BASCOM will be listed. When a chip has SRAM, and is not supported yet, it will be in the near future since the goal is to support all chips. When you find an error in the pin description, please send an email to support so it can be corrected. View PDF viewer Top Previous Next The PDF viewer is dock able panel which is located by default on the right side of the IDE. The viewer itself contains a tree with the topics and the actual PDF viewer. The tree topics can be searched by right clicking on the tree. Choose 'Search' and enter a search text. When a topic has sub topics, the topic is bold. When you have enabled 'Auto open Processor PDF' in Options, Environment, PDF, the data sheet will be automatically loaded when you change the $REGFILE value. It can be shown in a new sheet or it can replace the current PDF. Open a PDF. Copy selected text to the clipboard. You can not copy from protected PDF documents. First page. Previous page. Current page indicator. You can enter a page number to jump to a different page. Next page. Last page. Find text in PDF. Zoom in. Zoom out. Rotate page to the left and right. Print page(s). When you right click in the PDF, a pop up menu with the most common options will appear. In Options, Environment, PDF you can specify how data sheets must be downloaded. Data sheets can be downloaded automatic. When the $REGFILE is changed and the PDF is not present, you will be asked if the PDF must be downloaded. If you choose to download, it will be downloaded from the Atmel website. When you click 'Do not show this message again' , you will not be asked anymore if you want to download the Mega32.PDF. You will be asked to download other PDF documents when they do not exist. During the download you will see a similar window: You can also download all newer PDF's from the Atmel website with the option : Tools, PDF Update When PDF's are downloaded with the UpdateWiz, they are downloaded from the MCS Electronics website. View Error Panel Top Previous Next This option will show the Error panel. When there are no errors, the list will be empty. You will also be able to close the window. When there are errors : You will not be able to close the window until the error is solved and the program is checked/compiled. The panel is dockable and by default docked to the bottom of the IDE. When you right click the mouse inside the error panel, a menu will popup with one option : Copy to Clipboard. All data from the error window will be copied to the windows clipboard if you select this option. View Tip Top Previous Next Action Shows the Tip of the day Window You can click the Next-button to show another tip. Or you can close the window. When you do not want to see the tips when BASCOM is started, you can unselect the 'Show tips at startup' option. You can submit your own tips at the register : http://register.mcselec.com View Project Files Top Previous Next Action Shows the Project Explore Window. The project explorer window is intended to be used in project mode. Project mode is a mode where all files belong to one project. Here you have a main file and optional include files. The project explorer is a dock able window. It lists all files assigned to the project. When you double click a file, it will be opened in the editor. - Use the ADD button to add files to the project - Use the REMOVE button to remove files from the project. Files you remove are only removed from the project, they are not removed from disk - Use SET MAIN to set the main project file. The main project file is the file that is compiled. View Code Explorer Top Previous Next Action Shows the Code Explorer Window The code explorer shows code elements in a tree. By double clicking an element the cursor will be set to the matching code in the editor. You can also drag an element into the editor window. By clicking the right mouse a pop up menu will allow you to filter out constants and variables (registers) from the definition file. The following code elements will be shown in the explorer: - Aliases. These are the user ALIASes. - Assembler. This is for single line asm using ! - Assembler Block. This is for assembler blocks using $asm .. $end asm. If you add comment after $asm, it will be shown in the tree as well. Example : $asm ; Test - Constants. Both user defined constants (CONST) and constants from the definition file are shown. - Declarations. Subs and Functions are both shown. Each with their own color. - Functions. These are the user function implementations. - Labels. When labels are used in subs and functions, the sub/functions name is listed first. - Macros. These are the user macro's created with MACRO. - Subs. These are the user sub implementations. - Variables. These are the variables from the user code and definition file. Each shown with their own color. Locals are shown under a branch of the sub/function. - CallStack. This is optional. Since it takes time to trace the call stack it is turned off by default. Use right mouse click and the pop up menu to activate it. The call stack shows a tree of the calls you make to user subs and functions. And each sub/function also shows the user functions it calls. When multiple calls are made, three dots are added for each additional call. - Information. Processor, free ERAM and SRAM. Estimated $hwstack, $swstack and $framesize. The calculated stack settings are based on the program call tree and local variables. This is just a tool to give you an idea about stack usage. Not taken into account is the stack required by the assembler routines. This means that you need to add a certain amount to the calculated values. When your code uses interrupts you need to increase the calculated $HWSTACK by 32. Otherwise increase it by 16. The $FRAMESIZE should have a minimum value of 24. Add a value of 16 to $SWSTACK. Applications using AVR-DOS should use a minimum of 128 for all stacks. A future version will also take the assembler code into account. When the Code Explorer has the focus, pressing CTRL+F will search in the code explorer and not in the editor. The code explorer works in a separate thread. It will be updated a few seconds after you have quit typing. By making the Code Explorer window invisible, the explorer is deactivated. The popup menu has the following options: Show Register Constants This option can toggle between showing and hiding the register constants. When register constants are shown the tree can become big. User constants and register constants are shown in a different color. Show Register Variables This option can toggle between showing and hiding the register variables. When register variables are shown the tree can become big. User variables and register variables are shown in a different color. Show Call Stack This option can show the Call Stack. This reveals the nesting of your code. Show Errors This option deserves a warning. The option is turned off by default. It can be useful to find errors but it can also point to errors which are not considered an error for the compiler. The compiler has a separate parser. The parser from the IDE is a different new parser. While in 2080 all DAT files are updated, you still can get errors which are no real errors. You might want to report them to support. Please send a small as possible program that will show the error. Show Unused Items When this option is turned on, all unused items will be shown in grey. For example : In this sample, _temp1 , so_rx_data and DataPtr are unused or unreferenced. _temp1 is an internal variable and so is DataPtr. They do not occupy any space. But so_rx_data is a user variable which is not referenced. You could remove or remark it. Refresh This option will parse the project and update the code explorer tree. Find References This option can find all references for an item. For example when you go to Variables, and select a variable the option becomes enabled in the menu. After choosing this option, the references will be added to the tree. Now by clicking the item you will go to the point in your code where the item is referenced/used. Show References This options shows a panel on the bottom of the code explorer tree. When you activate the tooltip keeping SHIFT pressed and hovering an item in the editor, the references panel will be updated with all references of that item. A single click on an item in this list will set the cursor in the IDE to referred item. Consider this simple piece of code : Dim S As Single Input "s " , S Print S When pressing SHIFT and hovering the mouse over the variable S , the tooltip will be shown : The references list will be updated as well. The item in bold points to the definition, in this case the DIM S. The following two items in the list point to the INPUT "s ", S and the Print S. The panel can be shown or hidden using the right click menu from the explorer. View Vertical Splitter Top Previous Next You can split the editor window into two parts. By default you use the horizontal splitter marked with the arrow. This will create a split screen : With the option Vertical Splitter, you switch between horizontal en vertical splitter. The splitter is located near the code explorer window. This will result in a vertical split window. When you chose the vertical splitter option again the window will be split horizontal again. Notice that in order to show two different code windows you need to open the two windows and use Tile Vertically. Program Compile Top Previous Next With this option, you compile your current program. Your program will be saved automatically before being compiled. The following files will be created depending on the Option Compiler Settings. File Description xxx.BIN Binary file which can be programmed into the microprocessor. xxx.DBG Debug file that is needed by the simulator. xxx.OBJ Object file for simulating using AVR Studio. Also needed by the internal simulator. xxx.HEX Intel hexadecimal file, which is needed by some programmers. xxx.ERR Error file. Only created when errors are found. xxx.RPT Report file. xxx.EEP EEPROM image file If a serious error occurs, you will receive an error message in a dialog box and the compilation will end. All other errors will be displayed at the bottom of the edit window, just above the status bar. When you click on the line with the error info, you will jump to the line that contains the error. The margin will also display the sign. At the next compilation, the error window will disappear or reappear if there are still errors. See also 'Syntax Check' for further explanation of the Error window. Program compile shortcut: , F7 Program Syntax Check Top Previous Next With this option, your program is checked for syntax errors. No file will be created except for an error file, if an error is found. Program syntax check shortcut , CTRL + F7 When there is an error, an error window will be made visible at the bottom of the screen. You can double click the error line to go to the place where the errors is found. Some errors point to a line zero that does not exist. These errors are caused by references to the assembler library and are the result of other errors. The error window is a dockable window that is docked by default to the bottom of the screen. You can drag it outside this position or double click the caption(Errors) to make it undock : Here the panel is undocked. Like most windows you can close it. But the error must be resolved (corrected and syntax checked/recompiled) for this window can be closed ! By double clicking the caption (top space where the name of the window is show) you can dock it back to it's original position. When you have closed the window and want to view it again, you can choose the View, Error Panel option from the main menu. Program Show Result Top Previous Next Use this option to view information concerning the result of the compilation. See the Options Compiler Output for specifying which files will be created. The files that can be viewed are "report" and "error". File show result shortcut : ,CTRL+W Information provided in the report: Info Description Report Name of the program Date and time The compilation date and time. Compiler The version of the compiler. Processor The selected target processor. SRAM Size of microprocessor SRAM (internal RAM). EEPROM Size of microprocessor EEPROM (internal EEPROM). ROMSIZE Size of the microprocessor FLASH ROM. ROMIMAGE Size of the compiled program. BAUD Selected baud rate. XTAL Selected XTAL or frequency. BAUD error The error percentage of the baud rate. XRAM Size of external RAM if available. Stack start The location in memory, where the hardware stack points to. The HW-stack pointer grows downward. S-Stacksize The size of the software stack. S-Stackstart The location in memory where the software stack pointer points to. The software stack pointer grows downward. Framesize The size of the frame. The frame is used for storing local variables. Framestart The location in memory where the frame starts. LCD address The address that must be placed on the bus to enable the LCD display E-line. LCD RS The address that must be placed on the bus to enable the LCD RS-line LCD mode The mode the LCD display is used with. 4 bit mode or 8 bit mode. LCD DB7-DB4 The port pins used for controlling the LCD in pin mode. LCD E The port pin used to control the LCD enable line. LCD RS The port pin used to control the LCD RS line. Variable The variable name and address in memory Constant Constants name and value Some internal constants are : _CHIP : number that identifies the selected chip _RAMSIZE : size of SRAM _ERAMSIZE : size of EEPROM _XTAL : value of crystal _BUILD : number that identifies the version of the compiler _COMPILER : number that identifies the platform of the compiler Warnings This is a list with variables that are dimensioned but not used. Some of them EEPROM binary image map This is a list of all ERAM variables with their value. It is only shown when DATA lines are used to create the EEP file. (EEPROM binary image). When the option : Load Report in IDE, is set, the report will be shown as a text file in the IDE. Program Simulate Top Previous Next With this option, you can simulate your program. You can simulate your programs with AVR Studio or any other Simulator available or you can use the built in Simulator. The simulator that will be used when you press F2, depends on the selection you made in the Options Simulator TAB. The default is the built in Simulator. Program Simulate shortcut : , F2 To use the built in Simulator the files DBG and OBJ must be selected from the Options Compiler Output TAB. The OBJ file is the same file that is used with the AVR Studio simulator. The DBG file contains info about variables and many other info needed to simulate a program. The yellow dot means that the line contains executable code. The Simulator window is divided into a few sections: The Toolbar The toolbar contains the buttons you can press to start an action. This is the RUN button, it starts a simulation. You can also press F5. The simulation will pause when you press the pause button. It is advised, that you step through your code at the first debug session. When you press F8, you step through the code line by line which is a clearer way to see what is happening. This is the PAUSE button. Pressing this button will pause the simulation. This is the STOP button. Pressing this button will stop the simulation. You can't continue from this point, because all of the variables are reset. You need to press the RUN button when you want to simulate your program again. This is the STEP button. Pressing this button (or F8) will simulate one code line of your BASIC program. The simulator will go to the RUN state. After the line is executed the simulator will be in the PAUSE state. If you press F8 again, and it takes a long time too simulate the code, press F8 again, and the simulator will go to the pause state. This is the STEP OVER button or SHIFT+F8). It has the same effect as the STEP button, but sub programs are executed completely, and th simulator does not step into the SUB program. This is the RUN TO button. The simulator will RUN until it gets to the current line. The line must contain executable code. Move the cursor to the desired line before pressing the button. This button will show the processor registers window. The values are shown in hexadecimal format. To change a value, click the cell in the VAL column, and type the new value. When you right click the mouse, you can choose between the Decimal, Hexadecimal and Binary formats. The register window will show the values by default in black. When a register value has been changed, the color will change into red. Each time you step through the code, all changed registers are marked blue. This way, the red colored value indicate the registers that were changed since you last pressed F8(step code). A register that has not been changed at all, will remain black. This is the IO button and will show processor Input and Output registers. The IO window works similar as the Register window. A right click of the mouse will show a popup menu so you can choose the format of the values. And the colors also work the same as for the registers : black, value has not been changed since last step(F8). Red : the value was changed the last time your pressed F8. Blue : the value was changed since the begin of simulation. When you press the STOP-button, all colors will be reset to black. Pressing this button shows the Memory window. The values can be changed the same way as in the Register window. When you move from cell to cell you can view in the status bar which variable is stored at that address. The SRAM TAB will show internal memory and XRAM memory. The EEPROM TAB will show the memory content of the EEPROM. The colors work exactly the same as for the register and IO windows. Since internal ram is cleared by the compiler at startup, you will see all values will be colored blue. You can clear the colors by right clicking the mouse and choosing 'Clear Colors'. The refresh variables button will refresh all variables during a run (F5). When you use the hardware simulator, the LEDS will only update their state when you have enabled this option. Note that using this option will slow down simulation. That is why it is an option. When you use F8 to step through your code you do not need to turn this option on as the variables are refreshed after each step. When you want to simulate the processors internal timers you need to turn this option on. Simulating the timers uses a lot of processor time, so you might not want this option on in most cases. When you are debugging timer code it is helpful to simulate the timers. The simulator supports the basic timer modes. As there are many new chips with new timer modes it is possible that the simulator does not support all modes. When you need to simulate a timer the best option may be to use the latest version of AVR Studio and load the BASCOM Object file. Even AVR Studio may have some flaws, so the best option remains to test the code in a real chip. The TIMER simulation only simulates TIMER0 and 16 bit TIMER1. And only counting/time modes are supported. PWM mode is not simulated. This option allows you to use a real terminal emulator for the serial communication simulation. Normally the simulator prints serial output to the blue window, and you can also enter data that needs to be sent to the serial port. When you enable the terminal option, the data is sent to the actual serial port, and when serial data is received by the serial port, it will be shown. This option turns on/off trace information. When enabled, a file with the name of your project will be created with the .TRACELOG extension. This file will contain the file, line number and source code that is executed. It is intended to check which parts of your code execute. Under the toolbar section there is a TAB with a number of pages: VARIABLES This section allows you to see the value of program variables. You can add variables by double clicking in the Variable-column. A list will pop up from which you can select the variable. To watch an array variable, type the name of the variable with the index. During simulation you can change the values of the variables in the Value-column, Hex-column or Bin-column. You must press ENTER to store the changes. To delete a variable, you can press CTRL+DEL. To enter more variables, press the DOWN-key so a new row will become visible. It is also possible to watch a variable by selecting it in the code window, and then pressing enter. It will be added to the variable list automatically. Notice that it takes time to refresh the variables. So remove variables that do not need to be watched anymore for faster simulation speed. LOCALS The LOCALS window shows the variables found in a SUB or FUNCTION. Only local variables are shown. You can not add variables in the LOCALS section. Changing the value of local variables works the same as in the Variables TAB. WATCH The Watch-TAB can be used to enter an expression that will be evaluated during simulation. When the expression is true the simulation is paused. To enter a new expression, type the expression in the text-field below the Remove button, and press the Add-button. When you press the Modify-button, the current selected expression from the list will be replaced with the current typed value in the text field. To delete an expression, select the desired expression from the list, and press the Remove-button. During simulation when an expression becomes true, the expression that matches will be selected and the Watch-TAB will be shown. uP This TAB shows the value of the microprocessor status register (SREG). The flags can be changed by clicking on the check boxes. The software stack, hardware stack, and frame pointer values are shown. The minimum or maximum value that occurred during simulation is also shown. When one of these data areas enter or overlap another one, a stack or frame overflow occurs. This will be signaled with a pause and a check box. Pressing the snapshot-button will save a snapshot of the current register values and create a copy of the memory. You will notice that the Snapshot-button will change to �Stop� Now execute some code by pressing F8 and press the Snapshot-button again. A window will pop up that will show all modified address locations. This can help to determine which registers or memory a statement uses. When you write an ISR (Interrupt Service Routine) with the NOSAVE option, you can use this to determine which registers are used and then save only the modified registers. INTERRUPTS This TAB shows the interrupt sources. When no ISR's are programmed all buttons will be disabled. When you have written an ISR (using ON INT...), the button for that interrupt will be enabled. Only the interrupts that are used will be enabled. By clicking an interrupt button the corresponding ISR is executed. This is how you simulate the interrupts. When you have enabled 'Sim Timers' it can also trigger the event. The pulse generator can be used to supply pulses to the timer when it is used in counter mode. First select the desired pin from the pull down box. Depending on the chip one or more pins are available. Most chips have 2 counters so there will usually be 2 input pins. Next, select the number of pulses and the desired delay time between the pulses, then press the Pulse-button to generate the pulses. The delay time is needed since other tasks must be processed as well. The option �Sim timers� must be selected when you want to simulate timers/counters. TERMINAL Section Under the window with the TABS you will find the terminal emulator window. It is the dark blue area. In your program when you use PRINT, the output will be shown in this window. When you use INPUT in your program, you must set the focus to the terminal window and type in the desired value. You can also make the print output go directly to the COM port. Check the Terminal option to enable this feature. The terminal emulator settings will be used for the baud rate and COM port. Any data received by the COM port will also be shown in the terminal emulator window. Notice that most microprocessors have only 1 UART. The UART0-TAB is used to communicate with tis UART. The UART1-TAB need to be selected in order to view the UART1 output, or to send data to UART1. Software UARTS are not supported by the simulator. They can not be simulated. SOURCE Section Under the Terminal section you find the Source Window. It contains the source code of the program you are simulating. All lines that contain executable code have a yellow point in the left margin. You can set a breakpoint on these lines by selecting the line and pressing F9. By holding the mouse cursor over a variable name, the value of the variable is shown in the status bar. If you select a variable, and press ENTER, it will be added to the Variable window. In order to use the function keys (F8 for stepping for example), the focus must be set to the Source Window. A blue arrow will show the line that will be executed next.. The hardware simulator. By pressing the hardware simulation button the windows shown below will be displayed. The top section is a virtual LCD display. It works to display code in PIN mode, and bus mode. For bus mode, only the 8-bit bus mode is supported by the simulator. Below the LCD display area are LED bars which give a visual indication of the ports. By clicking an LED it will toggle. PA means PORTA, PB means PORTB, etc. IA means PINA, IB means PINB etc. (Shows the value of the Input pins) It depends on the kind of microprocessor you have selected, as to which ports will be shown. Right beside the PIN led's, there is a track bar. This bar can be used to simulate the input voltage applied the ADC converter. Note that not all chips have an AD converter. You can set a value for each channel by selecting the desired channel below the track bar. Next to the track bar is a numeric keypad. This keypad can be used to simulate the GETKBD() function. When you simulate the Keyboard, it is important that you press/click the keyboard button before simulating the getkbd() line !!! To simulate the Comparator, specify the comparator input voltage level using Comparator IN0. Enable Real Hardware Simulation By clicking the button you can simulate the actual processor ports in-circuit! The processor chip used must have a serial port. In order simulate real hardware you must compile the basmon.bas file. To do this, follow this example: Lets say you have the DT006 simmstick, and you are using a 2313 AVR chip. Open the basmon.bas file and change the line $REGFILE = "xxx" to $REGFILE = "2313def.dat" Now compile the program and program the chip. It is best to set the lock bits so the monitor does not get overwritten if you accidentally press F4. The real hardware simulation only works when the target micro system has a serial port. Most have and so does the DT006. Connect a cable between the COM port of your PC and the DT006. You probably already have one connected. Normally it is used to send data to the terminal emulator with the PRINT statement. The monitor program is compiled for 19200 baud. The Options Communication settings must be set to the same baud rate! The same settings for the monitor program are used for the Terminal emulator, so select the COM port, and the baud rate of 19200. Power up or reset the DT006. It probably already is powered since you just previously compiled the basmon.bas program and stored it in the 2313. When you press the real hardware simulation button now the simulator will send and receive data when a port, pin or DDR register is changed. This allows you to simulate an attached hardware LCD display for example, or something simpler, like an LED. In the SAMPLES dir, you will find the program DT006. You can compile the program and press F2. When you step through the program the LED's will change! All statements can be simulated this way but they have to be able to use static timing. Which means that 1-wire will not work because it depends on timing. I2C has a static bus and thus will work. NOTE: It is important that when you finish your simulation sessions that you click the button again to disable the Real hardware simulation. When the program hangs it probably means that something went wrong with the serial communication. The only way to escape is to press the Real hardware Simulation button again. The Real Hardware Simulation is a cost effective way to test attached hardware. The refresh variables button will refresh all variables during a run(F5). When you use the hardware simulator, the LEDS will only update their state when you have enabled this option. Note that using this option will slow down the simulation. Watchdog Simulation Most AVR chips have an internal Watchdog. This Watchdog timer is clocked from an internal oscillator. The frequency is approximately 1 MHz. Voltage and temperature variations can have an impact on the WD timer. It is not a very precise timer. So some tolerance is needed when you refresh/reset the WD-timer. The Simulator will warn you when a WD overflow will occur. But only when you have enabled the WD timer. The status bar The status bar shows the PC (program counter) and the number of cycles. You can reset the cycles by positioning the mouse cursor on the status bar and then right click. You will then get a pop up menu with the option to reset the cycles. You can use this to determine how much time a program statement takes. Do not jump to a conclusion too quick, the time shown might also depend on the value of a variable. For example, with WAITMS var this might be obvious, but with the division of a value the time might vary too. Program Send to Chip Top Previous Next Program send to chip shortcut , F4 When you access the programmer from the main menu, you will notice the submenu. From the sub menu you can choose 'Program' or 'Manual Program'. Program will erase and program the processor without any user intervention. Manual Program will only show the programmer window. You can manually choose the options to program the chip when the programmer supports it. Auto Program also needs the option 'Auto Flash' to be set in the Programmer options. The following section applies to the Programmer window (program chip directly NOT selected) otherwise this is not shown to the user. �Buffer� below refers to the buffer memory that holds data to be programmed to, or read from the chip. Menu item Description File Exit Return to editor File, Test With this option you can set the logic level to the LPT pins. This is only intended for the Sample Electronics programmer. Buffer Clear Clears buffer Buffer Load from file Loads a file into the buffer Buffer Save to file Saves the buffer content to a file Chip Identify Identifies the chip Write buffer into chip Programs the buffer into the chip ROM or EEPROM Read chip code into buffer Reads the code or data from the chips code memory or data memory Chip blank check Checks if the chip is blank or erased Chip erase Erase the content of both the program memory and the data memory Chip verify Verifies if the buffer is the same as the chip program or data memory Chip Set lock bits Writes the selected lock bits LB1 and/or LB2. Only an erase will reset the lock bits Chip auto program Erases the chip and programs the chip. After the programming is completed, verification is performed. The following window will be shown for most programmers: Note that a chip must be ERASED before it can be programmed. By default the Flash ROM TAB is shown and the binary data is displayed. When you have an EEPROM in your project, the EEPROM TAB will show this data too. The most important TAB is in many cases the Lock & Fuse Bits TAB. When you select it , the lock and fuse bits will be read. These Lock and Fuse bits are different in almost every chip ! You can select new settings and write them to the chip. But be careful ! When you select a wrong oscillator option , you can not program the chip anymore without applying an external clock signal. This is also the solution to communicate with the chip again : connect a clock pulse to the oscillator input. You could use an output from a working micro, or a clock generator or simple 555 chip circuit. When you found the right settings, you can use $PROG to write the proper settings to new, un-programmed chips. To get this setting you press the 'Write PRG' button. After a new chip is programmed with $PROG, you should remark the line for safety and quicker programming. The 'Write PRG' will write the settings, read from the Microprocessor, it will NOT insert the unsaved settings you have made manual. Thus, you must first use the 'Write XXX' buttons to write the changed fuse bits settings to the chip, then you can use the 'Write PRG'. Notice that the Write xxx buttons are disabled by default. Only after you have changed a lock or fuse bit value, the corresponding button will be enabled. You must click this button in order to apply the new Lock or Fuse bit settings. Many new chips have an internal oscillator. The default value is in most cases 8 MHz. But since in most cases the 'Divide by 8' option is also enabled, the oscillator value will be 1 MHz. We suggest to change the 'Divide by 8' fuse bit so you will have a speed of 8 MHz. In your program you can use $crystal = 8000000 then. $crystal will only inform the compiler which oscillator speed you have selected. This is needed for a number of statements. $crystal will NOT set the speed of the oscillator itself. Do not change the fuse bit that will change the RESET to a port pin. Some chips have this option so you can use the reset pin as a normal port pin. While this is a great option it also means you can not program the chip anymore using the ISP. Tools Terminal Emulator Top Previous Next With this option you can communicate via the RS-232 interface to the microcomputer. The following window will appear: Information you type and information that the computer board sends are displayed in the same window. Note that you must use the same baud rate on both sides of the transmission. If you compiled your program with the Compiler Settings at 4800 baud, you must also set the Communication Settings to 4800 baud. The setting for the baud rate is also reported in the report file. NOTE: The focus MUST be on this window in order to see any data (text, etc) sent from the processor. You will NOT see any data sent by the processor right after a reset. You must use an external hardware reset AFTER the terminal Emulator window is given focus in order to see the data. Using the Reset shortcut, you will not be able to see any data because pressing the shortcut causes the Terminal emulator to lose focus. This is different than �Hyper Terminal� which always receives data even when the Hyper terminal window does not have focus. Use Hyper terminal if you need to see the program output immediately after programming or reset. Or use the option 'Keep terminal emulator open' from the Options, Communication. File Upload Uploads the current program from the processor chip in HEX format. This option is meant for loading the program into a monitor program for example. It will send the current compiled program HEX file to the serial port. File Escape Aborts the upload to the monitor program. File Exit Closes terminal emulator. Terminal Clear Clears the terminal window. Terminal Open Log Opens or closes the LOG file. When there is no LOG file selected you will be asked to enter a filename or to select a filename. All info that is printed to the terminal window is captured into the log file. The menu caption will change into 'Close Log' and when you choose this option the file will be closed. Terminal Send ASCII This option allows you to send any ASCII character you need to send. Values from 000 to 255 may be entered. Terminal Send Magic number This option will send 4 bytes to the terminal emulator. The intention is to use it together with the boot loader examples. Some of the boot loader samples check for a number of characters when the chip resets. When they receive 4 'magic' characters after each other, they will start the boot load procedure. This menu options send these 4 magic characters. Terminal Setting This options will show the terminal settings so you can change them quickly. It is the same as Options, Communication. Terminal User Commands This option will show or hide the toolbar with the user definable command buttons. There are 16 user definable buttons named CMD1-CMD16. When you hover the mouse cursor above the button, the button data will be shown. When you right click the mouse above the button, you can enter the data for the button. Example for CMD4: In the sample above the data "test" will be sent. No carriage return(CR) or line feed(LF) will be sent. If you want to send them as well you need to include them as special characters. Special characters are entered with their 3 digit ASCII value between brackets : {xxx} For example to send CR + LF you wend enter {013}{010} See Also Options, Communication Tools LCD Designer Top Previous Next With this option you can design special characters for LCD-text displays. The following window will appear: The LCD-matrix has 7x5 points. The bottom row is reserved for the cursor but can be used. You can select a point by clicking the left mouse button. If a cell was selected it will be unselected. Clicking the Set All button will set all points. Clicking the Clear All button will clear all points. When you are finished you can press the Ok button : a statement will be inserted in your active program-editor window at the current cursor position. The statement looks like this : Deflcdchar ?,1,2,3,4,5,6,7,8 You must replace the ?-sign with a character number ranging from 0-7. The eight bytes define how the character will appear. So they will be different depending on the character you have drawn. See Also Font Editor Tools LIB Manager Top Previous Next With this option the following window will appear: The Libraries are shown in the left pane. When you select a library, the routines that are in the library will be shown in the right pane. After selecting a routine in the left pane, you can DELETE it with the DELETE button.. Clicking the ADD button allows you to add an ASM routine to the library. The COMPILE button will compile the lib into an LBX file. When an error occurs you will get an error. By watching the content of the generated lbx file you can determine the error. A compiled LBX file does not contain comments and a huge amount of mnemonics are compiled into object code. This object code is inserted at compile time of the main BASIC program. This results in faster compilation time. The DEMO version comes with the compiled MCS.LIB file which is named MCS.LBX. The ASM source (MCS.LIB) is included only with the commercial edition. With the ability to create LBX files you can create add on packages for BASCOM and sell them. For example, the LBX files could be distributed for free, and the ASM source could be sold. Some library examples : · MODBUS crc routine for the modbus slave program. · Glcd.lib contains the graphical LCD asm code Commercial packages available from MCS: · I2CSLAVE library · BCCARD for communication with www.basiccard.com chipcards See Also $LIB for writing your own libraries Tools Graphic Converter Top Previous Next The Graphic converter is intended to convert BMP files into BASCOM Graphic Files (.BGF) that can be used with Graphic LCD displays. The following dialog box will be shown: To load a picture click the Load button. The picture can be maximum 128 pixels high and 240 pixels width. When the picture is larger it will be adjusted. You can use your favorite graphic tool to create the bitmaps and use the Graphic converter to convert them into black and white images. When you click the Save-button the picture will be converted into black and white. Any non-white color will be converted into black. The resulting file will have the BGF extension. You can also paste a picture from the clipboard by clicking the Paste button. Press the Ok-button to return to the editor. The picture can be shown with the ShowPic statement or the ShowpicE statement. The BGF files are RLE encoded to save space. When you use your own drawing routine you can also save the pictures uncompressed by setting the Uncompressed check box. The resulting BGF files can not be shown with the showpic or showpicE statements anymore in that case! The BGF format is made up as following: · first byte is the height of the picture · second byte is the width of the picture · for each row, all pixels are scanned from left to right in steps of 6 or 8 depending on the font size. The resulting byte in stored with RLE compression The RLE method used is : byte value, AA(hex), repeats. So a sequence of 5, AA, 10 means that a byte with the value of 5 must be repeated 16 times (hex notation used) Option Description Height The height in pixels of the image. Width The width in pixels of the image. Font The T6963 supports 6x8 and 8x8 fonts. This is the font select that must match the CONFIG statement. For other displays, use 8*8. Type The size of the display. When the size is not listed, use one with the same width. SED Series If your display is a SEDxxxx chip, select this option. Uncompressed Images are RLE encoded. Select this option when you do not want to compress the image. Tools Stack Analyzer Top Previous Next The Stack analyzer helps to determine the proper stack size. See $DBG for the proper usage of this option. Tools Plugin Manager Top Previous Next The Plug in Manager allows you to specify which Plug-in's needs to be loaded the next time you start BASCOM. Just select the plug in's you want to load/use by setting the check box. The plug in's menu's will be loaded under the Tools Menu. To add a button to the toolbar, right click the mouse on the menu bar, and choose customize. When you want to write your own plug in's, contact support@mcselec.com Tools Batch Compile Top Previous Next The Batch Compiler is intended to compile multiple files. Shortcut : CTRL+B The Batch compile option was added for internal test usage. It is used by MCS to test the provided test samples. The following window is shown : There are a number of menu options. File Load Batch Load an earlier created and saved batch file list from disk. File Save Batch Save a created list of files to disk When you have composed a list with various files it is a good idea to save it for later re usage. File Save Result Save the batch compile log file to disk. A file named batchresult.txt will be saved in the BASCOM application directory. File Exit Close window Batch Compile Compile the checked files. By default all files you added are checked. During compilation all files that were compiled without errors are unchecked. This screen print shows that $inc.bas could not be compiled. And that array.bas was not yet compiled. Batch Add Files Add files to the list. You can select multiple *.BAS files that will be added to the list. Batch Add Dir Add a directory to the list. All sub directories will be added too. The entire directory and the sub directories are searched for *.BAS files. They are all added to the list. Batch Clear List Clear the list of files. Batch Clear Good Remove the files that were compiled without error. You will keep a list with files that compiled with an error. All results are shown in an error list at the bottom of the screen. When you double click an item, the file will be opened by the editor. See Also $NOCOMP Tools PDF Update 2079 improved Top Previous Next Use this option to update all Atmel PDF files. The Atmel data sheets are stored in the \PDF subdirectory. The following window will be shown : There is only one option available : Check. When you click the Check-button, the MCS server will be checked for newer versions of the PDF documents. You need to make sure that BASCOM is allowed to contact the internet. You also need to have port 211 open. This port is used in FTP mode to contact the MCS server. The MCS server is synchronizing all PDF files each day with the ATMEL server. This means that the copy on the MCS server can be maximum 24 hours old. The check will read all available DAT files and check if there is a reference to the PDF. When an item is disabled(grayed) then it means there is no link to the PDF in the DAT file. During the check the window will look like this : All PDF's that are newer will have a check mark. These need an update. You can manual unselect or select the PDF's. In the log window at the bottom of the window you can view which files will be downloaded. When you want to download the selected files, press the Download-button. This will close all PDF documents in the PDF viewer. A backup of each PDF file downloaded will be made before it is downloaded. You need to restore it when something goes wrong during the download(server drops the connection for example). When a document is downloaded, the check mark will be removed. After all documents are downloaded, they documents are opened again in the PDF viewer. As of version 2077 the PDF documents are downloaded from the MCS Electronics server. Previously they were downloaded from Atmels webserver. When Atmel change the file name the link is broken and you can not update the file. To solve this all files are stored on the MCS server and each day all files are synchronized with atmel so all files are maximum 1 day old. As of version 2079 the PDF files are downloaded using FTP. This results in a better performance. Just make sure port 411 is open in your firewall for outgoing connections. Tools Resource Editor Top Previous Next The resource editor can be used to edit the resource strings of your application. The resource editor will create a .BCR file. The resource editor is part of the Resource Add On, and is only available when you have this add on installed. The simplest way to get the resources from your application is to create a BCS file using the DUMP option. Then import them with the resource editor. The following options are available when you right click with the mouse in the resource editor. Option Description Search Search for a string. Find Next Find next occurrence. Delete Row Delete the current row. Add Row Add a new row for a new string. Import This option will import the BCS file which you can create with the $RESOURCE DUMP option. Set Language Name Change the language name of the current language/column. Add Language Add a new column for a new language. Delete Language Delete the current column (language). The resource editor is pretty simple. The only task is allow you to edit the various strings. You can also use notepad or Excel to create the BCR file which is explained in the $RESOURCE topic. Tools Font Editor Top Previous Next The Font Editor was a Plug in which is now integrated into the Tools menu. The editor is intended to create Fonts that can be used with Graphical display such as SED1521, KS108, color displays, etc. When you choose this option the following window will appear: You can open an existing Font file, or Save a modified file. The supplied font files are installed in the Samples\lcdgraph folder. You can copy an image from the clipboard, and you can then move the image up , down, left and right. When you select a new character, the current character is saved. The suggest button will draw an image of the current selected character. When you keep the left mouse button pressed, you can set the pixels in the grid. When you keep the right mouse button pressed, you can clear the pixels in the grid. When you choose the option to create a new Font, you must provide the name of the font, the height of the font in pixels and the width of the font in pixels. The Max ASCII is the last ASCII character value you want to use. Each character will occupy space. So it is important that you do not choose a value that is too high and will not be used. When you display normal text, the maximum number is 127 so it does not make sense to specify a value of 255. A font file is a plain text file. Lets have a look at the first few lines of the 8x8 font: Font8x8: $asm .db 1,8,8,0 .db 0,0,0,0,0,0,0,0 ; .db 0,0,6,95,6,0,0,0 ; ! The first line contains the name of the font. With the SETFONT statement you can select the font. Essential, this sets a data pointer to the location of the font data. The second line ($ASM) is a directive for the internal assembler that asm code will follow. All other lines are data lines. The third line contains 4 bytes: 1 (height in bytes of the font) , 8 (width in pixels of the font), 8 (block size of the font) and a 0 which was not used before the 'truetype' support, but used for aligning the data in memory. This because AVR object code is a word long. This last position is 0 by default. Except for 'TrueType' fonts. In BASCOM a TrueType font is a font where every character can have it's own width. The letter 'i' for example takes less space then the letter 'w'. The EADOG128 library demonstrates the TrueType option. In order to display TT, the code need to determine the space at the left and right of the character. This space is then skipped and a fixed space is used between the characters. You can replace the 0 by the width you want to use. The value 2 seems a good one for small fonts. All other lines are bytes that represent the character. Options Compiler Top Previous Next With this option, you can modify the compiler options. The following TAB pages are available: Options Compiler Chip Options Compiler Output Options Compiler Communication Options Compiler I2C , SPI, 1WIRE Options Compiler LCD Options Compiler Chip Top Previous Next The following options are available: Options Compiler Chip Item Description Chip Selects the target chip. Each chip has a corresponding x.DAT file with specifications of the chip. Note that some DAT files are not available yet. XRAM Selects the size of the external RAM. KB means Kilo Bytes. For 32 KB you need a 62256 STATIC RAM chip. HW Stack The amount of bytes available for the hardware stack. When you use GOSUB or CALL, you are using 2 bytes of HW stack space. When you nest 2 GOSUB�s you are using 4 bytes (2*2). Most statements need HW stack too. An interrupt needs 32 bytes. Soft Stack Specifies the size of the software stack. Each local variable uses 2 bytes. Each variable that is passed to a sub program uses 2 bytes too. So when you have used 10 locals in a SUB and the SUB passes 3 parameters, you need 13 * 2 = 26 bytes. Frame size Specifies the size of the frame. Each local variable is stored in a space that is named the frame space. When you have 2 local integers and a string with a length of 10, you need a frame size of (2*2) + 11 = 15 bytes. The internal conversion routines used when you use INPUT num, or STR(), or VAL(), etc, also use the frame. They need a maximum of 16 bytes. So for this example 15+16 = 31 would be a good value. XRAM wait state Select to insert a wait state for the external RAM. External Access enable Select this option to allow external access of the micro. The 8515 for example can use port A and C to control a RAM chip. This is almost always selected if XRAM is used Default Press or click this button to use the current Compiler Chip settings as default for all new projects. Options Compiler Output Top Previous Next Options Compiler Output Item Description Binary file Select to generate a binary file. (xxx.bin) Debug file Select to generate a debug file (xxx.dbg) Hex file Select to generate an Intel HEX file (xxx.hex) Report file Select to generate a report file (xxx.rpt) Error file Select to generate an error file (xxx.err) AVR Studio object file Select to generate an AVR Studio object file (xxx.obj) Using the OBJ file you can debug with AVR Studio. This also allows to use tools like ICE. In Studio 6.0 (fixed in 6.1) you need to make these changes in Studio : Locate the file atmelstudio.pkgundef under the installation folder for Atmel. Studio. Remove (or remark) the below lines from the file and save the file. [$RootKey$\Languages\Language Services\Basic] [$RootKey$\AutomationProperties\TextEditor\Basic] Size warning Select to generate a warning when the code size exceeds the Flash ROM size. Swap words This option will swap the bytes of the object code words. Useful for some programmers. Should be disabled for most programmers. Don't use it with the internal supported programmers. Optimize code This options does additional optimization of the generated code. Since it takes more compile time it is an option. Show internal variables Internal variables are used. Most of them refer to a register. Like _TEMP1 = R24. This option shows these variables in the report. Options Compiler Communication Top Previous Next Options Compiler Communication Item Description Baud rate Selects the baud rate for the serial communication statements. You can also type in a new baud rate. It is advised to use $BAUD in the source code which overrides this setting. Frequency Select the frequency of the used crystal. You can also type in a new frequency. It is advised to use $CRYSTAL in the source code which overrides this setting. Settings in source code are preferred since it is more clear. The settings for the internal hardware UART are: No parity , 8 data bits , 1 stop bit Some AVR chips have the option to specify different data bits and different stop bits and parity. Note that these settings must match the settings of the terminal emulator. In the simulator the output is always shown correct since the baud rate is not taken in consideration during simulation. With real hardware when you print data at 9600 baud, the terminal emulator will show weird characters when not set to the same baud rate, in this example, to 9600 baud. Options Compiler I2C, SPI, 1WIRE Top Previous Next Options Compiler I2C, SPI, 1WIRE Item Description SCL port Select the port pin that serves as the SCL-line for the I2C related statements. SDA port Select the port pin that serves as the SDA-line for the I2C related statements. 1WIRE Select the port pin that serves as the 1WIRE-line for the 1Wire related statements. Clock Select the port pin that serves as the clock-line for the SPI related statements. MOSI Select the port pin that serves as the MOSI-line for the SPI related statements. MISO Select the port pin that serves as the MISO-line for the SPI related statements. SS Select the port pin that serves as the SS-line for the SPI related statements. Use hardware SPI Select to use built-in hardware for SPI, otherwise software emulation of SPI will be used. The 2313 does not have internal HW SPI so it can only be used with software SPI mode. When you do use hardware SPI, the above settings are not used anymore since the SPI pins are dedicated pins and can not be chosen by the user. It is advised to use the various CONFIG commands in your source code. It make more clear in the source code which pins are used. Options Compiler LCD Top Previous Next Options Compiler LCD Item Description LCD type The LCD display used. Bus mode The LCD can be operated in BUS mode or in PIN mode. In PIN mode, the data lines of the LCD are connected to the processor port pins. In BUS mode the data lines of the LCD are connected to the data lines of the BUS. Select 4 when you have only connect DB4-DB7. When the data mode is 'pin' , you should select 4. Data mode Select the mode in which the LCD is operating. In PIN mode, individual processor pins can be used to drive the LCD. In BUS mode, the external data bus is used to drive the LCD. LCD address In BUS mode you must specify which address will select the enable line of the LCD display. For the STK200, this is C000 = A14 + A15. RS address In BUS mode you must specify which address will select the RS line of the LCD display. For the STK200, this is 8000 = A15 Enable For PIN mode, you must select the processor pin that is connected to the enable line of the LCD display. RS For PIN mode, you must select the processor pin that is connected to the RS line of the LCD display. DB7-DB4 For PIN mode, you must select the processor pins that are connected to the upper four data lines of the LCD display. Make upper 3 bits high in LCD designer Some displays require that for setting custom characters, the upper 3 bits must be 1. Should not be used by default. It is advised to use the CONFIG LCD command. This way the settings are stored in your source code and not in the separate CFG file. Options Communication Top Previous Next With this option, you can modify the communication settings for the terminal emulator. Item Description Comport The communication port of your PC that you use for the terminal emulator. Baud rate The baud rate to use. Parity Parity, default None. Data bits Number of data bits, default 8. Stop bits Number of stop bits, default 1. Handshake The handshake used, default is none. Emulation Emulation used, default TTY and VT100. Font Font type and color used by the emulator. Back color Background color of the terminal emulator. Keep TE open This option will keep the terminal emulator COM port open when you close the window or move the focus away. Some serial programmers which close the COM port when they need to program, will not work in this mode when they use the same COM port. Use Existing COM ports When you select this option, you will get a list with the available COM ports only at places you can select a COM port. When you insert an USB virtual COM port, it will be added to list automatically. Removing virtual COM ports will also update the available COM port list. When you do not select this option you get a list with COM1-COM255. Note that the baud rate of the terminal emulator and the baud rate setting of the compiler options, must be the same in order to work correctly. The reason why you can specify them both to be different is that you can use the terminal emulator for other purposes too. Options Environment Top Previous Next The Environment TAB has a few TABS of it's own. Options Environment Editor OPTION DESCRIPTION Auto Indent When you press return, the cursor is set to the next line at the current column position. Don't change case When set, the reformat won't change the case of the line after you have edited it. Default is that the text is reformatted so every word begins with upper case. Reformat BAS files Reformat files when loading them into the editor. All lines are reformatted so that multiple spaces are removed. This is only necessary when you are loading files that where created with another editor. Normally you won't need to set this option. Reformat code Reformat code when entered in the editor. The reformat option will change the modified line. For example a = a + 1 will be changed into : a = a + 1 . When you forget a string end marker ", one will be added, and endif will be changed into End If. And finally, ? is changed into Print. Smart TAB When set, a TAB will place the cursor to the column where text starts on the previous line. Syntax highlighting This options highlights BASCOM statements in the editor. Show margin Shows a margin on the right side of the editor. You can specify the position. By default this is 80. Comment The position of the comment. Comment is positioned to the right of your source code. Except when comment is first character of a line. TAB-size Number of spaces that are generated for a TAB. Key mapping Choose default, Classic, Brief or Epsilon. No reformat extension File extensions separated by a space that will not be reformatted when loaded. For example when DAT is entered, opening a DAT file can be done without that it is reformatted. Size of new editor window When a new editor window is created you can select how the windows will be created. Normal or Maximized (full window) Line Numbers Show line numbers in the margin. Show Subs/Labels This option will show sub modules/functions and labels at the top of the editor window in a drop down box. To get more screen space you can disable this option. Remove Empty Lines This option will remove empty lines when you paste data from the clipboard into the editor. When you copy & paste text from the help file (or any other source) you will find that windows inserts empty lines. This option will change two CR+LF into one. Indention When indention lines are drawn, you can select the color of each level. The default is gray. When you move the mouse over an indention line, the tooltip will show the start of the structure. The sample above shows the info for the green indention line. Obvious when the code fits into the screen, it is simple to see that the green line belongs to #IF _XMEGA. But when there is a lot of code in the editor, and you can not see all of the code, it can be a big help. Code Folding This option activates so called Code Folding. Code Folding allows you to hide/fold portions of your code. The screen shot above shows : 1 - The Sub DEMO is folded. So you only see Sub Demo in your code. To indicate that the sub is folded there is a marker at the end of the line (3 dots) Another indicator is the + sign. This means that the node is folded. 2 - When you put the cursor above the marker, you get a hint with the folded text/code. 3 - The minus means that you can fold that node. When you click the - it will turn into a + and the code is folded. This is how it looks when the node at (3) is clicked: When folding code, all child code (all levels under the node) will be folded/unfolded as well. A node is a point in your code that is part of a structure like sub/end sub , function/ end function, for/next, do/loop, while/wend When you press F11, the current SUB or FUNCTION will be folded/unfolded. The Editor menu also has options to fold/unfold all code. Draw Indention Lines This option will draw vertical indent lines for structures. Drawing indention lines may result in slower screen painting. Errors in your code might result in wrong painting of the lines. Options Environment Font OPTION DESCRIPTION Background color The background color of the editor window. Choose a color that is the same as your background. In a white room, using white would be best for your eyes. Keyword color The color of the reserved words. Default Navy. The keywords can be displayed in bold too. Comment color The color of comment. Default green. Comment can be shown in Italic too. ASM color Color to use for ASM statements. Default purple. HW registers color The color to use for the hardware registers/ports. Default maroon. String color The color to use for string constants : "test" Variable color The color to use for variables. Default is black. User Function Color The color to use for user SUBS and FUNCTIONS. The default is fuchsia. Editor font Click on this button to select another font for the editor window. A good choice is Fixedsys. Show Hidden Characters This option will show special characters in the editor. Special characters are characters such as CR and LF. And all characters with an ASCII value above 127. You can use this option to find odd characters in your code which could result in compilation errors. Options Environment IDE OPTION DESCRIPTION Tool tips Show tool tips when hovering over form elements such as buttons. File location Click to select a directory where your program files are stored. By default Windows will use the My Documents path. Sample Location Click to select the folder where the SAMPLE files are located. They are either stored in a sub folder of the application, or in a folder under the Documents\MCS Electronics\BASCOM-AVR\samples folder Use HTML Help Chose between old help and CHM Help. CHM is the preferred help file. Since HLP is not supported under Vista, it is advised to switch to CHM/HTML Help. The HLP file is not distributed but using the UpdateWiz you can still download the HLP file. Code hints Select this option to enable code hints. You can get code hints after you have typed a statement that is recognized as a valid statement or function. Hint Time The delay time in mS before a code hint will be shown. Hint Color The background color of the hints. Allow multiple Instances Select this option when you want to run multiple instances of BASCOM. When not enabled, running a second copy will terminate the first instance. Auto save on compile The code is always saved when you compile. When you select this option, the code is saved under the same name. When this option is not selected, you will be prompted for a new filename. Auto backup Check this option to make periodic backups. When checked you can specify the backup time in minutes. The file will also be saved when you press the compiler button. History Backup This option creates a history backup of the source file each time you save it. When you Compile code, the active source will be saved too before compilation and hence it will create a history file as well. The history file is a version of the code saved in the HISTORY folder. This folder is located in the same folder as the main project. The file will be named ~yymmdd hhnnss.hst Where is the original file name, and yymmdd is the date and hhNNss is the time. Auto load last file When enabled, this option will load the last file that was open into the editor, when you start BASCOM. Auto load all files When enabled, this option will load all files that were open when you closed BASCOM. Check for updates Select this option to check for updates when the IDE is started. Show TABS This option will enable/disable the TAB for multiple windows. While the TAB is convenient to switch between windows, it will also consume screen space. You can disable this option to get more screen space. Reset docking This will reset the dockable windows to the default position. Search Find Auto Complete This option can enable/disable the auto completion in the Find dialog. When it is active and you type some text, based on historical input, the text will be completed. This is not always desired and can be disabled. Language This will set the language in the main menu to the selected language. Not all listed languages are supported/translated yet. Clear Do not Ask Some messages have a 'do not ask again' option. To reset this and thus show the messages, you can click this button. Use New Method When compiling a project, the main file is searched for some settings like $regfile, $hwstack, $swstack and $framesize. This information is passed to the compiler DLL. This search is fast but simple : it will not work correct when using directives such as : #IF someConditon $regfile = "m88def.dat" #ELSE $regfile = "m2650def.dat" #ENDIF The parser used for the code explorer is capable to get the information but requires more time because it will parse the entire project. So you have the option to chose the old method(default) or the new method. It is good practice to start your project with the required info : $regfile = "yourmicro.dat" $hwstack=32 ' $swstack=32 $framesize=32 Code Explorer with separate INC files The Code explorer will put all elements in one tree without file names. Setting this option however will create a tree of elements with all file names under a branch named 'Inc Files'. Code explorer with separate inc files Code explorer without separate inc files Options Environment PDF OPTION DESCRIPTION Auto open processor PDF This option will automatic load the PDF of the selected micro processor in the PDF viewer. The $REGFILE value determines which data sheet is loaded. The PDF must exist otherwise it can not be loaded. Open PDF in new sheet Every time you change the value of the $REGFILE the processor PDF can be shown in the same sheet, or a new sheet can be shown with the PDF. A good option in case your project uses multiple processors. Auto save/load project PDF Load all PDF's when the project is opened that were loaded when the project was closed. Options Simulator Top Previous Next With this option you can modify the simulator settings. OPTION DESCRIPTION Use integrated simulator Set this option to use BASCOM�s simulator. You can also use AVR Studio by clearing this option. Run simulator after compilation Run the selected simulator after a successful compilation. Program The path with the program name of the external simulator. Parameter The parameter to pass to the program. {FILE}.OBJ will supply the name of the current program with the extension .OBJ to the simulator. Options Programmer Top Previous Next With this option you can modify the programmer settings. OPTION DESCRIPTION Programmer Select one from the list. Play sound Name of a WAV file to be played when programming is finished. Press the directory button to select a file. Erase Warning Set this option when you want a confirmation when the chip is erased. Auto flash Some programmers support auto flash. Pressing F4 will program the chip without showing the programmer window. Auto verify Some programmers support verifying. The chip content will be verified after programming. Upload code and data Set this option to program both the FLASH memory and the EEPROM memory Program after compile When compilation is successful, the chip will be programmed Set focus to terminal emulator When the chip is programmed, the terminal emulator will be shown Parallel printer port programmers LPT address Port address of the LPT that is connected to the programmer. Port delay An optional delay in uS. It should be 0. But on some systems a delay might be needed. Serial port programmer COM port The com port the programmer is connected to. STK500 EXE The path of stk500.exe. This is the full file location to the files stk500.exe that comes with the STK500. USB For mkII and other Atmel USB programmers you can enter the serial number here. Or you can look it up from the list. Other Use HEX Select when a HEX file must be sent instead of the bin file. Program The program to execute. This is your programmer software. Parameter The optional parameter that the program might need. Use {FILE} to insert the binary filename(file.bin) and {EEPROM} to insert the filename of the generated EEP file. When �Use Hex� is checked the filename (file.hex) will be inserted for {FILE}. In all cases a binary file will be inserted for {EEPROM} with the extension .EEP Use {CHIP} to insert the official device name of the chip. The device name is required by some programmers. See Also Supported programmers Supported Programmers Top Previous Next BASCOM supports the following programmers AVR ICP910 based on the AVR910.ASM application note STK200 ISP programmer from Atmel The PG302 programmer from Iguana Labs The simple cable programmer from Sample Electronics. KITSRUS KIT122 Programmer MCS Universal Interface Programmer The MCS Universal Interface supports a number of programmers as well. In fact it is possible to support most parallel printer port programmers. STK500 programmer and Extended STK500 programmer. Lawicel BootLoader USB-ISP Programmer MCS Bootloader PROGGY FLIP USBprog Programmer / AVR ISP mkII (AVRISP) KamProg for AVR USBASP STK600 ARDUINO BIPOM MINI-MAX/C mySmartUSB light UPDI Programmer ISP programmer Top Previous Next BASCOM supports the STK200 and STK200+ and STK300 ISP programmer from Atmel. This is a very reliable parallel printer port programmer. The STK200 ISP programmer is included in the STK200 starter kit. Most programs were tested with the STK200. For those who don't have this kit and the programmer the following schematic shows how to make your own programmer: The dongle has a chip with no identification but since the schematic is all over the web, it is included. MCS also sells a STK200 compatible programmer. Here is a tip received from a user : If the parallel port is disconnected from the interface and left floating, the '244 latch outputs will waver, causing your micro controller to randomly reset during operation. The simple addition of a 100K pull-up resistor between pin 1 and 20 of the latch, and another between pin 19 and 20, will eliminate this problem. You'll then have HIGH-Z on the latch outputs when the cable is disconnected (as well as when it's connected and you aren't programming), so you can use the MOSI etc. pins for I/O. PG302 programmer Top Previous Next The PG302 is a serial programmer. It works and looks exactly as the original PG302 software. Select the programmer from The Option Programmer menu or right click on the button to show the Option Programmer menu THIS PROGRAMMED IS MARKED FOR REMOVAL. Send a note to support if you use it. Sample Electronics cable programmer Top Previous Next Sample Electronics submitted the simple cable programmer. They produce professional programmers too. This simple programmer you can make yourself within 10 minutes. What you need is a DB25 centronics male connector, a flat cable and a connector that can be connected to the target MCU board. The connections to make are as following: DB25 pin Target MCU pin(AT90S8535) Target MCU M103/M128 Target MCU pin 8515 DT104 2, D0 MOSI, pin 6 PE.0, 2 MOSI, 6 J5, pin 4 4, D2 RESET, pin 9 RESET, 20 RESET, 9 J5, pin 8 5, D3 CLOCK, pin 8 PB.1,11 CLOCK, 8 J5, pin 6 11, BUSY MISO, pin 7 PE.1, 3 MISO, 7 J5, pin 5 18-25,GND GROUND GROUND GND,20 J5, pin 1 The MCU pin numbers are shown for an 8535! And 8515 Note that 18-25 means pins 18,19,20,21,22,23,24 and 25 You can use a small resistor of 100-220 ohm in series with the D0, D2 and D3 line in order not to short circuit your LPT port in the event the MCU pins are high. It was tested without these resistors and no problems occurred. Tip : when testing programmers etc. on the LPT it is best to buy an I/O card for your PC that has a LPT port. This way you don�t destroy your LPT port that is on the motherboard in the event you make a mistake! The following picture shows the connections to make. Both a setup for the DT104 and stand-alone PCB are shown. I received the following useful information: I have been having spurious success with the simple cable programmer from Sample Electronics for the AVR series. After resorting to hooking up the CRO I have figured it out (I think). When trying to identify the chip, no response on the MISO pin indicates that the Programming Enable command has not been correctly received by the target. The SCK line Mark/Space times were okay but it looked a bit sad with a slow rise time but a rapid fall time. So I initially tried to improve the rise time with a pull-up. No change ie still could not identify chip. I was about to add some buffers when I came across an Atmel app note for their serial programmer "During this first phase of the programming cycle, keeping the SCK line free from pulses is critical, as pulses will cause the target AVR to loose synchronization with the programmer. When synchronization is lost, the only means of regaining synchronization is to release the RESET line for more than 100ms." I have added a 100pF cap from SCK to GND and works first time every time now. The SCK rise time is still sad but there must have been enough noise to corrupt the initial command despite using a 600mm shielded cable. KITSRUS Programmer Top Previous Next The K122 is a KIT from KITSRUS. (www.kitsrus.com) The programmer supports the most popular 20 and 40 pins AVR chips. On the Programmer Options tab you must select this programmer and the COM port it is connected to. On the Monitor Options tab you must specify the upload speed of 9600, Monitor delay of 1 and Prefix delay 1. When you press the Program button the Terminal Emulator screen will pop up: A special toolbar is now visible. You must press the Program enable button to enable the programmer. When you enable the programmer the right baud rate will be set. When you are finished you must press the Enable button again to disable it. This way you can have a micro connected to your COM port that works with a different BAUD rate. There is an option to select between FLASH and EEPROM. The prompt will show the current mode which is set to FLASH by default. The buttons on the toolbar allow you to : ERASE, PROGRAM, VERIFY, DUMP and set the LOCK BITS. When DUMP is selected you will be asked for a file name. When the DUMP is ready you must CLOSE the LOGFILE where the data is stored. This can be done to select the CLOSE LOGFILE option form the menu. THIS PROGRAMMED IS MARKED FOR REMOVAL. Send a note to support if you use it. MCS Universal Interface Programmer Top Previous Next The MCS Universal Interface programmer allows you to customize the pins that are used for the ISP interface. The file prog.settings stores the various interfaces. The content : ;how to use this file to add support for other programmers ;first create a section like [newprog] ; then enter the entries: ; BASE= $hexaddress ; MOSI= address in form of BASE[+offset] , bit [,inverted] ; CLOCK= same as MOSI ; RESET=same as MOSI ; MISO=same as MOSI ; The bit is a numer that must be written to set the bit ; for example 128 to set bit 7 ; Optional is ,INVERTED to specify that inverse logic is used ; When 128 is specified for the bit, NOT 128 will be written(127) [FUTURELEC] ;tested and ok BASE=$378 MOSI=BASE+2,1,inverted CLOCK=BASE,1 RESET=BASE,2 MISO=BASE+1,64 [sample] ;tested and ok BASE=$378 MOSI=BASE,1 CLOCK=BASE,8 RESET=BASE,4 MISO=BASE+1,128,INVERTED [stk200] ;tested and ok BASE=$378 MOSI=BASE,32 CLOCK=BASE,16 RESET=BASE,128 MISO=BASE+1,64 Four programmers are supported : Futurelec, Sample and STK200/STK300 and WinAVR/ SP12. To add your own programmer open the file with notepad and add a new section name. For the example I will use stk200 that is already in the file. [stk200] The LPT base address must be specified. For LPT1 this is in most cases $378. $ means hexadecimal. The pins that are needed are MOSI, CLOCK, RESET and MISO. Add the pin name MOSI = After the pin name add the address of the register. For the STK200 the data lines are used so BASE must be specified. After the address of the register, specify the bit number value to set the pin high. Pin 0 will be 1, pin 1 would be 2, pin 2 would be 4 etc. D5 is used for the stk so we specify 32. When the value is set by writing a logic 0, also specify, INVERTED. After you have specified all pins, save the file and restart BASCOM. Select the Universal Programmer Interface and select the entry you created. After you have selected an entry save your settings and exit BASCOM. At the next startup of BASCOM, the settings will be used. The following picture shows the LPT connector and the relation of the pins to the LPT registers. Always add your entry to the bottom of the file and email the settings to support@mcselec.com so it can be added to BASCOM. STK500 Programmer 2081 ENHANCED Top Previous Next When you select the STK500 programmer, BASCOM will run the file named stk500.exe that is installed with AVR Studio. That is why you have to specify the file location of the stk500.exe The normal STK500 support will erase, and program the flash. The STK500.EXE supports a number of Atmel programmers which all use the STK500 V1 or V2 protocol. For the AVR ISP mkII, you need to supply the serial number of the USB programmer. The USB port will be used then instead of the serial port. You can also use the native driver which does not use/need the stk500.exe If you select this programmer, you will see the following window when you launch the programmer with F4(manual program) When the source code is compiled and the BIN file exists, it is loaded automatic into the buffer. When an EEPROM image file exists (EEP), it is loaded too into the EEPROM buffer. When it does not exist you will see a warning which you can ignore. When the target device is not read yet, the CHIP will be unidentified which is marked as ???. In the status bar you can see the loaded file, and the size of the file. Notice that 16000 will be shown as 16 KB. You can select the EEPROM-TAB to view the EEPROM image. Memory locations can be altered. Select a cell, and type a new value. Then press ENTER to confirm. You can immediately see the new value. When you select the Lock and Fusebits-TAB the lock and fuse bits will be read. As you can see that as soon as the target chip is determined, the chip name is shown under the tool bar. The FLASH size and EEPROM size are shown also. As soon as you alter a lock or fuse bit, the corresponding Write-button will be enabled. You need to click it to write the new value. The lock and fuse bits are read again so you can see if it worked out. The lock and fuse bits shown will depend on the used chip. Every chip has different fuse bits. Some fuse bits can not be altered via the serial programming method. The native stk500 driver uses the serial programming method. Some fuse bits require the parallel or high voltage programming method. For example the fuse bit 'enable serial downloading' can not be changed with the serial programming method. Fuse bits of interest are : the clock divider and the oscillator fuse bits. When you select a wrong oscillator fuse bit (for example you select an external oscillator) the chip will not work anymore till you connect such an external oscillator! Of course a simple 555 chip can generate a clock signal you can use to 'wake' a locked chip. Once you have all settings right, you can press the 'Write PRG' button which will insert some code into your program at the current cursor position. This is the $PROG directive. For example : $prog &HFF , &HED , &HD0 , &HFF When you compile your program with the $PROG directive it will generate a PRG file with the lock and fuse bit settings. If you then auto program(see later) a chip, it will use these settings. $PROG is great to load the right lock and fuse bits into a new chip. But be careful : do not enable $PROG till you are done with development. Otherwise programming will be slow because of the extra reading and writing steps. The following menu options are available: Option Description File Exit Close programmer. Buffer Clear Clear buffer. Will put a value of 255 (FF hex) into each memory location. When the FLASH-TAB has the focus, the FLASH buffer will be cleared. When the EEPROM-TAB has the focus, the EEPROM buffer will be cleared. 255 is the value of an empty memory location. Load from File This will shown an open file dialog so you can select a binary file (BIN) The file is loaded into the buffer. Save to File Will save the current buffer to a file. Reload Reloads the buffer from the file image. Chip Identify Will attempt to read the signature of the chip. When the signature is unknown(no DAT file available) or there is no chip or other error, you will get an error. Otherwise the chip name will be shown. Write buffer to chip This will write the active buffer(FLASH or EEPROM) into the chip. Read chipcode When the chip lock bit is not set you can read the FLASH or EEPROM into the buffer. Blank check Check if the chip FLASH or EEPROM is empty. Erase Erases the chip FLASH. It depends on the fusebits if the EEPROM is erased too. Normally the EEPROM is erased too but some chip have a fuse bit to preserve EEPROM when erasing the chip. A chip MUST be erased before it can be programmed. Verify Checks if the buffer matches the chip FLASH or EEPROM. Auto program This will eraser, and program the FLASH and EEPROM and if $PROG is used, it will set the lock and fusebits too. Under Options, you can find a setting to change the clock frequency. The clock frequency should not be higher then a quarter of the oscillator frequency. This means that a chip with an internal 8 MHz oscillator which has the 8-divider fuse enabled, will have a clock frequency of 1 Mhz. The programming clock may not exceed 250 KHz in this case. STK500 board When using the STK500 board, you can change the target voltage and the reference voltage. In 2081 you can also change the board oscillator frequency. The BOARD menu has a sub menu named STK500. This sub menu has a few options : - Read Settings : you should do this first - Vtarget : this is the target voltage. Make sure the chip can handle the voltage you enter - Vref : this is the reference voltage. It may not exceed Vtarget. - Osc : this is the oscillator frequency. - Write settings : this will write the new settings to the STK500 board. After doing so, read back the settings to see if the values are correct. You will notice that not all values you enter are possible. This is exactly the same when you use AVR Studio. Lawicel BootLoader Top Previous Next The Lawicel Boot loader must be used with the StAVeR. The StAVeR contains a boot loader so you only need a serial interface, no parallel programmer or other programmers. You can also use Hyper terminal. When you have selected the Lawicel Boot loader from the Options, Programmer, the following window will appear when you press F4. As the window suggests, press the reset button on the activity board or StAVeR, and the chip will be programmed. This is visible by a second wind that will be shown during programming. When the programming succeeds, both windows will be closed. When an error occurs, you will get an error message and you can clock the Cancel button in order to return to the Editor. THIS PROGRAMMED IS MARKED FOR REMOVAL. Send a note to support if you use it. AVR ISP Programmer Top Previous Next The AVRISP programmer is AVR ICP910 based on the AVR910.ASM application note. The old ICP910 does not support Mega chips. Only a modified version of the AVR910.ASM supports Universal commands so all chips can be programmed. The new AVRISP from Atmel that can be used with AVR Studio, is not compatible! You need to select STK500 programmer because the new AVRISP programmer from Atmel, uses the STK500 protocol. When you do not want to use the default baud rate that AVR910 is using, you can edit the file bascavr.ini from the Windows directory. Add the section [AVRISP] Then add: COM=19200,n,8,1 This is the default. When you made your own dongle, you can increase the baud rate You need to save the file and restart BASCOM before the settings will be in effect. USB-ISP Programmer Top Previous Next The USB-ISP Programmer is a special USB programmer that is fully compatible with BASCOM's advanced programmer options. Since many new PC's and especial Laptop's do not have a parallel programmer anymore, MCS selected the USB-ISP programmer from EMBUD. The drivers can be downloaded from the MCS Electronics website. Please download from http://www.mcselec.com/index.php?option=com_docman&task=doc_download&gid=204&Itemid=54 After downloading, unzip the files in the BASCOM-AVR application directory in a sub directory named USB. When you connect the programmer, Windows (98, ME, 2000, XP) will recognize the new device automatically. Then the Hardware wizard will be started : Select 'No, not this time' and click Next, as there is no driver at Microsoft's web. The Wiz will show : You need to select 'Install from a list or specific location' and click Next. You can specify the path of the USB driver. This is by default : C:\Program Files\MCS Electronics\BASCOM-AVR\USB Use the Browse-button to select it, or a different location, depending on your installation. As the driver is not certified by Micros ft, you will see the following window: You need to select 'Continue Anyway'. A restore point will be made if your OS supports this and the driver will be installed. After installation you must see the following window : After you press Finish you will see Windows can use the programmer : In BASCOM , Options, Programmer you can select the new programmer now. New models of the USB programmer allow to set the speed. The USB-ISP programmer is very quick and supports all options that the Sample Electronics and STK200 programmers support. It is good replacement for the STK200. When you use other USB devices that use the FTDI drivers, there might occur a problem. Manual install the drivers of these other devices, then install the USB-ISP driver. USB-ISP on VISTA For Vista and Vista 64, please follow the this installation description. When connection the ISP-PROG I to your PC the following window will show up. Here I have to select the top selection: Locate and Install driver software (recommended) Vista starts it search for the driver and will come finally with the question to Insert the driver disk. As we have no driver CD, you have to select: I don�t have the disc. Show me other options Now we select the Browse selection and locate the driver folder. And select Next button. As Vista 64 only allows certified drivers the following message will pop-up. Just select Install this driver software anyway and Vista 64 will now start with installing the driver. Be patient as it depends on your system configuration how long it will take. Finally Vista 64 will tell you that the driver is installed. To check your configuration you can go to your device manager to see if it is there. MCS Bootloader Top Previous Next The MCS Boot loader is intended to be used with the $LOADER sample. It uses the X-modem Checksum protocol to upload the binary file. It works very quick. The Boot loader sample can upload both normal flash programs and EEPROM images. The Boot loader sends a byte with value of 123 to the AVR Boot loader. This boot loader program then enter the boot loader or will jump to the reset vector (0000) to execute the normal flash program. When it receives 124 instead of 123, it will upload the EEPROM. When you select a BIN file the flash will be uploaded. When you select an EEP file, the EEPROM will be uploaded. The Boot loader has some specific options. BOOTSIZE You can choose the boot size which is 1024 for the BASCOM $LOADER example. Since this space is used from the normal flash memory, it means your application has 1024 less words for the main application. (A word is 2 byte, so 2KB less) The XMEGA has a separate boot space so for Xmega you can set the value to 0. RESET The boot loader is started when the chip is reset. Thus you need to reset the chip after you have pressed F4(program). But when you have connected the DTR line to the chip reset (with a MAX232 buffer) you can reset the chip automatically. You do need to set the 'Reset via DTR' option then. You can also chose to use the RTS line. When your program does not use the boot vector or needs a special sequence to activate the loader, you can chose the soft reset. To send ASCII characters you can embed them between brackets {}. For example {065} will be sent as the character A or byte with value 65. CLOSE By choosing 'Close programmer window when ready' the window will be closed when the loader returns 0. In all other cases it will remain opened so you can look at a possible cause. EEP If an EEP (EEPROM image file) exists, the loader can send this file instead of the flash binary file. If you enable this option, you will be asked if you want to send the EEP instead of the BIN file. After you have pressed F4 to following window will appear : As you can see the loader sends a byte with value of 123. You need to reset the chip, and then you will see that the loader returned 123 which means it received the value. It will start the upload and you see a progress bar. After the loader is ready, you see a finish code of 0. A finish code of 0 means that all wend well. Other finish codes will not close the window even if this option is enabled. You need to manual close the window then. ERROR CODES -6001 - Bad format in file name -6002 - file not found -6003 - file not found in folder -6004 - folder not found -6005 - canceled -6006 - time out -6007 - protocol error -6008 - too many errors -6009 - block sequence error -6016 - session aborted The most likely error is -6006 when the bootloader is not present or does not respond timely after the initial handshake. Increase the $timeout in the boot loader in that case. PROGGY Top Previous Next PROGGY is a popular USB programmer written by Red_Mamba. You need to install it and make sure that the registry key : HKEY_CURRENT_USER\Software\Red_Mamba\Atmel programator exists with the parameter : InstallPath InstallPath should point to the executable which name is atme.exe When you install PROGGY, it will be handled for you. When you have an older version, you need to update. BASCOM will call the programmer with the following options : -p -s -e The -e will cause the programmer to exit after the programming. FLIP Top Previous Next FLIP is a free USB bootloader from Atmel. With FLIP you can program an AVR without additional (ISP) programmer hardware. Because it is a USB bootloader it only work with AVR with built in USB functionality. FLIP is supported by the BASCOM-IDE so you can use it direct by pressing the Program Chip (F4) button and download a HEX file. FLIP can be downloaded from the Atmel site. Search for "FLIP bootloader" on the Atmel Website for the latest version: https://www.microchip.com/developmenttools/ProductDetails/flip 1. Download FLIP from Atmel Website 2. Install FLIP 3. In BASCOM-IDE Select FLIP from Options >>> Programmer , in order to program quickly without the FLIP executable 4. Now you can press Program Chip (F4) to program the HEX file into the chip As with other programmers, you press F4 to program the HEX file into the chip. A small window will become visible. A number of dialogs are possible: In this case, you try to program a chip which is not supported by FLIP. The Mega88 is not an USB chip so the error makes sense. If you are using an USB AVR you could get following dialog box: This dialog informs you about a missing DFU device and/or the device is not in boot loader mode: In this case, the boot loader is not found. You can run the boot loader by following the sequence from the dialog box. In order to make this work, the HWB (Hardware Bootloader Button) and RST (Reset Button) input both need a small switch to ground. When HWB is pressed(low) during a reset, the boot loader will be executed. Abbreviations: � ISP: In-system programming � RST: Rest � USB: Universal serial bus � DFU: Device firmware upgrade � FLIP: Flexible in-system programmer FAQ - Using FLIP with XMEGA-A3BU Xplained Board from Atmel (under Windows 7 32-Bit) 1. Read Atmel App Note: AVR1916: USB DFU Boot Loader for XMEGA 2. Download FLIP 3. Install FLIP 3.4.5 or higher for Windows (Java Runtime Environment included) 4. Connect the USB Cable during pressing Switch0 SW0 (Hardware Bootloader button) on the XMEGA-A3BU Xplained board 5. The USB Driver can be found in the FLIP Software directory (e.g.: C:\Program Files\Atmel\Flip 3.4.5\usb) 6. You can also search for DFU ATXMEGA256A3BU in the Windows 7 device manager and reinstall the driver by pointing it to this directory (e.g.: C:\Program Files\Atmel\Flip 3.4.5\usb) 7. Then you will find this here in the device manager Atmel USB Devices >>>> ATxmega256A3BU 8. In BASCOM-IDE Select FLIP from Options >>> Programmer , in order to program quickly without the FLIP executable 9. Now you can press Program Chip (F4) to program the HEX file into the chip If you see following dialog: Just connect the USB Cable during pressing Switch0 SW0 on the XMEGA-A3BU Xplained board Hit OK button then the XMEGA will be programmed. First example for XMEGA-A3BU board: $regfile = "XM256A3BUDEF.DAT" $crystal = 32000000 '32MHz $hwstack = 64 $swstack = 40 $framesize = 80 Config Osc = Enabled , 32mhzosc = Enabled '32MHz 'configure the systemclock Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 Config Porte.4 = Output Backlight Alias Porte.4 'LCD Backlight Config Portr.0 = Output Led0 Alias Portr.0 'LED 0 Config Portr.1 = Output Led1 Alias Portr.1 'LED 1 Do Waitms 500 Reset Led0 Set Led1 Waitms 500 Set Led0 Reset Led1 Loop End 'end program FAQ - FLIP with BASCOM-IDE On former versions like FLIP 3.3.1 there was on VISTA a problem with loading some of the FLIP DLL's. In case you get an error, copy the FLIP DLL's to the BASCOM application directory. You need to copy the following files : · atjniisp.dll · AtLibUsbDfu.dll · msvcp60.dll · msvcrt.dll You can also create a command file for that task like: flipDLLcopy.cmd to copy these files. The content of the command file : copy "c:\program files\atmel\flip 3.3.1\bin\atjniisp.dll" . copy "c:\program files\atmel\flip 3.3.1\bin\AtLibUsbDfu.dll" . copy "c:\program files\atmel\flip 3.3.1\bin\msvcp60.dll" . copy "c:\program files\atmel\flip 3.3.1\bin\msvcrt.dll" . pause The last line pauses so you can view the result. Notice the . (dot) that will copy the file to the current directory, which is the reason that you need to run this file from the BASCOM application directory. You also need to adapt the version of FLIP in the command file. In order to use BASCOM's FLIP support, you must have running FLIP successfully first ! Here is a good tip from a user : IMO he Flip 3.3.1 Installer is a little bit stupid. The dll´s are located in the Path ...\Atmel\Flip 3.3.1\bin . The Installer has set a correct Path-Variable in Windows for this path. But, the libusb0.dll isn´t in that location. It is in ...\Atmel\Flip 3.3.1\USB ! So I moved the libusb0.dll into the \bin dir and Flip runs without the errors. (GRRRR) In the ...\Atmel\Flip 3.3.1\USB dir I have also detected the missing .inf File. After installing this, Windows detects the AT90USB162 and Flip can connect the device. USBprog Programmer / AVR ISP mkII Top Previous Next The USBprog programmer is a neat small USB programmer which is fully compatible with the AVR ISP mkII programmer. When you select this programmer, you will get the same interface as for the STK500 native programmer. F4 will launch the programmer. For more details read the help section for the STK500 programmer. When programming XMEGA chips the interface for the fuse bits will be different. See STK600 programmer for a description. The default clock is 125 KHz. This because most/all chips ship with a clock frequency of 1 MHz. And since the clock frequency maximum is a quarter of the oscillator frequency, the default is 125 KHz, low enough to be able to program all chips. Once your chip runs at say 8 MHz, you can select 2 MHz as the maximum. You must have the LIBSUSB drivers installed on your PC. Without it, it will not work. Options In the Configuration options you can adjust the clock speed and the timeout of the USB. When you are using USB 1.1 and a lot of devices that generate a lot of USB traffic, you might need to increase the default timeout of 100 (msec). XMEGA When used in PDI mode, take care about the following for some of the processors: JTAG is activated by default which preventing from using the PDI because both interfaced share the same pins. In this case : 1 - Disable the JTAG before using the PDI. > You need a JTAG programmer 2 - Use a 47Kohm resistor to Pull down the clock pin to ground which allow you to have both JTAG and PDI working simultaneously. KamProg for AVR Top Previous Next KamProg for AVR is an USB programmer from Kamami. You need to install the software that comes with the KamProg. You can download the software from the web site of the manufacturer or from MCS Electronics web shop Kamprog product page. KamProg can be used with BASCOM but also with AVR Studio. BASCOM will use the KamProg software to either automatic or manual program the chip. The Kamprog programmer works on Vista32 and Vista64 and requires no special drivers. It has also been tested with Win7 and Win8 and Win8.1 The KamProg programmer is available from MCS Electronics webshop. When you use Auto program, you will see a small progress window while the processor is programmed. When you chose manual program, you will see a familiar window, known from USB-ISP. When the source code is compiled and the BIN file exists, it is loaded automatic into the buffer. When an EEPROM image file exists (EEP), it is loaded too into the EEPROM buffer. When it does not exist you will see a warning which you can ignore. When the target device is not read yet, the CHIP will be unidentified which is marked as ???. In the status bar you can see the loaded file, and the size of the file. Notice that 16000 will be shown as 16 KB. You can select the EEPROM-TAB to view the EEPROM image. Memory locations can be altered. Select a cell, and type a new value. Then press ENTER to confirm. You can immediately see the new value. When you select the Lock and Fusebits-TAB the lock and fuse bits will be read. As soon the target chip is determined, the chip name is shown under the tool bar. The FLASH size and EEPROM size are shown too. When you alter a lock or fuse bit, the corresponding Write-button will be enabled. You need to click it to write the new value. The lock and fuse bits are read again so you can see if it worked out. The lock and fuse bits shown will depend on the used chip. Every chip has different fuse bits. Some fuse bits can not be altered via the serial programming method. For example the fuse bit 'enable serial downloading' can not be changed using the serial programming method. Fuse bits of interest are : the clock divider and the oscillator fuse bits. When you select a wrong oscillator fuse bit (for example you select an external oscillator) the chip can not programmed anymore until you connect such an external oscillator! Of course a simple 555 chip can generate a clock signal you can use to 'wake' a locked chip. Once you have all settings right, you can press the 'Write PRG' button which will insert some code into your program at the current cursor position. This is the $PROG directive. For example : $prog &HFF , &HED , &HD0 , &HFF When you compile your program with the $PROG directive it will generate a PRG file with the lock and fuse bit settings. If you then auto program(see later) a chip, it will use these settings. $PROG is great to load the right lock and fuse bits into a new chip. But be careful : do not enable $PROG till you are done with development. Otherwise programming will be slow because of the extra reading and writing steps. The following menu options are available: Option Description File Exit Close programmer. Buffer Clear Clear buffer. Will put a value of 255 (FF hex) into each memory location. When the FLASH-TAB has the focus, the FLASH buffer will be cleared. When the EEPROM-TAB has the focus, the EEPROM buffer will be cleared. 255 is the value of an empty memory location. Load from File This will shown an open file dialog so you can select a binary file (BIN) The file is loaded into the buffer. Save to File Will save the current buffer to a file. Reload Reloads the buffer from the file image. Chip Identify Will attempt to read the signature of the chip. When the signature is unknown(no DAT file available) or there is no chip or other error, you will get an error. Otherwise the chip name will be shown. Write buffer to chip This will write the active buffer(FLASH or EEPROM) into the chip. Read chipcode When the chip lock bit is not set you can read the FLASH or EEPROM into the buffer. Blank check Check if the chip FLASH or EEPROM is empty. Erase Erases the chip FLASH. It depends on the fusebits if the EEPROM is erased too. Normally the EEPROM is erased too but some chip have a fuse bit to preserve EEPROM when erasing the chip. A chip MUST be erased before it can be programmed. Verify Checks if the buffer matches the chip FLASH or EEPROM. Auto program This will eraser, and program the FLASH and EEPROM and if $PROG is used, it will set the lock and fusebits too. In the toolbar you can also alter the ISP clock frequency. The clock frequency should not be higher then a quarter of the oscillator frequency. This means that a chip with an internal 8 MHz oscillator which has the 8-divider fuse enabled, will have a clock frequency of 1 Mhz. The programming clock may not exceed 250 KHz in that case. USBASP Top Previous Next The USBASP is a popular USB programmer created by Thomas Fischl The programmer uses a Mega8 or other AVR chip as an USB device. You can find the programmer at Thomas website : http://www.fischl.de/usbasp Make sure when programming the fuse and lock bits that the selected clock frequency is not too high. The clock frequency of the ISP programmer should be less then one quarter of the oscillator frequency. When your micro is running at 8 MHz, you can select up to 2 MHz. On the safe size, 125 KHz is always ok. By default most AVR processors run at 8 MHz with an 8-divider resulting in 1 MHz clock frequency. So 250 KHz is a safe value for most processors. You can select various clock frequencies. See also LIBUSB for installation of LIBUSB STK600 Top Previous Next The STK600 is a development board from Atmel. It uses a similar protocol as the STK500 and has an integrated USB programmer on board. The programmer can be connected with a cable to the STK600 board itself, but also to an external board. The STK600 replaces the STK500 and is advised for XMEGA development. For regular AVR chips we would recommend the STK500. The STK600 has actual 3 different programmers on board : ISP, PDI and JTAG. the ISP/PDI protocols are combined and placed on one connector. When programming XMEGA chips, the BASCOM programmers will automatic switch to the PDI protocol. The ISP protocol can not be used with XMEGA chips. For other chips, (non-xmega), the ISP protocol will be used. There are affordable PDI programmers available. The following description is also true for the AVRISP/mkII programmer which also supports the PDI protocol. In order to use the STK600 protocol you need to have LIBSUSB installed. Identification The BASCOM programmers always try to identify the chip before an action is performed. This is needed to check the size and to check if your program is intended for the selected chip. It would not be a good idea for example to program an attiny13 with xmega128a1 code. When you chose manual programming, you will get the following window: As you can see, the binary image is loaded and if an EEPROM EEP binary image was available it would have been loaded too. When you click the Identify button, the programmer will read the device id. The same will happen for any other action you chose. The Device ID is now read and you can see the ATXMEGA128A1 is detected. The programmer has the same options as the STK500 programmer. Only the lock and fuse byte differ for the Xmega. When you select the Lock and Fuse bits, you will get a similar screen: The XMEGA has one lock byte and 6 fuse byes named FUSE0-FUSE5. Not all fuse bytes are used. The options depend on the XMEGA chip you use. In the screen shot from above you can see that under the FUSE1 section, the 'Watchdog Window Configuration' is colored red. When you change an option and move focus or enter, a change will result in the option to be shown in red. When you have selected all values you can select the WRITE button to write the lock and fuse bytes. After this the values will be read again and updated. The WRITE PRG button will insert a $PROG directive into your code with all lock and fuse bytes. A description of the fuse bytes you can find in the PDF of the processor. ARDUINO Top Previous Next The ARDUINO is a hardware platform based on AVR processors. ARDUINO boards/chips are programmed with a bootloader. This bootloader is the old STK500 protocol, not longer supported by Atmel in Studio. There are various programmers for ARDUINO, AVRDUDE is probably the most versatile. BASCOM also supports the ARDUINO/STK500 v1 protocol. the DTR/RTS lines are used to reset the board. You can program/read flash/EEPROM but you can not read/write fuse/lock bytes. The STK500 bootloader for ARDUINO does not support this. Under options you only need to select the programmer, and the COM port. Since an FTDI chip is used on most ARDUINO boards, this is a virtual COM port. Only present when the USB cable is connected to your PC. Select 57600 baud for the baud rate. Older ARDUINO boards work with 19200 baud. ARDUINO V2 The developers of the ARDUINO finally implemented the STK500V2 protocol. This protocol is supported by Atmel and of course by BASCOM. Select the ARDUINO STK500V2 programmer in BASCOM programmer options to use this protocol. A board like the MEGA2560 R3 uses this protocol and probably all newer AVR based ARDUINO boards will support this protocol. The baud rate should be 115200 but could be different for your board. ARDUINO Leonardo For some reason each arduino board seems to use a different bootloader method. The leonardo implements a virtual COM port. When opened at 1200 baud, the board resets into another virtual COM device with a different COM port number. In BASCOM you need to chose the myAVR MK2 / AVR910 programmer since Leonardo uses the AVR910 loader from Atmel. You need to select the COM port that you get at Boot time. The baud is 115200. To program, press the reset button, wait till the USB is enumerated and the Virtual COM port is ready, then press F4 to program the processor. Using Bascom-AVR with Arduino Optiboot Bootloader (under Windows 7) For more information on Optiboot visit following website: http://code.google.com/p/optiboot/ 1. Download AVRDUDE from http://www.nongnu.org/avrdude/ 2. Latest Windows Version (April 2012): avrdude-5.11-Patch7610-win32.zip Complete link: http://download.savannah.gnu.org/releases/avrdude/avrdude-5.11-Patch7610-win32.zip 3. Create a folder like c:\AVRDUDE 4. Copy the content of avrdude-5.11-Patch7610-win32.zip in this new folder 5. Open Bascom-AVR 6. Click on Options >>> Programmer 7. Choose External programmer 8. Checkmark Use HEX file 9. Include the path to avrdude.exe 10. User Parameter: -C c:\avrdude\avrdude.conf -p m328p -P com19 -c arduino -b 115200 -U flash:w:{FILE}:i Explanation of Parameter: -C c:\avrdude\avrdude.conf The config file tells avrdude about all the different ways it can talk to the programmer. -p m328p This is just to tell it what microcontroller its programming. For example, if you are programming an Atmega328p, use m328p as the partnumber -P com19 This is the communication port to use to talk to the programmer (COM19) in this case. Change it to your COM port. -c arduino Here is where we specify the programmer type, if you're using an STK500 use stk500, use arduino for Optiboot -b 115200 Set serial baudrate for programmer. Use 115200 baud for Optiboot. -U flash:w:{FILE}:i You define here: · the memory type: flash or eeprom (this could be also hfuse, lfuse or effuse if you want to verfiy this) · r (read), w (write) or v (verify) · Use {FILE} to insert the filename {EEPROM} to insert the filename of the generated EEP file. · i = Intel Hex File After clicking on the F4 (Program Chip) Button in Bascom-AVR you see the CMD window of Windows 7 until AVRDUDE is ready flashing the Arduino. Complete documentation of AVRDUDE parameters: http://www.nongnu.org/avrdude/user-manual/avrdude_4.html#Option-Descriptions BIPOM MINI-MAX/C Top Previous Next The BiPOM MINI-MAX/AVR-C board from www.bipom.com can be set into PROGRAM and RUN modes. In programming mode, the board uses the STK500V2 protocol for program downloads. Selecting the BiPOM MINI-MAX/AVR-C programmer and the COM port is sufficient. Baud rate is fixed at 115200 baud. The IDE automatically handles switching between PROGRAM and RUN modes. If you press F4, the board will be put in PROGRAM mode, the firmware will be uploaded, and the board will be set back to RUN mode. mySmartUSB Light Top Previous Next The mySmartUSB Light programmer is an affordable and versatile ISP programmer. It supports the AVR911 and STK500V2 protocols. The mySmartUSB Light programmer is available form the MCS Webshop. It is an USB programmer that requires a virtual COM port driver. When your PC is connected to the internet, the driver will be installed automatically by Windows. The programmer is either shipped with the AVR911 protocol or the STK500V2 protocol. The support in BASCOM is for the STK500V2 mode. MyAVR has a simple utility that you can use to check and/or change the firmware. Download it here When you run the tool you get a window similar to this one: The window above shows that the current firmware is STK500 which is OK. When the version is AVR911, you can change it by selecting the STK500 1.11.xxxx in the list and click 'BRENNEN' (burning) The tool also allows to set the voltage of the programmer to 3V or 5V. And you can turn on the power while burning (this will use internal USB power) The above options are available from BASCOM as well. When you press manual program, the following window will be shown: The usual options are available. Please read STK500 Programmer for more info. The MyAVR programmer has a special menu accessible from the Board menu. Board, MyAVR, Voltage, 3V or 5V. This selects the output voltage of the programmer Board, MyAVR, Power On Program. This option can be set and cleared. When set, the programmer will route power to the target circuit during programming. Board, MyAVR, Board Power, turn on/off. These options can be used to power the target board while not programming. When using the options to power the circuit, you should notice that this power is taken from the USB bus. You should take care that your circuit does not draw too much current. For the manual see : http://www.myavr.info/download/produkte/mysmartusb_light/techb_mySmartUSB-light_de_en.pdf UPDI Programmer Top Previous Next The UPDI programmer is a serial based programmer. You need to select 115200 BAUD and the COM port which is connected to the UPDI interface. The UPDI interface is very simple : all you need is a TX, RX and a resistor. Connect TX from the PC UART to a 4K7 resistor. The other side of the resistor is connected to the PC RX and to the UPDI pin of the processor. We use DTR to switch the TX and RX from the PC to the processor. This allows to use the PC COM port to be used for serial communication and as a UPDI programmer. The programmer works similar as the other supported programmers : you can program the FLASH, EEPROM and the fuse/lock bytes In version 2082 you can only READ out the fuse bytes. LIBUSB Top Previous Next Using USB programmers in BASCOM-AVR Please read this document completely before starting to install software. Like every other USB device, an USB programmer requires a windows driver. Some programmers use drivers that are provided (built into) by windows. For example the KamProg uses the HID class and does not require an additional third party driver. A programmer like the AVRISP mkII does need an additional driver. This device driver is installed when you install AVR Studio. Studio is using device drivers from JUNGO. When you plug in the programmer and Windows informs you that it requires a driver you know that you need to install a third party driver. When Windows does not complain it will use a driver already available on your PC. Most USB devices need software installed before you plug them in for the first time. In many cases there is a warning sticker that you should first install the software. BASCOM uses LIBUSB to access USB devices. LIBUSB is available as a device driver or as a filter driver. When your device is using a device driver you must access the device with a filter driver. Some devices do not have a vendor supplied driver (USBASP programmer) and those require a device driver. Scenario one : you have a 32 bit or 64 bit OS and have a product that uses a device driver. In this example we use the AVRISP mkII that is supported by AVR Studio. When you do not have AVR Studio installed you can download it from Atmels website for free. The original programmer comes with a CD-ROM too. But many imitation/self build devices exist that do not come with a CD. For those you need to download and install AVR Studio. The next step is to plug your programmer, and see if it works with AVR Studio. Windows will recognize it, and install the device driver. When windows is ready, press the connect button in Studio. If you open Studio, and press the CON(nection) button, the window shown above will open. Now select your programmer, in this sample AVRISP mkII and press Connect When it functions, a new window will open You can select the device, the programming mode and ISP frequency. This frequency should be 125 KHz (or better said, should not exceed a quarter of the chip oscillator frequency). When you do not get this window but you return to the connection window, it means your programmer is not working. You have to solve this first before you can continue. The programmer will only work in BASCOM when it functions with the original software! In the windows device manager, you can find this info: (right click Computer, select manage, and chose device manager) The screen above shows the JUNGO usb driver which Atmel AVR Studio uses and the AVRISP mkII driver for the AVRISP mkII. If you install AVR Studio with the USB drivers, it will install JUNGO and the WinDriver. The AVRISP mkII entry you only get when you plug the programmer. To make it work with BASCOM, you need to install LIBUSB. LIBUSB is used by many different programs. Atmels FLIP is using it too. So there is a big change that it is available on your system already. You can install LIBUSB as a FILTER driver or a DEVICE driver. We install the FILTER driver, so we can use the programmer with Studio AND bascom. Before you install LIBUSB it is a good idea to make a restore point. When installing the USB driver, disconnect ALL USB devices. Obvious, you can not install from an USB flash drive since this is an USB device as well. You can read about LIBUSB and download it from : http://sourceforge.net/apps/trac/libusb-win32/wiki The last version is : http://sourceforge.net/projects/libusb-win32/files/libusb-win32-releases/1.2.4.0/libusb-win32-devel-filter-1.2.4.0.exe/download Notice that this an executable you can install. You MUST have ADMIN rights when you install this executable. After LIBUSB has been installed you can test if it is functional. - Look in the Program Files\LibUSB-Win32 folder (also named on Windows-7 64 bit !!!) You will find a sub folder named bin which contains a number of executables. - Run the testlibusb-win.exe application. When LIBUSB is functional you will see a screen with all USB devices. When it does not work, try to install again with compatibility mode set to XP SP2. Do this by selecting the the setup exe file properties, and select 'Compatibility'. Click Apply and/or OK. And run setup again. On Windows 7 - 64 bit, this was NOT required. Once the testlibusb-win.exe works, you can continue to the next step. Install the filter driver for the device You need to install a filter driver for your programmer. Each different programmer requires it's own filter driver. So you must repeat these steps if you have different programmers. - Plug in your programmer if it was not plugged in yet - Run the install-filter-win.exe application from the BIN folder. - You will see this window: Select 'Install a device filter' and press Next. Select the programmer and press Install. After some moments, you will get a confirmation: Now the programmer will work in BASCOM. Just select the proper programmer, and timeout of 100 ms. You can try lower time outs too to make it quicker. When you get errors, increase the time out. 100 ms should do for all programmers. Scenario two: you do not have a device driver. In this case you can follow scenario one till the filter driver installation. Instead of running install-filter-win.exe , you will run inf-wizard.exe. Press Next. And the following window will be shown. As you can see, the USBASP was inserted in this sample. Select it (or your programmer) and press Next. Press Next again and select a folder to store the device driver files. These files are required to install the device. After you have saved the files, you have the option to install the driver. Press Install Now.. button to do so. When ready : Final note The USB-ISP programmer form EMBUD, uses drivers from FTDI. It does not require LIBUSB. The Kamprog programmer from KAMAMI uses a HID class and does not require LIBUSB. Some devices gave a problem in 1.2.3.0. This problem is solved in 1.2.4.0. http://sourceforge.net/projects/libusb-win32/files/libusb-win32-releases/1.2.4.0/libusb-win32-devel-filter-1.2.4.0.exe/download Options Monitor Top Previous Next With this option you can modify the monitor settings. OPTION DESCRIPTION Upload speed Selects the baud rate used for uploading Monitor prefix String that will be send to the monitor before the upload starts Monitor suffix String that us sent to the monitor after the download is completed. Monitor delay Time in milliseconds to wait after a line has been sent to the monitor. Prefix delay Time in milliseconds to wait after a prefix has been sent to the monitor. Options Printer Top Previous Next With this option you can modify the printer settings. OPTION DESCRIPTION Font Printer font to use when printing Setup Click to change the printer setup Color Will print in color. Use this only for color printers. Wrap lines Wrap long lines. When not enabled, long lines will be partial shown. Print header Print a header with the filename. Line numbers Will be the line number before each line. Syntax Enable this to use the same syntax highlighting as the editor Left margin The left margin of the paper. Right margin The right margin of the paper. Top margin The top margin of the paper. Bottom margin The bottom margin of the paper. Window Cascade Top Previous Next Cascade all open editor windows. Window Tile Top Previous Next Tile all open editor windows horizontally. Window Tile Vertically Top Previous Next Tile all open editor windows vertically. Window Arrange Icons Top Previous Next Arrange the icons of the minimized editor windows. Windows Maximize All Top Previous Next Maximize all open editor windows. Window Minimize All Top Previous Next Minimize all open editor windows. Help About Top Previous Next This option shows an about box as shown below. Your serial number is shown on the third line of the about box. You will need this when you have questions about the product. The compiler and IDE version numbers are also shown. When you click the App data dir link, the folder which contains the BASCOM settings will be opened: It contains the bascom-avr.xml file with all settings and the bascavr.log file. When you need support, you might be asked to email these files. When you need support, also click the Copy-button. It will copy the following info to the clipboard, which you can paste in your email : Dont forget that Serial numbers should not be sent to the user list. Make sure you sent your email to support and not a public list ! Compiler version :1.11.8.3 IDE version :1.11.8.5 Serial number :XX-XXXX-XXXXX Windows OS :Microsoft Windows XP Windows SP :Service Pack 2 Explorer :7.0.5730.11 Company :MCS Owner :Mark Alberts Windows dir :C:\WINNT App data dir :C:\Documents and Settings System dir :C:\WINNT\system32 When you click the support link, your email client will be started and an email to support@mcselec.com will be created. Click on Ok to return to the editor. Help Index Top Previous Next Shows the BASCOM help file. When you are in the editor window, the current word selected or by the cursor will be used as a keyword. Notice that when the help window is small, you might need to make the help window bigger to show the whole content. The help contains complete sample code and partial sample code. In all cases the samples are shown to give you an idea of the operation. When trying a program you should always use the samples from the SAMPLES directory. These are updated and tested when new versions are published. The (partial) samples are not all updates, only when they contain errors. So the samples from the help might need some small adjustments while the samples form the SAMPLES dir will work at least on the used chip. Help MCS Forum Top Previous Next This option will start your default Web browser and direct it to http://www.mcselec.com/index2.php?option=com_forum&Itemid=59 This forum is hosted by MCS Electronics. There are various forums available. You can post your questions there. Do not cross post your questions on multiple forums and to support. The forum is available for all users : demo or commercial users. Note that everything you write might be on line for ever. So mind your language. Users of the commercial version can email MCS support. The forum allows uploads for code examples, circuits etc. If you try to abuse the forum or any other part of the MCS web, you will be banned from the site. Help MCS Shop Top Previous Next This option will start your default web browser and direct it to :http://www.mcselec.com/index.php?option=com_phpshop&Itemid=1 You can order items and pay with PayPal. PayPal will accept most credit cards. Before you order, it is best to check the resellers page to find a reseller near you. Resellers can help you in your own language, have all MCS items on stock, and are in the same time zone. Before you can order items, you need to create an account. Read the following about the new website : http://www.mcselec.com/index.php?option=com_content&task=view&id=133&Itemid=1 Help Support Top Previous Next This option will start your default browser with the following URL : http://www.mcselec.com/support-center/ It depends from your browser settings if a new window or TAB will be created. At the support site you can browse articles. You can also search on keywords. Help Knowledge Base Top Previous Next This option will ask you to enter a search string. This search string will be passed to the MCS support site. The above example that searches for "FUSEBIT" will result in the following : You can click one of the found articles to read it. Help Credits Top Previous Next BASCOM was "invented" in 1995. Many users gave feedback and helped with tips, code, suggestions, support, a user list, and of course with buying the software. The software improved a lot during the last 20 years and will so during the next decade. While it is impossible to thank everybody there are some people that deserve credits : · Peter Maroudas. He wrote and tested the FT80x FTDI display support. FT800 support would not exist without him. · · Josef Franz Vögel. He wrote a significant part of the libraries in BASCOM-AVR. He is also author of AVR-DOS. · Dr.-Ing. Claus Kuehnel for his book 'AVR RISC' , that helped me a lot when I began to study the AVR chips. Check his website at http://www.ckuehnel.ch · Atmel, who gave permission to use the AVR picture in the start up screen. And for the great tech support. Check their website at http://www.atmel.com · Brian Dickens, who did most of the Beta testing. He also checked the documentation on grammar and spelling errors. (he is not responsible for the spelling errors i added later :-) ) · Jack Tidwell. I used his FP unit for singles. It is the best one available. Help Update 2081 IMPROVED Top Previous Next The manual update process is explained here. The Help Update is an automated version. The DEMO version can not be updated. In order to do a successful update you need the following : - license validated in the register (https://register.mcselec.com) - working internet connection. - firewall and anti virus software must allow BASCOM to connect to the internet When you click Help, Update, the following window will be shown: You need to click the START button to start the actual update process. When there are unsaved files, you will get an error message : Your work/project must be saved since as soon the update download is finished, the setup will be executed and BASCOM is closed. When there are no unsaved files, the current version will be checked. Checking for update... Current version : 2.0.8.0 Latest version : 2.0.7.8 No newer version found In this case, there is no newer file and nothing happens. You need to click the CLOSE button to close the Update window. The IDE will not be closed in this case. If however a newer version exists, it will be downloaded and unzipped in your windows TEMP folder. After that setup.exe will be executed with admin rights. So you might get a windows security message that setup requires admin rights. BASCOM will close automatically so the new version can be installed in the same folder. There is no need to uninstall an older version first. This setup is the same as you used when you installed the software. But of course the latest version. You must install into the same folder, but you may also install into a new folder. When installing into a new folder you must manual install/copy the license file bscavrl.dll into the new folder yourself. The bscavrl.dll file you get when you purchase bascom. It is either on CD-ROM or in the bascom-avr application folder. Help Wiki Top Previous Next This option will open the browser at wiki.mcselec.com The wiki contains the help file, projects and is partial translated into German as well. When you want to contribute you need to create an account and send an email to tomi@mcselec.com to get the proper access rights. BASCOM Editor Keys Top Previous Next Key Action LEFT ARROW One character to the left RIGHT ARROW One character to the right UP ARROW One line up DOWN ARROW One line down HOME To the beginning of a line END To the end of a line PAGE UP Up one window PAGE DOWN Down one window CTRL+LEFT One word to the left CTRL+RIGHT One word to the right CTRL+HOME To the start of the text CTRL+END To the end of the text CTRL+ Y Delete current line INS Toggles insert/over strike mode F1 Help (context sensitive) F2 Run simulator F3 Find next text F4 Send to chip (run flash programmer) F5 Run F7 Compile File F8 Step F9 Set breakpoint F10 Run to F11 Collapse Code Toggle Sub/Function SHIFT+F11 or CTRL+ENTER Collapse Code Toggle current block CTRL+F7 Syntax Check CTRL+F Find text CTRL+G Go to line CTRL+K+x Toggle bookmark. X can be 1-8 CTRL+L LCD Designer CTRL+M File Simulation CTRL+N New File CTRL+O Load File CTRL+P Print File CTRL+Q+x Go to Bookmark. X can be 1-8 CTRL+R Replace text CTRL+S Save File CTRL+T Terminal emulator CTRL+P Compiler Options CTRL+W Show result of compilation CTRL+X Cut selected text to clipboard CTRL+Z Undo last modification SHIFT+CTRL+Z Redo last undo CTRL+INS Copy selected text to clipboard SHIFT+INS Copy text from clipboard to editor CTRL+SHIFT+J Indent Block CTRL+SHIFT+U Unindent Block Select text Hold the SHIFT key down and use the cursor keys to select text. or keep the left mouse key pressed and drag the cursor over the text to select. CTRL+SPACE Code help. SHIFT + MOUSE Hover on indention lines to see to which group they belong. Hover on an element in your code to get info about that element. CTRL+BACKSPACE Jump back CTRL+CLICK Hold the CTRL key down and hover with the mouse till an element is underlined like an URL. Click the left mouse to jump to the implementation. Program Development Order Top Previous Next · Start BASCOM · Open a file or create a new one · ! Important ! Check the chip settings, baud rate and frequency settings for the target system · Save the file · Compile the file (this will also save the file !!!) · If an error occurs fix it and recompile (F7) · Run the simulator(F2) · Program the chip(F4) Font Editor Top Previous Next In version 2079 the Font Editor plugin is replaced by the integrated Font Editor from the Tools menu. It has the same options. The Font Editor is a Plug in that is intended to create Fonts that can be used with Graphical display such as SED1521, KS108, color displays, etc. When you have installed the Font Editor , a menu option becomes available under the Tools menu : Font Editor. When you choose this option the following window will appear: You can open an existing Font file, or Save a modified file. The supplied font files are installed in the Samples directory. You can copy an image from the clipboard, and you can then move the image up , down, left and right. When you select a new character, the current character is saved. The suggest button will draw an image of the current selected character. When you keep the left mouse button pressed, you can set the pixels in the grid. When you keep the right mouse button pressed, you can clear the pixels in the grid. When you choose the option to create a new Font, you must provide the name of the font, the height of the font in pixels and the width of the font in pixels. The Max ASCII is the last ASCII character value you want to use. Each character will occupy space. So it is important that you do not choose a value that is too high and will not be used. When you display normal text, the maximum number is 127 so it does not make sense to specify a value of 255. A font file is a plain text file. Lets have a look at the first few lines of the 8x8 font: Font8x8: $asm .db 1,8,8,0 .db 0,0,0,0,0,0,0,0 ; .db 0,0,6,95,6,0,0,0 ; ! The first line contains the name of the font. With the SETFONT statement you can select the font. Essential, this sets a data pointer to the location of the font data. The second line ($ASM) is a directive for the internal assembler that asm code will follow. All other lines are data lines. The third line contains 4 bytes: 1 (height in bytes of the font) , 8 (width in pixels of the font), 8 (block size of the font) and a 0 which was not used before the 'truetype' support, but used for aligning the data in memory. This because AVR object code is a word long. This last position is 0 by default. Except for 'TrueType' fonts. In BASCOM a TrueType font is a font where every character can have it's own width. The letter 'i' for example takes less space then the letter 'w'. The EADOG128 library demonstrates the TrueType option. In order to display TT, the code need to determine the space at the left and right of the character. This space is then skipped and a fixed space is used between the characters. You can replace the 0 by the width you want to use. The value 2 seems a good one for small fonts. All other lines are bytes that represent the character. Additional Hardware Top Previous Next Of course just running a program on the chip is not enough. You will probably connect many types of electronic devices to the processor ports. BASCOM supports a lot of hardware and so it has lots of hardware related statements. Before explaining about programming the additional hardware, it might be better to talk about the chip. The AVR internal hardware Attaching an LCD display Using the I2C protocol Using the 1WIRE protocol Using the SPI protocol You can connect additional hardware to the ports of the microprocessor. The following are hardware related: I2CSEND and I2CRECEIVE and other I2C related statements. CLS,LCD,DISPLAY and other related LCD-statements. 1WRESET , 1WWRITE and 1WREAD There are many more hardware specific statements and functions. Adding XRAM Adding XRAM to XMEGA using EBI Adding SRAM 4-port Non Multiplexed AVR Internal Hardware Top Previous Next The AVR chips all have internal hardware that can be used. For this description of the hardware the 90S8515 was used. Newer chips like the Mega8515 may differ and have more or less internal hardware. You will need to read the manufacturers data sheet for the processor you are using to learn about the special internal hardware available. Timer / Counters The AT90S8515 provides two general purpose Timer/Counters - one 8-bit T/C and one 16-bit T/C. The Timer/Counters have individual pre-scaling selection from the same 10-bit pre-scaling timer. Both Timer/Counters can either be used as a timer with an internal clock time base or as a counter with an external pin connection which triggers the counting. More about TIMERO More about TIMER1 The WATCHDOG Timer Almost all AVR chips have the ports B and D. The 40 or more pin devices also have ports A and C that also can be used for addressing an external RAM chip (XRAM). Since all ports are similar except that PORT B and PORT D have alternative functions, only these ports are described. PORT B PORT D AVR Internal Registers Top Previous Next You can manipulate the internal register values directly from BASCOM. They are also reserved words. Each register acts like a memory location or program variable, except that the bits of each byte have a special meaning. The bits control how the internal hardware functions, or report the status of internal hardware functions. Read the data sheet to determine what each bit function is for. The internal registers for the AVR90S8515 are : (other processors are similar, but vary) Addr. Register $3F SREG I T H S V N Z C $3E SPH SP15 SP14 SP13 SP12 SP11 SP10 SP9 SP8 $3D SPL SP7 SP6 SP5 SP4 SP3 SP2 SP1 SP0 $3C Reserved $3B GIMSK INT1 INT0 - - - - - - $3A GIFR INTF1 INTF0 $39 TIMSK TOIE1 OCIE1A OCIE1B - TICIE1 - TOIE0 - $38 TIFR TOV1 OCF1A OCF1B -ICF1 -TOV0 - $37 Reserved $36 Reserved $35 MCUCR SRE SRW SE SM ISC11 ISC10 ISC01 ISC00 $34 Reserved $33 TCCR0 - - - - - CS02 CS01 CS00 $32 TCNT0 Timer/Counter0 (8 Bit) $31 Reserved $30 Reserved $2F TCCR1A COM1A1 COM1A0 COM1B1 COM1B0 - -PWM11 PWM10 $2E TCCR1B ICNC1 ICES1 - - CTC1 CS12 CS11 CS10 $2D TCNT1H Timer/Counter1 - Counter Register High Byte $2C TCNT1L Timer/Counter1 - Counter Register Low Byte $2B OCR1AH Timer/Counter1 - Output Compare Register A High Byte $2A OCR1AL Timer/Counter1 - Output Compare Register A Low Byte $29 OCR1BH Timer/Counter1 - Output Compare Register B High Byte $28 OCR1BL Timer/Counter1 - Output Compare Register B Low Byte $27 Reserved $26 Reserved $25 ICR1H Timer/Counter1 - Input Capture Register High Byte $24 ICR1L Timer/Counter1 - Input Capture Register Low Byte $23 Reserved $22 Reserved $21 WDTCR - - - WDTOE WDE WDP2 WDP1 WDP0 $20 Reserved $1F Reserved - - - - - - - EEAR8 $1E EEARL EEPROM Address Register Low Byte $1D EEDR EEPROM Data Register $1C EECR - - - - - EEMWE EEWE EERE $1B PORTA PORTA7 PORTA6 PORTA5 PORTA4 PORTA3 PORTA2 PORTA1 PORTA0 $1A DDRA DDA7 DDA6 DDA5 DDA4 DDA3 DDA2 DDA1 DDA0 $19 PINA PINA7 PINA6 PINA5 PINA4 PINA3 PINA2 PINA1 PINA0 $18 PORTB PORTB7 PORTB6 PORTB5 PORTB4 PORTB3 PORTB2 PORTB1 PORTB0 $17 DDRB DDB7 DDB6 DDB5 DDB4 DDB3 DDB2 DDB1 DDB0 $16 PINB PINB7 PINB6 PINB5 PINB4 PINB3 PINB2 PINB1 PINB0 $15 PORTC PORTC7 PORTC6 PORTC5 PORTC4 PORTC3 PORTC2 PORTC1 PORTC0 $14 DDRC DDC7 DDC6 DDC5 DDC4 DDC3 DDC2 DDC1 DDC0 $13 PINC PINC7 PINC6 PINC5 PINC4 PINC3 PINC2 PINC1 PINC0 $12 PORTD PORTD7 PORTD6 PORTD5 PORTD4 PORTD3 PORTD2 PORTD1 PORTD0 $11 DDRD DDD7 DDD6 DDD5 DDD4 DDD3 DDD2 DDD1 DDD0 $10 PIND PIND7 PIND6 PIND5 PIND4 PIND3 PIND2 PIND1 PIND0 $0F SPDR SPI Data Register $0E SPSR SPIF WCOL - - - - - - $0D SPCR SPIE SPE DORD MSTR CPOL CPHA SPR1 SPR0 $0C UDR UART I/O Data Register $0B USR RXC TXC UDRE FE OR - - - $0A UCR RXCIE TXCIE UDRIE RXEN TXEN CHR9 RXB8 TXB8 $09 UBRR UART Baud Rate Register $08 ACSR ACD - ACO ACI ACIE ACIC ACIS1 ACIS0 $00 Reserved The registers and their addresses are defined in the xxx.DAT files which are placed in the BASCOM-AVR application directory. The registers can be used as normal byte variables. PORTB = 40 will place a value of 40 into port B. Note that internal registers are reserved words. This means that they can't be dimensioned as BASCOM variables! So you can't use the statement DIM SREG As Byte because SREG is an internal register. You can however manipulate the register with the SREG = value statement, or var = SREG statement. AVR Internal Hardware TIMER0 Top Previous Next The 8-Bit Timer/Counter0 The 90S8515 was used for this example. Other chips might have a somewhat different timer. The 8-bit Timer/Counter0 can select its clock source from CK, pre-scaled CK, or an external pin. In addition it can be stopped (no clock). The overflow status flag is found in the Timer/Counter Interrupt Flag Register - TIFR. Control signals are found in the Timer/Counter0 Control Register - TCCR0. The interrupt enable/disable settings for Timer/Counter0 are found in the Timer/Counter Interrupt Mask Register - TIMSK. When Timer/Counter0 is externally clocked, the external signal is synchronized with the oscillator frequency of the CPU. To assure proper sampling of the external clock, the minimum time between two external clock transitions must be at least one internal CPU clock period. The external clock signal is sampled on the rising edge of the internal CPU clock. The 8-bit Timer/Counter0 features both a high resolution and a high accuracy mode with lower pre-scaling values. Similarly, high pre-scaling values make the Timer/Counter0 useful for lower speed functions or exact timing functions with infrequent actions. AVR Internal Hardware TIMER1 Top Previous Next The 16-Bit Timer/Counter1 The 90S8515 was used for the documentation. Other chips might have a somewhat different timer. The 16-bit Timer/Counter1 can select its clock source from CK, pre-scaled CK, or an external pin. In addition it can be stopped (no clock). The different status flags (overflow, compare match and capture event) and control signals are found in the Timer/Counter1 Control Registers - TCCR1A and TCCR1B. The interrupt enable/disable settings for Timer/Counter1 are found in the Timer/Counter Interrupt Mask Register - TIMSK. When Timer/Counter1 is externally clocked, the external signal is synchronized with the oscillator frequency of the CPU. To assure proper sampling of the external clock, the minimum time between two external clock transitions must be at least one internal CPU clock period. The external clock signal is sampled on the rising edge of the internal CPU clock. The 16-bit Timer/Counter1 features both a high resolution and a high accuracy usage with lower pre-scaling values. Similarly, high pre-scaling values make the Timer/Counter1 useful for lower speed functions or exact timing functions with infrequent actions. The Timer/Counter1 supports two Output Compare functions using the Output Compare Register 1 A and B -OCR1A and OCR1B as the data values to be compared to the Timer/Counter1 contents. The Output Compare functions include optional clearing of the counter on compareA match, and can change the logic levels on the Output Compare pins on both compare matches. Timer/Counter1 can also be used as a 8, 9 or 10-bit Pulse Width Modulator (PWM). In this mode the counter and the OCR1A/OCR1B registers serve as a dual glitch-free stand-alone PWM with centered pulses. The Input Capture function of Timer/Counter1 provides a capture of the Timer/Counter1 value to the Input Capture Register - ICR1, triggered by an external event on the Input Capture Pin - ICP. The actual capture event settings are defined by the Timer/Counter1 Control Register -TCCR1B. In addition, the Analog Comparator can be set to trigger the Capture. AVR Internal Hardware Watchdog timer Top Previous Next The Watchdog Timer The Watchdog Timer is clocked from a separate on-chip oscillator which runs at approximately 1MHz. This is the typical value at VCC = 5V. By controlling the Watchdog Timer pre-scaler, the Watchdog reset interval can be adjusted from 16K to 2,048K cycles (nominally 16 - 2048 ms). The BASCOM RESET WATCHDOG - instruction resets the Watchdog Timer. Eight different clock cycle periods can be selected to determine the reset period. If the reset period expires without another Watchdog reset, the AT90Sxxxx resets and program execution starts at the reset vector address. AVR Internal Hardware Port B Top Previous Next Port B Port B is an 8-bit bi-directional I/O port. Three data memory address locations are allocated for the Port B, one each for the Data Register - PORTB, $18($38), Data Direction Register - DDRB, $17($37) and the Port B Input Pins - PINB, $16($36). The Port B Input Pins address is read only, while the Data Register and the Data Direction Register are read/write. All port pins have individually selectable pull-up resistors. The Port B output buffers can sink 20mA and thus drive LED displays directly. When pins PB0 to PB7 are used as inputs and are externally pulled low, they will source current if the internal pull-up resistors are activated. The Port B pins with alternate functions are shown in the following table: When the pins are used for the alternate function the DDRB and PORTB register has to be set according to the alternate function description. Port B Pins Alternate Functions Port Pin Alternate Functions PORTB.0 T0 (Timer/Counter 0 external counter input) PORTB.1 T1 (Timer/Counter 1 external counter input) PORTB.2 AIN0 (Analog comparator positive input) PORTB.3 AIN1 (Analog comparator negative input) PORTB.4 SS (SPI Slave Select input) PORTB.5 MOSI (SPI Bus Master Output/Slave Input) PORTB.6 MISO (SPI Bus Master Input/Slave Output) PORTB.7 SCK (SPI Bus Serial Clock) The Port B Input Pins address - PINB - is not a register, and this address enables access to the physical value on each Port B pin. When reading PORTB, the PORTB Data Latch is read, and when reading PINB, the logical values present on the pins are read. PortB As General Digital I/O All 8 bits in port B are equal when used as digital I/O pins. PORTB.X, General I/O pin: The DDBn bit in the DDRB register selects the direction of this pin, if DDBn is set (one), PBn is configured as an output pin. If DDBn is cleared (zero), PBn is configured as an input pin. If PORTBn is set (one) when the pin configured as an input pin, the MOS pull up resistor is activated. To switch the pull up resistor off, the PORTBn has to be cleared (zero) or the pin has to be configured as an output pin. DDBn Effects on Port B Pins DDBn PORTBn I/O Pull up Comment 0 0 Input No Tri-state (Hi-Z) 0 1 Input Yes PBn will source current if ext. pulled low. 1 0 Output No Push-Pull Zero Output 1 1 Output No Push-Pull One Output By default, the DDR and PORT registers are 0. CONFIG PORTx=OUTPUT will set the entire DDR register. CONFIG PINX.Y will also set the DDR register for a single bit/pin. When you need the pull up to be activated, you have to write to the PORT register. AVR Internal Hardware Port D Top Previous Next Port D Port D Pins Alternate Functions Port Pin Alternate Function PORTD.0 RDX (UART Input line ) PORTD.1 TDX (UART Output line) PORTD.2 INT0 (External interrupt 0 input) PORTD.3 INT1 (External interrupt 1 input) PORTD.5 OC1A (Timer/Counter1 Output compareA match output) PORTD.6 WR (Write strobe to external memory) PORTD.7 RD (Read strobe to external memory) RD - PORTD, Bit 7 RD is the external data memory read control strobe. WR - PORTD, Bit 6 WR is the external data memory write control strobe. OC1- PORTD, Bit 5 Output compare match output: The PD5 pin can serve as an external output when the Timer/Counter1 com-pare matches. The PD5 pin has to be configured as an out-put (DDD5 set (one)) to serve this f unction. See the Timer/Counter1 description for further details, and how to enable the output. The OC1 pin is also the output pin for the PWM mode timer function. INT1 - PORTD, Bit 3 External Interrupt source 1: The PD3 pin can serve as an external interrupt source to the MCU. See the interrupt description for further details, and how to enable the source INT0 - PORTD, Bit 2 INT0, External Interrupt source 0: The PD2 pin can serve as an external interrupt source to the MCU. See the interrupt description for further details, and how to enable the source. TXD - PORTD, Bit 1 Transmit Data (Data output pin for the UART). When the UART transmitter is enabled, this pin is configured as an output regardless of the value of DDRD1. RXD - PORTD, Bit 0 Receive Data (Data input pin for the UART). When the UART receiver is enabled this pin is configured as an output regardless of the value of DDRD0. When the UART forces this pin to be an input, a logical one in PORTD0 will turn on the internal pull-up. When pins TXD and RXD are not used for RS-232 they can be used as an input or output pin. No PRINT, INPUT or other RS-232 statement may be used in that case. The UCR register will by default not set bits 3 and 4 that enable the TXD and RXD pins for RS-232 communication. It is however reported that this not works for all chips. In this case you must clear the bits in the UCR register with the following statements: RESET UCR.3 RESET UCR.4 or as an alernative : UCR=0 Adding XRAM with External Memory Interface Top Previous Next With ATMEGA AVR like ATMEGA128, ATMEGA1280 or older types like 90S8515 you can access external RAM (SRAM) or other peripherals through its External Memory Interface. Search in the Atmel ATMEGA datasheets for "External Memory Interface" For ATXMEGA devices see App Note: AVR1312: Using the XMEGA External Bus Interface for details. For example for an ATMEGA1280 the external memory interface consist of PORTA (multiplexed data and address low byte), PORTC (address high byte), and PORTG[2:0] (RD, WR and ALE). ATMEGA1280 pin connections to SRAM device: Port A = Multiplexed Address low byte (A0....A7) / Data (D0....D7) <--------> Direct connection to SRAM (D0...D7) and connected to Input D of octal latch (typically �74 x 573� or equivalent) to (A0.....A7) of SRAM chip Port C = Address high byte (A8....A15) <--------> direct connection to for example SRM (A8....A15) Port G Pin 0 = WR (Write strobe to external memory) <--------> direct connection to for example SRAM WR Port G Pin 1 = RD (Read strobe to external memory) <--------> direct connection to for example SRAM RD Port G Pin 2 = ALE (Address Latch Enable to external memory) <--------> Connected to G Input of octal latch (typically �74 x 573� like 74 x 573) Example for 74HTC573 (TTL variant): http://www.nxp.com/documents/data_sheet/74HC_HCT573.pdf Address latch with octal latch: The data bus and the low byte of the address bus is multiplexed on Port A. The ALE signal indicates when the address is present. This low byte must be stored by a latch until the memory access cycle is completed. Schematics for connecting the ATMEGA with octal latch and sram can be found in: · Atmel AVR Studio Help File (AVR tools user guide) search for: "external memory interface" and scroll down to APPENDIX. There you also find a list of 3.3 or 5V compatible SRAM's that can be used with ATMEGA's and there is a link to STK503.pdf which is part of the help file. · The list of compatible SRAM devices can be also found here: http://www.atmel.com/images/stk503_ug.pdf (page 16) · The datasheet of for example ATMEGA1280 also include a picture which show the connections between AVR, Octal Latch external SRAM device. The data memory map for example for ATmega640/1280/1281/2560/2561: Hex-Address: &H00 .... &H1F 32 Registers &H20 .... &H5F 64 I/O Registers &H60 .... &H1FF 416 external I/O Registers &H200 .... &H21FF Internal SRAM (8K in this case) &H2200 .... &HFFFF External SRAM (XRAM) XRAM will use an area in the remaining address locations in the 64K address space (&HFFFF). This starts at the address following the internal SRAM. Internal SRAM use the lowest 4,608/8,704 bytes, so when using 64KB (65,536 bytes) of XRAM, 60,478/56,832 Bytes of XRAM are available. See datasheet of ATMEGA device for a way to use the complete 64KByte. XRAM will be enabled by CONFIG XRAM (config XRAM is setting SRE bit of the atmega 1280 XMCRA Register) The Pins of Port A, Port C and Port G from ATMEGA1280 are automatically enabled for XRAM and can not be used for other tasks by default if XRAM is enabled. The external memory address space can be divided in two sectors (upper and lower sector) with different wait-state bits. You can also release some Port C pins for other tasks (in the XMCRB Register) . See atmega 1280 datasheet for details. See also: $XRAMSIZE and $XRAMSTART You can clear the XRAM for example with: For N = Ramstart To Ramend 'replace RamStart and RamEnd with the real values Out N , 0 'zero or any value you like Next With XRAM, you should dim all your global variables with XRAM. Example: Dim Var As Xram Byte This will leave the internal memory for the stacks and local created variables. You can also use $default Xram when you do not want to add the XRAM to each DIM. Example 1: A real Example for using SRAM and another Bus-mode device is WIZ200WEB from Wiznet. Here an ATMEGA128L, an external 32K SRAM and a W5300 Ethernet Chip is used. See also CONFIG TCPIP The data memory map for ATMEGA128: Hex-Address: &H00 .... &H1F 32 Registers &H20 .... &H5F 64 I/O Registers &H60 .... &HFF 160 external I/O Registers &H100 .... &H10FF Internal SRAM (4K in this case) &H1100 Start of External SRAM (XRAM) So the config is following (&H8000 = 32kByte): $xramstart = &H1100 $xramsize = &H8000 Config Xram = Enabled The W5300 Chip from Wiznet is setup to use Base Address &H8000. So the data memory map for ATMEGA128 is: Hex-Address: &H00 .... &H1F 32 Registers &H20 .... &H5F 64 I/O Registers &H60 .... &HFF 160 external I/O Registers &H100 .... &H10FF Internal SRAM (4K in this case) &H1100 Start of External SRAM (XRAM) &H8000 Base Address of W5300 Chip from WIZNET &H8400 .... &HFFFF Not in use See also CONFIG TCPIP for further details on W5300 Chip from Wiznet. Example 2: We use now an WIZ830mj module (which uses a W5300 Chip from Wiznet) on a board with an 64/128KByte SRAM in combination with ATMEGA1280: Hex-Address: &H00 .... &H1F 32 Registers &H20 .... &H5F 64 I/O Registers &H60 .... &H1FF 416 external I/O Registers &H200 .... &H21FF Internal SRAM (8K in this case) &H2200 .... &HFBFF External SRAM (XRAM) upper and lower &HFC00 Base Address of W5300 Chip over memory address selector XRAM configuration here is: $xramstart = &H2200 $xramsize = &HFBFF Config Xram = Enabled Writing to the first XRAM address is done by: Out &H2200 , &H01 Reading from first XRAM is done by: Var = Inp(&H2200) The datasheet of W5300 say: "In the case of using an 8bit data bus width, ADDR[9:0] is used " so we have Address 0.......Address 9 but the SRAM need Address 0.....15. Here an example of additional circuit between ATMEGA and W5300 and SRAM to solve the difference of address (A0...A15) for SRAM and (A0...A9) for W5300: The Base Address for W5300 (WIZ830mj) in this case is &HFC00 Address Bit A15 A14 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0 Binary: 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 Hex: FC00 For older 90S8515 chips for example the maximum size of XRAM can be 64 Kbytes. Example: The STK200 has a 62256 ram chip (32K x 8 bit). Here is some info from the BASCOM user list : If you do go with the external ram , be careful of the clock speed. Using a 4 MHz crystal , will require a SRAM with 70 nS access time or less. Also the data latch (74HC573) will have to be from a faster family such as a 74FHC573 if you go beyond 4 MHz. You can also program an extra wait state, to use slower memory. Here you will find a pdf file showing the STK200 schematics: See Stk200_schematic.pdf for more information. If you use a 32 KB SRAM, then connect the /CS signal to A15 which give to the range of &H0000 to &H7FFF, if you use a 64 KB SRAM, then tie /CS to GND, so the RAM is selected all the time. Adding XRAM to XMEGA using EBI Top Previous Next This information has been provided by Electronic Design Bitzer. Some XMEGA processors have an EBI. The following circuit shows how to set up the EBI for 8 bit bus mode where the SRAM can be selected with a jumper. 128 KB SM621008VLLP70T : SRAM LLPow 3,3V 128Kx8 70ns TSOP32(I) 512 KB SM624008VLLP70M : SRAM LLPow 3,3V 512Kx8 70ns SOP32 The BASCOM setup code : ' All EBI-Ports must be set to OUTPUT ' All Ports, ACTIVE-LOW , must be set to 1 !!! ' All Ports, ACTIVE-HIGH, must be set to 0 !!! Porth_dirset = &B1111_1111 : Porth = &B1111_0011 'WR, RD, ALE1, ALE2, CS0-3 = output : ALE1 & 2 auf 0 !!! Portj_dirset = &B1111_1111 : Portj = &B1111_1111 Portk_dirset = &B1111_1111 : Portk = &B1111_1111 Config Xram = 3port , Ale = Ale12 , Sdbus = 8 , Modesel0 = Sram , Adrsize0 = 256b , Waitstate0 = 4 , Baseadr0 = &H10000 , _ Modesel1 = Sram , Adrsize1 = 128k , Waitstate1 = 1 , Baseadr1 = &H20000 See also : CONFIG XRAM Adding SRAM 4-port Non Multiplexed Top Previous Next The following information was contributed by Juergen Bitzer. The EBI allows to use an SRAM in 4-port non multiplexed mode. This means that you need little parts but you loose 4 ports. Example $regfile = "xm128a1def.dat" $crystal = 32000000 $hwstack = &H32 $swstack = &H32 $framesize = &H32 $xramstart = &H100000 $xramsize = &H080000 '------------------ ' CPU: ' ATXMEGA128A1U-AU : 2,23/100 Mouser Muss -->A1U-AU<-- sein !!! ' ATXMEGA64A1U-AU '------------------ ' SRam: ' 512 KB AS6C4008-55PCN : SRAM 4MB 2.7V-5.5V, 512KX8, PDIP32 ' 512 KB AS6C4008-55SIN : SRAM 4MB 2.7V-5.5V, 512KX8, SOP32 ' 512 KB AS6C4008-55SIN : SRAM 4MB 2.7V-5.5V, 512KX8, SOP32 '------------------------------------------------------------------------------- '------------------------------------------------------------------------------- ' #### Four Port SRAM #### ' MODE SRAM 4Port direkt ' PortH.0 - Pin 55 /WR ' PortH.1 - Pin 56 /RD ' PortE.4 - Pin 39 /CS0 / A16 -> CS0: SRAM 512 KB ' PortE.5 - Pin 40 /CS1 / A17 -> CS1: unbenutzt ' PortE.6 - Pin 41 /CS2 / A18 -> CS2: unbenutzt ' PortE.7 - Pin 42 /CS3 / A19 -> CS3: unbenutzt ' PortJ.0 - Pin 65 D0 -> SRam ' PortJ.1 - Pin 66 D1 -> SRam ' PortJ.2 - Pin 67 D2 -> SRam ' PortJ.3 - Pin 68 D3 -> SRam ' PortJ.4 - Pin 69 D4 -> SRam ' PortJ.5 - Pin 70 D5 -> SRam ' PortJ.6 - Pin 71 D6 -> SRam ' PortJ.7 - Pin 72 D7 -> SRam ' PortK.0 - Pin 75 A0 -> SRam ' PortK.1 - Pin 76 A1 -> SRam ' PortK.2 - Pin 77 A2 -> SRam ' PortK.3 - Pin 78 A3 -> SRam ' PortK.4 - Pin 79 A4 -> SRam ' PortK.5 - Pin 80 A5 -> SRam ' PortK.6 - Pin 81 A6 -> SRam ' PortK.7 - Pin 82 A7 -> SRam ' PortF.0 - Pin 45 A8 -> SRam ' PortF.1 - Pin 46 A9 -> SRam ' PortF.2 - Pin 47 A10 -> SRam ' PortF.3 - Pin 48 A11 -> SRam ' PortF.4 - Pin 49 A12 -> SRam ' PortF.5 - Pin 40 A13 -> SRam ' PortF.6 - Pin 41 A14 -> SRam ' PortF.7 - Pin 42 A15 -> SRam ' PortH.2 - Pin 57 A16 -> SRam ' PortH.3 - Pin 58 A17 -> SRam ' PortH.4 - Pin 59 A18 -> SRam ' PortH.5 - Pin 60 A19 - unbenutzt ' PortH.6 - Pin 61 A20 - unbenutzt ' PortH.7 - Pin 62 A21 - unbenutzt '------------------------------------------------------------------------------- '----------generate a 32 MHz system clock by use of the PLL (2MHz * 23 = 46MHz) Config Osc = Disabled , Extosc = Enabled 'Set the Multiplication factor and select the clock Reference for the PLL 'Osc_pllctrl = &B00_0_10100 '2MHz clock Source and Multiplication factor = 23 ' 00 : 2 MHz internal OSC ' 01 : Reerved ' 10 : 32 MHz internal OSC ' 11 : External Clock Source ' 1 : 0=PLL-Output devided by 1 |1=PLL-Output devided by 2 ' xxxxx: Multiplikation of PLL 1-31 Osc_pllctrl = &B11_0_01000 : Const Mhz = 32 ' 32 MHz 'enable PLL Set Osc_ctrl.4 'PLL enable 'configure the systemclock Config Sysclock = Pll 'use PLL '------------------------------------------------------------------------------- '------------------------------------------------------------------------------- Config Com1 = 115200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 Open "com1:" For Binary As #1 ' Termninal initialisieren Printbin #1 , &H1B ; &H5B ; &H30 ; &H6D ' All attributes off(normal) Printbin #1 , &H1B ; &H5B ; &H32 ; &H4A ' Bildschirm löschen Printbin #1 , &H1B ; &H5B ; &H48 ; ' Cursor Home Printbin #1 , &H1B ; &H5B ; &H3F ; &H32 ; &H35 ; &H68 ; ' Cursor an '------------------------------------------------------------------------------- ' Einstellungen externer Speicher ' Alle EBI-Ports müssen auf OUTPUT ' ALLE Ports, die ATKIV-LOW sind müssen auf 1 gesetzt werden !!! ' ALLE Ports, die ATKIV-HIGH sind müssen auf 0 gesetzt werden !!! Print #1 , "Config Ports for external Adress / Data-Bus with no ALE... "; Portj_dirset = &B1111_1111 : Portj = &B0000_0000 ' D0:7 Portj_pin0ctrl = &B0_0_000_000 'Totem (PushPull) Portj_pin1ctrl = &B0_0_000_000 'Totem (PushPull) Portj_pin2ctrl = &B0_0_000_000 'Totem (PushPull) Portj_pin3ctrl = &B0_0_000_000 'Totem (PushPull) Portj_pin4ctrl = &B0_0_000_000 'Totem (PushPull) Portj_pin5ctrl = &B0_0_000_000 'Totem (PushPull) Portj_pin6ctrl = &B0_0_000_000 'Totem (PushPull) Portj_pin7ctrl = &B0_0_000_000 'Totem (PushPull) Portk_dirset = &B1111_1111 : Portk = &B1111_1111 ' A0:7 Portk_pin0ctrl = &B0_0_001_000 'Totem (PushPull) + Buskeeper Portk_pin1ctrl = &B0_0_001_000 'Totem (PushPull) + Buskeeper Portk_pin2ctrl = &B0_0_001_000 'Totem (PushPull) + Buskeeper Portk_pin3ctrl = &B0_0_001_000 'Totem (PushPull) + Buskeeper Portk_pin4ctrl = &B0_0_001_000 'Totem (PushPull) + Buskeeper Portk_pin5ctrl = &B0_0_001_000 'Totem (PushPull) + Buskeeper Portk_pin6ctrl = &B0_0_001_000 'Totem (PushPull) + Buskeeper Portk_pin7ctrl = &B0_0_001_000 'Totem (PushPull) + Buskeeper ' PortX_pinYctrl = &B0_0_001_000 : X= Port A... Y= Bit Nr. 0-7 ' X :7 : 0= SlewRate normal, 1= SlewRate limited ' X :6 : 0= IO normal, 1= IO inverted ' XXX :5:3: 000 = Totem (PushPull) ' XXX :5:3: 001 = Totem + Buskeeper ' XXX :5:3: 010 = Totem + Pulldown on Input ' XXX :5:3: 011 = Totem + PullUp on Input ' XXX :5:3: 100 = Wired or ' XXX :5:3: 101 = Wired and ' XXX :5:3: 110 = Wired Or + PullDown ' XXX :5:3: 111 = Wired And + PullUp ' XXX:2:0: 000 = Both edges trigger port Interrupts / Events ' XXX:2:0: 001 = Rising edge trigger port Interrupts / Events ' XXX:2:0: 010 = Falling edge trigger port Interrupts / Events ' XXX:2:0: 011 = Low Level trigger port Interrupts / Events ' XXX:2:0: 100 = Reserved ' XXX:2:0: 101 = Reserved ' XXX:2:0: 110 = Reserved ' XXX:2:0: 111 = Input Buffer Disabled (Only Port A to F) for use with ADC or AC Portf_dirset = &B1111_1111 : Portf = &B1111_1111 ' A8:15 Portf_pin0ctrl = &B0_0_001_000 'Totem (PushPull) + Buskeeper Portf_pin1ctrl = &B0_0_001_000 'Totem (PushPull) + Buskeeper Portf_pin2ctrl = &B0_0_001_000 'Totem (PushPull) + Buskeeper Portf_pin3ctrl = &B0_0_001_000 'Totem (PushPull) + Buskeeper Portf_pin4ctrl = &B0_0_001_000 'Totem (PushPull) + Buskeeper Portf_pin5ctrl = &B0_0_001_000 'Totem (PushPull) + Buskeeper Portf_pin6ctrl = &B0_0_001_000 'Totem (PushPull) + Buskeeper Portf_pin7ctrl = &B0_0_001_000 'Totem (PushPull) + Buskeeper Porth_dirset = &B1111_1111 : Porth = &B1111_1111 ' WR, RD , A16, A17, A18, A19, A20, A21 Porth_pin0ctrl = &B0_0_000_000 'Totem (PushPull) Porth_pin1ctrl = &B0_0_000_000 'Totem (PushPull) Porth_pin2ctrl = &B0_0_001_000 'Totem (PushPull) + Buskeeper Porth_pin3ctrl = &B0_0_001_000 'Totem (PushPull) + Buskeeper Porth_pin4ctrl = &B0_0_001_000 'Totem (PushPull) + Buskeeper Porth_pin5ctrl = &B0_0_001_000 'Totem (PushPull) + Buskeeper Porth_pin6ctrl = &B0_0_001_000 'Totem (PushPull) + Buskeeper Porth_pin7ctrl = &B0_0_001_000 'Totem (PushPull) + Buskeeper Porte_dirset = &B1111_1111 : Porte = &B1111_0000 ' CS3, CS2, CS1, CS0 Porte_pin0ctrl = &B0_0_000_000 'Totem (PushPull) CS3 Porte_pin1ctrl = &B0_0_000_000 'Totem (PushPull) CS2 SRAM Porte_pin2ctrl = &B0_0_000_000 'Totem (PushPull) CS1 SRAM Porte_pin3ctrl = &B0_0_000_000 'Totem (PushPull) CS0 TFT Porte_pin4ctrl = &B0_0_000_000 'Totem (PushPull) Porte_pin5ctrl = &B0_0_000_000 'Totem (PushPull) Porte_pin6ctrl = &B0_0_000_000 'Totem (PushPull) Porte_pin7ctrl = &B0_0_000_000 'Totem (PushPull) ' EBI-OUT legt die 4 ChipSelect's auf einen anderen Port, damit die Adressleitungen ' A16 bis A21 auf Port-H frei wird. Portcfg_ebiout = &B0000_00_11 ' XXXX : RESERVED ' -> 00 : EBI Port3 adress output on PORT-F 0..7: SD: 4'h0, A[11:8] - SR or SR-LPC with SD on CS3: A[23:16] - SR NoAle or ALE1: A[15:8] ' 01 : EBI Port3 adress output on PORT-E 0..7: SD: 4'h0, A[11:8] - SR or SR-LPC with SD on CS3: A[23:16] - SR NoAle or ALE1: A[15:8] ' 10 : EBI Port3 adress output on PORT-F 4..7: SD: A[11:8] - SR or SR-LPC with SD on CS3: A[19:16] - SR NoAle or ALE1: --- ' 11 : EBI Port3 adress output on PORT-E 4..7: SD: A[11:8] - SR or SR-LPC with SD on CS3: A[19:16] - SR NoAle or ALE1: --- ' 00 : EBI CS-output on PORT-H 4..7 ' 01 : EBI CS-output on PORT-L 4..7 ' 10 : EBI CS-output on PORT-F 4..7 ' -> 11 : EBI CS-output on PORT-E 4..7 Ebi_ctrl = &B01_00_11_10 'SRAM ALE12, 3Port ' XX : 00: 4 Bit Data Bus ' XX -> : 01: 8 Bit Data Bus ' XX : 10: RESERVED ' XX : 11: RESERVED ' XX -> : 00: LPC-Mode: ALE1 ' XX : 01: LPC-Mode: RESERVED ' XX : 10: LPC-Mode: ALE12 ' XX : 11: LPC-Mode: RESERVED ' XX : 00: ALE1 - Adressbyte 0 and 1 multiplexed ' XX : 01: ALE2 - Adressbyte 0 and 2 multiplexed ' XX : 10: ALE12- Adressbyte 0,1 and 2 multiplexed ' -> XX : 11: NOALE- No adress multiplexing ' XX: 00: Externer Bus disabled ' XX: 01: 3 Port Control-Bus # Data-Bus # A0:A7 und A8:A15 über ALE1 gemuxt ' -> XX: 10: 4 Port ' XX: 11: 2 Port '------------------------------------------------------------------------------- '------------------------------------------------------------------------------- '------------------------------------------------------------------------------- '------------------------------------------------------------------------------- 'ChipSelect0 für 512 KByte SRam ' xxxxxxxx xxxx---- ' Bit: 23 bis 12 11 bis 0 nicht verwendet ' | | Ebi_cs0_baseaddr = &B00010000_00000000 ' Start &H100000 = 1M ' 00000000_00100000_00000000 = &H002000 = 8K ' 00000000_00110000_00000000 = &H003000 = 12K ' 00000000_01000000_00000000 = &H004000 = 16K ' 00000000_10000000_00000000 = &H008000 = 32K ' 00000001_00000000_00000000 = &H010000 = 64K ' 00000010_00000000_00000000 = &H020000 = 128K ' 00000100_00000000_00000000 = &H040000 = 256K ' 00001000_00000000_00000000 = &H080000 = 512K ' -> 00010000_00000000_00000000 = &H100000 = 1M ' 00100000_00000000_00000000 = &H800000 = 2M ' 01000000_00000000_00000000 = &H800000 = 4M ' 10000000_00000000_00000000 = &H800000 = 8M Ebi_cs0_ctrla = &B0_01011_01 ' Size &H080000 = 512 KB ' X : RESERVED ' XXXXX : AdressBlockSize ' 00000 : 256 Byte ' 00001 : 512 Byte ' 00010 : 1 KByte ' 00011 : 2 KByte ' 00100 : 4 KByte ' 00101 : 8 KByte ' 00110 : 16 KByte ' 00111 : 32 KByte ' 01000 : 64 KByte ' 01001 : 128 KByte ' 01010 : 256 KByte ' -> 01011 : 512 KByte ' 01100 : 1 MByte ' 01101 : 2 MByte ' 00110 : 4 MByte ' 01111 : 8 MByte ' 10000 : 16 MByte ' XX : ChipSelectMode ' 00 : disabled ' -> 01 : Enabled for SRAM ' 10 : Enabled for SRAM LPC (LowPinCount) ' 11 : Enabled for SD-SRAM Ebi_cs0_ctrlb = &B00000_100 ' je nach Geschwindigkeit des SRam's ' XXXXX : RESERVED ' XXX : Waitstates ' 000 : 0 Waitstates ' 001 : 1 Waitstates ' 010 : 2 Waitstates ' 011 : 3 Waitstates ' -> 100 : 4 Waitstates ' 101 : 5 Waitstates ' 110 : 6 Waitstates ' 111 : 7 Waitstates '------------------------------------------------------------------------------- ' Nun kann das externe SRam genauso wie das interne SRam angesprochen werden. ' Vorteil: erheblich schneller im Zugriff, wie DRam !!! ' So kann auch Hardware "memory-mapped" eingebunden werden ' oder ein ISA-Bus realisiert werden. ' Now you can use the external SRAM just like the internal SRAM. ' This is much faster like DRAM ' This way you can also map hardware and access registers as you would do for SRAM $xramstart = &H100000 $xramsize = &H080000 Attaching an LCD Display Top Previous Next A LCD display can be connected with two methods. · By wiring the LCD-pins to the processor port pins. This is the pin mode. The advantage is that you can choose the pins and that they don't have to be on the same port. This can make your PCB design simple. The disadvantage is that more code is needed. · By attaching the LCD-data pins to the data bus. This is convenient when you have an external RAM chip and will add only a little extra code. The LCD-display can be connected in PIN mode as follows: LCD DISPLAY PORT PIN DB7 PORTB.7 14 DB6 PORTB.6 13 DB5 PORTB.5 12 DB4 PORTB.4 11 E PORTB.3 6 RS PORTB.2 4 RW Ground 5 Vss Ground 1 Vdd +5 Volt 2 Vo 0-5 Volt 3 This leaves PORTB.1 and PORTB.0 and PORTD for other purposes. You can change these pin settings from the Options LCD menu. BASCOM supports many statements to control the LCD-display. For those who want to have more control of the example below shows how to use the internal BASCOM routines. $ASM Ldi _temp1, 5 'load register R24 with value Rcall _Lcd_control 'it is a control value to control the display Ldi _temp1,65 'load register with new value (letter A) Rcall _Write_lcd 'write it to the LCD-display $END ASM Note that _lcd_control and _write_lcd are assembler subroutines which can be called from BASCOM. See the manufacturer's details from your LCD display for the correct pin assignment. Memory usage Top Previous Next SRAM Every variable uses memory. Variables are stored in memory. This memory is also called SRAM (static ram). The available memory depends on the chip. When you double click on the chip pinout, you can view the parameters of the used chip. A special kind of memory are the registers in the AVR. Registers 0-31 have addresses 0-31. Almost all registers are used by the compiler or might be used in the future. Which registers are used depends on the program statements you use. This brings us back to the SRAM. No SRAM is used by the compiler other than the space needed for the software stack ($SWSTACK) and frame ($FRAMESIZE) Some statements might use some SRAM. When this is the case it is mentioned in the help topic of that statement. For example, CONFIG CLOCK in user mode requires variables to hold the time. Variables like _sec , _min , _hour, _day , _month , _year. Each 8 bits used occupy one byte. When you dimension 1 bit, you will also use 1 byte. Each byte variable occupies one byte. Each integer/word variable occupies two bytes. Each Long, Dword or Single variable occupies four bytes. Each double variable occupies 8 bytes. Each string variable occupies at least 2 bytes. A string with a length of 10 occupies 11 bytes. Strings need an additional byte (Null termination) to indicate the end of the string. That's why a string of 10 bytes occupies 11 bytes. With dimension of a bit you will occupy one byte. Use bits or byte variables wherever you can to save memory. (not allowed for negative values) See also DIM The software stack is used to store the addresses of LOCAL variables and for variables that are passed to SUB routines. Each LOCAL variable and passed variable to a SUB/FUNCTION, requires two bytes to store the address (because it is a 16-Bit address = 2 bytes). So when you have a SUB routine in your program that passes 10 variables, you need 10 * 2 = 20 bytes. When you use 2 LOCAL variables in the SUB program that receives the 10 variables, you need additional 2 * 2 = 4 bytes. See also DECLARE SUB, DECLARE FUNCTION The software stack ($SWSTACK) size can be calculated by taking the maximum number of parameters in a SUB routine, adding the number of LOCAL variables and multiplying the result by 2. To be safe, add 4 more bytes for internally used LOCAL variables. LOCAL variables are stored in a place that is named the Frame ($FRAMESIZE) When you have a LOCAL STRING with a size of 40 bytes, and a LOCAL LONG, you need 41 + 4 bytes = 45 bytes of frame space. When you use conversion routines such as STR, VAL, HEX, INPUT etc. that convert from numeric to string and vice versa, you also need a frame. Note that the use of the INPUT statement with a numeric variable, or the use of the PRINT or LCD statement with a numeric variable, will also force you to reserve 24 bytes of frame space. This because these routines use the internal numeric<>string conversion routines. In fact, the compiler creates a buffer of 24 bytes that serves as scratchpad for temporary variables, and conversion buffer space. So the frame space should be 24 at minimum ($FRAMESIZE = 24). This 24 Byte start at the beginning of the Frame which act as the conversion buffer within the frame For an ATXMEGA or ATMEGA you have usually enough SRAM so you can start with higher values of Stack and Frame. With an ATTINY13 and 64Byte SRAM it is a challenge but also start with all stack defined and lower the Stack Values when your application program grows. · Avoid to use SUB or FUNCTIONS (If you want to save SRAM space) · If you use Functions like PRINT, LCD, INPUT and the FP num <> FORMAT(), String conversion you need to define the 24 Byte conversion buffer (at least 24Byte for Software Stack + FRAME together). In this case just 9 Bytes are left for global variables ! See also: $HWSTACK, $SWSTACK, $FRAMESIZE XRAM Some processors have an external memory interface. For example the ATMEGA128 has such an interface. The additional memory is named XRAM memory (extended or external memory). When you add 32 KB RAM, the first address will be 0. But because the XRAM can only start after the internal SRAM, the lower memory locations of the XRAM will not be available for use. The processor will automatically use the SRAM if an address is accessed that is in range of the SRAM memory. Thus adding 32KB of XRAM, will result in a total of 32 KB RAM. With ATXMEGA you can add XRAM with the EBI (External Bus Interface). There is no problem to add for example 16 MByte of external SDRAM. See CONFIG XRAM ERAM Most AVR chips have internal EEPROM on board. This EEPROM can be used to store and retrieve data. In BASCOM, this data space is called ERAM. An important difference is that an ERAM variable can only be written to a maximum of 100.000 times. So only assign an ERAM variable when it is required, and never use it in a loop or the ERAM will become unusable. Always use the Brown out detection of the processor to prevent EEPROM corruption. See also DIM For ATXMEGA see also CONFIG EEPROM Constant code usage Constants are stored in a constant table. Each used constant in your program will end up in the constant table. For example: Print "ABCD" Print "ABCD" This example will only store one constant (ABCD). Print "ABCD" Print "ABC" In this example, two constants will be stored because the strings differ. Stack See also: $HWSTACK, $SWSTACK, $FRAMESIZE The Stack is a part of SRAM (Static RAM). In SRAM the compiler stores user dimensioned variables, as well as internal variables, but SRAM holds also Hardware Stack, Software Stack and Frame. The Variables always start at the lowest SRAM Address. After Reset all SRAM Bytes are 0 (and strings are "") so the SRAM memory is cleared after reset. With the $noramclear option you can turn this behavior off which means the SRAM is not cleared after reset. The available SRAM depends on the Chip. With ATTINY13 for example you have 64Byte of SRAM and you will find this information beside the user manual in the *.DAT file. You can also double click the chip in Chip Pinout to view the chip parameters. The following you find in the attiny13.dat file: SRAM = 64 ; SRAM size Global Variables start with the lowest SRAM Address and the Hardware Stack start with the highest SRAM Address. Example for using with Bascom-AVR Simulator: $regfile = "attiny13.dat" $crystal = 4000000 $hwstack = 30 $swstack = 0 $framesize = 24 Dim B As Byte B = 5 Pcmsk = &B00000001 'PIN Change Int ON PCINT0 pin_change_isr Set Gimsk.5 Enable Interrupts Do !NOP Loop End 'end program pin_change_isr: B = 7 Return With an ATTINY13 the SRAM is just 64Byte and it is easy to see which SRAM Bytes will be overwritten with Bascom AVR Simulator Memory Window. Click on M to display the memory window. Picture: SRAM of ATTINY13 when executing the above ATTINY13 example in Bascom Simulator You can see the Hardware Stack (32 Byte) , Frame (24 Byte) and the Variable B. For this example you do not really need a Frame so it could be also $framesize = 0 for this example. With ATXMEGA128A1 there is 8K Byte of SRAM available and you can find in the DAT file (SRAM = 8192 ; SRAM size ) The Values of Stack should be ALWAYS defined at the beginning of any BASCOM-AVR Program in the main project file. The best place is right after the $REGFILE statement. Example: $hwstack = 32 ' default use 32 for the hardware stack $swstack = 32 ' default use 32 for the SW stack $framesize = 40 ' default use 40 for the frame space The following example show what can happen when you define NO Stacks or Frame or when you define not enough Stack or Frame. In this example we use: $hwstack = 64, $swstack = 0, $framesize = 8 As we know now Software Stack and FRAME together must be as absolute minimum 24 Byte (for the conversion buffer) so we force the overwriting of Hardware Stack which causes malfunction. (Reminder: Don�t start with the lowest values for Stack and Frame) Picture : SRAM for example with$hwstack = 64, $swstack = 0, $framesize = 8 You can now imagine what could happen: · Because of overwritten return address in Hardware Stack the micro is jumping to somewhere else and malfunction if forced. · Functions like PRINT overwrite addresses of LOCAL Variables and here also will the micro jump to somewhere else and malfunction is forced. Picture: Simulator Memory Windows for example with $hwstack = 64, $swstack = 0, $framesize = 8 Now an example for passing an Array to a SUB: With this example we see the complete SRAM. The SRAM start with the dimed variables. In this case it start with the variable I followed by the Array Ar of 16 Byte and in the end the variable B. Because it is easier with the memory window of Bascom Simulator I choose multiple of 16 for Stack and Framesize. We have here 2 Addresses stored in Software Stack. One address for the Array and one address for the variable B. So passing an Array to a SUB just need 2 Bytes for the address in Stack which is the same size as for one Byte variable (here variable B). Picture: Simulator Memory Window for example passing an Array to a SUB With this example you also see that especially with ATTINY and smaller ATMEGA it is not that complicated to see if other SRAM bytes will be overwritten by something and causes malfunction. You have with the Simulator window the �big picture� of SRAM and STACK together. As already written it is easier to use multiple of 16 for Hardware Stack, Software Stack and FRAME as a starting point because one line in Simulator Memory window is 16 Bytes. How to see which Variables are stored on which SRAM Byte ? You can find out the stored variable with the Bascom-AVR Simulator Memory Window by clicking on that byte. Click on SRAM Bytes show the OCCUPIED BY in the footer of that window. Only the first Byte of an Array will show the Name of the Array ! Picture: How to see which Variables are stored on which SRAM Byte You can also find this information in the Compiler output report: In this case under VARIABLES Picture: How to see which Variables are stored on which SRAM Address The following small example is good for examining the Bascom-AVR internal variables like _sec, _min or _hour in Bascom-AVR Simulator Memory Window. Config Clock = User for example create the internal variables for seconds (_sec), minutes (_min) ,hour (_hour) etc�. You can see this variables by clicking on the SRAM Byte and watch the footer of that Bascom-AVR Simulator Memory Window footer. $regfile = "m88def.dat" $hwstack = 48 $swstack = 80 $framesize = 80 Config Clock = User End 'end program Picture: Internal Variables in the Bascom-AVR Simulator Memory Window See also: $HWSTACK, $SWSTACK, $FRAMESIZE Statements and Hardware Resources Top Previous Next Some of the BASCOM statements and functions use a hardware resource. This is a list of hardware resources and the statement/functions that use them. USART0 $BAUD, BAUD USART1 $BAUD1 , BAUD1, USARTx BUFSPACE, CLEAR, ECHO, WAITKEY, ISCHARWAITING, INKEY, INPUTBIN, INPUTHEX, INPUT, PRINT, PRINTBIN TIMER0 DCF77 , READHITAG , GETRC5 , CONFIG SERVOS , TIME$, DATE$ TIMER1 DTMFOUT , RC5SEND, RC6SEND , SONYSEND. TIMER2 TIME$, DATE$ ADC GETADC EEPROM READEEPROM, WRITEEPROM TWI I2CINIT, I2CRECEIVE, I2CSEND, I2START I2CSTOP I2CRBYTE I2CWBYTE SPI SPIIN, SPIINIT, SPIMOVE, SPIOUT - SPI CAN CONFIG CANBUS, CONFIG CANMOB, CANBAUD, CANRESET, CANCLEARMOB, CANCLEARALLMOBS, CANSEND, CANRECEIVE, CANID, CANSELPAGE, CANGETINTS Using the UART Top Previous Next UART A Universal Asynchronous Receiver and Transmitter (UART) can be used to send and receive data between two devices. More specific these devices can be PC-to-PC, PC-to-micro controller and micro controller-to-micro controller. The UART communicates using TTL voltages +5V and 0V or LVTTL depending on your micro controllers VCC voltage. If you wish to connect to a PC you need to use RS232 protocol specifications. This means that the hardware communication is done with specific voltage levels. (+15V and -15V) This can be achieved by using a MAX232 level shifter. The hardware is explained in this schematic: The DB-9 connector has 9 pins but you only need to use 3 of them. Notice that the drawing above shows the FRONT VIEW thus remember that you are soldering on the other side. On most connectors the pin outs can also be found on the connector itself. If your controller has no UART you can use a software UART see below. If your controller has one UART you connect controller pins TxD and RxD to TxD and RxD in the schematic above. If your controller has more than one UART you connect controller pins TxD0 and RxD0 to TxD and RxD in the schematic above. You now need to initialize the program in your micro controller, open a new .bas file and add the following code in the beginning of your program. $regfile = "your micro here def.dat" $crystal = 8000000 $baud = 19200 Make sure to define your micro controller after $regfile for example if you use the ATMega32 $regfile = "m32def.dat" Some new chips can use an internal oscillator, also some chips are configured to use the internal oscillator by default. Using an internal oscillator means you do not need an external crystal. Perform this step only if you have an internal oscillator. Open the BASCOM-AVR programmer like this: · Select the �Lock and Fuse Bits� tab and maximize the programmer window. · Check if you see the following in the �Fusebit� section: "1:Divide Clock by 8 Disabled" and "Int. RC Osc. 8 MHz; Start-up time: X CK + X ms; [CKSEL=XXXX SUT=XX]" These options are not available for all AVR�s, if you don�t have the option do not change any fuse bits. If these options are available, but in a wrong setting. Change the setting in the drop down box and click another Fuse section. Finally click the "Program FS" button. Click "Refresh" to see the actual setting. Now connect a straight cable between the DB-9 connector, micro controller side and the PC side. Program a test program into your micro controller, it should look like this: $regfile = "m32def.dat" 'Define your own $crystal = 8000000 $baud = 19200 Do Print "Hello World" Waitms 25 Loop End Now open the BASCOM-AVR Terminal and set your connection settings by clicking �Terminal� -> �Settings� Select your computers COM port and select baud 19200, Parity none, Data bits 8, Stop bits 1, Handshake none, emulation none. If you see the Hello World displayed in the BASCOM-AVR Terminal emulator window, your configuration is OK. Congratulations. Example You can also try this example with the BASCOM Terminal emulator, it shows you how to send and receive with various commands. $regfile = "m88def.dat" $crystal = 8000000 $baud = 19200 Dim Akey As Byte 'Here we declare a byte variable Print Print "Hello, hit any alphanumerical key..." Akey = Waitkey() 'Waitkey waits untill a char is received from the UART Print Akey Wait 1 Print Print "Thanks!, as you could see the controller prints a number" Print "but not the key you pressed." Wait 1 Print Print "Now try the enter key..." Akey = Waitkey() Akey = Waitkey() Print Akey Print Print "The number you see is the ASCII value of the key you pressed." Print "We need to convert the number back to the key..." Print 'Notice what this line does Print "Please try an alphanumerical key again..." Akey = Waitkey() Print Chr(akey) 'Notice what this does Print "That's fine!" Wait 1 Print Print "For a lot of functions, just one key is not enough..." Print "Now type your name and hit enter to confirm" Dim Inputstring As String * 12 'Declare a string variable here Do Akey = Waitkey() If Akey = 13 Then Goto Thanks 'On enter key goto thanks Inputstring = Inputstring + Chr(akey) 'Assign the string Loop Thanks: Print "Thank you " ; Inputstring ; " !" 'Notice what ; does Wait 1 Print Print "Take a look at the program code and try to understand" Print "how this program works. Also press F1 at the statements" Print Print "If you understand everything continue to the next experiment" End ASCII As you could have seen in the previous example we use the PRINT statement to send something to the UART. Actually we do not send just text. We send ASCII characters. ASCII means American Standard Code for Information Interchange. Basically ASCII is a list of 127 characters. ASCII Table (Incomplete) Decimal Hex Binary Value ------- --- ------ ----- 000 000 00000000 NUL (Null char.) 008 008 00001000 BS (Backspace) 009 009 00001001 HT (Horizontal Tab) 010 00A 00001010 LF (Line Feed) 012 00C 00001100 FF (Form Feed) 013 00D 00001101 CR (Carriage Return) 048 030 00110000 0 049 031 00110001 1 052 034 00110100 4 065 041 01000001 A 066 042 01000010 B 067 043 01000011 C You can find a complete ASCII table here CARRIAGE RETURN (CR) AND LINE FEED (LF) In the previous example you can also see that a second print statement always prints the printed text to the following line. This is caused by the fact that the print statement always adds the CR and LF characters. Basically if we state: Print �ABC� We send 65 66 67 13 10 to the UART. (In binary format) The carriage return character (13) returns the cursor back to column position 0 of the current line. The line feed (10) moves the cursor to the next line. Print �ABC� ; When we type a semicolon ( ; ) at the end of the line... Bascom does not send a carriage return/line feed, so you can print another text after the ABC on the same line. Print �ABC� ; Chr(13) ; This would send only ABC CR. The next print would overwrite the ABC. OVERVIEW Here are some other commands that you can use for UART communications: Waitkey() Waitkey will until a character is received in the serial buffer. Ischarwaiting() Returns 1 when a character is waiting in the hardware UART buffer. Inkey() Inkey returns the ASCII value of the first character in the serial input buffer. Print Sends a variable or non-variable string to the UART ANOTHER EXAMPLE This example shows how to use Ischarwaiting to test if there is a key pressed. And if there is, read to a variable. 'Print "Press B key to start" Dim Serialcharwaiting As Byte, Serialchar As Byte Serialcharwaiting = Ischarwaiting() 'Check if B or b pressed then goto If Serialcharwaiting = 1 Then Serialchar = Inkey() If Serialchar = 66 Or Serialchar = 98 Then Goto MyRoutine End If End If Goto Main Myroutine: 'Statements Main: 'Statements End BUFFERING SERIAL DATA If you wish to send and receive data at high speed, you need to use serial input and serial output buffers. This buffering is implemented in BASCOM-AVR and can only be used for hardware UART�s. To configure a UART to use buffers, you need to use the Config statement. Config Serialout = Buffered , Size = 20 and/or Config Serialin = Buffered , Size = 20 More information can be found in BASCOM-Help. Search topic = "config serialin". There is also a sample program �RS232BUFFER.BAS� in the samples folder if you wish a demonstration of the buffering. SOFTWARE UART The previous examples used the hardware UART. That means the compiler uses the internal UART registers and internal hardware (RxD(0) and TxD(0)) of the AVR. If you don�t have a hardware UART you can also use a software UART. The Bascom compiler makes it easy to �create� additional UART�s. Bascom creates software UART�s on virtually every port pin. Remember that a software UART is not as robust as a hardware UART, thus you can get timing problems if you have lots of interrupts in your program. For this example we use micro controller pins portc.1 and portc.2. Connect portc.1 to TxD and portc.2 to RxD see the schematic above. Change the $regfile and program this example: $regfile = "m88def.dat" $crystal = 8000000 $baud = 19200 Dim B As Byte Waitms 100 'Open a TRANSMIT channel for output Open "comc.1:19200,8,n,1" For Output As #1 Print #1 , "serial output" 'Now open a RECEIVE channel for input Open "comc.2:19200,8,n,1" For Input As #2 'Since there is no relation between the input and output pin 'there is NO ECHO while keys are typed Print #1 , "Press any alpha numerical key" 'With INKEY() we can check if there is data available 'To use it with the software UART you must provide the channel Do 'Store in byte B = Inkey(#2) 'When the value > 0 we got something If B > 0 Then Print #1 , Chr(b) 'Print the character End If Loop Close #2 'Close the channels Close #1 End After you have programmed the controller and you connected the serial cable, open the terminal emulator by clicking on in Bascom. You should see the program asking for an alphanumerical input, and it should print the input back to the terminal. USING RS485 Top Previous Next RS485 RS485 is used for serial communication and well suited for transmission over large distances. Similar to RS232 we need a level shifter. The sample above uses a MEGA161 or MEGA162 which has 2 UARTS. This way you can have both a RS232 and RS485 interface. The RS232 is used for debugging. In order to test you need 2 or more similar circuits. One circuit would be the master. The other(s) would be a slave. The same hardware is used to test the MODBUS protocol. The bus need to be terminated at both ends with a resistor. 100 ohm is a typical used value. The GND of both circuits may not be connected ! Only connect point A and B from both circuits. For industrial usage it is best to use an optical isolated level shifter. Simple MASTER sample $regfile = "m162def.dat" ' specify the used micro $crystal = 8000000 $baud = 19200 ' use baud rate $hwstack = 42 ' default use 32 for the hardware stack $swstack = 40 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space $lib "modbus.lbx" Config Print1 = Portb.1 , Mode = Set ' use portb.1 for the direction Rs485dir Alias Portb.1 Config Rs485dir = Output Rs485dir = 0 ' go to receive mode Portc.0 = 1 ' a switch is connected to pinc.0 so activate pull up resistor ' TX RX ' COM0 PD.1 PD.0 monitor ' COM1 PB.3 PB.2 rs485 ' PB.1 data direction rs485 Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Config Com2 = 9600 , Synchrone = 0 , Parity = Even , Stopbits = 1 , Databits = 8 , Clockpol = 0 ' MUST MATCH THE SLAVE 'use OPEN/CLOSE for using the second UART Open "COM2:" For Binary As #1 'dimension some variables Dim B As Byte Dim W As Word Dim L As Long W = &H4567 ' set some values L = &H12345678 Print "RS-485 MODBUS master" Do If Pinc.0 = 0 Then ' test button Waitms 500 ' delay since we want to send just 1 frame Print "send request to slave/server" ' to debug terminal ' Print #1 , Makemodbus(2 , 3 , 8 , 2); 'slave 2, function 3, start address 8, 2 bytes ' Print #1 , Makemodbus(2 , 6 , 8 , W); 'slave 2, function 6, address 8 , value of w Print #1 , Makemodbus(b , 16 , 8 , L); 'send a long End If If Ischarwaiting(#1) <> 0 Then 'did we got something back? B = Waitkey(#1) ' yes so get it Print Hex(b) ; ","; ' print it End If Loop A slave would simply listen to data, and once enough data received, send it back. Using the I2C protocol Top Previous Next I²C bus I²C bus is an abbreviation for Inter Integrated Circuit bus or "I-Squared-C". Some manufacturer call it TWI (Two-Wire-Interface) which is technically the same as I2C. There is also SMBus. The I²C bus and the SMBus� are essentially compatible with each other. Normally devices, both masters and slaves, are freely interchangeable between both buses. Both buses feature addressable slaves (although specific address allocations can vary between the two). The buses operate at the same speed, up to 100kHz, but the I²C bus has both 400kHz and 2MHz versions. Complete compatibility between I2C and SMBus is ensured only below 100kHz. I²C is a serial and synchronous bus protocol. In standard applications hardware and timing are often the same. The way data is treated on the I²C bus is to be defined by the manufacturer of the I²C master and slave chips. In a simple I²C system there can only be one master, but multiple slaves. The difference between master and slave is that the master generates the clock pulse. The master also defines when communication should occur. For bus timing it is important that the slowest slave should still be able to follow the master�s clock. In other words the bus should be as fast as the slowest slave. A typical hardware configuration is shown in the figure below: Note that more slave chips can be connected to the SDA and SCL lines, normally Rp has a value of 1kOHM. The clock generated by the master is called Serial Clock (SCL) and the data is called Serial Data (SDA). Always check if the pull-up resistors are connected ! In most applications the micro controller is the I²C Master. Slave chips can be Real Time Clocks and Temperature sensors. For example the DS1307 and the DS1624 from http://www.maximintegrated.com . Of course you can also create your own I2C slaves by programming an ATTINY or ATMEGA . See CONFIG I2CSLAVE In that case there is AVR Master to AVR Slave communication. LOGIC BUS LEVELS AND CONDITIONS Data can only occur after the master generates a start condition. A start condition is a high-to-low transition of the SDA line while SCL remains high. After each data transfer a stop condition is generated. A stop condition is a low-to-high transition of the SDA line while SCL remains high. As said a data transfer can occur after a start condition of the master. The length of data sent over I²C is always 8 bit this includes a read/write direction bit, so you can effectively send 7 bits every time. The most significant bit MSB is always passed first on the bus. If the master writes to the bus the R/W bit = 0 and if the master reads the R/W bit = 1. After the R/W bit the master should generate one clock period for an acknowledgement ACK. Each receiving chip that is addressed is obliged to generate an acknowledge after the reception of each byte. A chip that acknowledges must pull down the SDA line during the acknowledge clock pulse in such a way that the SDA line is stable LOW during the HIGH period of the acknowledge related clock pulse. After an acknowledge there can be a stop condition, if the master wishes to leave the bus idle. Or a repeated start condition. A repeated start is the same as a start condition. When the master reads from a slave it should acknowledge after each byte received. There are two reasons for the master not to acknowledge. The master sends a not acknowledge if data was not received correctly or if the master wishes the stop receiving. In other words if the master wishes to stop receiving, it sends a not acknowledge after the last received byte. The master can stop any communication on the bus at any time by sending a stop condition. BUS ADRESSING Let�s say we have a slave chip with the address &B1101000 and that the master wishes to write to that slave, the slave would then be in receiver mode, like this: You can see here that the master always generates the start condition, then the master sends the address of the slave and a �0� for R/W. After that the master sends a command or word address. The function of that command or word address can be found in the data sheet of the slave addressed. After that the master can send the data desired and stop the transfer with a stop condition. Again the start condition and the slave address, only this time the master sends �1� for the R/W bit. The slave can then begin to send after the acknowledge. If the master wishes to stop receiving it should send a not acknowledge. OVERVIEW of Routines Config Sda = Portx.x Configures a port pin for use as serial data SDA. Config Scl = Portx.x Configures a port pin for use as serial clock SCL. I2cinit Initializes the SCL and SDA pins. I2cstart Sends the start condition. I2cstop Sends the stop condition. I2cwbyte Writes one byte to an I²Cslave. I2crbyte Reads one byte from an I²Cslave. I2csend Writes a number of bytes to an I²Cslave. I2creceive Reads a number of bytes from an I²Cslave. I2C write and read: A typical I2C write to send one byte of data looks like this: I2cstart I2cwbyte I2c_address_of_slave I2cwbyte Byte_to_send I2cstop (I2cstart generates the start condition on the I2C bus were all devices are listen to. After this we send the Slave address of the device we want to send a byte to. The I2C slave with this address will send out a Ack where all other do nothing. Now you can start to send a byte (or more bytes) to this Slave address. After this an I2cstop release the bus.) A typical I2C read to read one byte of data looks like this: I2cstart I2cwbyte I2c_address_of_slave I2crbyte Databyte_to_read , Nack I2cstop (Nack indicates that the master do not want to read more bytes) A typical I2C read to read one byte of data looks like this: I2cstart I2cwbyte I2c_address_of_slave I2crbyte Databyte_to_read , Ack I2crbyte Databyte_to_read , Nack I2cstop (Ack indicates that the master want to read more bytes from the slave and with the last byte to read the master indicate this with Nack) I2C Software vs. Hardware Routines By default BASCOM will use software routines when you use I2C statements. This because when the first AVR chips were introduced, there was no TWI yet. Atmel named it TWI because Philips is the inventor of I2C. But TWI is the same as I2C. So BASCOM allows you to use I2C on every AVR chip. Most newer AVR chips have build in hardware support for I2C. With the I2C_TWI lib you can use the TWI which has advantages as it require less code. To force BASCOM to use the TWI, you need to insert the following statement into your code: $LIB "I2C_TWI.LBX" You also need to choose the correct SCL and SDA pins with the CONFIG SCL and CONFIG SDA statements. The TWI will save code but the disadvantage is that you can only use the fixed SCL and SDA pins. When using XMEGA, there is a difference : here you are supposed to use the hardware TWI. So that is a default. To force to the software solution, use $FORCESOFTI2C See also: Using USI (Universal Serial Interface), Config TWI, CONFIG TWISLAVE, I2C_TWI, $FORCESOFTI2C I2CSEND , I2CSTART , I2CSTOP , I2CRBYTE , I2CWBYTE , I2C_TWI Library for using TWI EXAMPLE with Software Routines This example shows you how to setup and read the temperature from a DS1624 temperature sensor. Connect the DS1624 like this: Then program this sample into your micro controller and connect your micro controller to the serial port of your PC. $regfile = "m88def.dat" 'Define the chip you use $crystal = 8000000 'Define speed $hwstack = 40 $swstack = 30 $framesize = 40 $baud = 19200 'Define UART BAUD rate ' Declare RAM for temperature storage Dim I2ctemp As Byte 'Storage for the temperature ' We use here the software emulated I2C routines ' Configure pins we want to use for the I²C bus Config Scl = Portd.1 'Is serial clock SCL Config Sda = Portd.3 'Is serial data SDA I2cinit ' Declare constants - I2C chip addresses Const Ds1624wr = &B10010000 'DS1624 Sensor write Const Ds1624rd = &B10010001 'DS1624 Sensor read ' This section initializes the DS1624 I2cstart 'Sends start condition I2cwbyte Ds1624wr 'Sends the address 'byte with r/w 0 'Access the CONFIG register (&HAC address byte) I2cwbyte &HAC 'Set continuous conversion (&H00 command byte) I2cwbyte &H00 I2cstop 'Sends stop condition Waitms 25 'We have to wait some time after a stop I2cstart I2cwbyte Ds1624wr 'Start conversion (&HEE command byte) I2cwbyte &HEE I2cstop Waitms 25 'End of initialization Print 'Print empty line Do 'Get the current temperature I2cstart I2cwbyte Ds1624wr I2cwbyte &HAA 'Read temperature (&HAA command byte) I2cstart I2cwbyte Ds1624rd 'The chip will give register contents 'Temperature is stored as 12,5 but the ,5 first I2crbyte I2ctemp , Ack 'So you'll have to read twice... first the ,5 I2crbyte I2ctemp , Nack 'And then the 12... we don't store the ,5 I2cstop 'That's why we read twice. 'We give NACK if the last byte is read 'Finally we print Print "Temperature: " ; Str(i2ctemp) ; " degrees" ; Chr(13); Waitms 25 Loop End You should be able to read the temperature in your terminal emulator. Note that the used command bytes in this example can be found in DS1624 temperature sensor data sheet. Example which use I2C Master hardware in AVR See here: CONFIG TWI I2C Practice (Tips&Tricks) The design below shows how to implement an I2C-bus. The circuit is using a Mega88 as a master. The TWI bus is used. While you can use any pin for software mode I2C, when a micro has TWI hardware build in, it is advised to use the TWI hardware. R1 and R2 are 4K7 pull up resistors. There are many I2C slave chips available. The example shows the PCF8574. With the additional TWI slave library you can make your own slave chips. How to calculate Pull Up Resistor The maximum of bus capacitance is 400pF (which is independent of bus speed 100KHz or 400KHz). Here is a good article which describe how to calculate the Pull Up Resistor: http://www.edn.com/design/analog/4371297/Design-calculations-for-robust-I2C-communications Using AVR interal pull-up resistor (with Hardware Routines) It is recommended to use external pull-up resistors ! For testing you could use also the AVR interal pull-up resistors See example where Portc.4 and Portc.5 is SDA and SCL (the pull-up needs to be set after i2cinit): i2cinit Portc.4 = 1 Portc.5 = 1 Active Termination of I2C The following information was submitted by Detlef Queck: Many people have problems over and over with I2C(TWI) Termination. Use 4,7k or 10 k pull up? How long can the SCL, SDA line be when used with pull ups etc, etc. You can simplify this confusing problem. Here is a Schematic for an active Termination of I2C and TWI. We have used this Schematic for over 10 years, and have had no problems with it. The I2C (TWI) lines can be up to 80cm (400KHz) without any problem when the Terminator is at the end of the lines. How to handle longer cable length between I2C Master and Slaves or Multi-drop Configurations The I2C-bus capacitance limit of 400 pF restricts practical communication distances. You can extend the use of the I2C in systems with more devices and / or longer bus lengths with P82B715 or P82B96. P82B96 · Isolates capacitance allowing 400 pF on Sx/Sy side and 4000 pF on Tx/Ty side · 400 kHz operation over at least 20 meters of wire (see AN10148) · Create Multi-drop configurations · Supply voltage range of 2 V to 15 V with I2C-bus logic levels on Sx/Sy side independent of supply voltage · Splits I2C-bus signal into pairs of forward/reverse Tx/Rx, Ty/Ry signals for interface with opto-electrical isolators and similar devices that need unidirectional input and output signal paths. P82B715 · Increase the total connected capacitance of an I2C-bus system to around 3000 pF and drive signals over long cables to approximately 50m · Multi-drop distribution of I2C-bus signals using low cost twisted-pair cables I2C Multiplexing, Switch and Voltage Level translation between different I2C busses Some specialized devices only have one I2C or SMBus address and sometimes several identical devices are needed in the same system. The multiplexers and switches split the I2C bus into several sub-branches and allow the I2C master to select and address one of multiple identical devices, in order to resolve address conflict issues. An example is PCA9544A or PCA9546A (which also llows voltage level translation between 1.8 V, 2.5 V, 3.3 V and 5 V buses). Your I2C (TWI) connection is not working (Tips&Tricks): Checklist: - Is the configured I2C clock frequency matching the frequency of the connected chip - Check if you have pull-up resistors on SDA and SCL (and if the pull-up resistors are working) - Do you have the right SDA and SCL pins conected ? - connect also GND to have the same potential - You can use the Err variable to check which I2C function is not working. When an error occurs, the internal ERR variable will return 1. Otherwise it will be set to 0. - How about the voltage levels on both chips (do not connect 3.3V systems to 5V systems without voltage adapter) - Is the system you are connecting the I2C to using a 7 Bit address or 8 Bit address (8-bit addresses include the read/write bit) ? Then you can try with shift left: ' you can simply do this; &HC4 is an example address const someI2caddress= &H4C * 2 ' this would shift the address to the left. - It is important that you specify the proper crystal frequency. Otherwise it will result in a wrong TWI clock frequency - With following lib you do not use the software emulated TWI (I2C). You use the hardware I2C (for the AVR's that have an hardware I2C) $lib "i2c_twi.lbx" ' we do not use software emulated I2C but the TWI - By default BASCOM will use software routines for I2C. - Do you have the right I2C read address ? Here an example I2C write address which Bascom expects: &B01000000 = &H40 Read address would be for this example: &b01000001 = &h41 - In case of using TWI (I2C) Slave: Are you using the right library for your used chip ? With the I2C TWI Slave add-on library you get both libraries: � i2cslave.lib and i2cslave.lbx : This library is used for AVR�s which have no hardware TWI/I2C interface like for example ATTINY2313 or ATTINY13. In this case TIMER0 and INT0 is used for SDA and SCL (Timer0 Pin = SCL, INT0 Pin = SDA). Only AVR' with TIMER0 and INT0 on the same port can use this library like for example ATTINY2313 or ATTINY13. The i2cslave.lib file contains the ASM source. The i2cslave.lbx file contains the compiled ASM source. See CONFIG I2CSLAVE below. � i2c_TWI-slave.LBX : This library can be used when an AVR have an TWI/I2C hardware interface like for example ATMEGA8, ATMEGA644P or ATMEGA128. In this case the hardware SDA and SCL pin's of the AVR will be used (with ATMEGA8: SCL is PORTC.5 and SDA is PORTC.4). This library will be used when USERACK = OFF. When USERACK =ON then i2c_TWI-slave-acknack.LBX will be used. See also Config TWISLAVE Operation at 400 kHz Fast- mode devices can only be operated at 400 kHz clock frequency if no standard-mode devices (100KHz) are on the bus. You can use an I2C Scanner to find I2C devices: You basically use the Err variable. When an error occurs, the internal ERR variable will return 1. Otherwise it will be set to 0. So 0 means we have found a I2C Slave with that address. '------------------------------------------------------------------ ' (c) 1995-2016 MCS ' i2cscan.bas 'purpose : scan all i2c addresses to find slave chips 'use this sample in combination with twi-slave.bas 'Micro: Mega88 '------------------------------------------------------------------ $regfile = "M88def.dat" ' the used chip $crystal = 8000000 ' frequency used $baud = 19200 ' baud rate $hwstack = 40 $swstack = 30 $framesize = 40 Dim B As Byte 'we use the TWI pins of the Mega88 $lib "i2c_twi.lbx" ' we do not use software emulated I2C but the TWI Config Scl = Portc.5 ' we need to provide the SCL pin name Config Sda = Portc.4 ' we need to provide the SDA pin name I2cinit Config Twi = 100000 ' wanted clock frequency when using $lib "i2c_twi.lbx" 'will set TWBR and TWSR 'Twbr = 12 'bit rate register 'Twsr = 0 'pre scaler bits Print "Scan start" For B = 0 To 254 Step 2 'for all odd addresses I2cstart 'send start I2cwbyte B 'send address If Err = 0 Then 'we got an ack Print "Slave at : " ; B ; " hex : " ; Hex(b) ; " bin : " ; Bin(b) End If I2cstop 'free bus Next Print "End Scan" End I2C Slave Library See I2C TWI Slave I2C Slave LIB - how to Send/Receive more than 1 Byte for chips that do not have hardware I2C ? Using following config: Config I2cslave = &H34 , Int = Int0 , Timer = Timer0 When you want to receive/send multiple bytes, you need to keep track of them. You can do this with a byte counter. this counter you would need to reset when the slave is addressed. To do this the lib need to be altered: - open i2cslave.lib with notepad - look for label : I2c_adr_ack: Then add this line : rcall i2c_master_addressed -then save and add this label to your code: I2c_master_addressed: Br = 0 'clear the byte counter Bw = 0 return in your code where the bytes are passed you can increase them. The BR you increase when a byte is read, the BW you increase when a byte is passed. for example: I2c_master_has_data: Incr Bw Myarray(bw) = _a1 Return Using ATXMEGA I2C with Software Routines (then you can choose the SDA and SCL Pins) ATXMEGA have usually enough I2C interfaces. But nevertheless there is a possibility to use the I2C software routines and you can use any Pin you want as SDA and SCL. Following the ATXMEGA Master and below the ATMEGA328P I2C Slave which was tested with the ATXMEGA Master in I2C Software Mode: Master ' Using ATXMEGA with software I2C routines to use also pins which are no hardware SDA/SCL pins ' Needed Library: $lib "i2c.lbx" ' The $forcesofti2c directive force the ATXMEGA to use software I2c/TWI Library ' The hardware for this example is XMEGA-A3BU XPlained board from Atmel ' Don't forget the pull-ups on SDA/SCL pin ! ' Bascom Version 2.0.7.6 or higher needed $regfile = "XM256A3BUDEF.DAT" $crystal = 32000000 '32MHz $hwstack = 64 $swstack = 40 $framesize = 80 $forcesofti2c ' with this the software I2C/TWI commands are used when inlcuding i2c.lbx $lib "i2c.lbx" ' override the normal xmega i2c lib Config Osc = Enabled , 32mhzosc = Enabled Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 Config Portr.0 = Output Led0 Alias Portr.0 'LED 0 (XMEGA-A3BU XPlained board from Atmel ) Config Portr.1 = Output Led1 Alias Portr.1 'LED 1 (XMEGA-A3BU XPlained board from Atmel ) Dim B As Byte 'We use here Virtual port 0 Config Vport0 = B ' 'map portB to virtual port0 Config Scl = Port0 .1 ' Pin to use as SCL (The hardware pin is Pinb.1) Config Sda = Port0 .0 ' Pin to use as SDA (The hardware pin is Pinb.0) I2cinit ' Bring the Pin's in the proper state Do Waitms 500 Set Led1 Reset Led0 Waitms 500 Reset Led1 Set Led0 Incr B I2cstart I2cwbyte &H24 ' address of I2C Slave I2cwbyte B ' databyte to send to slave I2cstop Loop End 'end program Slave (for ATXMEGA using Soft I2C Master) ' I2C Slave Example for using with ATXMEGA ' ATMEGA328P running @ 3.3 Volt ! ' Terminal output of this example when used with XMEGA_ise_soft_i2c.bas: '( ATXMEGA using Software TWI/I2C <------> ATMEGA 328P Bascom-AVR @ 3.3V... >>> 180 >>> 181 >>> 182 >>> 183 >>> 184 >>> 185 >>> 186 >>> 187 >>> 188 >>> 189 >>> 190 >>> 191 ') $regfile = "m328pdef.dat" $crystal = 12e6 '16MHz $hwstack = 80 $swstack = 80 $framesize = 160 'CONFIG TWI SLAVE Config Twislave = &H24 , Btr = 1 , Bitrate = 100000 , Gencall = 1 ' With the CONFIG BTR, you specify how many bytes the master will read. Dim Receive As Byte Dim S As Byte Enable Interrupts Config Com1 = 19200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Wait 3 Print Print "ATXMEGA using Software TWI/I2C <------> ATMEGA 328P Bascom-AVR @ 3.3V..." Do nop Loop End 'end program '--------------------------------I2C-------------------------------------------- 'Master sent stop or repeated start Twi_stop_rstart_received: Return 'We were addressed and master will send data Twi_addressed_goread: Return 'We were addressed and master will read data Twi_addressed_gowrite: Return 'this label is called when the master sends data and the slave has received the byte 'the variable TWI holds the received value 'Twi_btw is the BYTE NUMBER Twi_gotdata: Receive = Twi 'lesen Print ">>> " ; Twi 'Print what we have received (ONLY FOR TESTING) Return 'this label is called when the master receives data and needs a byte 'the variable twi_btr is a byte variable that holds the index of the needed byte 'so when sending multiple bytes from an array, twi_btr can be used for the index 'twi_btr is the BYTE NUMBER Twi_master_needs_byte: Return 'when the mast has all bytes received this label will be called Twi_master_need_nomore_byte: Return '------------------------------------------------------------------------------- Using the 1 WIRE protocol Top Previous Next The 1-wire protocol was invented by Dallas Semiconductors and needs only 1 wire for two-way communication. You also need power and ground of course. This topic is written by Göte Haluza. He tested the new 1-wire search routines and is building a weather station. Dallas Semiconductor (DS) 1-wire. This is a brief description of DS 1-wire bus when used in combination with BASCOM. For more detailed explanations about the 1-wire bus, please go to http://www.maxim-ic.com. Using BASCOM makes the world a lot easier. This paper will approach the subject from a "BASCOM-user-point-of-view". 1-wire-net is a serial communication protocol, used by DS devices. The bus could be implemented in two basic ways : With 2 wires, then DQ and ground is used on the device. Power is supplied on the DQ line, which is +5V, and used to charge a capacitor in the DS device. This power is used by the device for its internal needs during communication, which makes DQ go low for short periods of time. This bus is called the 1-wire bus. With 3 wires, when +5V is supplied to the VDD line of the device, and DQ + ground as above. This bus is called the 2-wire bus. So, the ground line is "not counted" by DS. But hereafter we use DS naming conventions. How it works. (1-wire) The normal state of the bus is DQ=high. Through DQ the device gets its power, and performs the tasks it is designed for. When the host (your micro controller (uC)) wants something to happen with the 1-wire bus, it issues a reset-command. That is a very simple electric function that happens then; the DQ goes active low for a time (480uS on original DS 1-wire bus). This put the DS-devices in reset mode; then (they) send a presence pulse, and then (they) listen to the host. The presence pulse is simply an active low, this time issued by the device(s). Now, the host cannot know what is on the bus, it is only aware of that at least 1 DS device is attached on the bus. All communication on the 1-wire bus is initialized by the host, and issued by time-slots of active-low on a normally high line (DQ), issued by the device, which is sending at the moment. The devices(s) internal capacitor supplies its power needs during the low-time. How do you work with 1-wire-bus Thereafter, you can read a device, and write to it. If you know you only have 1 sensor attached, or if you want to address all sensors, you can start with a "Skip Rom" - command. This means; take no notice about the IDs of the sensors - skip that part of the communication. When you made a 1-wire-reset, all devices of the bus are listening. If you chose to address only one of them, the rest of them will not listen again before you have made a new 1-wire-reset on the bus. I do not describe BASCOM commands in this text - they are pretty much self-explanatory. But the uC has to write the commands to the bus - and thereafter read the answer. What you have to write as a command depends on devices you are using - and what you want to do with it. Every DS chip has a data sheet, which you can find at http://www.dalsemi.com/datasheets/pdfindex.html. There you can find out all about the actual devices command structure. There are some things to have in mind when deciding which of the bus-types to use. The commands, from BASCOM, are the same in both cases. So this is not a problem. The +5V power-supply on the VDD when using a 2-wire bus has to be from a separate power supply, according to DS. But it still works with taking the power from the same source as for the processor, directly on the stabilizing transistor. I have not got it to work taking power directly from the processor pin. Some devices consume some more power during special operations. The DS1820 consumes a lot of power during the operation "Convert Temperature". Because the sensors knows how they are powered (it is also possible to get this information from the devices) some operations, as "Convert T" takes different amount of time for the sensor to execute. The command "Convert T" as example, takes ~200mS on 2-wire, but ~700mS on 1-wire. This has to be considered during programming. And that power also has to be supplied somehow. If you use 2-wire, you don't have to read further in this part. You can do simultaneously "Convert T" on all the devices you attach on the bus. And save time. This command is the most power-consuming command, possible to execute on several devices, I am aware of. If you use 1-wire, there are things to think about. It is about not consuming more power than you feed. And how to feed power? That depends on the devices (their consumption) and what you are doing with them (their consumption in a specific operation). Short, not-so-accurate description of power needs, not reflecting on cable lengths. Only the processor pin as power supplier, will work < 5 sensors. (AVR, 1-wire-functions use an internal pull-up. 8051 not yet tested). Don't even think of simultaneous commands on multiple sensors. With +5V through a 4K7 resistor, to the DQ-line, 70 sensors are tested. But, take care, cause issuing "Convert T" simultaneously, would cause that to give false readings. About ~15 sensors is the maximum amount of usable devices, which simultaneously performs some action. This approach DS refers to as "pull-up resistor". With this in mind, a bus with up to 70 devices has been successfully powered this way. The resistor mentioned, 4K7, could be of smaller value. DS says minimum 1K5, I have tested down to 500 ohm - below that the bus is not usable any more. (AVR). Lowering the resistor feeds more power - and makes the bus more noise resistant. But, the resistor minimum value is naturally also depending on the uC-pin electric capabilities. Stay at 4K7 - which is standard recommendation. DS recommends yet another approach, called "strong pull-up" which (short) works via a MOS-FET transistor, feeding the DQ lines with enough power, still on 1-wire, during power-consuming tasks. This is not tested, but should naturally work. Because this functionality is really a limited one; BASCOM has no special support for that. But anyway, we tell you about it, just in case you wonder. Strong pull-up has to use one uC pin extra - to drive the MOS-FET. Cable lengths (this section is only for some limitation understanding) For short runs up to 30 meters, cable selection for use on the 1-Wire bus is less critical. Even flat modular phone cable works with limited numbers of 1-Wire devices. However, the longer the 1-Wire bus, the more pronounced cable effects become, and therefore greater importance is placed on cable selection. For longer distances, DS recommends twisted-pair-cable (CAT5). DS standard examples show 100 meters cable lengths, so they say, that's no problem. They also show examples with 300m cabling, and I think I have seen something with 600-meter bus (but I cant find it again). Noise and CRC The longer cable and the noisier environment, the more false readings will be made. The devices are equipped with a CRC-generator - the LSByte of the sending is always a checksum. Look in program examples to learn how to re-calculate this checksum in your uC. AND, if you notice that there are false readings - do something about your cables. (Shield, lower resistor) Transfer speed On the original 1-wire bus, DS says the transfer speed is about 14Kbits /second. And, if that was not enough, some devices has an overdrive option. That multiplies the speed by 10. This is issued by making the communication-time-slots smaller (from 60 uS to 6uS ) which naturally will make the devices more sensitive, and CRC-error will probably occur more often. But, if that is not an issue, ~140Kbit is a reachable speed to the devices. So, whatever you thought before, it is FAST. The BASCOM scanning of the bus is finds about 50 devices / second , and reading a specific sensors value to a uC should be about 13 devices / second. Topology Of the 1w-net - that is an issue we will not cover so much. Star-net, bus-net? It seems like you can mix that. It is a bus-net, but not so sensitive about that. The benefit of the 1-wire bus Each device is individual - and you can communicate with it over the media of 2 wires. Still, you can address one individual device, if you like. Get its value. There are 64 ^ 2 unique identifications-numbers. Naturally, if lot of cables are unwanted, this is a big benefit. And you only occupy 1 processor pin. DS supplies with different types of devices, which all are made for interfacing an uC - directly. No extra hardware. There are sensors, so you can get knowledge about the real world, and there are also potentiometers and relays, so you can do something about it. On the very same bus. And the Ibutton approach from DS (ever heard of it?) is based on 1wire technology. Maybe something to pick up. BASCOM let you use an uC with 1wire-devices so easy, that (since now) that also has to count as a benefit - maybe one of the largest. ;-) The disadvantages of the 1-wire bus So far as I know, DS is the only manufacturer of sensors for the bus. Some people think their devices are expensive. And, until now, it was really difficult to communicate with the devices. Particularly when using the benefit of several devices on one bus. Still some people say that the 1w-bus is slow - but I don't think so. Göte Haluza System engineer Using the SPI protocol Top Previous Next General description of the SPI The SPI allows high-speed synchronous data transfer between the AVR and peripheral devices or between several AVR devices. On most parts the SPI has a second purpose where it is used for In System Programming (ISP). The interconnection between two SPI devices always happens between a master device and a slave device. Compared to some peripheral devices like sensors which can only run in slave mode, the SPI of the AVR can be configured for both master and slave mode. The mode the AVR is running in is specified by the settings of the master bit (MSTR) in the SPI control register (SPCR). Special considerations about the /SS pin have to be taken into account. This will be described later in the section "Multi Slave Systems - /SS pin Functionality". The master is the active part in this system and has to provide the clock signal a serial data transmission is based on. The slave is not capable of generating the clock signal and thus can not get active on its own. The slave just sends and receives data if the master generates the necessary clock signal. The master however generates the clock signal only while sending data. That means that the master has to send data to the slave to read data from the slave. Data transmission between Master and Slave The interaction between a master and a slave AVR is shown in Figure 1. Two identical SPI units are displayed. The left unit is configured as master while the right unit is configured as slave. The MISO, MOSI and SCK lines are connected with the corresponding lines of the other part. The mode in which a part is running determines if they are input or output signal lines. Because a bit is shifted from the master to the slave and from the slave to the master simultaneously in one clock cycle both 8-bit shift registers can be considered as one 16-bit circular shift register. This means that after eight SCK clock pulses the data between master and slave will be exchanged. The system is single buffered in the transmit direction and double buffered in the receive direction. This influences the data handling in the following ways: 1. New bytes to be sent can not be written to the data register (SPDR) / shift register before the entire shift cycle is completed. 2. Received bytes are written to the Receive Buffer immediately after the transmission is completed. 3. The Receive Buffer has to be read before the next transmission is completed or data will be lost. 4. Reading the SPDR will return the data of the Receive Buffer. After a transfer is completed the SPI Interrupt Flag (SPIF) will be set in the SPI Status Register (SPSR). This will cause the corresponding interrupt to be executed if this interrupt and the global interrupts are enabled. Setting the SPI Interrupt Enable (SPIE) bit in the SPCR enables the interrupt of the SPI while setting the I bit in the SREG enables the global interrupts. Pins of the SPI The SPI consists of four different signal lines. These lines are the shift clock (SCK), the Master Out Slave In line (MOSI), the Master In Slave Out line (MISO) and the active low Slave Select line (/SS). When the SPI is enabled, the data direction of the MOSI, MISO, SCK and /SS pins are overridden according to the following table. Table 1. SPI Pin Overrides Pin Direction Overrides Master SPI Mode Direction Overrides Slave SPI Modes MOSI User Defined Input MISO Input User Defined SCK User Defined Input SS User Defined Input This table shows that just the input pins are automatically configured. The output pins have to be initialized manually by software. The reason for this is to avoid damages e.g. through driver contention. Multi Slave Systems - /SS pin Functionality The Slave Select (/SS) pin plays a central role in the SPI configuration. Depending on the mode the part is running in and the configuration of this pin, it can be used to activate or deactivate the devices. The /SS pin can be compared with a chip select pin which has some extra features. In master mode, the /SS pin must be held high to ensure master SPI operation if this pin is configured as an input pin. A low level will switch the SPI into slave mode and the hardware of the SPI will perform the following actions: 1. The master bit (MSTR) in the SPI Control Register (SPCR) is cleared and the SPI system becomes a slave. The direction of the pins will be switched according to Table 1. 2. The SPI Interrupt Flag (SPIF) in the SPI Status Register (SPSR) will be set. If the SPI interrupt and the global interrupts are enabled the interrupt routine will be executed. This can be useful in systems with more than one master to avoid that two masters are accessing the SPI bus at the same time. If the /SS pin is configured as output pin it can be used as a general purpose output pin which does not affect the SPI system. Note: In cases where the AVR is configured for master mode and it can not be ensured that the /SS pin will stay high between two transmissions, the status of the MSTR bit has to be checked before a new byte is written. Once the MSTR bit has been cleared by a low level on the /SS line, it must be set by the application to re-enable SPI master mode. In slave mode the /SS pin is always an input. When /SS is held low, the SPI is activated and MISO becomes output if configured so by the user. All other pins are inputs. When /SS is driven high, all pins are inputs, and the SPI is passive, which means that it will not receive incoming data. Table 2 shows an overview of the /SS Pin Functionality. Note: In slave mode, the SPI logic will be reset once the /SS pin is brought high. If the /SS pin is brought high during a transmission, the SPI will stop sending and receiving immediately and both data received and data sent must be considered as lost. TABLE 2. Overview of SS pin. Mode /SS Config /SS Pin level Description Slave Always input High Slave deactivated Low Slave activated Master Input High Master activated Low Master deactivated Output High Master activated Low As shown in Table 2, the /SS pin in slave mode is always an input pin. A low level activates the SPI of the device while a high level causes its deactivation. A Single Master Multiple Slave System with an AVR configured in master mode and /SS configured as output pin is shown in Figure 2. The amount of slaves, which can be connected to this AVR is only limited by the number of I/O pins to generate the slave select signals. The ability to connect several devices to the same SPI-bus is based on the fact that only one master and only one slave is active at the same time. The MISO, MOSI and SCK lines of all the other slaves are tri stated (configured as input pins of a high impedance with no pull up resistors enabled). A false implementation (e.g. if two slaves are activated at the same time) can cause a driver contention which can lead to a CMOS latch up state and must be avoided. Resistances of 1 to 10 k ohms in series with the pins of the SPI can be used to prevent the system from latching up. However this affects the maximum usable data rate, depending on the loading capacitance on the SPI pins. Unidirectional SPI devices require just the clock line and one of the data lines. If the device is using the MISO line or the MOSI line depends on its purpose. Simple sensors for instance are just sending data (see S2 in Figure 2), while an external DAC usually just receives data (see S3 in Figure 2). SPI Timing The SPI has four modes of operation, 0 through 3. These modes essentially control the way data is clocked in or out of an SPI device. The configuration is done by two bits in the SPI control register (SPCR). The clock polarity is specified by the CPOL control bit, which selects an active high or active low clock. The clock phase (CPHA) control bit selects one of the two fundamentally different transfer formats. To ensure a proper communication between master and slave both devices have to run in the same mode. This can require a reconfiguration of the master to match the requirements of different peripheral slaves. The settings of CPOL and CPHA specify the different SPI modes, shown in Table 3. Because this is no standard and specified different in other literature, the configuration of the SPI has to be done carefully. Table 3. SPI Mode configuration SPI Mode CPOL CPHA Shift SCK edge Capture SCK edge 0 0 0 Falling Rising 1 0 1 Rising Falling 2 1 0 Rising Falling 3 1 1 Falling Rising The clock polarity has no significant effect on the transfer format. Switching this bit causes the clock signal to be inverted (active high becomes active low and idle low becomes idle high). The settings of the clock phase, how-ever, selects one of the two different transfer timings, which are described closer in the next two chapters. Since the MOSI and MISO lines of the master and the slave are directly connected to each other, the diagrams show the timing of both devices, master and slave. The /SS line is the slave select input of the slave. The /SS pin of the master is not shown in the diagrams. It has to be inactive by a high level on this pin (if configured as input pin) or by configuring it as an output pin. A.) CPHA = 0 and CPOL = 0 (Mode 0) and CPHA = 0 and CPOL = 1 (Mode 1) The timing of a SPI transfer where CPHA is zero is shown in Figure 3. Two wave forms are shown for the SCK signal -one for CPOL equals zero and another for CPOL equals one. When the SPI is configured as a slave, the transmission starts with the falling edge of the /SS line. This activates the SPI of the slave and the MSB of the byte stored in its data register (SPDR) is output on the MISO line. The actual transfer is started by a software write to the SPDR of the master. This causes the clock signal to be generated. In cases where the CPHA equals zero, the SCK signal remains zero for the first half of the first SCK cycle. This ensures that the data is stable on the input lines of both the master and the slave. The data on the input lines is read with the edge of the SCK line from its inactive to its active state (rising edge if CPOL equals zero and falling edge if CPOL equals one). The edge of the SCK line from its active to its inactive state (falling edge if CPOL equals zero and rising edge if CPOL equals one) causes the data to be shifted one bit further so that the next bit is output on the MOSI and MISO lines. After eight clock pulses the transmission is completed. In both the master and the slave device the SPI interrupt flag (SPIF) is set and the received byte is transferred to the receive buffer. B.) CPHA = 1 and CPOL = 0 (Mode 2) and CPHA = 1 and CPOL = 1 (Mode 3) The timing of a SPI transfer where CPHA is one is shown in Figure 4. Two wave forms are shown for the SCK signal -one for CPOL equals zero and another for CPOL equals one. Like in the previous cases the falling edge of the /SS lines selects and activates the slave. Compared to the previous cases, where CPHA equals zero, the transmission is not started and the MSB is not output by the slave at this stage. The actual transfer is started by a software write to the SPDR of the master what causes the clock signal to be generated. The first edge of the SCK signal from its inactive to its active state (rising edge if CPOL equals zero and falling edge if CPOL equals one) causes both the master and the slave to output the MSB of the byte in the SPDR. As shown in Figure 4, there is no delay of half a SCK-cycle like in Mode 0 and 1. The SCK line changes its level immediately at the beginning of the first SCK-cycle. The data on the input lines is read with the edge of the SCK line from its active to its inactive state (falling edge if CPOL equals zero and rising edge if CPOL equals one). After eight clock pulses the transmission is completed. In both the master and the slave device the SPI interrupt flag (SPIF) is set and the received byte is transferred to the receive buffer. Considerations for high speed transmissions Parts which run at higher system clock frequencies and SPI modules capable of running at speed grades up to half the system clock require a more specific timing to match the needs of both the sender and receiver. The following two diagrams show the timing of the AVR in master and in slave mode for the SPI Modes 0 and 1. The exact values of the displayed times vary between the different pars and are not an issue in this application note. However the functionality of all parts is in principle the same so that the following considerations apply to all parts. The minimum timing of the clock signal is given by the times "1" and "2". The value "1" specifies the SCK period while the value "2" specifies the high / low times of the clock signal. The maximum rise and fall time of the SCK signal is specified by the time "3". These are the first timings of the AVR to check if they match the requirements of the slave. The Setup time "4" and Hold time "5" are important times because they specify the requirements the AVR has on the interface of the slave. These times determine how long before the clock edge the slave has to have valid output data ready and how long after the clock edge this data has to be valid. If the Setup and Hold time are long enough the slave suits to the requirements of the AVR but does the AVR suit to the requirements of the slave? The time "6" (Out to SCK) specifies the minimum time the AVR has valid output data ready before the clock edge occurs. This time can be compared to the Setup time "4" of the slave. The time "7" (SCK to Out) specifies the maximum time after which the AVR outputs the next data bit while the time "8" (SCK to Out high) the minimum time specifies during which the last data bit is valid on the MOSI line after the SCK was set back to its idle state. In principle the timings are the same in slave mode like previously described in master mode. Because of the switching of the roles between master and slave the requirements on the timing are inverted as well. The minimum times of the master mode are now maximum times and vice versa. SPI Transmission Conflicts A write collision occurs if the SPDR is written while a transfer is in progress. Since this register is just single buffered in the transmit direction, writing to SPDR causes data to be written directly into the SPI shift register. Because this write operation would corrupt the data of the current transfer, a write-collision error in generated by setting the WCOL bit in the SPSR. The write operation will not be executed in this case and the transfer continues undisturbed. A write collision is generally a slave error because a slave has no control over when a master will initiate a transfer. A master, however, knows when a transfer is in progress. Thus a master should not generate write collision errors, although the SPI logic can detect these errors in a master as well as in a slave mode. When you set the SPI option from the Options, Compiler, SPI menu SPCR will be set to 01010100 which means ; enable SPI, master mode, CPOL = 1 When you want to control the various options with the hardware SPI you can use the CONFIG SPI statement. See also: config SPI, Config SPIx, SPISLAVE, SPIINIT, SPIOUT, SPIIN, Using USI (Universal Serial Interface) Using USI (Universal Serial Interface) Top Previous Next The Universal Serial Interface (USI) is a multi purpose hardware resource which provide the basics hardware for various serial communications and is faster and reliable then implementing it in software. You mainly find the USI on ATTINY devices but also for example on ATMEGA169. USI Features: · Two-wire Synchronous Data Transfer � Three-wire Synchronous Data Transfer � Data Received Interrupt � Wakeup from Idle Mode The USI can be used in Two wire mode and in three wire mode: · 2 wire mode --> I2C/TWI · 3 wire mode --> SPI The USI handle only the low level communication. High level communication for example for 2 wire mode (I2C) like address setting, message interpreting or preparing of data needs to be handled by software in the main loop. There are Application Notes from Atmel available: AVR312: Using the USI module as a I2C slave AVR310: Using the USI module as a I2C master The 3 wire mode (SPI) is easier to implement and therefore shown here as an example. The Slave Select (SS) needs to be implemented in software if needed. The USI Pin names are: DI, DO and USCK. AVR319: Using the USI module for SPI communication See also: Using the SPI protocol, SPISLAVE, Using I2C Protocol, confiig TWISLAVE, I2C TWI Slave , USI as TWI Slave Following an example how to use an ATTINY as an SPI Master and another example show an SPI Slave over USI. Example (SPI Master with USI): 1. Configure the port pin's: '---------Using ATTINY as SPI MASTER over USI----------------------------------- Config Portb.2 = Output 'USCK ----> SCK (Slave) Config Portb.1 = Output 'DO ----> SDI (Slave) Config Portb.0 = Input 'DI ----> SDO (Slave) Set Portb.0 Sdo Alias Pinb.0 'Pullup 2. Configure the Slave Select Config Portb.3 = Output 'Slave Select (SS) ----> SEL (Slave) Set Portb.3 Sel Alias Portb.3 3. Configure the 3 wire mode Set Usicr.usiwm0 'Three-wire mode. Uses DO, DI, and USCK pins. 'The Data Output (DO) pin overrides the corresponding bit in the PORTA 'register. However, the corresponding DDRA bit still controls the data direction. 'When the port pin is set as input the pin pull-up is controlled by the PORTA bit. 'The Data Input (DI) and Serial Clock (USCK) pins do not affect the normal port 'operation. When operating as master, clock pulses are software generated by 'toggling the PORTA register, while the data direction is set to output. The 'USITC bit in the USICR Register can be used for this purpose. 4. Function for send or receive a byte over USI (SPI Master mode) Const Usi_clk_low = &B0001_0001 Const Usi_clk_high = &B0001_0011 'Wirte or read a byte over USI in SPI Master Mode Function Usi_byte(usi_out As Byte) As Byte Local I As Byte Usidr = Usi_out 'Byte to write over USI For I = 1 To 8 Usicr = Usi_clk_low 'Toggle the USI Clock to send or receive the single bits over USI (8 Bit) Usicr = Usi_clk_high Next Usi_byte = Usidr 'Byte received over USI End Function 5. call the function to send/receive a byte Reset Sel Usi_return = Usi_byte(my_byte) Set Sel Example (SPI Slave with USI): The following example show how to use an USI of ATTINY85 as SPI SLAVE. (you will also find the SPI Master for this USI of ATTINY85 as SPI SLAVE example) ATXMEGA (SPI Master) <-----SPI------> (SPI Slave over USI) ATTIN85 1. First we configure the USI in Three-wire Mode 2. Setup the USI Overflow Interrupt 3. And wait until the USI Oveflow Interrupt is fired 4. Then we read the USI Data-Register and clear the USI Interrupt flag ' Using USI as an SPI slave with Attiny85 ' The ATTINY85 work with 3.3 V so we can direct connect it to an ATXMEGA ' Following you find also a SPI configuration with an XMEGA as SPI Master which I have tested with this SPI Slave '( Config Spid = Hard , Master = Yes , Mode = 0 , Clockdiv = Clk128 , Data_order = Msb , Ss = Auto 'SS = Auto set the Slave Select (SS) automatically before a print #X or input #X command (including initialization of the pin) 'Master SPI clock = 32MHz/Clk128 = 250KHz Open "SPID" For Binary As #12 ') $regfile = "ATtiny85.DAT" $crystal = 8000000 'internal crystal $hwstack = 32 $swstack = 10 $framesize = 30 Dim B As Byte Dim Usi_data_ready As Bit Config Portb.1 = Output 'DO ---> MISO of ATXMEGA (PD6) Config Portb.2 = Output 'USCK ---> SCK of ATXMEGA (PD7) Set Portb.2 'enable Pullup Config Portb.0 = Input 'DI ---> MOSI of ATXMEGA (PD5) Set Portb.0 'enable Pullup 'We do not use Slave Select in this example but this would be the configuration Config Portb.4 = Input 'Slave Select Set Portb.4 ' enable Pullup Ss Alias Pinb.4 Config Portb.3 = Output 'Serial Debug output Open "comb.3:9600,8,n,1" For Output As #1 Print #1 , "serial output" 'Init USI as SPI Slave in USICR = USI Control Register Set Usicr.usiwm0 'Three-wire mode. Uses DO, DI, and USCK pins. Set Usicr.usics1 'Clock Source: External, positive edge ; External, both edges Set Usicr.usioie 'USI Counter Overflow Interrupt Enable On Usi_ovf Usi_overflow_int Enable Usi_ovf Enable Interrupts Do If Usi_data_ready = 1 Then Reset Usi_data_ready Print #1 , B 'print the received byte over debug output End If Loop End 'end program ' After eight clock pulses (i.e., 16 clock edges) the 4-Bit USI counter will generate an overflow interrupt ' A USI Overflow Int can also wakeup the Attiny from Idle mode if needed Usi_overflow_int: Set Usi_data_ready B = Usidr Usisr = &B01_000000 'Reset Overflow Flag and reset 4-Bit USI counter Return SPI Master for the ATTIN85 as SPI Slave over USI: 'This is the SPI MASTER for the ATTINY85 with USI in SPI Slave Mode $regfile = "xm256a3bdef.dat" $crystal = 32000000 '32MHz $hwstack = 64 $swstack = 40 $framesize = 80 Config Osc = Disabled , 32mhzosc = Enabled Config Sysclock = 32mhz '--> 32MHz 'configure the priority Config Priority = Static , Vector = Application , Lo = Enabled , Med = Enabled Enable Interrupts Config Com7 = 57600 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 Waitms 2 Open "COM7:" For Binary As #1 Print #1 , Print #1 , "------------SPI MASTER-Slave Test----------------" 'We use Port D for SPI Config Pind.7 = Output Config Pind.6 = Input Config Pind.5 = Output Config Pind.4 = Output 'Bit7 = SCK = Output ------> USCK (ATTINY85) (PinB.2) 'Bit6 = MISO = Input ------> DO (ATTINY85) (PinB.1) 'Bit5 = MOSI = Output ------> DI (ATTINY85) (PinB.0) 'Bit4 = SS = Output ------> SS (ATTINY85) (PinB.4) Slave_select Alias Portd.4 Set Slave_select Portd_pin4ctrl = Bits(3 , 4) ' Enalbe Pullup Dim Bspivar As Byte Dim Spi_send_byte As Byte Dim Spi_receive_byte As Byte Dim Spi_master_want_send As Byte 'SPI, Master|Slave , MODE, clock division Config Spid = Hard , Master = Yes , Mode = 0 , Clockdiv = Clk128 , Data_order = Msb , Ss = Auto 'SS = Auto set the Slave Select (SS) automatically before a print #X or input #X command (including initialization of the pin) 'Master SPI clock = 32MHz/Clk128 = 250KHz Open "SPID" For Binary As #12 Main: Do Wait 3 'Every 3 seconds Incr Spi_send_byte Print #1 , "Spi_send_byte = " ; Spi_send_byte 'SEND TO SLAVE Print #12 , Spi_send_byte 'SEND one BYTE TO SLAVE Waitms 10 Input #12 , Spi_receive_byte Print #1 , Spi_receive_byte Loop End 'end program 'there is NO CLOSE for SPI ' Power Up Top Previous Next At power up all ports are in Tri-state and can serve as input pins. When you want to use the ports (pins) as output, you must set the data direction first with the statement : CONFIG PORTB = OUTPUT Individual bits can also be set to be used as input or output. For example : DDRB = &B00001111 , will set a value of 15 to the data direction register of PORTB. PORTB.0 to PORTB.3 (the lower 4 bits) can be used as outputs because they are set high. The upper four bits (PORTB.4 to PORTB.7), can be used for input because they are set low. You can also set the direction of a port pin with the statement : CONFIG PINB.0 = OUTPUT | INPUT The internal RAM is cleared at power up or when a reset occurs. Use $NORAMCLEAR to disable this feature. You may use $INITMICRO to set a port level and direction immediately on startup. EM4095 RFID Reader Top Previous Next Introduction RFID technology is an exciting technology. The EM4095 chip allows us to create a reader with little code or processor resources. A complete KIT is available from the web shop at www.mcselec.com This topic describes the reference design. The data sheets you can download from: EM4095 (chip) , EM4102 (transponder) The circuit As you can see from the data sheets, the EM4095 needs little external hardware. A coil, capacitors that tune the coil for 125 KHz, are basically all that you need. IC1 is a voltage regulator that regulates the input voltage to 5V. (you can operate it from a 9V battery). The capacitors stabilize the output voltage. The DEMOD output of the EM4095 is connected to the microprocessor and the pin is used in input mode. The MOD and SHD pins are connected to micro pins that are used in output mode. The micro(mega88) has a small 32 KHz crystal so the soft clock can be used. There are 3 switches that can be used for menu input, and there is a relay that can be used to activate a door opener. Parallel on the relay there is a LED for a visible indication. IC4 is a serial interface buffer so we can connect the PCB to our computer for logging and programming. The Mega88 is delivered with a Boot loader and thus can be serial programmed with the MCS Boot loader. That is why pin 4 of X6 (DTR) is connected via IC4(pin 8-9) to the reset pin of the micro(pin 1). Further there is a standard 10-pins ISP programmer connector for the USB-ISP or STK200, and an LCD connector for an optional LCD display. The PCB Part list Component Value C1 470uF/25V C2,C3,C5,C6,C9,CDEC,CAGND 100nF (104) C4 100uF/16V CRES1,CRES, CDV2 1nF(102) CDV1 47pF CDC2,CFCAP 10nF(103) C11,C12,C13,C14 1uF/16V RSER 68 R4,R6 10K R5 470 R8 47 R3 47K R9 1K-10K pot IC1 7805 IC2 EM4095 IC3 ATMEGA88 IC4 MAX232 20 pin IC feet, 16 pin IC feet X1,X2 2-pin header X3 16 pin boxed header X4 3-pin header X5 10-pin boxed header X6 DB-9 female connector T1 BC547 D1 1N4148 LED1 3 mm LED, red K1 Relay, 5V S1,S2,S3 switch Q1 32768 Hz crystal Antenna M3x6 bolt and nut 4 rubber feet Building the PCB As usually we start with the components that have the lowest height. And normally we would solder all passive components first, and insert/solder the active components last. This to prevent damage to the active components(IC). But since the EM4095 is only available in SMD, we need to solder this chip first. Make sure the chip is lined out right and that pin 1 matches the small dot on the chip which is an indication for pin 1. Then solder pin 1 and 16 so the chip can not be moved anymore. Now solder the remaining pins. Use an iron with a small tip. When you use too much solder, and two feet are soldered together do not panic. Just finish soldering and when ready, use some copper braid to remove the solder between the 2 feet. This works best when you lay the braid over the 2 pins, then push the solder iron to the braid so it will heat up. Then after some seconds, add some solder which will get sucked into the braid. This will in turn suck the other solder into the braid. While it does not seem logical to add solder, it will conduct the heat better. But since the used SMD chip is relatively large there should not be any problem. Now mount and solder the following components : · RSER (68 ohm) · R3 (47K) · R4,R6 (10 K) · R5 (470) · R8 (47 for LCD) · D1 (diode 1N4148). The black line must match the line on the PCB(Kathode) · C2,C3,C5,C6,C9,CDEC,CAGND (100 nF) · CRES1,CRES , CDV2 (1nF) · CDV1 (47pF) · CDC2,CFCAP (10nF) · 28 pins IC feet for the Mega88 and 16 pins IC feet for the MAX232 · Bend the wires of IC1 and mount IC1 with the bolt and nut · Bend the wires of the crystal and mount Q1 · S1,S2,S3 (switches) · LED1. The square pad matches the longest wire of the LED(Anode) · R9 (potmeter for LCD contrast) · T1(transistor BC547) · Boxed header X5 and X3. Notice the gap in the middle which must match with the PCB · X6 (DB9-female connector) · K1 (relay) · C11,C12,C13,C14 (1uF/16V) · C4 (100uF/16V) · X1,X2 (2 pins screw connectors) · X4 (3 pin screw connector) · C1 (470 uF/25V) · 4 rubber feet Operation Now the PCB is ready. Make sure there are no solder drops on the PCB. You can measure with an Ohm-meter if there is a short circuit. Measure pin 1 and pin 2 of IC1 (the voltage input) and pin 3 and pin 2 of IC1 (the voltage output). When everything is ok, insert the MAX232 and the MEGA88. You can connect the battery cord to header X1. The red wire is the plus. Since the circuit is not for beginners, there is no reverse polarity protection. While the 7805 does not mind a short circuit, the C1 elco might not like it. Connect the battery and measure with a Volt meter if IC1 actual outputs 5V. If not, check the input voltage, and for a possible shortcut. Connect the antenna to connector X2. The PCB is now ready for use. When you have the LCD display, connect it to the LCD header and adjust the variable resistor R9 so you can see square blocks. Since the chip has a boot loader, you can serial program the device. We made a simple AN that can be used as a door opener. It has simple menu, and we can add new tags. When a valid tag is held in front of the antenna, it will activate the relay for 2 seconds. The LED will be turned on as well. Compile the program AN_READHITAG_EM4095.BAS and select the MCS Boot Loader programmer. Connect a serial cable to X6 and press F4 to program. You need a normal straight cable. When you did not used the MCS Bootloader before, check the COM port settings and make sure the BAUD is set to 38400 as in the following screenshot: You also need to set 'RESET via DTR' on the 'MCS Loader' TAB. Now the program will start and show some info on the LCD. Each time you hold a RFID tag before the antenna/coil, the TAG ID will be shown. When you press S3, you can store an RFID. Press S3, and then hold the TAG before the coil. When there is room , or the tag is new, it will be stored. Otherwise it will be ignored. The TAG ID is also stored in EEPROM. Now when you hold the tag before the coil, the relay is activated for 2 seconds. The AN is very simple and you can change and extend it easily. One nice idea from Gerhard : use one TAG as a master tag to be able to add/remove tags. Security To make the code more secure you could add a delay so that a valid tag must be received twice, so after the valid TAG, wait 1 second, and then start a new measurement and check if the TAG is valid again. This will prevent where a bit generator could be used to generate all possible codes. With 64 bit times a second, it would take ages before it would work. The other hack would be to listen with a long range 125 KHz antenna, and recording all bits. A long range scanner would be very hard to make. It would be easier to open the door with a crowbar. When you open your door with this device, make sure you have a backup option like a key in case there is no power. Also, when the door is opened by a magnetic door opener, make sure it has the right quality for the entrance you want to protect. AN Code '------------------------------------------------------------------------------- ' (c) 1995-2016 MCS Electronics ' This sample will read a HITAG chip based on the EM4095 chip ' Consult EM4102 and EM4095 datasheets for more info '------------------------------------------------------------------------------- ' The EM4095 was implemented after an idea of Gerhard Günzel ' Gerhard provided the hardware and did research at the coil and capacitors. ' The EM4095 is much simpler to use than the HTRC110. It need less pins. ' A reference design with all parts is available from MCS '------------------------------------------------------------------------------- $regfile = "M88def.dat" $baud = 19200 $crystal = 8000000 $hwstack = 40 $swstack = 40 $framesize = 40 Declare Function Havetag(b As Byte ) As Byte 'Make SHD and MOD low _md Alias Portd.4 Config _md = Output _md = 0 _shd Alias Portd.5 Config _shd = Output _shd = 0 Relay Alias Portd.2 Config Relay = Output S3 Alias Pinb.0 S2 Alias Pinb.2 S1 Alias Pinb.1 Portb = &B111 ' these are all input pins and we activate the pull up resistor Config Clock = Soft 'we use a clock Config Date = Dmy , Separator = - Enable Interrupts ' the clock and RFID code need the int Date$ = "15-12-07" ' just a special date to start with Time$ = "00:00:00" 'Config Lcd Sets The Portpins Of The Lcd Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0 Config Lcd = 16 * 2 '16*2 type LCD screen Cls Lcd " EM4095 sample" Lowerline : Lcd "MCS Electronics" Dim Tags(5) As Byte 'make sure the array is at least 5 bytes Dim J As Byte , Idx As Byte Dim Eramdum As Eram Byte ' do not use first position Dim Etagcount As Eram Byte ' number of stored tags Dim Etags(100) As Eram Byte 'room for 20 tags Dim Stags(100) As Byte 'since we have enough SRAM store them in sram too Dim Btags As Byte , Tmp1 As Byte , Tmp2 As Byte Dim K As Byte , Tel As Byte , M As Byte Config Hitag = 64 , Type = Em4095 , Demod = Pind.3 , Int = @int1 Print "EM4095 sample" 'you could use the PCINT option too, but you must mask all pins out so it will only respond to our pin ' Pcmsk2 = &B0000_0100 ' On Pcint2 Checkints ' Enable Pcint2 On Int1 Checkints Nosave 'we use the INT1 pin all regs are saved in the lib Config Int1 = Change 'we have to config so that on each pin change the routine will be called Enable Interrupts 'as last we have to enable all interrupts 'read eeprom and store in sram 'when the program starts we read the EEPROM and store it in SRAM For Idx = 1 To 100 'for all stored tags Stags(idx) = Etags(idx) Print Hex(stags(idx)) ; ","; Next Btags = Etagcount ' get number of stored tags If Btags = 255 Then ' an empty cell is FF (255) Print "No tags stored yet" Btags = 0 : Etagcount = Btags ' reset and write to eeprom Else ' we have some tags For J = 1 To Btags Tmp2 = J * 5 'end Tmp1 = Tmp2 - 4 'start Print "RFID ; " ; J ' just for debug For Idx = Tmp1 To Tmp2 Print Hex(stags(idx)) ; ","; Next Print Next End If Do Print "Check..." Upperline : Lcd Time$ ; " Detect" If Readhitag(tags(1)) = 1 Then 'this will enable INT1 Lowerline For J = 1 To 5 Print Hex(tags(j)) ; ","; Lcd Hex(tags(j)) ; "," Next M = Havetag(tags(1)) 'check if we have this tag already If M > 0 Then Print "Valid TAG ;" ; M Relay = 1 'turn on relay Waitms 2000 'wait 2 secs Relay = 0 'relay off End If Print Else Print "Nothing" End If If S3 = 0 Then 'user pressed button 3 Print "Button 3" Cls : Lcd "Add RFID" Do If Readhitag(tags(1)) = 1 Then 'this will enable INT1 If Havetag(tags(1)) = 0 Then 'we do not have it yet If Btags < 20 Then 'will it fit? Incr Btags 'add one Etagcount = Btags Idx = Btags * 5 'offset Idx = Idx - 4 Lowerline For J = 1 To 5 Lcd Hex(tags(j)) ; "," Stags(idx) = Tags(j) Etags(idx) = Tags(j) Incr Idx Next Cls Lcd "TAG stored" : Waitms 1000 End If End If Exit Do End If Loop End If If S2 = 0 Then Print "Button 2" End If If S1 = 0 Then Print "Button 1" End If Waitms 500 Loop 'check to see if a tag is stored already 'return 0 if not stored 'return value 1-20 if stored Function Havetag(b As Byte ) As Byte Print "Check if we have TAG : "; For K = 1 To 5 Print Hex(b(k)) ; "," Next For K = 1 To 20 Tmp2 = K * 5 'end addres Tmp1 = Tmp2 - 4 'start Tel = 0 For Idx = Tmp1 To Tmp2 Incr Tel If Stags(idx) <> B(tel) Then 'if they do not match Exit For 'exit and try next End If Next If Tel = 5 Then 'if we did found 5 matching bytes we have a match Print "We have one" Havetag = K 'set index Exit Function End If Next Havetag = 0 'assume we have nothing yet End Function Checkints: Call _checkhitag 'in case you have used a PCINT, you could have other code here as well Return Tips and Tricks The oscillator frequency must be 125 KHz. You can measure this with an oscilloscope. It is possible that you need to remove a few windings of the antenna coil to get an exact 125 KHz. This will result in a higher distance that you can use for the tags. AVR Top Previous Next This topic describes some general hardware related problems that were found by users. Unexpected brown out - Processors with analog ports (used for A/D) are connected to AVCC and not VCC. This can cause the brown out detection to trigger. For example this is true for the Mega1284 PORTC. Using the ports to switch a small load would trigger the brown out while using a different port, powered from VCC would not give this problem. Errata The Errata you will find in the data sheet of the processor. It contains information about bugs in the hardware. Some times there are work around's, and some times there is no solution. It is a good idea to read the Errata BEFORE you begin to use the processor for a new design. AT86RF401 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. AT90CAN32 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. AT90CAN128 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. AT90S1200 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. AT90S2313 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. The ATTiny2313 should be used for new designs. AT90S2323 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. AT90S2333 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. AT90S2343 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. [tip from Martin Verschuren] When using the AT90S2343 with BASCOM-AVR 1.11.6.4 and the STK200. Programming must be done with jumper ext-clk. The BASCOM build in programmer will detect a Tiny22, which seems to have the same ID string as the 2343 (Atmel source) so no wonder. By using the internal clock RCEN=0, then the jumper of the STK200 must be on int.clk after programming. Don't leave this away, some AT90S2343 will not correctly startup. In your own project notice that you have to pull up the clk pin(2) at power up else it won't work. (I just looked for it for a day to get this problem solved:-) Note : the at90s2343 and tiny22 have the same chip ID. In BASCOM you need to choose the tiny22 even if you use the 2343. I note from MCS : only the AT23LS43-1 has the internal oscillator programmed by default! All other 2343 chips need an external clock signal. Tip: use a AT90S2313 and connect X2 to the clock input of the 2343. [tip from David Chambers] Using the AT90S2343 with BASCOM 1.11.7.3 the DT006 hardware there are no problems with programming the chip ie no special jumper conditions to enable programming. However it is best to remove links connecting ports to the DT006 LED�s before programming. If access to PB3 and PB4 is desired then jumpers J11 & J12 must be installed with pins 2 and 3 linked in both cases. Note that PB3 and PB4 are each connected to a momentary pushbutton on the DT006 board. These can be used to check contact closure functions, so bear this in mind when writing code for contact monitoring. The current ATMEL data sheet specifies that all versions �1, -4 and �10 are supplied with a fuse bit set for the internal clock that operates at approximately 1Mhz. If using the internal clock make sure to enter 1000000 under Options\Compiler\Communication\frequency. A great little chip with minimal external components. Only the resistor and capacitor required for RESET during power up. Note that the LED�s on the DT006 are not connected to the same programmed port pins when changing the chip type. This is because the special functions assigned ports varies between the 8pin, 20 pin and 28 pin products eg the MOSI, MISI and SCK functions are assigned to PB0, PB1 and PB2 for an 8 pin processor and PB5, PB6 and PB7 for a 20 pin processor. The result is that for a given program the LED�s that respond are different. AT90S4414 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. AT90S4433 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. AT90S4434 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. AT90S8515 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. AT90S8535 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. AT90PWM2-3 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. AT90PWM216 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. AT90US82 Top Previous Next The USB82 is supported by the optional USB Add On. PORTC.4 is used to sense the power of the USB bus. AT90USB162 Top Previous Next The USB162 is supported by the optional USB Add On. PORTC.4 is used to sense the power of the USB bus. AT90USB646 Top Previous Next AT90USB1286 Top Previous Next AT90USB1287 Top Previous Next ATTINY12 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATTINY13 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATTINY13A Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATTINY15 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATTINY20 Top Previous Next The ATTINY20 is a 14 pins AVR chip. It has NO EEPROM. It also does not have a UART. The TWI slave interface is not compatible with TWI found in other AVR chips. The chip has a PDI programming interface and does not support ISP or JTAG. The watchdog is also different compared to other AVR chips. It is using a CCP register which is similar as the Xmega. The processor also only has 16 registers (R16-R31) and is missing registers R0-R15. This does not make the chip a good choice for using with BASCOM since BASCOM uses the lower registers as well. ATTINY22 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATTINY24 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. The data sheet does not specify that HWMUL is supported. The DAT file reflect this : HWMUL=0 ; this chip does not have hardware multiplication Some users reported that the HWMUL did work. Some batches might support the HW MUL, but since we found chips that did not, the value is set to 0. You can change it at your own risk. ATTINY25 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATTINY26 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATTINY43U Top Previous Next ATTINY44 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. The data sheet does not specify that HWMUL is supported. The DAT file reflect this : HWMUL=0 ; this chip does not have hardware multiplication Some users reported that the HWMUL did work. Some batches might support the HW MUL, but since we found chips that did not, the value is set to 0. You can change it at your own risk. ATTINY45 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATTINY48 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. Notice that the TINY48 is NOT the same as the MEGA48. The TINY48 does not have a UART. ATTINY84 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. The data sheet does not specify that HWMUL is supported. The DAT file reflect this : HWMUL=0 ; this chip does not have hardware multiplication Some users reported that the HWMUL did work. Some batches might support the HW MUL, but since we found chips that did not, the value is set to 0. You can change it at your own risk. ATTINY85 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATTINY87 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. The TINY167/87 have a special LIN/UART. In version 2077 this UART is supported in normal mode. Buffered input/output is not supported. ATTINY88 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. Notice that the TINY88 is NOT the same as the MEGA88. The TINY88 does not have a UART. ATTINY167 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. The TINY167/87 have a special LIN/UART. In version 2077 this UART is supported in normal mode. Buffered input/output is not supported. ATTINY261 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATTINY441 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATTINY461 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. The processor has only one PCINT interrupt. But there are two PCINT interrupt masks to serve all the PCINTx pins. Most processors have their own interrupt for each PCINT mask register so you have better control over the different pins which caused the interrupt. Since there is only one interrupt, the ENABLE and DISABLE statements, set/reset both the PCIE0 and PCIE1 flags in the GIMSK register. You still have to set the PCMSK0 and PCMSK1 registers to specify which bits can cause a PCINT interrupt. ATTINY828 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATTINY841 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATTINY861 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. The processor has only one PCINT interrupt. But there are two PCINT interrupt masks to serve all the PCINTx pins. Most processors have their own interrupt for each PCINT mask register so you have better control over the different pins which caused the interrupt. Since there is only one interrupt, the ENABLE and DISABLE statements, set/reset both the PCIE0 and PCIE1 flags in the GIMSK register. You still have to set the PCMSK0 and PCMSK1 registers to specify which bits can cause a PCINT interrupt. ATTINY1634 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATTINY2313 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. The tiny2313 has an internal oscillator that can run at various frequencies. The 4 MHz seems not to work precise. when using the UART for serial communication you can get wrong output. You can best use the 8 MHz internal oscillator , or tweak the UBRR register. For example, UBRR=UBRR+1 That worked for 4 Mhz, at 19200 baud. ATTINY2313A Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATTINY4313 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. The tiny4313 has an internal oscillator that can run at various frequencies. The 4 MHz seems not to work precise. when using the UART for serial communication you can get wrong output. You can best use the 8 MHz internal oscillator , or tweak the UBRR register. For example, UBRR=UBRR+1 That worked for 4 Mhz, at 19200 baud. ATTINY4313A Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA8, Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA8A Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA8U2 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA16 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA16A Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA16U2 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA16U4 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA16M1 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA32 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA32A Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA32C1 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA32M1 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. - FOR ISP programming, notice that pin PD.2, PD.3 and PD4 are used. ATMEGA32U2 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA32U4 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA48 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA48P Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA48PB Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. NO DIP version available ATMEGA64 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA64C1 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA64M1 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA88 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA88A Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA88P Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA88PB Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. NO DIP version available ATMEGA103 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA128 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. - When using XRAM and IDLE, the micro need the CONFIG XRAM after returing from the power down mode. - The register mapping for PORTF is not in sequence. Which means that PINF, DDRF and PORTF are not placed in memory after each other. This has some impact on some of the functions that use the ability. 1wire and soft i2c for example. But also serin will not work. It is best to use PORTF for normal digital tasks. ATMEGA128RFA1 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA161 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA162 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. The M162 has a clock-16 divider enabled by default. See the M162.bas sample file ATMEGA163 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. The M163 by default uses the internal clock running at 1 MHz When you have problems with timing set the right fuse bit A987= 0101. This will solve this problem. I have just found a small difference in PortB when using the Mega163 in place of a 8535. The difference is in regard to PortB.4 - PortB.7 when not used as a SPI interface. The four upper bits of PortB are shared with the hardware SPI unit. If the SPI is configured in SLAVE mode (DEFAULT) the MOSI , SCK , /SS Are configured as inputs, Regardless of the DDRB setting ! The /SS (slave select) pin also has restrictions on it when using it as a general input.- see data sheet ATmega163 - p57. This sample allows you to use the upper nibble of PortB as outputs. Portb = &B0000_0000 DDRB = &B1111_0000 'set upper bits for output. Spcr = &B0001_0000 ' set SPI to Master and Disable. If The SPCR register is not set for Master, you cannot set the pins for Output. ATMEGA164P Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. While the data sheet might make you believe this processor has a TIMER3, there is NO TIMER3 in the MEGA164. You need a MEGA1284 when you need a TIMER3. ATMEGA164PA Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. While the data sheet might make you believe this processor has a TIMER3, there is NO TIMER3 in the MEGA164. You need a MEGA1284 when you need a TIMER3. ATMEGA165 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA165A Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA168 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA168P Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA168PB Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. NO DIP version available ATMEGA169 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA169P Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA169PA Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA323 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. The JTAG interface is enabled by default. This means that portC.2-portC.5 pins can not be used. Program the JTAG fuse bit to disable the JTAG interface. ATMEGA324A Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA324P Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA324PA Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA324PB Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. . There is a bug in the chip : When you configure the second UART, the timer1 channel B will not work. This info came from microchip : Yes, your observation is correct. It is a known device bug. We already report this bug to our concern team. This is due to the fact that timer 1 channel B is shared with XCK1 pin of UART1 Usually this functionality should take priority over timer 1 channel B only when UART is configured in Synchronous mode but after discussing with our internal team confirmed that timer 1 channel B is disconnected based on UART1 activation No matter even if the UART is configured in Asynchronous mode(in which case there is no use of XCK1) timer 1 channel B still gets disconnected. This issue also presents in UART2 XCK2/OC2A. ATMEGA325 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA328 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA328P Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA328PB Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. Notice that this processor is compatible with M328 but that extra pins have been added at location of VCC/GND. ATMEGA329 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA406 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. The image is from a preliminary data sheet. It is not clear yet if SCL and SDA have pin names too. This chip can only programmed parallel and with JTAG. Normal (serial) ISP programming is not available. ATMEGA603 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. When you have a better image available, please send it to support@mcselec.com ATMEGA640 Top Previous Next . ATMEGA644 Top Previous Next ATMEGA644P Top Previous Next Notice that there are Mega644 and Mega644P chips. P stand for PICO power. You should use the P-version for new designs. These Pico version usual add some functionality such as a second UART. ATMEGA644PA Top Previous Next Notice that there are Mega644 and Mega644P chips. P stand for PICO power. You should use the P-version for new designs. These Pico version usual add some functionality such as a second UART. ATMEGA645 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA649 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA649PA Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA1280 Top Previous Next ATMEGA1281 Top Previous Next ATMEGA1284 Top Previous Next The M1284 seems to have an internal problem where large amounts of serial data can choke the processor. A capacitor of 100pF on the RX pin to ground can solve this problem. More info : http://www.mcselec.com/index2.php?option=com_forum&Itemid=59&page=viewtopic&p=60860#60860 PORTC is connected to AVCC and not VCC. This can cause the brown out detection to trigger. ATMEGA1284P Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. The M1284 seems to have an internal problem where large amounts of serial data can choke the processor. A capacitor of 100pF on the RX pin to ground can solve this problem. More info : http://www.mcselec.com/index2.php?option=com_forum&Itemid=59&page=viewtopic&p=60860#60860 ATMEGA2560 Top Previous Next ATMEGA2561 Top Previous Next ATMEGA3250P Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA6450P Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATMEGA8515 Top Previous Next ATMEGA8535 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATXMEGA Top Previous Next The ATXMEGA is a great new chip. It has a lot of hardware on board and a huge amount of hardware registers. Some changes in the architecture are however breaking compatibility with normal AVR (ATMEGA/ATTINY) processors. Dont miss the FAQ - ATXMEGA section below ! The ATXMEGA bring a huge amount of interfaces like UART, I2C, SPI, Counter/Timer, 12-Bit Analog Input/Output and also new features like DMA (Direct Memory Access), the Event System or AES hardware encryption/decryption. Regarding more infos on ATXMEGA ANALOG DIGITAL CONVERTER (ADC) see here: CONFIG ADCX All ATXMEGA have their registers at the same address. Some chips might not have all registers because the hardware is not inside the chip, but all DAT* files are similar. And all hardware has a fixed offset. This allows to use dynamic code. For example Bascom-AVR can now use a variable for the UART and the code is only needed once because all hardware has a fixed offset. * DAT files are the register files. The register files are stored in the BASCOM-AVR application directory and they all have the DAT extension. The register file holds information about the chip such as the internal registers and interrupt addresses. The register file info is derived from ATMEL definition files. The ATXMEGA work with 3.3V so please do not connect something which output 5V to the XMEGA Pin's. Use a Level Shifter for that. The maximum rating for a ATXMEGA Pin is 3.6 V. When using the internal 32MHz oscillator you need at least 2.7V Vcc. The internal 32MHz oscillator is stable enough for a lot of applications. The maximum CPU Clock Frequency is 12MHz when using the XMEGA with just 1.6V Vcc. Read Application Note AVR1012: XMEGA A Schematic Checklist for special considerations in your hardware design. You can find Bascom samples for ATXMEGA in Bascom-AVR folder: · General samples ��..\BASCOM-AVR\SAMPLES\XMEGA · Bootloader samples in ���\BASCOM-AVR\SAMPLES\BOOT · For chips like xm128a1 in ��.\BASCOM-AVR\SAMPLES\CHIPS Manuals for ATXMEGA: There are 2 manuals available from ATMEL for every ATXMEGA Chip 1. One Family Manual like for example for a ATXMEGA128A1 it is Atmel AVR XMEGA A Manual 2. Another Manual for the single chips like for example for an ATXMEGA128A1 it is the ATxmega64A1/128A1/192A1/256A1/384A1 Manual. In this Manual you find for example the Alternate Pin Functions. So you can find which Pin on Port C is the SDA and SCL Pin when you want to use the I2C/TWI Interface of this Port. Beside the Manuals for the ATXMEGA chips there are a lot of Appliaction Notes available on the ATMEL website which explain for example the ATXMEGA Event System or Direct Memory Access (DMA) and so forth. What you need to get started with ATXMEGA and BASCOM-AVR 1. The latest Bascom-AVR FULL Version (The Demo Version of Bascom-AVR do not support ATXMEGA). 2. An evaluation board like the Atmel AVR XMEGA® Xplained evaluation kit or any other ATXMEGA evaluation board with PDI (Program and Debug Interface) header. 3. A Programmer like AVRISP MKII or any other PDI or JTAG programmer which support ATXMEGA. 4. Latest AVR-Studio 4.X or 5.X only for setting fuse bits and to flash Bootloader to ATXMEGA. 5. Programming the ATXMEGA can be done direct from BASCOM-IDE. See also LIBUSB for further information. The most important parts of an Bascom-AVR Program for XMEGA are: 1. The Register file for the chip, crystal init and Stacks $regfile = "xm128a1def.dat" $crystal = 32000000 '32MHz $hwstack = 64 $swstack = 40 $framesize = 64 2. Enable and configure the oscillator of your choice: Config Osc = Enabled , 32mhzosc = Enabled ' enable 2 MHz and 32 MHz internal oscillators 3. Select the oscillator source for the system clock and prescaler (this must match with $crystal = XXXXXX). The following configure the internal 32MHz oscillator as system clock without prescaler so the system clock is 32MHz which match with $crystal = 32000000 Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 4. If you intend to use interrupts you need to configure it before you use the Enable Interrupt command. Bascom-AVR will automatically enable the medium level interrupt when Enable Interrupt is in the code but not the low and high level interrupts. Config Priority = Static , Vector = Application , Lo = Enabled , Med = Enabled , Hi = enabled 5. Also when you want to use EEPROM you need to configure it before you can use it: Config Eeprom = Mapped 'Setup memory mode for EEPROM in XMEGA 6. After this you can add Enable Interrupts and your code in the Main Loop. Do 'Insert your code Loop 7. End End 'end program A first simple program with ATXMEGA which toggle an output every second: $regfile = "xm64a3def.dat" $crystal = 32000000 $hwstack = 40 $swstack = 16 $framesize = 32 Config Osc = Enabled , 32mhzosc = Enabled Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 Config Portb = Output Do toggle Portb.0 Waitms 1000 loop end 'end program FAQ - ATXMEGA Q: How to set clock source and clock frequency with ATXMEGA ? A: See CONFIG OSC and CONFIG SYSCLOCK Q: Do I need to set the XMEGA fuses to get started ? A: No, to get started there is no need to set the fuses because opposed to megaAVR or ATTINY, where fuses are used to set the clock source and frequency you can set the clock source and frequency in the program by Bascom-AVR. You also do not need an external clock source. You can use the internal 32MHz or 2MHz RC oscillator as clock source. Q: Which Interrupt Level (Low, Med, High) is used when I do not specify the priority ? A: MED is used when the priority is not specified. Q: Is AVR-DOS supported for XMEGA ? A: Yes, see AVR-DOS File System Q: What else is supported (Status: Bascom-AVR 2.0.7.6) where users of Bascom-AVR forum asked for ? A: Following list: - 1-WIRE, EEPROM, XRAM, Event System, Config Servos, AVR-DOS SDHC driver, DCF77, RTC32, - INP/OUT support Xmega huge memory, xmega LCD simulation, dmxslave, RS-485, pulsein, pulseout, DMA - Bascom Simulator, Event System, getrc5, CONFIG POWER_REDUCTION, buffered serial output (com1-com4) - virtual portmap config, config tcXX for xmega timers, xmega comparator, $forcesofti2c will force the xmega to use software i2c - AES encyption/decryption, xmega TWI, SPI, UART Q: Where do I find which pin of ATXMEGA is SDA and SCL ? A: There are 2 manuals available from ATMEL 1. One Family Manual like for example for a ATXMEGA128A1 it is Atmel AVR XMEGA A Manual 2. Another Manual for the single chips like for example for an ATXMEGA128A1 it is the ATxmega64A1/128A1/192A1/256A1/384A1 Manual. In this Manual you find for example the Alternate Pin Functions. So you can find which Pin on Port C is the SDA and SCL Pin when you want to use the I2C/TWI Interface of this Port. Q: How to program/flash an ATXMEGA ? A: There is no ISP programming support. Only JTAG and PDI is supported. Of course the MCS Bootloader can be used but you need to program the chip first with for example an AVRISP MKII programmer. After this programming the ATXMEGA can be done direct from BASCOM-IDE Important is also that the AVRISP MKII programmer need 3.3V supply voltage from the Target. Q: Is there a special boot loader source code I can use for ATXMEGA ? A: There are example boot loader in following Bascom-AVR folder (C:\......\BASCOM-AVR\SAMPLES\BOOT) like ATXMEGA32A4 or ATXEMGA128A1. For other ATXMEGA Chips the source code can be easily adapted. Q: What is the Program and Debug Interface (PDI) ? A: The Program and Debug Interface (PDI) is an Atmel proprietary interface for external programming and on-chip debugging of a device. �The XMEGA doesn�t have the SPI based In-System Programming (ISP) interface for external programming, which has been used for megaAVR. Nor does it have the debugWIRE interface. These have been replaced by a two wire �Programming and Debugging Interface� (PDI).� [from Atmel App Note AVR1005] Q: How to read/write from/to ATXMEGA Register ? A: If you want or need to write or read ATXMEGA Registers direct you just need to find the name by using the ATXMEGA DAT file. For example if you want to read the ATXMEGA Revision there is the register Mcu_revid in the DAT file. The DAT files can be found in the BASCOM-AVR folder. Take care with protected registers. Before you can write to this registers you need to release it. An example for this is the Software Reset. Q: How to initiate a software Reset of an ATXMEGA ? A: Before you can write the Software Reset Bit you need to release the write protection for this bit and register. 'enable change of protected Registers for following 4 CPU Instruction Cycles CPU_CCP = &HD8 'Initiate Software Reset by setting Bit0 of RST_CTRL Register Rst_ctrl.0 = 1 'When this bit is set a software reset occur Q: How are External Interrupts (Port Interrupt) used with ATXMEGA ? A: Each XMEGA port (like PortA or PortF) with pin's from Pin0....Pin7 has 2 interrupts (INT0 and INT1). So there is INT0 and INT1 available for every port. Port Interrupts must be enabled before they can be used like for example Int1 on PortA = PORTA_INT1 Steps to use PortE.0 as Port Interrupt where INT0 is used: 1. enable the INT0 Interrupt on Port E On Porte_int0 Port_e_int0__isr Enable Porte_int0 , Lo 'Enable this Interrupt as Lo Level Interrupt Enable Interrupts 2. Config Porte.0 as Input: Config Pine.0 = Input 'Set PINE.0 as Input 3. Configure the reaction: Config Xpin = Porte.0 , Outpull = Pullup , Sense = Falling 'enable Pull up and reaction on falling edge 4. Set the interrupt mask (which pin will be activated to generate an INT0 in this case): Porte_int0mask = &B0000_0001 'include PIN0 in INT0 Mask 1 = Pin is activated for interrupt 0 = Pin is deactivated for interrupt You could also set more pin's as activated (set to 1) but then you need to check in the interrupt service routine which pin was the root cause for generating the interrupt. 5. The Interrupt Service Routine: 'Port E INT0 Interrupt Service Routine Port_e_int0__isr: 'do something.... Return Additional info for Port Interrupts: For asynchronous sensing, only port pin 2 on each port has full asynchronous sense support. This means that for edge detection, pin 2 will detect and latch any edge and it will always trigger an interrupt request. The other port pins have limited asynchronous sense support [ATXMEGA A Manual]. See also below for an example for Port Interrupt (External Interrupt) Q: For what do I need Fuse Bits (Fuses) with ATXMEGA ? A: �The Fuses are used to set important system function and can only be written from an external programming interface. The application software can read the fuses. The fuses are used to configure reset sources such as Brown-out Detector and Watchdog, Start-up configuration, JTAG enable and JTAG user ID, Bootloader�..An unprogrammed fuse or lock bit will have the value one, while a programmed flash or lock bit will have the value zero..� [ATXEMGA A Manual] Q: How to write to 16-Bit (Word) Register of ATXMEGA ? A: You do not care about the 16-Bit (Word) Register because the compiler will handle this for you automatic. For this you can find the [WIO] (Word IO) Section in the DAT file. You can only write direct to 16-Bit Register over the defined register in the [WIO] section of the DAT file If there is a need to manual write/read to/from 16-Bit register you always need to write/read the LOW Byte (LSB) and then the HIGH Byte (MSB). Q: Is there also a linear memory architecture as with ATMEGA or ATTINY AVR's ? A: The power of the AVR is/was the linear memory architecture. In the ATXMEGA this has been changed : the registers are placed into a separate address space. This makes code like this fail: Clr r31 Ldi r30,10 ; point to register R10 Ld r24,z+ ; load value from R10 and inc pointer Code like LDS r16, 0 will not load the content of register R0 either with Xmega If your ASM code contains such code you need to rewrite it. Q: Is the Bascom-AVR Demo version supporting ATXMEGA ? A: ATXMEGA is not available in PDIP. This means that the ATXMEGA is not really suited for hobby projects. As a result, the DEMO version does not support the ATXMEGA. Q: For what are Virtual Port Registers good for ? A: �Virtual port registers allow for port registers in the extended I/O memory space to be mapped virtually in the I/O memory space. When mapping a port, writing to the virtual port register will be the same as writing to the real port register. This enables use of I/O memory specific instructions for bit-manipulation, and the I/O memory specific instructions IN and OUT on port register that normally resides in the extended I/O memory space. There are four virtual ports, so up to four ports can be mapped virtually at the same time. The mapped registers are IN, OUT, DIR and INTFLAGS.� [from ATXMEGA A Manual] Q: On which port of ATXMEGA can I find the COM1.....COM8 ? A: See table below: COM1 --> Usartc0 COM2 --> Usartc1 COM3 --> Usartd0 COM4 --> Usartd1 COM5 --> Usarte0 COM6 --> Usarte1 COM7 --> Usartf0 COM8 --> Usartf1 Q: Is Serialin and Serialout supported for UART Interfaces above COM4 A: Yes since version 2077 all 8 UARTS support buffered serial input and output. For ATXMEGA the first 4 UARTS can use for example serialin: SERIALIN : first UART/UART0 --> COM1 SERIALIN1 : second UART/UART1 --> COM2 SERIALIN2 : third UART/UART2 --> COM3 SERIALIN3 : fourth UART/UART3 --> COM4 SERIALIN4 : fourth UART/UART4 --> COM5 SERIALIN5 : fourth UART/UART5 --> COM6 SERIALIN6 : fourth UART/UART6 --> COM7 SERIALIN7 : fourth UART/UART7 --> COM8 For example with an ATXMEGA128A1 you get 8 UARTS: Every of the 8 USART�s has for example a Receive Interrupt which you can use to analyze incoming data: ATXMEGA128A1 Receive Interrupts: COM1 --> Usartc0_rxc COM2 --> Usartc1_rxc COM3 --> Usartd0_rxc COM4 --> Usartd1_rxc COM5 --> Usarte0_rxc COM6 --> Usarte1_rxc COM7 --> Usartf0_rxc COM8 --> Usartf1_rxc In the interrupt routine you need to use the inkey(#X) function because inkey(#X) is reading the data register and therefore reset the interrupt flag. Without reading the data register or resetting the interrupt flag manual the interrupt will fire again and again. Example the interrupt routine: Rxc_isr: Rs232 = Inkey(#1) 'do something with the data Return Q: How to get the reason for a reset of ATXMEGA (like power on, watchdog or software rest) A: There is a special register for that RST_STATUS you can read and analyze. You can also read R0 register using GetReg(R0) function : myvar=GetReg(r0). You need to do this early in your code. Q: How to auto calibrate the internal 2MHz and 32MHz Oscillators during runtime ? A: The automatic runtime calibration of internal oscillators is activated by enabling the DFLL (Digital Frequency-locked Loops) and autocalibration. 'The internal 32.768 KHz Oscillator is used for calibration Osc_dfllctrl = &B00000000 'Enable DFLL and autocalibration Set Dfllrc32m_ctrl.0 Additional hint from ATMEL for some chip revisions: "....Both DFLLs and both oscillators has to be enabled for one to work In order to use the automatic runtime calibration for the 2 MHz or the 32 MHz internal oscillators, the DFLL for both oscillators and both oscillators has to be enabled for one to work. Problem fix/Workarund Enabled both DFLLs and oscillators when using automatic runtime calibration for one of the internal oscillators....." Q: How many Flash and EEPROM Write/Erase Cycles can be done with ATXMEGA ? A: One write cycle consists of erasing a sector, followed by programming the same sector. You can find the maximum numbers for an ATXMEGA128A1 here: XMEGA Flash and EEPROM Write/Erase Cycles: For ATxmega128A1 devices Flash: 25°C - 10K Write/Erase cycles 85°C - 10KWrite/Erase cycles EEPROM: 25°C 80K- Write/Erase cycles 85°C 30K- Write/Erase cycles Example for XMEGA Port Interrupt (External Interrupt) from user hzz: '----------------------------------------------------------------------------------------------------------------------- ' Configuring external interrupts with XMEGA ' Tested OK with BASCOM 2.0.7.5 and an XMEGA128A3 board by Chip45 ' 14-aug-2012 '----------------------------------------------------------------------------------------------------------------------- '________________________________________________________________________________ $regfile = "xm128a3def.dat" $hwstack = 256 $swstack = 128 $framesize = 128 '________________________________________________________________________________ ' For 16MHz crystal $crystal = 32000000 Config Osc = Disabled , Extosc = Enabled , Range = 12mhz_16mhz , Startup = Xtal_1kclk , 32khzosc = Enabled ' Set PLL OSC conditions: Osc_pllctrl = &B1100_0010 ' reference external oscillator, set the PLL' multiplication factor to 2 (bits 0 - 4) Set Osc_ctrl.4 ' Enable PLL Oscillator Bitwait Osc_status.4 , Set ' wait until the pll clock reference source is stable Clk_ctrl = &B0000_0100 ' switch system clock to pll Config Sysclock = Pll , Prescalea = 1 , Prescalebc = 1_1 '________________________________________________________________________________ ' Setup: Led1 Alias Portd.0 : Config Portd.0 = Output : Led1 = 1 ' Each XMEGA port has two interrupt vectors: INT0 and INT1. ' For example, the XMEGA A3 has 7 ports: A, B, C, D, E, F, each with 8 pins ranging from pin0 to pin7, and port R, with just two pins, normally used by an external XTAL. ' Therefore up to 12 pins can be used as external interrupts with an XMEGA A3 (or up to 14 if an external XTAL is not used and PORTR.0 and PORTR.1 are free) ' For each port, any two pins can be defined as an external interrupt source as follows: ' The following example configures the following ports as external interrupt sources: ' PORTB.0 using interrupt vector INT0 of PORTB ' PORTB.3 using interrupt vector INT1 of PORTB ' (no more port B pins can be defined as external interruopt sources ) ' PORTA.3 using interrupt vector INT0 of PORTA ' 1) Set the Interrupt Service Routines Labels for the interrupt vectors used and ' enable interrupts setting the intrerrupt level: On Portb_int0 B0_b0_isr : Enable Portb_int0 , Hi On Portb_int1 B1_b3_isr : Enable Portb_int1 , Lo On Porta_int0 A0_a3_isr : Enable Porta_int0 , Lo ' I choose the label names to indicate the interruopt vector used and the pin that will be assigned ' next. For instance B1_b3_isr: uses INT vector 1 of port B assigned to pin b3 ' 2) Config pins as inputs and define what should cause the interrupt: low level, hi level, or transitions: rising, falling or both Config Portb.0 = Input : Config Xpin = Portb.0 , Sense = Rising Config Portb.3 = Input : Config Xpin = Portb.3 , Sense = Falling Config Porta.3 = Input : Config Xpin = Porta.3 , Sense = Both ' Three switches are connected these pins, PORTB.0, PORTB.3 and PORTA.3, for testing ' 3) Assign pins to interrupt vectors: Portb_int0mask = &B0000_0001 ' Assign pin b0 to Portb_int0 Portb_int1mask = &B0000_1000 ' Assign pin b3 to Portb_int1 Porta_int0mask = &B0000_1000 ' Assign pin a3 to Porta_int0 ' Notice that more than one pin can be assigned to the same vector. For instance, we could have ' written: ' PROTB_INT0MASK = &B0000_1001 ' Assign pin b0 and b3 to Portb_int0 ' In this case, both "b0" and "b3" pins will result in executing the same ISR (If possible, the ISR could ' distinguish which pin has produced the interrupt and execute a different code. This is a way of ' having more than two external interrupt sources per port). Another way will be assigning other ' pins to event channels. ' 4) Write the Interrupt service routines (locate then after the do loop where they will not be ' executed except when they are called) ' B0_b0_isr: ' ' Do whatever at each rising edge of pin b0 ' Return ' ' B1_b3_isr: ' ' Do whatever at each falling edge of pin b3 ' Return ' ' A0_a3_isr: ' ' Do whatever at each rising and falling edges of pin a3 ' Return '5) Don't forget to enable interrupts and config priorities Enable Interrupts Config Priority = Static , Vector = Application , Lo = Enabled , Med = Enabled , Hi = Enabled '_________________________________________________________________________________ Do ' No need to do anything here Loop '_________________________________________________________________________________ B0_b0_isr: ' The switch connected to PORTB.0 will toggle the LED each time it goes HI Toggle Led1 Return B1_b3_isr: ' The switch connected to PORTB.3 will toggle the LED each time it goes LO Toggle Led1 Return A0_a3_isr: ' The switch connected to PORTA.3 will toggle the LED each time it goes LO or HI Toggle Led1 Return ATXMEGA8E5 Top Previous Next - The XMEGA E series requires that you reset the interrupt yourself. For example : TCC4_INTflags.0=1 'clear OV flag - The ERASE_APP NVM command (&H20) erases the complete flash, thus the boot space included. Use &H25 instead to erase and write a page. - There is a fixed map for the virtual ports : VPORT0 - Virtual port A VPORT1 - Virtual port C VPORT2 - Virtual port D VPORT3 - Virtual port R ATXMEGA16A4 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. Read the generic info about Xmega. ATXMEGA16D4 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. Read the generic info about Xmega. ATXMEGA16E5 Top Previous Next - The XMEGA E series requires that you reset the interrupt yourself. For example : TCC4_INTflags.0=1 'clear OV flag - The ERASE_APP NVM command (&H20) erases the complete flash, thus the boot space included. Use &H25 instead to erase and write a page. - There is a fixed map for the virtual ports : VPORT0 - Virtual port A VPORT1 - Virtual port C VPORT2 - Virtual port D VPORT3 - Virtual port R ATXMEGA32A4 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. Read the generic info about Xmega. ATXMEGA32A4U Top Previous Next ATXMEGA32D4 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. Read the generic info about Xmega. ATXMEGA32E5 Top Previous Next - The XMEGA E series requires that you reset the interrupt yourself. For example : TCC4_INTflags.0=1 'clear OV flag - The ERASE_APP NVM command (&H20) erases the complete flash, thus the boot space included. Use &H25 instead to erase and write a page. - There is a fixed map for the virtual ports : VPORT0 - Virtual port A VPORT1 - Virtual port C VPORT2 - Virtual port D VPORT3 - Virtual port R ATXMEGA64A1 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. Here a note about the spike detector : >The calibration byte in the production signature row show 0xFF and 0x00 >for the ADC Calibration byte. Are these really the calibration values ? >And I'm not able to set the HIGH Byte of the calibration register. >Errata of Rev H don't show something from calibration bytes. Reply from Atmel : The voltage spike detector has been removed from the latest revision of the XMEGA A manual. This is because we have, unfortunately, not been able to validate the spike detector fully. The module is disabled in currently available parts to avoid unforeseen problems for any customers. ATXMEGA64A3 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATXMEGA64D3 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATXMEGA64D4 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. Read the generic info about Xmega. ATXMEGA128A1 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. Question: The DVDSON FUSE BIT the ATxmega A MANUAL says that for characterization data on VDROP and tSD consult the device data sheet. (Device: ATXMEGA128A1 RevH). But I can't find this Information in the datasheet ? Answer: The voltage spike detector has been removed from the latest revision of the XMEGA A manual. This is because we have, unfortunately, not been able to validate the spike detector fully. Question: The calibration byte in the production signature row show 0xFF and 0x00 for the ADC Calibration byte. Are these really the calibration values ? Errata of Rev H don't show something from calibration bytes. (Device: ATXMEGA128A1 RevH) Answer: Yes this is a known issue with ATXMEGA128A1 RevH. We will be fixing up this issue in the later version of the device. You should write the code for loading the calibration registers in the firmware so that when we fix it in the later version you do not have to fix the code. Also loading it now will not cause any problem in the ADC operation. ATXMEGA128A3 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATXMEGA128A4U Top Previous Next ATXMEGA128B1 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATXMEGA128B3 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATXMEGA128C3 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATXMEGA128D3 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATXMEGA128D4 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. Read the generic info about Xmega. ATXMEGA192A3 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATXMEGA192D3 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATXMEGA256A3 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATXMEGA256A3B Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATXMEGA256A3BU Top Previous Next ATXMEGA256D3 Top Previous Next This page is intended to show the outline of the chip and to provide additional information that might not be clear from the data sheet. ATXMEGA384C3 Top Previous Next Changes compared to BASCOM-8051 Top Previous Next The design goal was to make BASCOM-AVR compatible with BASCOM-8051. For the AVR compiler some statements had to be removed. New statements were also added. And some statements were changed. They need specific attention, but the changes to the syntax will be made available to BASCOM-8051 too in the future. Statements that were removed STATEMENT DESCRIPTION $LARGE Not needed anymore. $ROMSTART Code always starts at address 0 for the AVR. Added again in 1.11.6.2 $LCDHEX Use LCD Hex(var) instead. $NOINIT Not needed anymore. Added in 1.11.6.2 $NOSP Not needed anymore $NOBREAK Can't be used anymore because there is no object code that can be used for it. $OBJ Removed. BREAK Can't be used anymore because there is no object code that can be used for it. PRIORITY AVR does no allow setting priority of interrupts PRINTHEX You can use Print Hex(var) now LCDHEX You can use Lcd Hex(var) now Statements that were added STATEMENT DESCRIPTION FUNCTION You can define your own user FUNCTIONS. LOCAL You can have LOCAL variables in SUB routines or FUNCTIONS. ^ New math statement. Var = 2 ^ 3 will return 2*2*2 SHIFT Because ROTATE was changed, I added the SHIFT statement. SHIFT works just like ROTATE, but when shifted left, the LS BIT is cleared and the carry doesn't go to the LS BIT. LTRIM LTRIM, trims the leftmost spaces of a string. RTRIM RTRIM, trims the rightmost spaces of a string. TRIM TRIM, trims both the leftmost and rightmost spaces of a string. Statements that behave differently STATEMENT DESCRIPTION ROTATE Rotate now behaves like the ASM rotate, this means that the carry will go to the most significant bit of a variable or the least significant bit of a variable. CONST String were added to the CONST statement. I also changed it to be compatible with QB. DECLARE BYVAL has been added since real subprograms are now supported. DIM You can now specify the location in memory of the variable. Dim v as byte AT 100, will use memory location 100. Language Fundamentals Top Previous Next Characters from the BASCOM character set are put together to form labels, keywords, variables and operators. These in turn are combined to form the statements that make up a program. This chapter describes the character set and the format of BASCOM program lines. In particular, it discusses: · The specific characters in the character set and the special meanings of some characters. · The format of a line in a BASCOM program. · Line labels. · Program line length. Character Set The BASCOM BASIC character set consists of alphabetic characters, numeric characters, and special characters. The alphabetic characters in BASCOM are the uppercase letters (A-Z) and lowercase letters (a-z) of the alphabet. The BASCOM numeric characters are the digits 0-9. The letters A-H can be used as parts of hexadecimal numbers. The following characters have special meanings in BASCOM statements and expressions: Character Name ENTER Terminates input of a line Blank ( or space) ' Single quotation mark (apostrophe) * Asterisks (multiplication symbol) + Plus sign , Comma - Minus sign . Period (decimal point) / Slash (division symbol) will be handled as \ : Colon " Double quotation mark ; Semicolon < Less than = Equal sign (assignment symbol or relational operator) > Greater than \ Backslash (integer/word division symbol) ^ Exponent The BASCOM program line BASCOM program lines have the following syntax: [[line-identifier]] [[statement]] [[:statement]] ... [[comment]] Using Line Identifiers BASCOM support one type of line-identifier; alphanumeric line labels: An alphabetic line label may be any combination of from 1 to 32 letters and digits, starting with a letter and ending with a colon. BASCOM keywords are not permitted. The following are valid alphanumeric line labels: Alpha: ScreenSUB: Test3A: Case is not significant. The following line labels are equivalent: alpha: Alpha: ALPHA: Line labels may begin in any column, as long as they are the first characters other than blanks on the line. Blanks are not allowed between an alphabetic label and the colon following it. A line can have only one label. When there is a label on the line, no other identifiers may be used on the same line. So the label is the sole identifier on a line. BASCOM Statements A BASCOM statement is either "executable" or " non-executable". An executable statement advances the flow of a programs logic by telling the program what to do next. Non executable statement perform tasks such as allocating storage for variables, declaring and defining variable types. The following BASCOM statements are examples of non-executable statements: · REM or (starts a comment) · DIM A "comment" is a non-executable statement used to clarify a programs operation and purpose. A comment is introduced by the REM statement or a single quote character('). The following lines are equivalent: PRINT " Quantity remaining" : REM Print report label. PRINT " Quantity remaining" ' Print report label. More than one BASCOM statement can be placed on a line, but colons(:) must separate statements, as illustrated below. FOR I = 1 TO 5 : PRINT " Gday, mate." : NEXT I Comment Comment is intended to clarify your code. Describe what the code is supposed to do. You can use single line comment using the REM statement. By default, comment is shown in green. Since REM is a lot of type work, you can also use the ' sign When you want to comment multiple lines, you can also use block comment. Block comment starts with '( It ends with ') Please notice that block comment must be the first non white space on the line. Rem some comment Print 'also comment '( block comment multiple lines ') print "ok" BASCOM LineLength If you enter your programs using the built-in editor, you are not limited to any line length, although it is advised to shorten your lines to 80 characters for clarity. Data Types Every variable in BASCOM has a data type that determines what can be stored in the variable. The next section summarizes the elementary data types. Elementary Data Types Type Bytes used Range Description Bit 1/8 Byte 0-1 A bit can hold only the value 0 or 1. A group of 8 bits is called a byte Byte 1 Byte 0 to 255 Bytes are stored as unsigned 8-bit binary numbers Integer 2 Bytes -32,768 to +32,767 Integers are stored as signed sixteen-bit binary numbers Word 2 Bytes 0 to 65535 Words are stored as unsigned sixteen-bit binary numbers Dword 4 Bytes 0 to 4294967295 Dwords are stored as unsigned 32-bit binary numbers Long 4 Bytes -2147483648 to 2147483647 Longs are stored as signed 32-bit binary numbers Single 4 Bytes 1.5 x 10^�45 to 3.4 x 10^38 Singles are stored as signed 32 bit binary numbers Double 8 Bytes 5.0 x 10^�324 to 1.7 x 10^308 Doubles are stored as signed 64 bit binary numbers String up to 254 Bytes Strings are stored as bytes and are terminated with a chr(0) byte. A string dimensioned with a length of 10 bytes will occupy 11 bytes Variables can be stored internal (default) , external or in EEPROM. Variables A variable is a name that refers to an object--a particular number. A numeric variable, can be assigned only a numeric value (either integer, byte, long, single or bit). The following list shows some examples of variable assignments: · A constant value: A = 5 C = 1.1 · The value of another numeric variable: abc = def k = g · The value obtained by combining other variables, constants, and operators: Temp = a + 5 Temp = C + 5 · The value obtained by calling a function: Temp = Asc(S) Constants A constant is a placeholder for a fixed value : you can assign it with a value only once : CONST Something = 100 Constants can be assigned with a numeric or string value. To assign a string use double quotes : CONST SomeString = "BASCOM" You can also use expressions with constants : CONST SomeThing = 1 + 2 / (3+4) When you keep the SHIFT key pressed and hover the mouse cursor over a constant, a tooltip/hint will show the value. When using numeric constants in DATA lines, you need to inform the compiler about the data type. This is done by ending the constant value with a suffix. See the help for DATA. Variable Names A BASCOM variable name may contain up to 32 characters. The characters allowed in a variable name are letters and numbers. The first character in a variable name must be a letter. A variable name cannot be a reserved word, but embedded reserved words are allowed. For example, the following statement is illegal because AND is a reserved word. AND = 8 However, the following statement is legal: ToAND = 8 Reserved words include all BASCOM commands, statements, function names, internal registers and operator names. (see BASCOM Reserved Words , for a complete list of reserved words). You can specify a hexadecimal or binary number with the prefix &H or &B. a = &HA , a = &B1010 and a = 10 are all the same. Before assigning a variable, you must tell the compiler about it with the DIM statement. Dim b1 As Bit, I as Integer, k as Byte , s As String * 10 The STRING type needs an additional parameter to specify the length. You can also use DEFINT, DEFBIT, DEFBYTE ,DEFWORD ,DEFLNG or DEFSNG. For example,DEFINT c tells the compiler that all variables that are not dimensioned and that are beginning with the character c are of the Integer type. BITS and Interrupts Bits are stored in bytes. A write to a bit/boolean variable is non-atomic. Which means that multiple operations are required to update the bit value in the byte. When interrupts are used that update bits in the same byte, you can have the effect that a change becomes lost. To prevent this you can disable interrupts and enable them after you have updated the bit variable. Or you can use a byte instead which is recommended since it would use less code. Expressions and Operators This chapter discusses how to combine, modify, compare, or get information about expressions by using the operators available in BASCOM. Anytime you do a calculation you are using expressions and operators. This chapter describes how expressions are formed and concludes by describing the following kind of operators: · Arithmetic operators, used to perform calculations. · Relational operators, used to compare numeric or string values. · Logical operators, used to test conditions or manipulate individual bits. · Functional operators, used to supplement simple operators. Expressions and Operators An expression can be a numeric constant, a variable, or a single value obtained by combining constants, variables, and other expressions with operators. Operators perform mathematical or logical operations on values. The operators provided by BASCOM can be divided into four categories, as follows: 1. Arithmetic 2. Relational 3. Logical 4. Functional Arithmetic Arithmetic operators are +, - , * , \, / and ^. · Integer Integer division is denoted by the backslash (\). Example: Z = X \ Y · Modulo Arithmetic Modulo arithmetic is denoted by the modulus operator MOD. Modulo arithmetic provides the remainder, rather than the quotient, of an integer division. Example: X = 10 \ 4 : remainder = 10 MOD 4 · Overflow and division by zero Division by zero, produces an error. At the moment no message is produced, so you have to make sure yourself that this won't happen. Relational Operators Relational operators are used to compare two values as shown in the table below. The result can be used to make a decision regarding program flow. Operator Relation Tested Expression = Equality X = Y <> Inequality X <> Y < Less than X < Y > Greater than X > Y <= Less than or equal to X <= Y >= Greater than or equal to X >= Y Logical Operators Logical operators perform tests on relations, bit manipulations, or Boolean operators. There four operators in BASCOM are : Operator Meaning NOT Logical complement AND Conjunction OR Disjunction XOR Exclusive or It is possible to use logical operators to test bytes for a particular bit pattern. For example the AND operator can be used to mask all but one of the bits of a status byte, while OR can be used to merge two bytes to create a particular binary value. Example A = 63 And 19 PRINT A A = 10 Or 9 PRINT A Output 19 11 Floating point SINGLE (4 BYTE)(ASM code used is supplied by Jack Tidwell) Single numbers conforming to the IEEE binary floating point standard. An eight bit exponent and 24 bit mantissa are supported. Using four bytes the format is shown below: 31 30________23 22______________________________0 s exponent mantissa The exponent is biased by 128. Above 128 are positive exponents and below are negative. The sign bit is 0 for positive numbers and 1 for negative. The mantissa is stored in hidden bit normalized format so that 24 bits of precision can be obtained. All mathematical operations are supported by the single. You can also convert a single to an integer or word or vise versa: Dim I as Integer, S as Single S = 100.1 'assign the single I = S 'will convert the single to an integer Here is a fragment from the Microsoft knowledge base about FP: Floating-point mathematics is a complex topic that confuses many programmers. The tutorial below should help you recognize programming situations where floating-point errors are likely to occur and how to avoid them. It should also allow you to recognize cases that are caused by inherent floating-point math limitations as opposed to actual compiler bugs. Decimal and Binary Number Systems Normally, we count things in base 10. The base is completely arbitrary. The only reason that people have traditionally used base 10 is that they have 10 fingers, which have made handy counting tools. The number 532.25 in decimal (base 10) means the following: (5 * 10^2) + (3 * 10^1) + (2 * 10^0) + (2 * 10^-1) + (5 * 10^-2) 500 + 30 + 2 + 2/10 + 5/100 _________ = 532.25 In the binary number system (base 2), each column represents a power of 2 instead of 10. For example, the number 101.01 means the following: (1 * 2^2) + (0 * 2^1) + (1 * 2^0) + (0 * 2^-1) + (1 * 2^-2) 4 + 0 + 1 + 0 + 1/4 _________ = 5.25 Decimal How Integers Are Represented in PCs ----------------------------------- Because there is no fractional part to an integer, its machine representation is much simpler than it is for floating-point values. Normal integers on personal computers (PCs) are 2 bytes (16 bits) long with the most significant bit indicating the sign. Long integers are 4 bytes long. Positive values are straightforward binary numbers. For example: 1 Decimal = 1 Binary 2 Decimal = 10 Binary 22 Decimal = 10110 Binary, etc. However, negative integers are represented using the two's complement scheme. To get the two's complement representation for a negative number, take the binary representation for the number's absolute value and then flip all the bits and add 1. For example: 4 Decimal = 0000 0000 0000 0100 1111 1111 1111 1011 Flip the Bits -4 = 1111 1111 1111 1100 Add 1 Note that adding any combination of two's complement numbers together using ordinary binary arithmetic produces the correct result. Floating-Point Complications Every decimal integer can be exactly represented by a binary integer; however, this is not true for fractional numbers. In fact, every number that is irrational in base 10 will also be irrational in any system with a base smaller than 10. For binary, in particular, only fractional numbers that can be represented in the form p/q, where q is an integer power of 2, can be expressed exactly, with a finite number of bits. Even common decimal fractions, such as decimal 0.0001, cannot be represented exactly in binary. (0.0001 is a repeating binary fraction with a period of 104 bits!) This explains why a simple example, such as the following SUM = 0 FOR I% = 1 TO 10000 SUM = SUM + 0.0001 NEXT I% PRINT SUM ' Theoretically = 1.0. will PRINT 1.000054 as output. The small error in representing 0.0001 in binary propagates to the sum. For the same reason, you should always be very cautious when making comparisons on real numbers. The following example illustrates a common programming error: item1# = 69.82# item2# = 69.20# + 0.62# IF item1# = item2# then print "Equality!" This will NOT PRINT "Equality!" because 69.82 cannot be represented exactly in binary, which causes the value that results from the assignment to be SLIGHTLY different (in binary) than the value that is generated from the expression. In practice, you should always code such comparisons in such a way as to allow for some tolerance. General Floating-Point Concepts It is very important to realize that any binary floating-point system can represent only a finite number of floating-point values in exact form. All other values must be approximated by the closest represent able value. The IEEE standard specifies the method for rounding values to the "closest" represent able value. BASCOM supports the standard and rounds according to the IEEE rules. Also, keep in mind that the numbers that can be represented in IEEE are spread out over a very wide range. You can imagine them on a number line. There is a high density of represent able numbers near 1.0 and -1.0 but fewer and fewer as you go towards 0 or infinity. The goal of the IEEE standard, which is designed for engineering calculations, is to maximize accuracy (to get as close as possible to the actual number). Precision refers to the number of digits that you can represent. The IEEE standard attempts to balance the number of bits dedicated to the exponent with the number of bits used for the fractional part of the number, to keep both accuracy and precision within acceptable limits. IEEE Details Floating-point numbers are represented in the following form, where [exponent] is the binary exponent: X = Fraction * 2^(exponent - bias) [Fraction] is the normalized fractional part of the number, normalized because the exponent is adjusted so that the leading bit is always a 1. This way, it does not have to be stored, and you get one more bit of precision. This is why there is an implied bit. You can think of this like scientific notation, where you manipulate the exponent to have one digit to the left of the decimal point, except in binary, you can always manipulate the exponent so that the first bit is a 1, since there are only 1s and 0s. [bias] is the bias value used to avoid having to store negative exponents. The bias for single-precision numbers is 127 and 1023 (decimal) for double-precision numbers. The values equal to all 0's and all 1's (binary) are reserved for representing special cases. There are other special cases as well, that indicate various error conditions. Single-Precision Examples 2 = 1 * 2^1 = 0100 0000 0000 0000 ... 0000 0000 = 4000 0000 hex Note the sign bit is zero, and the stored exponent is 128, or 100 0000 0 in binary, which is 127 plus 1. The stored mantissa is (1.) 000 0000 ... 0000 0000, which has an implied leading 1 and binary point, so the actual mantissa is 1. -2 = -1 * 2^1 = 1100 0000 0000 0000 ... 0000 0000 = C000 0000 hex Same as +2 except that the sign bit is set. This is true for all IEEE format floating-point numbers. 4 = 1 * 2^2 = 0100 0000 1000 0000 ... 0000 0000 = 4080 0000 hex Same mantissa, exponent increases by one (biased value is 129, or 100 0000 1 in binary. 6 = 1.5 * 2^2 = 0100 0000 1100 0000 ... 0000 0000 = 40C0 0000 hex Same exponent, mantissa is larger by half -- it's (1.) 100 0000 ... 0000 0000, which, since this is a binary fraction, is 1-1/2 (the values of the fractional digits are 1/2, 1/4, 1/8, etc.). 1 = 1 * 2^0 = 0011 1111 1000 0000 ... 0000 0000 = 3F80 0000 hex Same exponent as other powers of 2, mantissa is one less than 2 at 127, or 011 1111 1 in binary. .75 = 1.5 * 2^-1 = 0011 1111 0100 0000 ... 0000 0000 = 3F40 0000 hex The biased exponent is 126, 011 1111 0 in binary, and the mantissa is (1.) 100 0000 ... 0000 0000, which is 1-1/2. 2.5 = 1.25 * 2^1 = 0100 0000 0010 0000 ... 0000 0000 = 4020 0000 hex Exactly the same as 2 except that the bit which represents 1/4 is set in the mantissa. 0.1 = 1.6 * 2^-4 = 0011 1101 1100 1100 ... 1100 1101 = 3DCC CCCD hex 1/10 is a repeating fraction in binary. The mantissa is just shy of 1.6, and the biased exponent says that 1.6 is to be divided by 16 (it is 011 1101 1 in binary, which is 123 n decimal). The true exponent is 123 - 127 = -4, which means that the factor by which to multiply is 2**-4 = 1/16. Note that the stored mantissa is rounded up in the last bit. This is an attempt to represent the un-representable number as accurately as possible. (The reason that 1/10 and 1/100 are not exactly representable in binary is similar to the way that 1/3 is not exactly representable in decimal.) 0 = 1.0 * 2^-128 = all zeros -- a special case. Other Common Floating-Point Errors The following are common floating-point errors: 1. Round-off error This error results when all of the bits in a binary number cannot be used in a calculation. Example: Adding 0.0001 to 0.9900 (Single Precision) Decimal 0.0001 will be represented as: (1.)10100011011011100010111 * 2^(-14+Bias) (13 Leading 0s in Binary!) 0.9900 will be represented as: (1.)11111010111000010100011 * 2^(-1+Bias) Now to actually add these numbers, the decimal (binary) points must be aligned. For this they must be Unnormalized. Here is the resulting addition: .000000000000011010001101 * 2^0 <- Only 11 of 23 Bits retained +.111111010111000010100011 * 2^0 ________________________________ .111111010111011100110000 * 2^0 This is called a round-off error because some computers round when shifting for addition. Others simply truncate. Round-off errors are important to consider whenever you are adding or multiplying two very different values. 2. Subtracting two almost equal values .1235 -.1234 _____ .0001 This will be normalized. Note that although the original numbers each had four significant digits, the result has only one significant digit. 3. Overflow and underflow This occurs when the result is too large or too small to be represented by the data type. 4. Quantizing error This occurs with those numbers that cannot be represented in exact form by the floating-point standard. Rounding When a Long is assigned to a single, the number is rounded according to the rules of the IEEE committee. For explanation: 1.500000 is exact the middle between 1.00000 and 2.000000. If x.500000 is always rounded up, than there is trend for higher values than the average of all numbers. So their rule says, half time to round up and half time to round down, if value behind LSB is exact ..500000000. The rule is, round this .500000000000 to next even number, that means if LSB is 1 (half time) to round up, so the LSB is going to 0 (=even), if LSB is 0 (other half time) to round down, that means no rounding. This rounding method is best since the absolute error is 0. You can override the default IEEE rounding method by specifying the $LIB LONG2FLOAT.LBX library which rounds up to the next number. This is the method used up to 1.11.7.4 of the compiler. Double The double is essential the same as a single. Except the double consist of 8 bytes instead of 4. The exponent is 11 bits leaving 52 bits for the mantissa. Arrays An array is a set of sequentially indexed elements having the same type. Each element of an array has a unique index number that identifies it. Changes made to an element of an array do not affect the other elements. The index must be a numeric constant, a byte, an integer, word or long. The maximum number of elements is 65535. For Xmega with huge memory it is 8MB! The first element of an array is always one by default. This means that elements are 1-based. You can change this with CONFIG BASE=0. In this case, the first element will be element 0. Arrays can be used on each place where a 'normal' variable is expected. You can add an offset to the index too. This could be used to emulate a 2 dimensional array. row_index = row : shift row_index, left,4 value = parameter_array(column+row_index) Example: 'create an array named a, with 10 elements (1 to 10) Dim A(10) As Byte 'create an integer Dim C As Integer 'now fill the array For C = 1 To 10 'assign array element A(c)= C ' print it Print A(c) Next 'you can add an offset to the index too C = 0 A(c + 1)= 100 Print A(c + 1) End Strings A string is used to store text. A string must be dimensioned with the length specified. DIM S as STRING * 5 Will create a string that can store a text with a maximum length of 5 bytes. The space used is 6 bytes because a string is terminated with a null byte. To assign the string: Ds = "abcd" To insert special characters into the string : s= "AB{027}cd" The {ascii} will insert the ASCII value into the string. The number of digits must be 3. s = "{27}" will assign "{27}" to the string instead of escape character 27! Because the null byte (ASCII 0) is used to terminate a string, you can not embed a null byte into a string. Casting In BASCOM-AVR when you perform operations on variables they all must be of the same data type. long = long1 * long2 ' for example The assigned variables data type determines what kind of math is performed. For example when you assign a long, long math will be used. If you try to store the result of a LONG into a byte, only the LSB of the LONG will be stored into the BYTE. Byte = LONG When LONG = 256 , it will not fit into a BYTE. The result will be 256 AND 255 = 0. Of course you are free to use different data types. The correct result is only guaranteed when you are using data types of the same kind or that result always can fit into the target data type. When you use strings, the same rules apply. But there is one exception: Dim b as Byte b = 123 ' ok this is normal b = "A" ' b = 65 When the target is a byte and the source variable is a string constant denoted by "", the ASCII value will be stored in the byte. This works also for tests : IF b = "A" then ' when b = 65 END IF This is different compared to QB/VB where you can not assign a string to a byte variable. SINGLE CONVERSION When you want to convert a SINGLE into a byte, word, integer or long the compiler will automatic convert the values when the source string is of the SINGLE data type. integer = single You can also convert a byte, word, integer or long into a SINGLE by assigning this variable to a SINGLE. single = long Mixing ASM and BASIC Top Previous Next BASCOM allows you to mix BASIC with assembly. This can be very useful in some situations when you need full control of the generated code. In order to use ASM you must start the line with the character ! Optional you can create a block of ASM using $ASM end $END ASM Use CTRL + SPACE to get a list of ASM mnemonics. For example : Dim a As Byte At &H60 ' A is stored at location &H60 !Ldi R27 , $00 ' Load R27 with MSB of address !Ldi R26 , $60 ' Load R26 with LSB of address !Ld R1, X ' load memory location $60 into R1 !SWAP R1 ' swap nibbles As you can see the SWAP mnemonic is preceded by a ! sign. Without it, it would be the BASIC SWAP statement. Another option is to use the assembler block directives: $ASM Ldi R27 , $00 ' Load R27 with MSB of address Ldi R26 , $60 ' Load R26 with LSB of address Ld R1, X ' load memory location $60 into R1 SWAP R1 ' swap nibbles $END ASM A special assembler helper function is provided to load the address into the register X or Z. Y can may not be used because it is used as the soft stack pointer. Dim A As Byte ' reserve space LOADADR a, X ' load address of variable named A into register pair X This has the same effect as : Ldi R26, $60 ' for example ! Ldi R27, $00 ' for example ! Some registers are used by BASCOM R4 and R5 are used to point to the stack frame or the temp data storage R6 is used to store some bit variables: R6 bit 0 = flag for integer/word conversion R6 bit 1 = temp bit space used for swapping bits R6 bit 2 = error bit (ERR variable) R6 bit 3 = show/noshow flag when using INPUT statement R8 and R9 are used as a data pointer for the READ statement. All other registers are used depending on the used statements. To Load the address of a variable you must enclose them in brackets. Dim B As Bit Lds R16, {B} 'will replace {B} with the address of variable B To refer to the bit number you must precede the variable name by BIT. Sbrs R16 , BIT.B 'notice the point! Since this was the first dimensioned bit the bit number is 7. Bits are stored in bytes and the first dimensioned bit goes in the MS (most significant) bit. To load an address of a label you must use : LDI ZL, Low(lbl * 1) LDI ZH, High(lbl * 1) Where ZL = R30 and may be R24, R26, R28 or R30 And ZH = R31 and may be R25, R27, R29 or R31. These are so called register pairs that form a pointer. When you want to use the LPM instruction to retrieve data you must multiply the address with 2 since the AVR object code consist of words. LDI ZL, Low(lbl * 2) LDI ZH, High(lbl * 2) LPM ; get data into R0 Lbl: Atmel mnemonics must be used to program in assembly. You can download the pdf from www.atmel.com that shows how the different mnemonics are used. Some points of attention : * All instructions that use a constant as a parameter only work on the upper 16 registers (r16-r31) So LDI R15,12 WILL NOT WORK * The instruction SBR register, K will work with K from 0-255. So you can set multiple bits! The instruction SBI port, K will work with K from 0-7 and will set only ONE bit in a IO-port register. The same applies to the CBR and CBI instructions. You can use constants too: .equ myval = (10+2)/4 ldi r24,myval+2 '5 ldi r24,asc("A")+1 ; load with 66 Or in BASIC with CONST : CONST Myval = (10+2) / 4 Ldi r24,myval How to make your own libraries and call them from BASIC? The files for this sample can be found as libdemo.bas in the SAMPLES dir and as mylib.lib in the LIB dir. First determine the used parameters and their type. Also consider if they are passed by reference or by value For example the sub test has two parameters: x which is passed by value (copy of the variable) y which is passed by reference(address of the variable) In both cases the address of the variable is put on the soft stack which is indexed by the Y pointer. The first parameter (or a copy) is put on the soft stack first To refer to the address you must use: ldd r26 , y + 0 ldd r27 , y + 1 This loads the address into pointer X The second parameter will also be put on the soft stack so : The reference for the x variable will be changed : To refer to the address of x you must use: ldd r26 , y + 2 ldd r27 , y + 3 To refer to the last parameter y you must use ldd r26 , y + 0 ldd r27 , y + 1 Write the sub routine as you are used too but include the name within brackets [] [test] test: ldd r26,y+2 ; load address of x ldd r27,y+3 ld r24,x ; get value into r24 inc r24 ; value + 1 st x,r24 ; put back ldd r26,y+0 ; address of y ldd r27,y+1 st x,r24 ; store ret ; ready [end] To write a function goes the same way. A function returns a result so a function has one additional parameter. It is generated automatic and it has the name of the function. This way you can assign the result to the function name For example: Declare Function Test(byval x as byte , y as byte) as byte A virtual variable will be created with the name of the function in this case test. It will be pushed on the soft stack with the Y-pointer. To reference to the result or name of the function (test) the address will be: y + 0 and y + 1 The first variable x will bring that to y + 2 and y + 3 And the third variable will cause that 3 parameters are saved on the soft stack To reference to test you must use : ldd r26 , y + 4 ldd r27 , y + 5 To reference variable x ldd r26 , y + 2 ldd r27 , y + 3 And to reference variable y ldd r26 , y + 0 ldd r27 , y + 1 When you use exit sub or exit function you also need to provide an additional label. It starts with sub_ and must be completed with the function / sub routine name. In our example: sub_test: LOCALS When you use local variables thing become more complicated. Each local variable address will be put on the soft stack too When you use 1 local variable its address will become ldd r26, y+0 ldd r27 , y + 1 All other parameters must be increased with 2 so the reference to y variable changes from ldd r26 , y + 0 to ldd r26 , y + 2 ldd r27 , y + 1 to ldd r27 , y + 3 And of course also for the other variables. When you have more local variables just add 2 for each. Finally you save the file as a .lib file Use the library manager to compile it into the lbx format. The declare sub / function must be in the program where you use the sub / function. The following is a copy of the libdemo.bas file : ' define the used library $lib "mylib.lib" 'also define the used routines $external Test 'this is needed so the parameters will be placed correct on the stack Declare Sub Test(byval X As Byte , Y As Byte) 'reserve some space Dim Z As Byte 'call our own sub routine Call Test(1 , Z) 'z will be 2 in the used example End When you use ports in your library you must use .equ to specify the address: .equ EEDR=$1d In R24, EEDR This way the library manager knows the address of the port during compile time. As an alternative precede the mnemonic with a * so the code will not be compiled into the lib. The address of the register will be resolved at run time in that case. This chapter is not intended to teach you ASM programming. But when you find a topic is missing to interface BASCOM with ASM send me an email. Translation In version 1.11.7.5 of the compiler some mnemonics are translated when there is a need for. For example, SBIC will work only on normal PORT registers. This because the address may not be greater then 5 bits as 3 bits are used for the pin number(0-7). SBIC worked well in the old AVR chips(AT90Sxxxx) but in the Mega128 where PORTG is on a high address, it will not work. You always needs a normal register when you want to manipulate the bits of an external register. For example : LDS r23, PORTG ; get value of PORTG register SBR r23,128 ; set bit 7 STS PORTG, R23 The mnemonics that are translated by the compiler are : IN, OUT, SBIC, SBIS, SBI and CBI. The compiler will use register R23 for this. So make sure it is not used. Special instructions ADR Label ; will create a word with the address of the label name ADR2 Label ; will create a word with the address of the label name, multiplied by 2 to get the byte address ; since word addresses are used. This is convenient when loading the Z-pointer to use (E)LPM. .align ; This directive will align the code to a 256 byte page so that the address LSB becomes 0. ; When storing data at an address where the LSB is zero, you can test for an overflow of the MSB only. Assembler mnemonics Top Previous Next BASCOM supports the mnemonics as defined by Atmel. The Assembler accepts mnemonic instructions from the instruction set. A summary of the instruction set mnemonics and their parameters is given here. For a detailed description of the Instruction set, refer to the AVR Data Book. Mnemonics Operands Description Operation Flags Clock ARITHMETIC AND LOGIC INSTRUCTIONS ADD Rd, Rr Add without Carry Rd = Rd + Rr Z,C,N,V,H 1 ADC Rd, Rr Add with Carry Rd = Rd + Rr + C Z,C,N,V,H 1 SUB Rd, Rr Subtract without Carry Rd = Rd � Rr Z,C,N,V,H 1 SUBI Rd, K Subtract Immediate Rd = Rd � K Z,C,N,V,H 1 SBC Rd, Rr Subtract with Carry Rd = Rd - Rr - C Z,C,N,V,H 1 SBCI Rd, K Subtract Immediate with Carry Rd = Rd - K - C Z,C,N,V,H 1 AND Rd, Rr Logical AND Rd = Rd · Rr Z,N,V 1 ANDI Rd, K Logical AND with Immediate Rd = Rd · K Z,N,V 1 OR Rd, Rr Logical OR Rd = Rd v Rr Z,N,V 1 ORI Rd, K Logical OR with Immediate Rd = Rd v K Z,N,V 1 EOR Rd, Rr Exclusive OR Rd = Rd Å Rr Z,N,V 1 COM Rd Ones Complement Rd = $FF - Rd Z,C,N,V 1 NEG Rd Twos Complement Rd = $00 - Rd Z,C,N,V,H 1 SBR Rd,K Set Bit(s) in Register Rd = Rd v K Z,N,V 1 CBR Rd,K Clear Bit(s) in Register Rd = Rd · ($FFh - K) Z,N,V 1 INC Rd Increment Rd = Rd + 1 Z,N,V 1 DEC Rd Decrement Rd = Rd - 1 Z,N,V 1 TST Rd Test for Zero or Minus Rd = Rd · Rd Z,N,V 1 CLR Rd Clear Register Rd = Rd Å Rd Z,N,V 1 SER Rd Set Register Rd = $FF None 1 ADIW Adiw r24, K6 Rdl, K6 Add Immediate to Word Rdh:Rdl = Rdh:Rdl + K Z,C,N,V,S 2 SBIW Sbiw R24,K6 Rdl, K6 Subtract Immediate from Word Rdh:Rdl = Rdh:Rdl - K Z,C,N,V,S 2 MUL Rd,Rr Multiply Unsigned R1, R0 = Rd * Rr C 2 * BRANCH INSTRUCTIONS RJMP K Relative Jump PC = PC + k + 1 None 2 IJMP Indirect Jump to (Z) PC = Z None 2 JMP K Jump PC = k None 3 RCALL K Relative Call Subroutine PC = PC + k + 1 None 3 ICALL Indirect Call to (Z) PC = Z None 3 CALL K Call Subroutine PC = k None 4 RET Subroutine Return PC = STACK None 4 RETI Interrupt Return PC = STACK I 4 CPSE Rd,Rr Compare, Skip if Equal if (Rd = Rr) PC = PC + 2 or 3 None 1 / 2 CP Rd,Rr Compare Rd - Rr Z,C,N,V,H, 1 CPC Rd,Rr Compare with Carry Rd - Rr - C Z,C,N,V,H 1 CPI Rd,K Compare with Immediate Rd - K Z,C,N,V,H 1 SBRC Rr, b Skip if Bit in Register Cleared If (Rr(b)=0) PC = PC + 2 or 3 None 1 / 2 SBRS Rr, b Skip if Bit in Register Set If (Rr(b)=1) PC = PC + 2 or 3 None 1 / 2 SBIC P, b Skip if Bit in I/O Register Cleared If(I/O(P,b)=0) PC = PC + 2 or 3 None 2 / 3 SBIS P, b Skip if Bit in I/O Register Set If(I/O(P,b)=1) PC = PC + 2 or 3 None 2 / 3 BRBS s, k Branch if Status Flag Set if (SREG(s) = 1) then PC=PC+k + 1 None 1 / 2 BRBC s, k Branch if Status Flag Cleared if (SREG(s) = 0) then PC=PC+k + 1 None 1 / 2 BREQ K Branch if Equal if (Z = 1) then PC = PC + k + 1 None 1 / 2 BRNE K Branch if Not Equal if (Z = 0) then PC = PC + k + 1 None 1 / 2 BRCS K Branch if Carry Set if (C = 1) then PC = PC + k + 1 None 1 / 2 BRCC K Branch if Carry Cleared if (C = 0) then PC = PC + k + 1 None 1 / 2 BRSH K Branch if Same or Higher if (C = 0) then PC = PC + k + 1 None 1 / 2 BRLO K Branch if Lower if (C = 1) then PC = PC + k + 1 None 1 / 2 BRMI K Branch if Minus if (N = 1) then PC = PC + k + 1 None 1 / 2 BRPL K Branch if Plus if (N = 0) then PC = PC + k + 1 None 1 / 2 BRGE K Branch if Greater or Equal, Signed if (N V= 0) then PC = PC+ k + 1 None 1 / 2 BRLT K Branch if Less Than, Signed if (N V= 1) then PC = PC + k + 1 None 1 / 2 BRHS K Branch if Half Carry Flag Set if (H = 1) then PC = PC + k + 1 None 1 / 2 BRHC K Branch if Half Carry Flag Cleared if (H = 0) then PC = PC + k + 1 None 1 / 2 BRTS K Branch if T Flag Set if (T = 1) then PC = PC + k + 1 None 1 / 2 BRTC K Branch if T Flag Cleared if (T = 0) then PC = PC + k + 1 None 1 / 2 BRVS K Branch if Overflow Flag is Set if (V = 1) then PC = PC + k + 1 None 1 / 2 BRVC K Branch if Overflow Flag is Cleared if (V = 0) then PC = PC + k + 1 None 1 / 2 BRIE K Branch if Interrupt Enabled if ( I = 1) then PC = PC + k + 1 None 1 / 2 BRID K Branch if Interrupt Disabled if ( I = 0) then PC = PC + k + 1 None 1 / 2 DATA TRANSFER INSTRUCTIONS MOV Rd, Rr Copy Register Rd = Rr None 1 LDI Rd, K Load Immediate Rd = K None 1 LDS Rd, k Load Direct Rd = (k) None 2 LD Rd, X Load Indirect Rd = (X) None 2 LD Rd, X+ Load Indirect and Post-Increment Rd = (X), X = X + 1 None 2 LD Rd, -X Load Indirect and Pre-Decrement X = X - 1, Rd =(X) None 2 LD Rd, Y Load Indirect Rd = (Y) None 2 LD Rd, Y+ Load Indirect and Post-Increment Rd = (Y), Y = Y + 1 None 2 LD Rd, -Y Load Indirect and Pre-Decrement Y = Y - 1, Rd = (Y) None 2 LDD Rd,Y+q Load Indirect with Displacement Rd = (Y + q) None 2 LD Rd, Z Load Indirect Rd = (Z) None 2 LD Rd, Z+ Load Indirect and Post-Increment Rd = (Z), Z = Z+1 None 2 LD Rd, -Z Load Indirect and Pre-Decrement Z = Z - 1, Rd = (Z) None 2 LDD Rd, Z+q Load Indirect with Displacement Rd = (Z + q) None 2 STS k, Rr Store Direct (k) = Rr None 2 ST X, Rr Store Indirect (X) = Rr None 2 ST X+, Rr Store Indirect and Post-Increment (X) = Rr, X = X + 1 None 2 ST -X, Rr Store Indirect and Pre-Decrement X = X - 1, (X) = Rr None 2 ST Y, Rr Store Indirect (Y) = Rr None 2 ST Y+, Rr Store Indirect and Post-Increment (Y) = Rr, Y = Y + 1 None 2 ST -Y, Rr Store Indirect and Pre-Decrement Y = Y - 1, (Y) = Rr None 2 STD Y+q,Rr Store Indirect with Displacement (Y + q) = Rr None 2 ST Z, Rr Store Indirect (Z) = Rr None 2 ST Z+, Rr Store Indirect and Post-Increment (Z) = Rr, Z = Z + 1 None 2 ST -Z, Rr Store Indirect and Pre-Decrement Z = Z - 1, (Z) = Rr None 2 STD Z+q,Rr Store Indirect with Displacement (Z + q) = Rr None 2 LPM Load Program Memory R0 =(Z) None 3 IN Rd, P In Port Rd = P None 1 OUT P, Rr Out Port P = Rr None 1 PUSH Rr Push Register on Stack STACK = Rr None 2 POP Rd Pop Register from Stack Rd = STACK None 2 BIT AND BIT-TEST INSTRUCTIONS LSL Rd Logical Shift Left Rd(n+1) =Rd(n),Rd(0)= 0,C=Rd(7) Z,C,N,V,H 1 LSR Rd Logical Shift Right Rd(n) = Rd(n+1), Rd(7) =0, C=Rd(0) Z,C,N,V 1 ROL Rd Rotate Left Through Carry Rd(0) =C, Rd(n+1) =Rd(n),C=Rd(7) Z,C,N,V,H 1 ROR Rd Rotate Right Through Carry Rd(7) =C,Rd(n) =Rd(n+1),C¬Rd(0) Z,C,N,V 1 ASR Rd Arithmetic Shift Right Rd(n) = Rd(n+1), n=0..6 Z,C,N,V 1 SWAP Rd Swap Nibbles Rd(3..0) « Rd(7..4) None 1 BSET S Flag Set SREG(s) = 1 SREG(s) 1 BCLR S Flag Clear SREG(s) = 0 SREG(s) 1 SBI P, b Set Bit in I/O Register I/O(P, b) = 1 None 2 CBI P, b Clear Bit in I/O Register I/O(P, b) = 0 None 2 BST Rr, b Bit Store from Register to T T = Rr(b) T 1 BLD Rd, b Bit load from T to Register Rd(b) = T None 1 SEC Set Carry C = 1 C 1 CLC Clear Carry C = 0 C 1 SEN Set Negative Flag N = 1 N 1 CLN Clear Negative Flag N = 0 N 1 SEZ Set Zero Flag Z = 1 Z 1 CLZ Clear Zero Flag Z = 0 Z 1 SEI Global Interrupt Enable I = 1 I 1 CLI Global Interrupt Disable I = 0 I 1 SES Set Signed Test Flag S = 1 S 1 CLS Clear Signed Test Flag S = 0 S 1 SEV Set Twos Complement Overflow V = 1 V 1 CLV Clear Twos Complement Overflow V = 0 V 1 SET Set T in SREG T = 1 T 1 CLT Clear T in SREG T = 0 T 1 SHE Set Half Carry Flag in SREG H = 1 H 1 CLH Clear Half Carry Flag in SREG H = 0 H 1 NOP No Operation None 1 SLEEP Sleep None 1 WDR Watchdog Reset None 1 XMEGA ONLY LAC Load and clear RAM loc None 2 LAT Load and toggle RAM loc None 2 LAS Load and set RAM loc None 2 XCH Exchange RAM loc None 2 * ) Not available in base-line microcontrollers The Assembler is not case sensitive. The operands have the following forms: Rd: R0-R31 or R16-R31 (depending on instruction) Rr: R0-R31 b: Constant (0-7) s: Constant (0-7) P: Constant (0-31/63) K: Constant (0-255) k: Constant, value range depending on instruction. q: Constant (0-63) Rdl: R24, R26, R28, R30. For ADIW and SBIW instructions Reserved Words Top Previous Next See Keyword Reference Additional, there are also these reserved words : LBYTE , HBYTE, TYPE Error Codes Top Previous Next The following table lists errors that can occur. Error Description 1 Unknown statement 2 Unknown structure EXIT statement 3 WHILE expected 4 No more space for IRAM BIT 5 No more space for BIT 6 . expected in filename 7 IF THEN expected 8 BASIC source file not found 9 Maximum 128 aliases allowed 10 Unknown LCD type 11 INPUT, OUTPUT, 0 or 1 expected 12 Unknown CONFIG parameter 13 CONST already specified 14 Only IRAM bytes supported 15 Wrong data type 16 Unknown Definition 17 9 parameters expected 18 BIT only allowed with IRAM or SRAM 19 STRING length expected (DIM S AS STRING * 12 ,for example) 20 Unknown DATA TYPE 21 Out of IRAM space 22 Out of SRAM space 23 Out of XRAM space 24 Out of EPROM space 25 Variable already dimensioned 26 AS expected 27 parameter expected 28 IF THEN expected 29 SELECT CASE expected 30 BIT's are GLOBAL and can not be erased 31 Invalid data type 32 Variable not dimensioned 33 GLOBAL variable can not be ERASED 34 Invalid number of parameters 35 3 parameters expected 36 THEN expected 37 Invalid comparison operator 38 Operation not possible on BITS 39 FOR expected 40 Variable can not be used with RESET 41 Variable can not be used with SET 42 Numeric parameter expected 43 File not found 44 2 variables expected 45 DO expected 46 Assignment error 47 UNTIL expected 50 Value doesn't fit into INTEGER 51 Value doesn't fit into WORD 52 Value doesn't fit into LONG 60 Duplicate label 61 Label not found 62 SUB or FUNCTION expected first 63 Integer or Long expected for ABS() 64 , expected 65 device was not OPEN 66 device already OPENED 68 channel expected 70 BAUD rate not possible 71 Different parameter type passed then declared 72 Getclass error. This is an internal error. 73 Printing this FUNCTION not yet supported 74 3 parameters expected 80 Code does not fit into target chip 81 Use HEX(var) instead of PRINTHEX 82 Use HEX(var) instead of LCDHEX 85 Unknown interrupt source 86 Invalid parameter for TIMER configuration 87 ALIAS already used 88 0 or 1 expected 89 Out of range : must be 1-4 90 Address out of bounds 91 INPUT, OUTPUT, BINARY, or RANDOM expected 92 LEFT or RIGHT expected 93 Variable not dimensioned 94 Too many bits specified 95 Falling or rising expected for edge 96 Pre scale value must be 1,8,64,256 or 1024 97 SUB or FUNCTION must be DECLARED first 98 SET or RESET expected 99 TYPE expected 100 No array support for IRAM variables 101 Can't find HW-register 102 Error in internal routine 103 = expected 104 LoadReg error 105 StoreBit error 106 Unknown register 107 LoadnumValue error 108 Unknown directive in device file 109 = expected in include file for .EQU 110 Include file not found 111 SUB or FUNCTION not DECLARED 112 SUB/FUNCTION name expected 113 SUB/FUNCTION already DECLARED 114 LOCAL only allowed in SUB or FUNCTION 115 #channel expected 116 Invalid register file 117 Unknown interrupt 126 NEXT expected. 129 ( or ) missing. 200 .DEF not found 201 Low Pointer register expected 202 .EQU not found, probably using functions that are not supported by the selected chip 203 Error in LD or LDD statement 204 Error in ST or STD statement 205 } expected 206 Library file not found 207 Library file already registered 210 Bit definition not found 211 External routine not found 212 LOW LEVEL, RISING or FALLING expected 213 String expected for assignment 214 Size of XRAM string 0 215 Unknown ASM mnemonic 216 CONST not defined 217 No arrays allowed with BIT/BOOLEAN data type 218 Register must be in range from R16-R31 219 INT0-INT3 are always low level triggered in the MEGA 220 Forward jump out of range 221 Backward jump out of range 222 Illegal character 223 * expected 224 Index out of range 225 () may not be used with constants 226 Numeric of string constant expected 227 SRAM start greater than SRAM end 228 DATA line must be placed after the END statement 229 End Sub or End Function expected 230 You can not write to a PIN register 231 TO expected 232 Not supported for the selected micro 233 READ only works for normal DATA lines, not for EPROM data 234 ') block comment expected first 235 '( block comment expected first 236 Value does not fit into byte 238 Variable is not dimensioned as an array 239 Invalid code sequence because of AVR hardware bug 240 END FUNCTION expected 241 END SUB expected 242 Source variable does not match the target variable 243 Bit index out of range for supplied data type 244 Do not use the Y pointer 245 No arrays supported with IRAM variable 246 No more room for .DEF definitions 247 . expected 248 BYVAL should be used in declaration 249 ISR already defined 250 GOSUB expected 251 Label must be named SECTIC 252 Integer or Word expected 253 ERAM variable can not be used 254 Variable expected 255 Z or Z+ expected 256 Single expected 257 "" expected 258 SRAM string expected 259 - not allowed for a byte 260 Value larger than string length 261 Array expected 262 ON or OFF expected 263 Array index out of range 264 Use ECHO OFF and ECHO ON instead 265 offset expected in LDD or STD like Z+1 266 TIMER0, TIMER1 or TIMER2 expected 267 Numeric constant expected 268 Param must be in range from 0-3 269 END SELECT expected 270 Address already occupied 322 Data type not supported with statement 323 Label too long 324 Chip not supported by I2C slave library 325 Pre-scale value must be 1,8,32,128,256 or 1024 326 #ENDIF expected 327 Maximum size is 255 328 Not valid for SW UART 329 FileDateTime can only be assigned to a variable 330 Maximum value for OUT is &H3F 332 $END ASM expected 334 ') blockcomment end expected 335 Use before DIM statements 336 Could not set specified CLOCK value 337 No more space for labels 338 AS expected 339 Bytes to read may not be 0. 340 Variable is used as CONSTANT 341 OFFSET Error, contact MCS 342 OFFSET not allowed, too many locals used 343 Variable not supported with this function/statement 344 Program will overwrite bootloader 345 UART not available for the selected micro 346 External interrupt not supported or no settings found in DAT file 347 External interrupt mode not supported or found in DAT file 349 Setting not supported or not found in DAT file 350 Interrupt needs return 351 Not supported yet. 352 ALIAS can not be CONST or DIMMED variable 353 Reserved word may not be used 354 Previous Macro definition must be ended first 355 Macro previously defined 356 String constant size exceeded 357 Too many constants, increase resource languages 358 .DEF error, already defined 359 Operation not allowed on register 360 PRESCALE can not be used in COUNTER mode 361 Member expected 362 SBIC or SBIS was used followed by IN, OUT, SBIC, SBIS, SBI or CBI that also need to be converted. 363 No more room for EPROM DATA Index 364 Name not allowed, is used by constant/variable 365 Function not allowed in PRINT 366 Bit value out or range 367 Function name not allowed 368 Name used by label 369 Duplicate label name used by const or variable 370 Out of Flash memory 371 Function not allowed 372 SE entry missing in DAT file 373 Re-Configuration not allowed 374 . not allowed. 375 Duplicate definition 376 Config not found 377 Unexpected non numeric characters found 378 CAN BAUD not possible 379 Syntax error 380 Array<>Non Array mismatch 381 CONFIG RC5 not found 382 variable does not match FOR 383 Register range must be within [R16-R23] 384 Register range must be within [R16-R31] 385 Register must be even within [R0-R30] 386 Register R0 expected 387 IO address must be in range [0-31] 388 Bit number must be in range [0-7] 389 Constant out of range [0-65535] 390 Float not allowed for index 391 JTAG can not be disabled 392 Invalid operator 393 UART is fixed 394 Unsupported data type for BYREG 395 Index out of range 396 Delay not possible with selected frequency. Use WAITMS 397 .ORG exceeds PC 398 Single or Double expected 999 DEMO/BETA only supports 4096 bytes of code 9999 Illegal version. Please remove this illegal crack. You will not always get this message or error. When bascom finds traces of an illegal version it will generated random bugs in your code which are hard to find. It can also show this error. Only download software from the mcselec.com server. Other error codes are internal ones. Please report them to support@ when you encounter them. The Code explorer can give different errors. Here is a table with errors and how you can modify your code. Config Lcd = 16 * 2 Config Lcd = 16X2 Change the * into an X Cursor Off Noblink Cursor Off , Noblink Add a comma Newbie problems Top Previous Next When you are using the AVR like ATTINY, ATMEGA, ATXMEGA without knowledge of the architecture you can experience some problems as a Newbie. Regarding XMEGA see also ATXMEGA As a newbie always use stack and framesize (until you know what you do) ! $hwstack = 24 $swstack = 10 $framesize = 30 When you encounter problems always try to increase the values behind the stack's and framesize and test the program again. If you want to learn more about hwstack, swstack and framesize start with Memory usage Do not include too much in Interrupt Service Routines (ISR). Keep the ISR as short as possible ! Avoid something like print function in ISR (temporarily for debugging this is OK). See also Language Fundamentals FAQ: Question: What can I use as the first "Hello World" Bascom-AVR program ? Answer: Following a "Hello World" example: $regfile = "m16def.dat" ' specify the used AVR $crystal = 8000000 ' used crystal frequency $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space $baud = 19200 ' use baud rate 19200 baud Do Print "Hello World" ' Print Hello World Waitms 1000 ' Wait 1000ms = 1 second Loop End ' end program With ATTINY and ATMEGA you need to check if the fuse bits are set correct for the 8MHz (for this example). Some chips will be shipped by the manufacturer (Atmel) with 1MHz frequency fuse bit settings. If you want to change the UART Interface (like stopbits) use this here in addition to $baud. (Dummy is used because the baudrate is already configured with $baud = 19200 ) Config Com1 = Dummy, Synchrone = 0, Parity = None, Stopbits = 1, Databits = 8, Clockpol = 0 Q: How can I program (flash) the AVR with Bascom ? A: You can use an external programmer. See Supported Programmers (For ATTINY you need to use an external hardware programmer) You can also use the MCS bootloader MCS Bootloader (ATMEGA or ATXMEGA) See also Application Note: 143 http://www.mcselec.com/index.php?option=com_content&task=view&id=159&Itemid=57 Instead of using the BASCOM-AVR build in programmer you can also use our stand alone Bootloader application (for Windows): http://www.mcselec.com/index.php?option=com_docman&task=doc_download&gid=153&Itemid=54 Q: I'm using an Arduino hardware with Bascom-AVR. How can I program it ? A: See ARDUINO Q: I can not set a pin high or low ? I can not read the input on a pin ? A: The AVR has 3 registers for each port. A port normally consists of 8 pins. A port is named with a letter from A-F (ATMEGA) and even more with ATXMEGA. All parts have PORTB. When you want to set a single pin high or low you can use the SET and RESET statements. But before you use them the AVR chip must know in which direction you are going to use the pins. Therefore there is a register named DDRx for each port. In our sample it is named DDRB. When you write a 0 to the bit position of the pin you can use the pin as an input. When you write a 1 you can use it as output. You can also use CONFIG PORTX.Y = INPUT|OUTPUT After the direction bit is set you must use either the PORTx register to set a logic level or the PINx register to READ a pin level. Yes the third register is the PINx register. In our sample, PINB. For example we like to use PORTB.7 as an OUTPUT pin: CONFIG PORTB.7=OUTPUT ' will write a '1' to DDRB.7 SET PORTB.7 ' will set the MS bit to +5V RESET PORTB.7 ' will set MS bit to 0 V When using a PIN in INPUT mode, you can also activate an internal pull up resistor. Pull up means that the pin is connected with an internal resistor to VCC. To enable the pull up resistor, you need to write a '1' to the PORT register. Example to read PORTB.0 pin : CONFIG PORTB.0=INPUT ' clears DDRB.0 PORTB.0=1 ' activate pull up Print PINB.0 ' will read LS bit and send it to the RS-232 You may also read from PORTx but it will return the value that was last written to it and not the input of the pin. To read or write whole bytes use : PORTB = 0 ' write 0 to register making all pins low PRINT PINB ' print input on pins Config a Pin as output: Config Porte.0 = Output which is the same as: DDRE = &B00000001 or can be written as: set DDRE.0 Set Output: Set porte.0 which is the same as: porte.0 = 1 Reset Output: Reset porte.0 which is the same as: porte.0 = 0 Config a Pin as Input: Config Pine.0 = Input which is the same as: DDRE.0 = 0 or can be written as: DDRE = &B00000000 Read Input: Variabel = PINE.0 To check one pin for status in an if .... statement: If Pine.0 = 1 Then ' do someting.... End If Q: I want to write a special character but they are not printed correct ? A: Well this is not a newbie problem but I put it here so you could find it. Some ASCII characters above 127 are interpreted wrong depending on country settings. To print the right value use : PRINT "Test{123}?" The {xxx} will be replaced with the correct ASCII character. You must use 3 digits otherwise the compiler will think you want to print {12} for example. This should be {012} Q: My application was working but with a new micro it is slow and print funny ? A: Most new micro�s have an internal oscillator that is enabled by default. As it runs on 1 or 2 or 4 or 8 or 32 MHz, this might be slower or faster then your external or internal crystal. This results in slow operation. As the baud rate is derived from the clock, it will also result in wrong baud rates. Solution : change frequency with $crystal so the internal clock will be used. Or change the fuse bits (or change config with XMEGA) so correct clock source like external xtal will be used. Q: Some bits on Port C are not working ? A: Some chips have a JTAG interface. Disable it with the proper fuse bit . Or use DISABLE JTAG in your code. Q: Can I use an ATTINY or ATMEGA as TWI/I2C Slave ? A: Yes, there is a commercial add on Bascom library available Here the link: I2CSLAVE Library (Download version) See also: CONFIG TWISLAVE Q: What is Overlay ? A: See DIM Q: Is there a way to use a buffer with software UART ? A: No, this is not supported. Q: I have an ATTINY without UART or I need an additional UART on ATMEGA. Is there a "Software UART" in Bascom-AVR ? A: See Using the UART and scroll down to SOFTWARE UART Q: How can I start with ATXMETGA and Bascom-AVR ? A: See ATXMEGA Q: How to declare a subroutine or function ? A: See DECLARE SUB or DECLARE FUNCTION Q: I have a number like 1234.888999 but I just want to have one digit after decimal point (1234.8). How can I do that ? A: See CONFIG SINGLE Q: How can I set or reset single bits in byte/integer/long variables ? A: There are several ways to write or read a single bit: 1. You can use NBITS or BITS to set or reset one or more bits 2. You can use it following way: Example on how to set/reset single bits in a variable. Dim my_long_var As Long My_long_var.0 = 1 You can also use SET or RESET Set My_long_var.31 Reset My_long_var.31 You even can use a variable as index Dim Idx As Byte Idx = 3 Reset My_long_var.idx For a long variable Idx can be from 0......31 For an integer Idx can be from 0....15 For a byte Idx can be from 0......7 3. You can use BITWAIT to wait until a bit is set (1) or reset (0). Example: Dim A As Bit Bitwait A , Set ' wait until bit a is set 'the above will never continue because it is not set i software 'it could be set in an ISR routine Bitwait Pinb.7 , Reset ' wait until bit 7 of Port B is 0. 4. You can use TOGGLE to invert the state of a bit Dim my_long_var As Long Toggle My_long_var.31 Q: Can I create BIT ARRAYS larger then a LONG variable ? A: Yes, here is a way to do it: $regfile = "m162def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Dim Byte_arr(32) As Byte Dim Idx As Byte Byte_arr(1).8 = 1 Print "Byte_arr(2) = " ; Bin(byte_arr(2)) Byte_arr(1).15 = 1 Print "Byte_arr(2) = " ; Bin(byte_arr(2)) Byte_arr(1).29 = 1 Print "Byte_arr(4) = " ; Bin(byte_arr(4)) Idx = 63 Byte_arr(1).idx = 1 Print "Byte_arr(8) = " ; Bin(byte_arr(8)) Idx = 255 Byte_arr(1).idx = 1 Print "Byte_arr(32) = " ; Bin(byte_arr(32)) '( Bascom Simulator Output = Byte_arr(2) = 00000001 Byte_arr(2) = 10000001 Byte_arr(4) = 00100000 Byte_arr(8) = 10000000 Byte_arr(32) = 10000000 ') End Q: Can I pass a BIT variable to SUB routines or user FUNCTION ? A: You can not pass BIT variables to SUB routines or user FUNCTION Use a BYTE for that. Here is one of many workarounds for that: $regfile = "m162def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Submode = New Dim C As Byte Sub Test(byref B As Byte) Local C As Byte C = B And &B00000001 If C = 1 Then Print "B = 1" Else Print "B = 0" End If End Sub 'Main program Set C.0 Call Test(c) Reset C.0 Call Test(c) End ' end program Q: Can I dimension a LOCAL variable in a function or sub routine as BIT ? A: You can not. BIT variables are not possible because they are GLOBAL to the system. Q: I still have a problem. What to do ? A: Here is the link to the Bascom-AVR forum: http://www.mcselec.com/index2.php?option=com_forum&Itemid=59 At first please try to search the forum (often you can find users with the same problem) . The search page is here: http://www.mcselec.com/index2.php?option=com_forum&Itemid=59&page=search If the forum can not help you, here is the Email address for support: support@mcselec.com PLEASE provide as much as possible information in your post or Email: - Include the Bascom-AVR version number and your serial number in the Email to support Do not post your serial number in the Forum !!! - Always test with the latest available version, support is only available for the latest version - Include a small sample that will demonstrate the error. - Make sure you include all required files for compilation or for showing the problem. - Be clear if the problem exist in the simulator or the hardware and what kind of hardware you use Tips and tricks Top Previous Next Tips & Tricks: 1. You can specify a binary number with the &B and you can use underscore "_" like: Dim Var As Byte Var = &B00_110000 Var = &B0000_1111 Var = &B00_11_00_11 2. How to use longer formulas: Dim A As Byte Dim B As Byte Dim C As Byte ' Now you want to use following formula: a = B / 4 + C ' In Bascom you write A = B / 4 A = A + C 3. You can use more than one Bascom statement in one line with colons ":" Dim A As Byte Dim B As Byte Dim C As Byte ' Now you want to use following formula: a = B / 4 + C ' In Bascom you write A = B / 4 : A = A + C 4. You can use overlay to have easy access to the low byte and high byte of a WORD (the same approach also work for e.g. LONG) Dim My_word As Word Dim Low_byte As Byte At My_word Overlay Dim High_byte As Byte At My_word + 1 Overlay Low_byte = &B0000_1111 High_byte = &B1111_0000 ' This is how it will be stored in SRAM ' <-------my_word--------> ' +-----------+----------+ ' | Low_byte |High_byte | ' +-----------+----------+ 5. To split a word into High byte and Low byte you can also use HIGH and LOW 6. Here is a way to print the content of a variable or AVR register: Use Print Bin(X) Example: $regfile = "m88def.dat" ' we use the M88 $crystal = 8000000 $baud = 19200 $hwstack = 32 $swstack = 8 $framesize = 24 Dim A As Byte A = &B00000001 A = A * 2 Print Bin(a) End ' end program 7. If you do not want that Bascom-AVR is sending Carriage + Return after a print command use semi-colon ";" after the print funtion: Example: $regfile = "m88def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Print "Hello World" ; End 8. For the user who want to use external editors: The bascomp.exe has been updated. It can be downloaded from the download section. It now supports a simpler way to be called. The utility has been updated and now will retrieve all info from the source file, but only when your main program contains these directive : $regfile, $hwstack, $swstack, $framesize Example : bascomp.exe "c:\my folder\source\sample.bas" auto The 'auto' is a switch so the utility will retrieve the settings from your code. 9. You can use $initmicro if you want to run special tasks at startup: See $INITMICRO 10. You can use $include to make larger projects better readable: See $INCLUDE 11. Your LCD is not working and you need a list of steps what do check: a. Check fuse bit settings b. Are the AVR pins are OK ? To test the AVR pins you can do following: Write a program that toggles all the lcd pins and then measure the logic level. Then check with a DVM or led-series resistor if all pins change level. if they do, there is a problem with the lcd If the pin do not toggle: - pin defect - track or solder problem. Here the test program: $regfile = "m328pdef.dat" ' Specify The Used Micro $crystal = 16000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for thehardware stack $swstack = 10 ' default use 10 for theSW stack $framesize = 40 ' default use 40 for theframe space Config Clockdiv = 1 ' divide xtal clock by 1, default fuse bit is set ' to 8 by elektor Config Portc.3 = Output ' RW Config Portd.4 = Output ' Db4 Config Portd.5 = Output ' Db5 Config Portd.6 = Output ' Db6 Config Portd.6 = Output ' Db7 Config Portc.1 = Output ' E Config Portc.2 = Output ' RS do toggle portc toggle portd waitms 1000 Loop End ' end program 12. With the Lib Manager you can compile a Library (*.lib) into an *.lbx file. See here: Tools LIB Manager 13. There is a timeout function for hardware and software UART See $TIMEOUT 14. How to use the Powerdown function: See also: CONFIG POWERMODE If you can not measure the same power down current as written in the data sheet you also need to use a Low Quiescent Current LDO Regulator to meet that specs (if you measure the current including the Current LDO Regulator). Examples for 3.3Volt Low Quiescent Current LDO Regulator : · MCP1702 --> typical 2µA · MCP1700 --> typical 1.6µA · AS1375 low power LDO --> 1µA (typ.) of quiescent current · TPS78233 3,3V --> 0.4µA ' Using the new config powermode = PowerDown function with ATTINY13 ' Used Bascom-AVR Version 2.0.7.3 ' Fuse Bits: ' Disable DWEN (Debug Wire) Fuse Bit ' Disable Brown-Out Detection in Fuse Bits ' Disable Watchdog in Fuse Bits ' You can also just use Config Powermode = Powerdown ' But this example here also considers what the data sheet write under "MINIMIZING POWER CONSUMPTION" ' You need to follow this when you want to achieve the current consumption which you find in the ' data sheet under Powerdown Mode. ' 1. Disable/Switch off ADC ' 2. Disable/Switch off Analog Comparator ' 3. Disable Brown-out Detection when not needed ' 4. Disable internal voltage reference ' 5. Disable Watchdog Timer when not needed ' 6. Disable the digital input buffer ' 7. Enable Pull-up or pull-down an all unused pins $regfile = "attiny13.dat" $crystal = 9600000 ' 9.6MHz $hwstack = 10 $swstack = 0 $framesize = 24 On Int0 Int0_isr ' INT0 will be the wake-up source for Powerdown Mode Config Int0 = Low Level Enable Int0 ' Prepare Powerdown: ' To minimize power consumption, enable pull-up or -down on all unused pins, and ' disable the digital input buffer on pins that are connected to analog sources Config Portb.0 = Input Set Portb.0 Config Portb.1 = Input ' INT0 --> external 47K pull-up 'Set Portb.1 Config Portb.2 = Input Set Portb.2 Config Portb.3 = Input Set Portb.3 Config Portb.4 = Input Set Portb.4 Config Portb.5 = Input ' External Pull-Up (Reset) Didr0 = Bits(ain1d , Ain0d) ' Disable digital input buffer on the AIN1/0 pin Set Acsr.acd ' Switch off the power to the Analog Comparator ' alternative: ' Stop Ac Reset Acsr.acbg ' Disable Analog Comparator Bandgap Select Reset Adcsra.aden ' Switch off ADC ' alternative: ' Stop Adc '############################################################################### Do Wait 3 ' now we have 3 second to measure the Supply Current ' in Active Mode Enable Interrupts ' Now call Powerdown function Config Powermode = Powerdown ' Here you have time to measure PowerDown current consumption until a Low Level ' on Portb.1 which is the PowerDown wake-up Loop '############################################################################### End Int0_isr: ' wake_up Return ASCII chart Top Previous Next Decimal Octal Hex Binary Value ------- ----- --- ------ ----- 000 000 000 00000000 NUL (Null char) 001 001 001 00000001 SOH (Start of Header) 002 002 002 00000010 STX (Start of Text) 003 003 003 00000011 ETX (End of Text) 004 004 004 00000100 EOT (End of Transmission) 005 005 005 00000101 ENQ (Enquiry) 006 006 006 00000110 ACK (Acknowledgment) 007 007 007 00000111 BEL (Bell) 008 010 008 00001000 BS (Backspace) 009 011 009 00001001 HT (Horizontal Tab) 010 012 00A 00001010 LF (Line Feed) 011 013 00B 00001011 VT (Vertical Tab) 012 014 00C 00001100 FF (Form Feed) 013 015 00D 00001101 CR (Carriage Return) 014 016 00E 00001110 SO (Shift Out) 015 017 00F 00001111 SI (Shift In) 016 020 010 00010000 DLE (Data Link Escape) 017 021 011 00010001 DC1 (XON) (Device Control 1) 018 022 012 00010010 DC2 (Device Control 2) 019 023 013 00010011 DC3 (XOFF)(Device Control 3) 020 024 014 00010100 DC4 (Device Control 4) 021 025 015 00010101 NAK (Negative Acknowledgement) 022 026 016 00010110 SYN (Synchronous Idle) 023 027 017 00010111 ETB (End of Trans. Block) 024 030 018 00011000 CAN (Cancel) 025 031 019 00011001 EM (End of Medium) 026 032 01A 00011010 SUB (Substitute) 027 033 01B 00011011 ESC (Escape) 028 034 01C 00011100 FS (File Separator) 029 035 01D 00011101 GS (Group Separator) 030 036 01E 00011110 RS (Request to Send)(Record Separator) 031 037 01F 00011111 US (Unit Separator) 032 040 020 00100000 SP (Space) 033 041 021 00100001 ! (exclamation mark) 034 042 022 00100010 " (double quote) 035 043 023 00100011 # (number sign) 036 044 024 00100100 $ (dollar sign) 037 045 025 00100101 % (percent) 038 046 026 00100110 & (ampersand) 039 047 027 00100111 ' (single quote) 040 050 028 00101000 ( (left/opening parenthesis) 041 051 029 00101001 ) (right/closing parenthesis) 042 052 02A 00101010 * (asterisk) 043 053 02B 00101011 + (plus) 044 054 02C 00101100 , (comma) 045 055 02D 00101101 - (minus or dash) 046 056 02E 00101110 . (dot) 047 057 02F 00101111 / (forward slash) 048 060 030 00110000 0 049 061 031 00110001 1 050 062 032 00110010 2 051 063 033 00110011 3 052 064 034 00110100 4 053 065 035 00110101 5 054 066 036 00110110 6 055 067 037 00110111 7 056 070 038 00111000 8 057 071 039 00111001 9 058 072 03A 00111010 : (colon) 059 073 03B 00111011 ; (semi-colon) 060 074 03C 00111100 < (less than) 061 075 03D 00111101 = (equal sign) 062 076 03E 00111110 > (greater than) 063 077 03F 00111111 ? (question mark) 064 100 040 01000000 @ (AT symbol) 065 101 041 01000001 A 066 102 042 01000010 B 067 103 043 01000011 C 068 104 044 01000100 D 069 105 045 01000101 E 070 106 046 01000110 F 071 107 047 01000111 G 072 110 048 01001000 H 073 111 049 01001001 I 074 112 04A 01001010 J 075 113 04B 01001011 K 076 114 04C 01001100 L 077 115 04D 01001101 M 078 116 04E 01001110 N 079 117 04F 01001111 O 080 120 050 01010000 P 081 121 051 01010001 Q 082 122 052 01010010 R 083 123 053 01010011 S 084 124 054 01010100 T 085 125 055 01010101 U 086 126 056 01010110 V 087 127 057 01010111 W 088 130 058 01011000 X 089 131 059 01011001 Y 090 132 05A 01011010 Z 091 133 05B 01011011 [ (left/opening bracket) 092 134 05C 01011100 \ (back slash) 093 135 05D 01011101 ] (right/closing bracket) 094 136 05E 01011110 ^ (caret/circumflex) 095 137 05F 01011111 _ (underscore) 096 140 060 01100000 ` 097 141 061 01100001 a 098 142 062 01100010 b 099 143 063 01100011 c 100 144 064 01100100 d 101 145 065 01100101 e 102 146 066 01100110 f 103 147 067 01100111 g 104 150 068 01101000 h 105 151 069 01101001 i 106 152 06A 01101010 j 107 153 06B 01101011 k 108 154 06C 01101100 l 109 155 06D 01101101 m 110 156 06E 01101110 n 111 157 06F 01101111 o 112 160 070 01110000 p 113 161 071 01110001 q 114 162 072 01110010 r 115 163 073 01110011 s 116 164 074 01110100 t 117 165 075 01110101 u 118 166 076 01110110 v 119 167 077 01110111 w 120 170 078 01111000 x 121 171 079 01111001 y 122 172 07A 01111010 z 123 173 07B 01111011 { (left/opening brace) 124 174 07C 01111100 | (vertical bar) 125 175 07D 01111101 } (right/closing brace) 126 176 07E 01111110 ~ (tilde) 127 177 07F 01111111 DEL (delete) #AUTOCODE Top Previous Next Action Informs the IDE that code can be maintained by the IDE. Syntax #AUTOCODE CONFIG STATEMENTS #ENDAUTOCODE Remarks Auto code informs the IDE that it may alter the code. A new IDE uses a property editor for the configuration. It will only update, add or delete, CONFIG statements that are enclosed in an #AUTOCODE block. #AUTOCODE must be closed with a matching #ENDAUTOCODE You can still use CONFIG statements in other places of your code. But the property editor will only work on the ones inside the block. The compiler will ignore #AUTOCODE and #ENDAUTOCODE. #IF ELSE ELSEIF ENDIF Top Previous Next Action Conditional compilation directives intended for conditional compilation. Syntax #IF condition #ELSEIF condition #ELSE #ENDIF Remarks Conditional compilation is supported by the compiler. What is conditional compilation? Conditional compilation will only compile parts of your code that meet the criteria of the condition. By default all your code is compiled. Conditional compilation needs a constant to test. So before a condition can be tested you need to define a constant. CONST test = 1 #IF TEST Print "This will be compiled" #ELSE Print "And this not" #ENDIF Note that there is no THEN and that #ENDIF is not #END IF (no space) You can nest the conditions and the use of #ELSE and #ELSEIF is optional. There are a few internal constants that you can use. These are generated by the compiler: _CHIP = 0 _RAMSIZE = 128 _ERAMSIZE = 128 _SIM = 0 _XTAL = 4000000 _BUILD = 11162 _CHIP is an integer that specifies the chip, in this case the 2313 _RAMSIZE is the size of the SRAM _ERAMSIZE is the size of the EEPROM _SIM is set to 1 when the $SIM directive is used _XTAL contains the value of the specified crystal _BUILD is the build number of the compiler. The build number can be used to write support for statements that are not available in a certain version : #IF _BUILD >= 11162 s = Log(1.1) #ELSE Print "Sorry, implemented in 1.11.6.2" #ENDIF Conditional compilation allows you to create different versions of your program but that you keep one source file. For example you could make a multi lingual program like this : CONST LANGUAGE=1 'program goes here #IF LANGUAGE=1 DATA "Hello" #ENDIF #IF LANGUAGE=2 DATA "Guten tag" #ENDIF By changing the just one constant you then have for example English or German data lines. Conditional compilation does not work with the $REGFILE directive. If you put the $REGFILE inside a condition or not, the compiler will use the first $REGFILE it encounters. This will be changed in a future version. A special check was added to 1.11.8.1 to test for existence of constants or variables. #IF varexist("S") ' the variable S was dimensioned so we can use it here #ELSE ' when it was not dimmed and we do need it, we can do it here DIM S as BYTE #ENDIF See Also CONST , Edit Show Excluded Code Compiler Directives Top Previous Next $AESKEY Top Previous Next Action This directive accepts a 16 byte AES key and informs the compiler to encrypt the binary image. Syntax $AESKEY 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 Remarks $AESKEY accepts 16 parameters. These are the 16 bytes which form a 128 bit key. When your code is compiled, the resulting binary code will be encrypted with the provided key. A boot loader could then use AES and decrypt the binary file before writing to flash memory. Only the binary image is encrypted, the HEX file is not encrypted! You can not simulate an encrypted program. Add this option when your project is ready. See also $XTEAKEY , AESENCRYPT , AESDECRYPT Example See the Samples\boot\xmega_dos_boot_AES.zip , an Xmega boot loader with AES decryption. $ASM Top Previous Next Action Start of inline assembly code block. Syntax $ASM Remarks Use $ASM together with $END ASM to insert a block of assembler code in your BASIC code. You can also precede each line with the ! sign. See also the chapter Mixing BASIC and Assembly and assembler mnemonics Example Dim C As Byte Loadadr C , X 'load address of variable C into register X $asm Ldi R24,1 ; load register R24 with the constant 1 St X,R24 ; store 1 into variable c $end Asm Print C End $BAUD Top Previous Next Action Instruct the compiler to override the baud rate setting from the options menu. Syntax $BAUD = var Remarks Var The baud rate that you want to use. This must be a numeric constant. The baud rate is selectable from the Compiler Settings. It is stored in a configuration file. The $BAUD directive overrides the setting from the Compiler Settings. In the generated report, you can view which baud rate is actually generated. The generated baud rate does depend on the used micro and crystal. When you simulate a program you will not notice any problems when the baud rate is not set to the value you expected. In real hardware a wrong baud rate can give weird results on the terminal emulator screen. For best results use a crystal that is a multiple of the baud rate. In the simulator you need to select the UART0-TAB to view the output of the UART0, or to send data to this UART. See also $CRYSTAL , BAUD Example $regfile = "m48def.dat" $crystal = 4000000 $baud = 19200 Config Com1 = Dummy, Synchrone = 0, Parity = None, Stopbits = 1, Databits = 8, Clockpol = 0 Print "Hello" 'Now change the baud rate in a program Baud = 9600 Print "Did you change the terminal emulator baud rate too?" End $BAUD1 Top Previous Next Action Instruct the compiler to set the baud rate for the second hardware UART. Syntax $BAUD1 = var Remarks Var The baud rate that you want to use. This must be a numeric constant. In the generated report, you can view which baud rate is actually generated. When you simulate a program you will not notice any problems when the baud rate is not set to the value you expected. In real hardware a wrong baud rate can give weird results on the terminal emulator screen. For best results use a crystal that is a multiple of the baud rate. Some AVR chips have 2 UARTS. For example the Mega161, Mega162, Mega103 and Mega128. There are several other's and some new chips even have 4 UARTS. In the simulator you need to select the UART1-TAB to view the output of the UART1, or to send data to this UART. See also $CRYSTAL , BAUD , $BAUD Example '------------------------------------------------------------------------------- 'copyright : (c) 1995-2016, MCS Electronics 'micro : Mega162 'suited for demo : yes 'commercial addon needed : no 'purpose : demonstrates BAUD1 directive and BAUD1 statement '------------------------------------------------------------------------------- $regfile = "M162def.dat" $baud1 = 2400 $crystal= 14000000 ' 14 MHz crystal Open "COM2:" For BINARY As #1 Print #1 , "Hello" 'Now change the baud rate in a program Baud1 = 9600 ' Print #1 , "Did you change the terminal emulator baud rate too?" Close #1 End $BGF Top Previous Next Action Includes a BASCOM Graphic File. Syntax $BGF "file" Remarks file The file name of the BGF file to include. Use SHOWPIC to display the BGF file. $BGF only task is to store the picture into the compressed BASCOM Graphics Format(BGF). See also SHOWPIC , PSET , CONFIG GRAPHLCD Example '----------------------------------------------------------------- ' (c) 1995-2016 MCS Electronics ' T6963C graphic display support demo '----------------------------------------------------------------- 'The connections of the LCD used in this demo ' LCD pin Connected to ' 1 GND GND ' 2 GND GND ' 3 +5V +5V ' 4 -9V -9V potmeter ' 5 /WR PORTC.0 ' 6 /RD PORTC.1 ' 7 /CE PORTC.2 ' 8 C/D PORTC.3 ' 9 NC not ' 10 RESET PORTC.4conneted ' 11-18 D0-D7 PA ' 19 FS PORTC.5 ' 20 NC not connected $crystal = 8000000 'First we define that we use a graphic LCD Config Graphlcd = 240 * 128 , Dataport = Porta , Controlport = Portc , Ce = 2 , Cd = 3 , Wr = 0 , Rd = 1 , Reset = 4 , Fs = 5 , Mode = 8 ' The dataport is the portname that is connected to the data lines of the LCD ' The controlport is the portname which pins are used to control the lcd ' CE, CD etc. are the pin number of the CONTROLPORT. ' For example CE =2 because it is connected to PORTC.2 ' mode 8 gives 240 / 8 = 30 columns , mode=6 gives 240 / 6 = 40 columns ' Dim variables (y not used) Dim X As Byte , Y As Byte ' Clear the screen will both clear text and graph display Cls ' Other options are : ' CLS TEXT to clear only the text display ' CLS GRAPH to clear only the graphical part Cursor Off Wait 1 ' locate works like the normal LCD locate statement ' LOCATE LINE,COLUMN LINE can be 1-8 and column 0-30 Locate 1 , 1 ' Show some text Lcd "MCS Electronics" ' And some other text on line 2 Locate 2 , 1 : Lcd "T6963c support" Locate 3 , 1 : Lcd "1234567890123456789012345678901234567890" Wait 2 Cls Text ' draw a line using PSET X,Y, ON/OFF ' PSET on.off param is 0 to clear a pixel and any other value to turn it on For X = 0 To 140 Pset X , 20 , 255 ' set the pixel Next Wait 2 ' Now it is time to show a picture ' SHOWPIC X,Y,label ' The label points to a label that holds the image data Showpic 0 , 0 , Plaatje Wait 2 Cls Text ' clear the text End ' This label holds the mage data Plaatje: ' $BGF will put the bitmap into the program at this location $bgf "mcs.bgf" ' You could insert other picture data here $BIGSTRINGS Top Previous Next Action Instruct the compiler to use big strings. Syntax $BIGSTRINGS Remarks By default each string has a maximum length of 254 bytes. A null character is used to mark the end of a string. When a longer string is needed, the compiler can not use bytes for passing the length. A word is needed to hold the length. The $BIGSTRINGS directive will include the bigstrings.lbx and will handle all string routines different when parameters are passed which influence the length. The alternative library contains modified routines for code not compatible with big strings. The following string routines are supported: ASC, CHARPOS GET INPUT LCD , INPUT SERIAL INSTR LCASE LEFT LEN MID RIGHT PUT UCASE See also DIM Example $BIGSTRINGS $BOOT Top Previous Next Action Instruct the compiler to include boot loader support. Syntax $BOOT = address Remarks address The boot loader address. This is a WORD address. Some new AVR chips have a special boot section in the upper memory of the flash. By setting some fuse bits you can select the code size of the boot section. The code size also determines the address of the boot loader. With the boot loader you can reprogram the chip when a certain condition occurs. The sample checks a pin to see if a new program must be loaded. When the pin is low there is a jump to the boot address. The boot code must always be located at the end of your program. It must be written in ASM since the boot loader may not access the application flash rom. This because otherwise you could overwrite your running code! The example is written for the M163. You can use the Upload file option of the terminal emulator to upload a new hex file. The terminal emulator must have the same baud rate as the chip. Under Options, Monitor, set the right upload speed and set a monitor delay of 20. Writing the flash take time so after every line a delay must be added while uploading a new file. The $BOOT directive is replaced by $LOADER. $LOADER works much simpler. $BOOT is however still supported. See also $LOADER , $LOADERSIZE Example See BOOT.BAS from the samples dir. But better look at the $LOADER directive. $BOOTVECTOR Top Previous Next Action This compiler directive will force the compiler to create an interrupt vector table(IVR). Syntax $BOOTVECTOR Remarks By default an IVR is always created for normal applications. There is no good reason not to create an IVR for a normal application. When making a boot loader application things are different. A boot loader application resides in upper flash memory inside the boot area. And when the boot loader applications runs, it has special rights so it can update the flash memory which resides in the lower flash memory. The boot loader area size depends on the processor but is usual small. An interrupt vector table can use up to 250 bytes or more and it would be a waste of space in many cases. So by default the $LOADER directive which is used to create a boot loader application, will not create an IVR. The downside is that when you do not have an IVR you can not use interrupts. The $BOOTVECTOR directive will force the compiler to create an IVR when the $LOADER directive is used. This way your boot loader application will include an IVR and you can use interrupts in your code. The $BOOTVECTOR directive will only work when the processor has an option to move the IVR to the boot area using the IVSEL bit. By default the interrupts are located after address 0. Address 0 is the reset vector and usually contains a jump to the real code. Behind the reset address, a table with jumps to the interrupt routines is located. That the code contains an IVR is not enough : in case of a boot loader the interrupt table must be moved to the boot area. For this purpose most processors have a register and bit to switch the IVR between the normal address 0 and the boot loader address. In BASCOM you can use : Config Intvectorselection = Enabled to set the selection to the boot area. When the boot loader application finishes, it is best to use a watchdog timeout to reset the processor so the intvector selection is set to the default address 0. Or you can use Config Intvectorselection = Disabled in your main (normal) application before you enable the interrupts. So in short you only need to add the $BOOTVECTOR directive and Config Intvectorselection = Enabled to your code. And do not forget to switch back the intvectorselection in the main application! See also $LOADER , CONFIG INTVECTORSELECTION , $REDUCEIVR Example '----------------------------------------------------------------- ' (c) 1995-2016, MCS ' BootEDB-IVSEL.bas ' This Bootloader is for the BASCOM-EDB ' VERSION 4 of the BOOTLOADER. ' IMPORTANT : ' When changing the vector table in the boot loader you MUST ' reset the vector table in your code using : ' Config Intvectorselection = Disabled ' otherwise your code points to the wrong table '----------------------------------------------------------------- 'The loader is supported by the IDE $prog &HFF , &HE2 , &HDF , &HF8 ' generated. Take care that the chip supports all fuse bytes.'---------------------------------------------------------------- $crystal = 8000000 $baud = 38400 'this loader uses serial com 'It is VERY IMPORTANT that the baud rate matches the one of the boot loader 'do not try to use buffered com as we can not use interrupts 'This bootloader uses buffers serial input Config Serialin = Buffered , Size = 250 'in order to use interrupts in a bootloader, the processor must support IVSEL 'since the vector table occupies space some processors will not support it. $bootvector ' put int table into bootloader section so we can use interrupts Config Intvectorselection = Enabled ' enabled means that the vector table points to the boot section 'since this boot loader uses interrupts we need to activate them but : 'AFTER the interrupt vector table is enabled Enable Interrupts $regfile = "m88def.dat" Const Loaderchip = 88 #if Loaderchip = 88 'Mega88 $loader = $c00 'this address you can find in the datasheet 'the loader address is the same as the boot vector address Const Maxwordbit = 5 Const Maxpages = 96 - 1 ' total WORD pages available for program Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 #endif Const Maxword =(2 ^ Maxwordbit) * 2 '128 Const Maxwordshift = Maxwordbit + 1 Const Cdbg = 0 ' leave this to 0 #if Cdbg Print Maxword Print Maxwordshift ' Print Maxpages #endif 'Dim the used variables Dim Bstatus As Byte , Bretries As Byte , Bblock As Byte , Bblocklocal As Byte Dim Bcsum1 As Byte , Bcsum2 As Byte , Buf(128) As Byte , Csum As Byte Dim J As Byte , Spmcrval As Byte ' self program command byte value Dim Z As Long 'this is the Z pointer word Dim Vl As Byte , Vh As Byte ' these bytes are used for the data values Dim Wrd As Word , Page As Word 'these vars contain the page and word address Dim Bkind As Byte , Bstarted As Byte 'Mega 88 : 32 words, 128 pages 'in this loader we may not disable interrupts ! 'Disable Interrupts 'we do not use ints 'Waitms 100 'wait 100 msec sec 'We start with receiving a file. The PC must send this binary file 'some constants used in serial com Const Nak = &H15 Const Cack = &H06 Const Can = &H18 'we use some leds as indication in this sample , you might want to remove it Config Pind.7 = Output Portd.7 = 0 $timeout = 200000 'we use a timeout 'When you get LOADER errors during the upload, increase the timeout value 'for example at 16 Mhz, use 200000 Bretries = 5 'we try 5 times Testfor123: #if Cdbg Print "Try " ; Bretries Print "Wait" #endif Bstatus = Waitkey() 'wait for the loader to send a byte #if Cdbg Print "Got " #endif Print Chr(bstatus); If Bstatus = 123 Then 'did we received value 123 ? Bkind = 0 'normal flash loader Goto Loader Elseif Bstatus = 124 Then ' EEPROM Bkind = 1 ' EEPROM loader Goto Loader Elseif Bstatus <> 0 Then Decr Bretries If Bretries <> 0 Then Goto Testfor123 'we test again End If For J = 1 To 10 'this is a simple indication that we start the normal reset vector Toggle Portd.7 : Waitms 100 Next #if Cdbg Print "RESET" #endif Goto _reset 'goto the normal reset vector at address 0 'this is the loader routine. It is a Xmodem-checksum reception routine Loader: #if Cdbg Print "Clear buffer" #endif Do Bstatus = Waitkey() Loop Until Bstatus = 0 For J = 1 To 3 'this is a simple indication that we start the normal reset vector Toggle Portd.7 : Waitms 250 Next If Bkind = 0 Then Spmcrval = 3 : Gosub Do_spm ' erase the first page Spmcrval = 17 : Gosub Do_spm ' re-enable page End If Bretries = 10 'number of retries Do Bblocklocal = 1 Bstarted = 0 ' we were not started yet Csum = 0 'checksum is 0 when we start Print Chr(nak); ' firt time send a nack Do Bstatus = Waitkey() 'wait for statuse byte Select Case Bstatus Case 1: ' start of heading, PC is ready to send Csum = 1 'checksum is 1 Bblock = Waitkey() : Csum = Csum + Bblock 'get block Bcsum1 = Waitkey() : Csum = Csum + Bcsum1 'get checksum first byte For J = 1 To 128 'get 128 bytes Buf(j) = Waitkey() : Csum = Csum + Buf(j) Next Bcsum2 = Waitkey() 'get second checksum byte If Bblocklocal = Bblock Then 'are the blocks the same? If Bcsum2 = Csum Then 'is the checksum the same? Gosub Writepage 'yes go write the page Print Chr(cack); 'acknowledge Incr Bblocklocal 'increase local block count Else 'no match so send nak Print Chr(nak); End If Else Print Chr(nak); 'blocks do not match End If Case 4: ' end of transmission , file is transmitted If Wrd > 0 Then 'if there was something left in the page Wrd = 0 'Z pointer needs wrd to be 0 Spmcrval = 5 : Gosub Do_spm 'write page Spmcrval = 17 : Gosub Do_spm ' re-enable page End If Print Chr(cack); ' send ack and ready Portd.7 = 0 ' simple indication that we are finished and ok Waitms 20 Goto _reset ' start new program Case &H18: ' PC aborts transmission Goto _reset ' ready Case 123 : Exit Do 'was probably still in the buffer Case 124 : Exit Do Case Else Exit Do ' no valid data End Select Loop If Bretries > 0 Then 'attempte left? Waitms 1000 Decr Bretries 'decrease attempts Else Goto _reset 'reset chip End If Loop 'write one or more pages Writepage: If Bkind = 0 Then For J = 1 To 128 Step 2 'we write 2 bytes into a page Vl = Buf(j) : Vh = Buf(j + 1) 'get Low and High bytes ! lds r0, {vl} 'store them into r0 and r1 registers ! lds r1, {vh} Spmcrval = 1 : Gosub Do_spm 'write value into page at word address Wrd = Wrd + 2 ' word address increases with 2 because LS bit of Z is not used If Wrd = Maxword Then ' page is full Wrd = 0 'Z pointer needs wrd to be 0 Spmcrval = 5 : Gosub Do_spm 'write page Spmcrval = 17 : Gosub Do_spm ' re-enable page If Page < Maxpages Then 'only if we are not erasing the bootspace Page = Page + 1 'next page Spmcrval = 3 : Gosub Do_spm ' erase next page Spmcrval = 17 : Gosub Do_spm ' re-enable page Else Portd.7 = 0 : Waitms 200 End If End If Next Else 'eeprom For J = 1 To 128 Writeeeprom Buf(j) , Wrd Wrd = Wrd + 1 Next End If Toggle Portd.7 : Waitms 10 : Toggle Portd.7 'indication that we write Return Do_spm: Bitwait Spmcsr.0 , Reset ' check for previous SPM complete Bitwait Eecr.1 , Reset 'wait for eeprom Z = Page 'make equal to page Shift Z , Left , Maxwordshift 'shift to proper place Z = Z + Wrd 'add word ! lds r30,{Z} ! lds r31,{Z+1} #if Loaderchip = 128 ! lds r24,{Z+2} ! sts rampz,r24 ' we need to set rampz also for the M128 #endif Spmcsr = Spmcrval 'assign register ! spm 'this is an asm instruction ! nop ! nop Return 'How you need to use this program: '1- compile this program '2- program into chip with sample elctronics programmer '3- select MCS Bootloader from programmers '4- compile a new program for example M88.bas '5- press F4 and reset your micro ' the program will now be uploaded into the chip with Xmodem Checksum ' you can write your own loader.too 'A stand alone command line loader is also available $CRYPT Top Previous Next Action This directive marks encrypted BASIC code. Syntax $CRYPT data Remarks In some cases you might want to share only portions of your code. The IDE can encrypt your code, and the compiler can process this encrypted code. AES encryption is used. You do need a commercial add on to use the encryption. The $crypt command can be processed by all bascom editions starting from version 2.0.5.0. So you only need an add on when you want to encrypt the code. Once encrypted, you can NOT DECRYPT into source code! Thus make a BACKUP of your source code before you encrypt the code. See also Edit Encrypt Selected Code Example $CRYPT 6288E522B4A1429A6F16D639BFB7405B $CRYPT 7ABCF89E7F817EB166E03AFF2EB64C4B $CRYPT 645C88E996A87BF94D34726AA1B1BCCC $CRYPT 9405555D91FA3B51DEEC4C2186F09ED1 $CRYPT 6D4790DA2ADFF09DE0DA97C594C1B074 $CRYSTAL Top Previous Next Action Instruct the compiler to override the crystal frequency options setting. Syntax $CRYSTAL = var Remarks var A numeric constant with the Frequency of the crystal. The frequency is selectable from the Compiler Settings. It is stored in a configuration file. The $CRYSTAL directive overrides this setting. It is best to use the $CRYSTAL directive as the used crystal frequency is visible in your program that way. The $CRYSTAL directive only informs the compiler about the used frequency. It does not set any fuse bit. The frequency must be know by the compiler for a number of reasons. First when you use serial communications, and you specify $BAUD, the compiler can calculate the proper settings for the UBR register. And second there are a number of routines like WAITMS, that use the execution time of a loop to generate a delay. When you specify $CRYSTAL = 1000000 (1 MHz) but in reality, connect a 4 MHz XTAL, you will see that everything will work 4 times as quick. Most new AVR chips have an internal oscillator that is enabled by default. Check the data sheet for the default value. Most new AVR chips have an option to divide the oscillator frequency by a number of values. If these options are used you need to take this into account. For example, you connect a 16 MHz crystal and select the external oscillator fuse byte, this would result in a 16 MHz clock for most old processors. Most new processors have an internal divider which can be enabled. This is an 8-divider in most cases. So in such a case, the resulting frequency would be 2 MHz. $crystal should have a value of 2 MHz in that case. Instead of changing the divider fusebyte you can also use the CONFIG CLOCKDIV statement to select the division factor. In case you have a crystal with 16 MHz and you code has code like : CONFIG CLOCKDIV=4 , you would use $CRYSTAL=4000000 Thus $crystal is the clock value used to clock the processor. See also $BAUD , BAUD , CONFIG CLOCKDIV Example $regfile = "m48def.dat" $crystal = 4000000 $baud = 19200 Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Print "Hello world" End $DATA Top Previous Next Action Instruct the compiler to store the data in the DATA lines following the $DATA directive, in code memory. Syntax $DATA Remarks The AVR has built-in EEPROM. With the WRITEEEPROM and READEEPROM statements, you can write to and read from the EEPROM. To store information in the EEPROM, you can add DATA lines to your program that hold the data that must be stored in the EEPROM. A separate file is generated with the EEP extension. This file can be used to program the EEPROM. The compiler must know which DATA must go into the code memory and which into the EEPROM memory and therefore two compiler directives were added. $EEPROM and $DATA. $EEPROM tells the compiler that the DATA lines following the compiler directive must be stored in the EEP file. To switch back to the default behavior of the DATA lines, you must use the $DATA directive. The READ statement that is used to read the DATA info may only be used with normal DATA lines. It does not work with DATA stored in EEPROM. Do not confuse $DATA directive with the DATA statement. So while normal DATA lines will store the specified data into the code memory of the micro which is called the flash memory, the $EEPROM and $DATA will cause the data to be stored into the EEPROM. The EEP file is a binary file. See also $EEPROM , READEEPROM , WRITEEEPROM , DATA ASM NONE Example '------------------------------------------------------------------------------- 'copyright : (c) 1995-2016, MCS Electronics 'micro : AT90S2313 'suited for demo : yes 'commercial addon needed : no 'purpose : demonstrates $DATA directive '------------------------------------------------------------------------------- $regfile = "2313def.dat" $baud = 19200 $crystal = 4000000 ' 4 MHz crystal Dim B As Byte Readeeprom B , 0 'now B will be 1 End Dta: $eeprom Data 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 $data End $DBG Top Previous Next Action Enables debugging output to the hardware UART. Syntax $DBG Remarks Calculating the hardware, software and frame space can be a difficult task. With $DBG the compiler will insert characters for the various spaces. To the Frame space 'F' will be written. When you have a frame size of 4, FFFF will be written. To the Hardware space 'H' will be written. If you have a hardware stack space of 8, HHHHHHHH will be written to this space. To the software space 'S' will be written. If you have a software stack space of 6, SSSSSS will be written. The idea is that when a character is overwritten, it is being used. So by watching these spaces you can determine if the space is used or not. With the DBG statement a record is written to the HW UART. The record must be logged to a file so it can be analyzed by the stack analyzer. Make the following steps to determine the proper values: · Make the frame space 40, the soft stack 20 and the HW stack 50 · Add $DBG to the top of your program · Add a DBG statement to every Subroutine or Function · Open the terminal emulator and open a new log file. By default it will have the name of your current program with the .log extension · Run your program and notice that it will dump information to the terminal emulator · When your program has executed all sub modules or options you have build in, turn off the file logging and turn off the program · Choose the Tools Stack analyzer option · A window will be shown with the data from the log file · Press the Advise button that will determine the needed space. Make sure that there is at least one H, S and F in the data. Otherwise it means that all the data is overwritten and that you need to increase the size. · Press the Use button to use the advised settings. As an alternative you can watch the space in the simulator and determine if the characters are overwritten or not. The DBG statement will assign an internal variable named ___SUBROUTINE Because the name of a SUB or Function may be 32 long, this variable uses 33 bytes! ___SUBROUTINE will be assigned with the name of the current SUB or FUNCTION. When you first run a SUB named Test1234 it will be assigned with Test1234 When the next DBG statement is in a SUB named Test, it will be assigned with Test. The 234 will still be there so it will be shown in the log file. Every DBG record will be shown as a row. The columns are: Column Description Sub Name of the sub or function from where the DBG was used FS Used frame space SS Used software stack space HS Used hardware stack space Frame space Frame space Soft stack Soft stack space HW stack Hardware stack space The Frame space is used to store temp and local variables. It also stores the variables that are passed to subs/functions by value. Because PRINT , INPUT and the FP num<>String conversion routines require a buffer, the compiler always is using 24 bytes of frame space. When the advise is to use 2 bytes of frame space, the setting will be 24+2=26. For example when you use : print var, var need to be converted into a string before it can be printed or shown with LCD. An alternative for the buffer would be to setup a temp buffer and free it once finished. This gives more code overhead. In older version of BASCOM the start of the frame was used for the buffer but that gave conflicts when variables were printed from an ISR. See also DBG $DEFAULT Top Previous Next Action Set the default for data types dimensioning to the specified type. Syntax $DEFAULT var Remarks Var SRAM, XRAM, ERAM Each variable that is dimensioned will be stored into SRAM, the internal memory of the chip. You can override it by specifying the data type. Dim B As XRAM Byte , will store the data into external memory. When you want all your variables to be stored in XRAM for example, you can use the statement : $DEFAULT XRAM Each Dim statement will place the variable in XRAM in that case. To switch back to the default behavior, use $END $DEFAULT See also NONE ASM NONE Example $regfile = "m48def.dat" $crystal = 4000000 $baud = 19200 Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 $default Xram Dim A As Byte , B As Byte , C As Byte 'a,b and c will be stored into XRAM $default Sram Dim D As Byte 'D will be stored in internal memory, SRAM $EEPLEAVE Top Previous Next Action Instructs the compiler not to recreate or erase the EEP file. Syntax $EEPLEAVE Remarks When you want to store data in the EEPROM, and you use an external tool to create the EEP file, you can use the $EEPLEAVE directive. Normally the EEP file will be created or erased, but this directive will not touch any existing EEP file. Otherwise you would erase an existing EEP file, created with another tool. See also $EEPROMHEX Example NONE $EEPROM Top Previous Next Action Instruct the compiler to store the data in the DATA lines following the $EEPROM directive in an EEP file. Syntax $EEPROM Remarks The AVR has built-in EEPROM. With the WRITEEEPROM and READEEPROM statements, you can write to and read from the EEPROM. To store information in the EEPROM, you can add DATA lines to your program that hold the data that must be stored in the EEPROM. A separate file is generated with the EEP extension. This file can be used to program the EEPROM. The compiler must know which DATA must go into the code memory and which into the EEPROM memory and therefore two compiler directives were added. $EEPROM and $DATA. $EEPROM tells the compiler that the DATA lines following the compiler directive must be stored in the EEP file. To switch back to the default behavior of the DATA lines, you must use the $DATA directive. The READ statement that is used to read the DATA info may only be used with normal DATA lines. It does not work with DATA stored in EEPROM. Do not confuse $DATA directive with the DATA statement. So while normal DATA lines will store the specified data into the code memory of the micro which is called the flash memory, the $EEPROM and $DATA will cause the data to be stored into the EEPROM. The EEP file is a binary file. The $EEPROMHEX directive can be used to create Intel HEX records in the EEP file See also $EEPROM , READEEPROM , WRITEEEPROM , DATA , $EEPROMHEX ASM NONE Example '------------------------------------------------------------------------------- 'copyright : (c) 1995-2016, MCS Electronics 'micro : AT90S2313 'suited for demo : yes 'commercial addon needed : no 'purpose : demonstrates $DATA directive '------------------------------------------------------------------------------- $regfile = "2313def.dat" $baud = 19200 $crystal = 4000000 ' 4 MHz crystal Dim B As Byte Readeeprom B , 0 'now B will be 1 End Dta: $eeprom Data 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 $data End $EEPROMHEX Top Previous Next Action Instruct the compiler to store the data in the EEP file in Intel HEX format instead of binary format. Syntax $EEPROMHEX Remarks The AVR has build in EEPROM. With the WRITEEEPROM and READEEPROM statements, you can write and read to the EEPROM. To store information in the EEPROM, you can add DATA lines to your program that hold the data that must be stored in the EEPROM. $EEPROM must be used to create a EEP file that holds the data. The EEP file is by default a binary file. When you use the STK500 you need an Intel HEX file. Use $EEPROMHEX to create an Intel Hex EEP file. $EEPROMHEX must be used together with $EEPROM. See also $EEPROMLEAVE Example $eeprom'the following DATA lines data will go to the EEP file Data 200 , 100,50 $data This would create an EEP file of 3 bytes. With the values 200,100 and 50. Add $eepromhex in order to create an Intel Hex file. This is how the EEP file content looks when using $eepromhex :0A00000001020304050A141E283251 :00000001FF $EEPROMSIZE Top Previous Next Action Instruct the compiler to override the EEPROM size of the micro processor. Syntax $EEPROMSIZE = size size The size in bytes of the EEPROM. Remarks The AVR has build in EEPROM. With the WRITEEEPROM and READEEPROM statements, you can write and read to the EEPROM. You can also use the ERAM pseudo variables to read/write EEPROM. When you use an external EEPROM and an alternative EEPROM library such as FM24C16 or FM25C256 you can override the internal EEPROM. All EEPROM routines will use the external EEPROM then. This way you are able to use a bigger EEPROM than internal available. Or you can use a quicker EEPROM such as a RAMTRON FRAM EEPROM. These EEPROM's are as quick as SRAM and also can be written to almost unlimited times. When using an external EEPROM and $EEPROMSIZE , take care that the supported programmers can not write to this EEPROM. They assume the internal EEPROM. See also FM24C16, FM25C256 Example $eepromsize = &H8000 $EXTERNAL Top Previous Next Action Instruct the compiler to include ASM routines from a library. Syntax $EXTERNAL Myroutine [, myroutine2] Remarks You can place ASM routines in a library file. With the $EXTERNAL directive you tell the compiler which routines must be included in your program. See also $LIB Example $regfile = "m48def.dat" $crystal = 4000000 $baud = 19200 Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 'In order to let this work you must put the mylib.lib file in the LIB dir 'And compile it to a LBX '------------------------------------------------------------------------- 'define the used library $lib"mylib.lbx" 'you can also use the original ASM : '$LIB "mylib.LIB" 'also define the used routines $external Test 'this is needed so the parameters will be placed correct on the stack Declare Sub Test(byval X Asbyte , Y Asbyte) 'reserve some space Dim Z As Byte 'call our own sub routine Call Test(1 , Z) 'z will be 2 in the used example End $FILE Top Previous Next Action Change name of generated files. Syntax $FILE = "myname.bin" Remarks In some cases it is desired to change the name of the output file. By default, the generated files have the same base name as the opened project file. So if your program name is "mytest.bas" , all generated files will start with the base "mytest". The $FILE directive let you change this base name. Simulating and programming will NOT work since the IDE uses the base name of your project. If you change it with $FILE, the files can not be located. See also NONE Example $FILE = "mytest.bin" $FORCESOFTI2C Top Previous Next Action The $forcesofti2c directive force the ATXMEGA to use software I2C/TWI Library instead of the hardware I2C registers of ATXMEGA. Syntax $forcesofti2c Remarks ATXMEGA have usually enough I2C interfaces with fixed SDA and SCL pins but if you want to use other pins as SDA/SCL you can use this directive. Required Library: $lib "i2c.lbx" You can not combine the soft mode with the hardware TWI. Thus when using $forcesofti2c, you can not add an additional TWI channel. $forcesofti2c ' with this the software I2C/TWI commands are used when inlcuding i2c.lbx $lib "i2c.lbx" ' override the normal xmega i2c lib Then you need to configure the SDA and SCL Pin and initialize the pins: Config Scl = Port0.1 ' Pin to use as SCL (The hardware pin is Pinb.1) Config Sda = Port0.0 ' Pin to use as SDA (The hardware pin is Pinb.0) I2cinit ' Bring the Pin's in the proper state See also Using the I2C protocol Example ' Using ATXMEGA with software I2C routines to use also pins which are no hardware SDA/SCL pins ' Needed Library: $lib "i2c.lbx" ' The $forcesofti2c directive force the ATXMEGA to use software I2c/TWI Library ' The hardware for this example is XMEGA-A3BU XPlained board from Atmel ' Don't forget the pull-ups on SDA/SCL pin ! ' Bascom Version 2.0.7.6 or higher needed $regfile = "XM256A3BUDEF.DAT" $crystal = 32000000 '32MHz $hwstack = 64 $swstack = 40 $framesize = 80 $forcesofti2c ' with this the software I2C/TWI commands are used when inlcuding i2c.lbx $lib "i2c.lbx" ' override the normal xmega i2c lib Config Osc = Enabled , 32mhzosc = Enabled Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 Config Portr.0 = Output Led0 Alias Portr.0 'LED 0 (XMEGA-A3BU XPlained board from Atmel ) Config Portr.1 = Output Led1 Alias Portr.1 'LED 1 (XMEGA-A3BU XPlained board from Atmel ) Dim B As Byte 'We use here Virtual port 0 Config Vport0 = B ' 'map portB to virtual port0 Config Scl = Port0.1 ' Pin to use as SCL (The hardware pin is Pinb.1) Config Sda = Port0.0 ' Pin to use as SDA (The hardware pin is Pinb.0) I2cinit ' Bring the Pin's in the proper state Do Waitms 500 Set Led1 Reset Led0 Waitms 500 Reset Led1 Set Led0 Incr B I2cstart I2cwbyte &H24 ' address of I2C Slave I2cwbyte B ' databyte to send to slave I2cstop Loop End 'end program $FRAMEPROTECT Top Previous Next Action This directive will enable or disable interrupt frame protection. Syntax $FRAMEPROTECT = value Remarks Value must be a constant expression that evaluates to false (0) or true (<>0). By default the frame protection is off. When a user function/sub passes parameters with byval, a copy is created and passed to the user sub/function. When an interrupt is executed, and it calls user sub/functions with parameters passed with byval, the values can get corrupted. When activated, the compiler disables interrupts before passing variables, and enables interrupts (when they were enabled) inside the user sub/function. This ensures that the values can not get corrupted from an interrupt which is calling other user sub/functions. When you do not call user sub/functions from inside your interrupt you can omit the $frameprotect directive or set it to 0 in order to reduce code. In version 2075 the compiler had frame protection as a default, and the $NOFRAMEPROTECT served as an override. While you can still use $NOFRAMEPROTECT, it is off by default in 2076 to the preferred switch is $FRAMEPROTECT = 0|1 When you activate frame protection the internal constant named _FPROTECT will be set to 1. When you have a user function that calls an ASM library, you must include code to restore the I-flag. The bcd.lib user lib sample demonstrates this with this code : #IF _FPROTECT Out sreg,r3 ; restore I flag #ENDIF See also $NOFRAMEPROTECT Example '************************************************ ' TESTING THE FRAME PARAMETER PASSING ' UNDER HEAVY INTERRUPT LOAD '************************************************ ' file: frame_pass_test.bas $regfile = "m88def.dat" $crystal = 8000000 $hwstack = 100 $swstack = 100 $framesize = 100 $noframeprotect ' in this sample, disabling the frame protection will result in errors $frameprotect=0 ' from version 2076, this is the preferred method Dim Ww As Word , Www As Word , Wwww As Word Declare Sub Stack_checking(byval Identifier As Integer ) $baud = 19200 Open "com1:" For Binary As #1 Const T0_idozito = 100 Config Timer0 = Timer , Prescale = 1024 '256 --> 4.096 msec egység, 1024 --> 16.384 msec On Ovf0 Timer0_interrupt Enable Timer0 Start Timer0 Load Timer0 , T0_idozito ' These routines are called under the timer interrupt Declare Sub Under_it_pass_1(byval Inpar1_uit As Word ) Declare Sub Under_it_pass_2(byval Inpar2_uit As Word ) Declare Sub Test() ' These routines are called in the main loop Declare Sub Inmain_test_routine_1(byval Im1_par1 As Word , Byval Im1_par2 As Word , Byval Im1_par3 As Word , Byval Im1_par4 As Word , Byval Im1_par5 As Word , Byval Im1_par6 As Word ) Declare Sub Inmain_test_routine_2(byval Im2_par1 As Word , Byval Im2_par2 As Word , Byval Im2_par3 As Word , Byval Im2_par4 As Word , Byval Im2_par5 As Word , Byval Im2_par6 As Word ) Declare Sub Inmain_test_routine_3(byval Im3_par1 As Word , Byval Im3_par2 As Word , Byval Im3_par3 As Word , Byval Im3_par4 As Word , Byval Im3_par5 As Word , Byval Im3_par6 As Word ) ' Routine-1 parameters are stored here Dim Dim1_p1 As Word Dim Dim1_p2 As Word Dim Dim1_p3 As Word Dim Dim1_p4 As Word Dim Dim1_p5 As Word Dim Dim1_p6 As Word ' Routine-3 parameters are stored here Dim Dim3_p1 As Word Dim Dim3_p2 As Word Dim Dim3_p3 As Word Dim Dim3_p4 As Word Dim Dim3_p5 As Word Dim Dim3_p6 As Word Program_begins_here: Enable Interrupts Print #1 , "PROGRAM BEGIN" Do Call Inmain_test_routine_1(&Haaaa , &HAAAA , &HAAAA , &HAAAA , &HAAAA , &HAAAA ) Call Inmain_test_routine_2(&Haaaa , &HAAAA , &HAAAA , &HAAAA , &HAAAA , &HAAAA ) Call Inmain_test_routine_3(&Haaaa , &HAAAA , &HAAAA , &HAAAA , &HAAAA , &HAAAA ) Loop ' All the three routines always gets all parameters as &hAAAA, if they see anything else, they print an error ' routine_1 stores to DIM area and checks the stored values ' routine 2 check immediately the incoming parameters ' routine_3 completely identical to routine_1, except the parameter passing protection ' Sub Inmain_test_routine_1(byval Im1_par1 As Word , Byval Im1_par2 As Word , Byval Im1_par3 As Word , Byval Im1_par4 As Word , Byval Im1_par5 As Word , Byval Im1_par6 As Word ) Dim1_p1 = Im1_par1 : Dim1_p2 = Im1_par2 : Dim1_p3 = Im1_par3 : Dim1_p4 = Im1_par4 : Dim1_p5 = Im1_par5 : Dim1_p6 = Im1_par6 If Dim1_p1 <> &HAAAA Or Dim1_p2 <> &HAAAA Or Dim1_p3 <> &HAAAA Or Dim1_p4 <> &HAAAA Or Dim1_p5 <> &HAAAA Or Dim1_p6 <> &HAAAA Then Print #1 , " PAR ERROR R1 " ; Hex(dim1_p1 ) ; " " ; Hex(dim1_p2 ) ; " " ; Hex(dim1_p3 ) ; " " ; Print #1 , Hex(dim1_p4 ) ; " " ; Hex(dim1_p5 ) ; " " ; Hex(dim1_p6 ) End If End Sub Sub Inmain_test_routine_2(byval Im2_par1 As Word , Byval Im2_par2 As Word , Byval Im2_par3 As Word , Byval Im2_par4 As Word , Byval Im2_par5 As Word , Byval Im2_par6 As Word ) If Im2_par1 <> &HAAAA Or Im2_par2 <> &HAAAA Or Im2_par3 <> &HAAAA Or Im2_par4 <> &HAAAA Or Im2_par5 <> &HAAAA Or Im2_par6 <> &HAAAA Then Print #1 , " PAR ERROR R2 " ; Hex(im2_par1 ) ; " " ; Hex(im2_par2 ) ; " " ; Hex(im2_par3 ) ; " " ; Print #1 , Hex(im2_par4 ) ; " " ; Hex(im2_par5 ) ; " " ; Hex(im2_par6 ) End If End Sub Sub Inmain_test_routine_3(byval Im3_par1 As Word , Byval Im3_par2 As Word , Byval Im3_par3 As Word , Byval Im3_par4 As Word , Byval Im3_par5 As Word , Byval Im3_par6 As Word ) Dim3_p1 = Im3_par1 : Dim3_p2 = Im3_par2 : Dim3_p3 = Im3_par3 : Dim3_p4 = Im3_par4 : Dim3_p5 = Im3_par5 : Dim3_p6 = Im3_par6 If Dim3_p1 <> &HAAAA Or Dim3_p2 <> &HAAAA Or Dim3_p3 <> &HAAAA Or Dim3_p4 <> &HAAAA Or Dim3_p5 <> &HAAAA Or Dim3_p6 <> &HAAAA Then Print #1 , " PAR ERROR R3 " ; Hex(dim3_p1 ) ; " " ; Hex(dim3_p2 ) ; " " ; Hex(dim3_p3 ) ; " " ; Print #1 , Hex(dim3_p4 ) ; " " ; Hex(dim3_p5 ) ; " " ; Hex(dim3_p6 ) End If End Sub Dim Under_it_store_1 As Word Dim Under_it_store_2 As Word ' these two routines are called under timer IT ' They don't do much, except use the frame for parameter passing Sub Under_it_pass_1(byval Inpar1_uit As Word ) Under_it_store_1 = Inpar1_uit End Sub Sub Under_it_pass_2(byval Inpar2_uit As Word ) Under_it_store_2 = Inpar2_uit End Sub ' Timer IT calling two routines which use the frame Timer0_interrupt: Load Timer0 , T0_idozito Call Under_it_pass_1(&H5555 ) Call Under_it_pass_2(&H3333 ) Return End $FRAMESIZE Top Previous Next Action Sets the available space for the frame. Syntax $FRAMESIZE = var Remarks Var A numeric decimal value. While you can configure the Frame Size in Options, Compiler, Chip, it is good practice to put the value into your code. This way you do no need the cfg(configuration) file. The $FRAMESIZE directive overrides the value from the IDE Options. It is important that the $FRAMESIZE directive occurs in your main project file. It may not be included in an $include file as only the main file is parsed for $FRAMESIZE. $FRAMESIZE only accepts numeric values. Functions like PRINT, LCD, INPUT and the FP num <> FORMAT String conversion routines require a buffer in SRAM. Because of that the compiler always is using 24 bytes of frame space. This 24 Byte start at the beginning of the Frame which act as the conversion buffer within the frame (See also picture). Because the FRAME is growing bottom up and this 24 Byte start at the beginning of the FRAME this 24 Byte conversion buffer start at the lowest FRAME Address (See picture). Here you also see that a too small $framesize causes an overwriting of Software Stack and/or Hardware Stack which lead to malfunction. If you use Print numVar, then the numeric variable "numvar" is converted into a string representation of the binary number. The framespace buffer is also used for that. When there is not enough room inside the frame, the ERR variable will be set to 1. See also $SWSTACK, $HWSTACK, Memory usage Picture: Memory of ATXMEGA128A1 A LOCAL variable is a temporary variable that is stored in frame. There can be only LOCAL variables of the type BYTE, INTEGER, WORD, LONG, SINGLE, DOUBLE or STRING. A LOCAL Integer will use 2 Bytes of Frame , A LOCAL Long will use 4 Bytes. A LOCAL string * 20 will use 20 + 1 = 21 Byte (this additional 1 Byte is because every String is terminated with a 0-Byte) When the SUB or FUNCTION is terminated, the memory will be released back to the frame but the FRAME will not be cleared ! Therefore a LOCAL variable is not initialized. So you can not assume the variable is 0. If you like it to be 0, you need to assign it ! BIT variables are not possible as LOCAL because they are always GLOBAL to the system. Arrays can NOT be used as LOCAL (but arrays can be passed by REFERENCE as parameter to SUB and FUNCTIONS which just need 2 Bytes Software Stack of the Address of Array start) See following example for frame calculation: Example $regfile = "xm128a1def.dat" $crystal = 32000000 '32MHz $hwstack = 64 $swstack = 128 $framesize = 288 Config Osc = Enabled , 32mhzosc = Enabled '32MHz 'configure the systemclock Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 '32MHz 'Config Interrupts Config Priority = Static , Vector = Application , Lo = Enabled 'Enable Lo Level Interrupts Config Com1 = 57600 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 Declare Sub My_sub() Call My_sub() End 'end program Sub My_sub() Local A1 As Byte , A2 As Byte , A3 As Byte , A4 As Byte , A5 As Byte Local S As String * 254 For A1 = 1 To 254 S = S + "1" Next A1 A1 = 1 A2 = 2 A3 = 3 A4 = 4 A5 = 5 Print A1 End Sub Now we calculate the FRAME: The Print A1 will be placed in the first frame-Byte of the 24 Byte conversion buffer. 5 LOCAL Byte (A1 � A5) = 5 Byte of FRAME LOCAL String: 254 Byte + 1 Byte = 255 Byte Frame needed = 24Byte Frame conversion Buffer + 5 Byte + 255 Byte = 284 Byte This can be easy double checked with BASCOM-AVR Simulator (see following picture). In following picture you see the start of FRAME which start with the 24Byte conversion buffer. The 31 in the first Frame Byte is from Print A1. After the 24 Byte conversion buffer follow the 5 Local Byte variables (A1 �. A5) and then the 255 Byte for the LOCAL String. As with Software Stack you need to calculate the Framesize needed by the SUB or FUNCTION with the most LOCAL Variables and parameter passed by REFERENCE etc.. Take care when calling a SUB within a SUB. In this case you need to add the FRAME needed by both SUB ! When both SUB need 284 Byte you need to use: 24 Byte conversion Buffer + 2* 5 Byte (A1�A5) + 2*255 Byte (String) = 544 Byte (the conversion buffer is needed only once !) Picture: Memory window of BASCOM-AVR Simulator (Frame calculation example) For further investigation of Stacks and Frame we use a SUB with 5 LOCAL Byte Variables and a PRINT function within the SUB. We start with hwstack, swstack and framesize defined and in second step we set swstack to 0. In addition we will lower the framesize to a not recommended value to force overwriting of other stack bytes. $regfile = "xm128a1def.dat" $crystal = 32000000 '32MHz $hwstack = 64 $swstack = 128 $framesize = 256 Config Osc = Enabled , 32mhzosc = Enabled '32MHz 'configure the systemclock Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 '32MHz 'Config Interrupts Config Priority = Static , Vector = Application , Lo = Enabled 'Enable Lo Level Interrupts Config Com1 = 57600 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 Declare Sub My_sub() Call My_sub() End 'end program Sub My_sub() Local A1 As Byte , A2 As Byte , A3 As Byte , A4 As Byte , A5 As Byte A1 = 1 A2 = 2 A3 = 3 A4 = 4 A5 = 5 Print A1 End Sub Here we see the 64 Byte Hardware Stack followed by 128 Byte Software Stack and then 256 Byte Frame. As always the Frame is the 24 Byte conversion buffer + rest of frame. Picture : SRAM for Example with $hwstack = 64, $swstack = 128, $framesize = 256 The Simulator Memory Window show give us the details: Picture: Simulator Memory Window for Example with $hwstack = 64, $swstack = 128, $framesize = 256 The second example use $hwstack = 64, $swstack = 0, $framesize = 256 Without defining a software Stack or with $swstack = 0 the Frame follows direct after the Hardware Stack. The Frame is as always 24 Byte conversion buffer + Rest of Frame. Rest of Frame is in this case: 256 Byte � 24 Byte = 232 Byte Picture: SRAM for example with $hwstack = 64, $swstack = 0, $framesize = 256 In the BASCOM Simulator Window you now see the addresses of the LOCAL variables are now stored in FRAME (which are usually in the Software Stack). This is not a problem as long as the Frame is big enough not to overwrite these addresses of the LOCAL variables. (Remember: Address of LOCAL variables are stored in Software Stack (when Software Stack is defined) . The LOCAL Variables itself are stored in FRAME) And here you see also with the 24 Byte conversion buffer the absolute minimum you need to define for software Stack and Framesize together is 24 Byte ! But this is not the recommendation. The recommendation is always define values for all Stack and Frame ! Picture: Simulator Memory Window for Example with $hwstack = 64, $swstack = 0, $framesize = 256 $HWSTACK Top Previous Next Action Sets the available space for the Hardware stack. Syntax $HWSTACK = var Remarks Var A numeric decimal value. While you can configure the HW Stack in Options, Compiler, Chip, it is good practice to put the value into your code. This way you do no need the cfg(configuration) file. The $HWSTACK directive overrides the value from the IDE Options. It is important that the $HWSTACK directive occurs in your main project file. It may not be included in an $include file as only the main file is parsed for $HWSTACK. $HWSTACK only accepts numeric values. The Hardware stack is room space in SRAM that is needed by your program. Each time you call a SUB or FUNCTION, or use GOSUB, the processor need to know at which address to return after returning from the call. Also for RETURN Address after Interrupt this is needed by the program. For this purpose, the processor saves this address on the hardware stack. When you use GOSUB label, the microprocessor pushes the return address on the hardware stack and will use 2 Bytes for that. When you use RETURN, the Hardware stack is popped back and the program can continue at the proper address. When you nest GOSUB, CALL or functions, you will use more stack space. Most statements use HW stack because a machine language routine is called. The Hardware Stack is growing top down. The Hardware Stack start at the highest available SRAM Address and therefore is located before Software Stack and/or Frame. See also $SWSTACK , $FRAMESIZE, Memory Usage Example for using an Interrupt and examine Hardware Stack: With the following example we just define and enable the Receive Interrupt of the UART and examine when clicking on Interrupt button within the Bascom-AVR Simulator Interrupts Tab how many Hardware Stack is needed. $regfile = "m328pdef.dat" $crystal = 16000000 $hwstack = 48 $swstack = 32 $framesize = 32 $baud = 19200 Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim Rs232 As Byte 'Enable Receive Interrupt for COM1 On Urxc Rxc_isr Enable Urxc Enable Interrupts Do !nop Loop End Rxc_isr: Rs232 = Inkey() Print Rs232 Return Bascom-AVR Simulator output of the example above: Picture : The Hardware Stack will be filled by clicking the Bascom-AVR Simulator Interrupt With this example we see (by counting the changed SRAM Bytes in Bascom Simulator Memory Window) that Software Stack is NOT needed but at least 39 Byte of Hardware Stack and the Frame with the 24 Byte conversion buffer because of PRINT. Most of the 39 Bytes are the saved Registers when jumping in Interrupt Service Routine. These are SREG , R31 to R16 and R11 to R0 with exception of R6,R8 and R9. The following should be considered in any case (not only when using NOSAVE): Take care when using floating point math in the ISR because the Register R12 to R15 are not saved in the regular process of processor register backup. Using floating point math in ISR is not recommended anyway. When you try the same example with NOSAVE () you will see the example will need less Hardware Stack but you are responsible then to save all of the Registers with PUSH and POP in the Interrupt Service Routine that are needed or changed during the Interrupt Service Routine. The easier, and above all safer way is not using NOSAVE which is also the default way. By clicking on the Interrupts Button will fire an interrupt in Simulator $HWCHECK, $FRAMECHECK, $SOFTCHECK Top Previous Next Action This directive can be used to determine the required stack space. Syntax $HWCHECK $FRAMECHECK $SOFTCHECK Remarks All variables you DIM in your application require RAM or SRAM space. But an application needs more RAM space. Each time you call a sub or function, or us gosub, the processor need to know at which address to return after returning from the call. For this purpose, the processor saves this address on the hardware stack. There is noting you can do about this. This hardware stack grows downwards. Some basic statements compile into code that do not need any calls. But some call a machine language function which in turn can call other functions. Which and how many other calls will be made depend on the selected processor and other options. sometimes it also depends on variable parameters. When parameters are passed to a sub or function, the address is passed of the variables. These are word addresses thus using 2 bytes for each variable. This passing is being done via the so called soft stack. This area is located below the HW stack space. And it also grows down. All LOCAL variables you use also need 2 bytes of the soft stack. When you pass a parameter with BYVAL or when you create a LOCAL variable, some temporarily space is need. Consider this example : somestring = "abc" + somestring When the compiler assigns "abc" to somestring, the somestring variable will become "abc" and it will overwrite the content making it impossible to add it's content after the "abc". So we first need to store the content of somestring before we can start assigning new data to this string. This copy also requires space. This space is created dynamically and is taken from the so called frame space. This space is located below the soft stack. Now you can use $DBG or some default values for most projects to determine the values. But when you have a problem and have absolutely no idea how the settings must be made, you can use the $HWCHECK option. You start with including a special library named "stackcheck.lib" to your code. Then you run your application and somewhere in your code you print the value of the generated _hw_lowest variable. This variable is set to &HFFFF and each time a call is made, the stack is compared to this value. If the hardware stack (SPL and SPH registers) are lower then the _hw_lowest value, _hw_lowest is assigned with the new lowest stack value. This way you determine the lowest possible hardware stack value that occurred during the runtime of your application. Of course it is important that your application runs all code. You can print the value or show it on LCD. To determine the actual needed space you subtract it from the stacktop value. For the softstack the same applies. It will store the lowest Y-pointer value to the variable named _sw_lowest. For the framespace the the variable _fw_highest is used and this variables is increasing. The stackcheck.bas example demonstrates how to retrieve the values when a recursive sub is used. See also NONE Example $regfile = "m88def.dat" $hwstack = 40 $swstack = 80 $framesize = 80 $lib "stackcheck.lib" Declare Sub Test(byval Prm As Byte) Print "stack test" Dim G As Byte , W As Word Dim P As Byte $hwcheck 'hw stack check on $framecheck $softcheck Test P Print _hw_lowest W = _hwstackstart - _hw_lowest Print "HW stack needed : " ; W Print _fw_highest If _fw_highest > 0 Then W = _frame_high - _fw_highest Print "Frame space needed : " ; W End If Print _sw_lowest W = _hwstack_low - _sw_lowest Print "SW stack needed : " ; W End Sub Test(byval Prm As Byte) Local L As Byte Print "HWSTACK:" ; _hw_lowest Print "Frame:" ; _fw_highest Print "SWSTACK:" ; _sw_lowest G = G + 1 ' global var If G >= 5 Then Exit Sub Else Test P 'recursive call End If End Sub $INC Top Previous Next Action Includes a binary file in the program at the current position. Syntax $INC label , size | nosize , "file" Remarks Label The name of the label you can use to refer to the data. Nosize Specify either nosize or size. When you use size, the size of the data will be included. This way you know how many bytes you can retrieve. File Name of the file which must be included. Use RESTORE to get a pointer to the data. And use READ, to read in the data. The $INC statement is an alternative for the DATA statement. While DATA works ok for little data, it is harder to use on large sets of data. See Also RESTORE, DATA , READ Example $regfile = "m48def.dat" $crystal = 4000000 $baud = 19200 Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim Size As Word , W As Word , B As Byte Restore L1 ' set pointer to label Read Size ' get size of the data Print Size ; " bytes stored at label L1" For W = 1 To Size Read B : Print Chr(b); Next End 'include some data here $inc L1 , Size , "c:\test.bas" 'when you get an error, insert a file you have on your system $INCLUDE Top Previous Next Action Includes an ASCII file in the program at the current position. Syntax $INCLUDE "file" Remarks File Name of the ASCII file, which must contain valid BASCOM statements. This option can be used if you make use of the same routines in many programs. You can write modules and include them into your program. If there are changes to make you only have to change the module file, not all your BASCOM programs. You can only include ASCII files! An include file will only be included once, even if you include it multiple times. Use $INC when you want to include binary files. You can specify an absolute file name (with a drive and full path) like : $INCLUDE "c:\folder\myfile.bas" Or you can specify a relative file name like : $INCLUDE "myfile.bas" The main program path will be used to determine the absolute file name. If your main file is stored under c:\abc\main.bas , and you include a file named "test.inc" , the compiler expects a file named "c:\abc\test.inc" You can include a path too. The path is relative to the main file. When used in sub folders use " \ " (back slash). The path uses the DOS/Windows convention. A forward slash will work too since windows does not seem to be bothered with it. Example with sub folder Test: $include "Test\my_functions.bas" When you include sub procedures and functions before the actual code, your code will run into this code. You can use a GOTO to jump over the included code or you can use CONFIG SUBMODE=NEW so that the compiler will only include the used functions. See Example2 See Also $INC , CONFIG SUBMODE=NEW Example $regfile = "m48def.dat" $crystal = 4000000 $hwstack = 10 $swstack = 10 $framesize = 26 $baud = 19200 Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 '-------------------------------------------------------------- Print "INCLUDE.BAS" 'Note that the file 123.bas contains an error $include "123.bas" 'include file that prints Hello Print "Back in INCLUDE.BAS" End Example2 $regfile = "m48def.dat" $crystal = 4000000 $hwstack = 10 $swstack = 10 $framesize = 26 $baud = 19200 Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 '-------------------------------------------------------------- $include "mysubs.bas" 'include file with sub procedures 'this is the included code : Sub Test() ' print "Test" ' End Sub 'Without a GOTO to jump over the included code the code will run into the sub without a call ' Or use CONFIG SUBMODE=NEW so you do not need to change a thing Print "Back in INCLUDE.BAS" End $INITMICRO Top Previous Next Action Calls a user routine at startup to perform important initialization functions such as setting ports. Syntax $INITMICRO Remarks This directive will call a label named _INIT_MICRO just after the most important initialization is performed. You can put the _INIT_MICRO routine into your program, or you can put it in a library. Advantage of a library is that it is the same for all programs, and advantage of storing the code into your program is that you can change it for every program. It is important that you end the routine with a RETURN as the label is called and expects a return. The $initmicro can be used to set a port direction or value as it performs before the memory is cleared which can take some mS. The best solution for a defined logic level at startup remains the usage of pull up/pull down resistors. See Also NONE Example $regfile = "m48def.dat" $crystal = 4000000 $hwstack = 10 $swstack = 10 $framesize = 26 $baud = 19200 Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 $initmicro Print Version() 'show date and time of compilation Print Portb Do nop Loop End 'do not write a complete application in this routine. 'only perform needed init functions _init_micro: Config Portb = Output Portb = 3 Return $LCD Top Previous Next Action Instruct the compiler to generate code for 8-bit LCD displays attached to the data bus. Syntax $LCD = [&H]address Remarks Address The address where must be written to, to enable the LCD display and the RS line of the LCD display. The db0-db7 lines of the LCD must be connected to the data lines D0-D7. (or is 4 bit mode, connect only D4-D7) The RS line of the LCD can be configured with the LCDRS statement. On systems with external RAM, it makes more sense to attach the LCD to the data bus. With an address decoder, you can select the LCD display. Do not confuse $LCD with the LCD statement. The compiler will create a constant named ___LCD_ADR which you could use in an alternative LCD library. See also $LCDRS , CONFIG LCD Example '-------------------------------------------------------------- ' (c) 1995-2016 MCS Electronics '-------------------------------------------------------------- ' file: LCD.BAS ' demo: LCD, CLS, LOWERLINE, SHIFTLCD, SHIFTCURSOR, HOME ' CURSOR, DISPLAY '-------------------------------------------------------------- 'note : tested in bus mode with 4-bit on the STK200 'LCD - STK200 '------------------- 'D4 D4 'D5 D5 'D6 D6 'D7 D7 'WR WR 'E E 'RS RS '+5V +5V 'GND GND 'V0 V0 'D0-D3 are not connected since 4 bit bus mode is used! 'Config Lcdpin = Pin , Db4 = Portb.1 , Db5 = Portb.2 , Db6 = Portb.3 , Db7 = Portb.4 , E = Portb.5 , Rs = Portb.6 Rem with the config lcdpin statement you can override the compiler settings $regfile = "8515def.dat" $lcd = &HC000 $lcdrs = &H8000 Config Lcdbus = 4 Dim A As Byte Config Lcd = 16 * 2 'configure lcd screen 'other options are 16 * 2 , 16 * 4 and 20 * 4, 20 * 2 , 16 * 1a 'When you dont include this option 16 * 2 is assumed '16 * 1a is intended for 16 character displays with split addresses over 2 lines '$LCD = address will turn LCD into 8-bit databus mode ' use this with uP with external RAM and/or ROM ' because it aint need the port pins ! Cls 'clear the LCD display Lcd "Hello world." 'display this at the top line Wait 1 Lowerline 'select the lower line Wait 1 Lcd "Shift this." 'display this at the lower line Wait 1 For A = 1 To 10 Shiftlcd Right 'shift the text to the right Wait 1 'wait a moment Next For A = 1 To 10 Shiftlcd Left 'shift the text to the left Wait 1 'wait a moment Next Locate 2 , 1 'set cursor position Lcd "*" 'display this Wait 1 'wait a moment Shiftcursor Right 'shift the cursor Lcd "@" 'display this Wait 1 'wait a moment Home Upper 'select line 1 and return home Lcd "Replaced." 'replace the text Wait 1 'wait a moment Cursor Off Noblink 'hide cursor Wait 1 'wait a moment Cursor On Blink 'show cursor Wait 1 'wait a moment Display Off 'turn display off Wait 1 'wait a moment Display On 'turn display on '-----------------NEW support for 4-line LCD------ Thirdline Lcd "Line 3" Fourthline Lcd "Line 4" Home Third 'goto home on line three Home Fourth Home F 'first letteer also works Locate 4 , 1 : Lcd "Line 4" Wait 1 'Now lets build a special character 'the first number is the characternumber (0-7) 'The other numbers are the rowvalues 'Use the LCD tool to insert this line Deflcdchar 1 , 225 , 227 , 226 , 226 , 226 , 242 , 234 , 228 ' replace ? with number (0-7) Deflcdchar 0 , 240 , 224 , 224 , 255 , 254 , 252 , 248 , 240 ' replace ? with number (0-7) Cls 'select data RAM Rem it is important that a CLS is following the deflcdchar statements because it will set the controller back in datamode Lcd Chr(0) ; Chr(1) 'print the special character '----------------- Now use an internal routine ------------ _temp1 = 1 'value into ACC !rCall _write_lcd 'put it on LCD End $LCDPUTCTRL Top Previous Next Action Specifies that LCD control output must be redirected. Syntax $LCDPUTCTRL = label Remarks Label The name of the assembler routine that must be called when a control byte is printed with the LCD statement. The character must be placed in register R24. With the redirection of the LCD statement, you can use your own routines. See also $LCDPUTDATA Example $regfile = "m48def.dat" $crystal = 4000000 $baud = 19200 Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 'dimension used variables Dim S As String* 10 Dim W As Long 'inform the compiler which routine must be called to get serial 'characters $lcdputdata= Myoutput $lcdputctrl= Myoutputctrl 'make a never ending loop Do Lcd "test" Loop End 'custom character handling routine 'instead of saving and restoring only the used registers 'and write full ASM code, we use Pushall and PopAll to save and 'restore 'all registers so we can use all BASIC statements '$LCDPUTDATA requires that the character is passed in R24 Myoutput: Pushall 'save all registers 'your code here Popall 'restore registers Return MyoutputCtrl: Pushall 'save all registers 'your code here Popall 'restore registers Return $LCDPUTDATA Top Previous Next Action Specifies that LCD data output must be redirected. Syntax $LCDPUTDATA = label Remarks Label The name of the assembler routine that must be called when a character is printed with the LCD statement. The character must be placed in R24. With the redirection of the LCD statement, you can use your own routines. See also $LCDPUTCTRL Example $regfile = "m48def.dat" $crystal = 4000000 $baud = 19200 Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 'dimension used variables Dim S As String* 10 Dim W As Long 'inform the compiler which routine must be called to get serial 'characters $lcdputdata= Myoutput $lcdputctrl= Myoutputctrl 'make a never ending loop Do Lcd "test" Loop End 'custom character handling routine 'instead of saving and restoring only the used registers 'and write full ASM code, we use Pushall and PopAll to save and 'restore 'all registers so we can use all BASIC statements '$LCDPUTDATA requires that the character is passed in R24 Myoutput: Pushall 'save all registers 'your code here Popall 'restore registers Return MyoutputCtrl: Pushall 'save all registers 'your code here Popall 'restore registers Return $LCDRS Top Previous Next Action Instruct the compiler to generate code for 8-bit LCD displays attached to the data bus. Syntax $LCDRS = [&H]address Remarks Address The address where must be written to, to enable the LCD display. The db0-db7 lines of the LCD must be connected to the data lines D0-D7. (or is 4 bit mode, connect only D4-D7) On systems with external RAM, it makes more sense to attach the LCD to the data bus. With an address decoder, you can select the LCD display. The compiler will create a constant named ___LCDRS_ADR which you could use in an alternative LCD library. See also $LCD , CONFIG LCDBUS Example '-------------------------------------------------------------- ' (c) 1995-2016 MCS Electronics '-------------------------------------------------------------- ' file: LCD.BAS ' demo: LCD, CLS, LOWERLINE, SHIFTLCD, SHIFTCURSOR, HOME ' CURSOR, DISPLAY '-------------------------------------------------------------- 'note : tested in bus mode with 4-bit on the STK200 'LCD - STK200 '------------------- 'D4 D4 'D5 D5 'D6 D6 'D7 D7 'WR WR 'E E 'RS RS '+5V +5V 'GND GND 'V0 V0 ' D0-D3 are not connected since 4 bit bus mode is used! 'Config Lcdpin = Pin , Db4 = Portb.1 , Db5 = Portb.2 , Db6 = Portb.3 , Db7 = Portb.4 , E = Portb.5 , Rs = Portb.6 Rem with the config lcdpin statement you can override the compiler settings $regfile = "8515def.dat" $lcd = &HC000 $lcdrs = &H8000 Config Lcdbus = 4 Dim A As Byte Config Lcd = 16 * 2 'configure lcd screen 'other options are 16 * 2 , 16 * 4 and 20 * 4, 20 * 2 , 16 * 1a 'When you dont include this option 16 * 2 is assumed '16 * 1a is intended for 16 character displays with split addresses over 2 lines '$LCD = address will turn LCD into 8-bit databus mode ' use this with uP with external RAM and/or ROM ' because it aint need the port pins ! Cls 'clear the LCD display Lcd "Hello world." 'display this at the top line Wait 1 Lowerline 'select the lower line Wait 1 Lcd "Shift this." 'display this at the lower line Wait 1 For A = 1 To 10 Shiftlcd Right 'shift the text to the right Wait 1 'wait a moment Next For A = 1 To 10 Shiftlcd Left 'shift the text to the left Wait 1 'wait a moment Next Locate 2 , 1 'set cursor position Lcd "*" 'display this Wait 1 'wait a moment Shiftcursor Right 'shift the cursor Lcd "@" 'display this Wait 1 'wait a moment Home Upper 'select line 1 and return home Lcd "Replaced." 'replace the text Wait 1 'wait a moment Cursor Off Noblink 'hide cursor Wait 1 'wait a moment Cursor On Blink 'show cursor Wait 1 'wait a moment Display Off 'turn display off Wait 1 'wait a moment Display On 'turn display on '-----------------NEW support for 4-line LCD------ Thirdline Lcd "Line 3" Fourthline Lcd "Line 4" Home Third 'goto home on line three Home Fourth Home F 'first letteer also works Locate 4 , 1 : Lcd "Line 4" Wait 1 'Now lets build a special character 'the first number is the characternumber (0-7) 'The other numbers are the rowvalues 'Use the LCD tool to insert this line Deflcdchar 1 , 225 , 227 , 226 , 226 , 226 , 242 , 234 , 228 ' replace ? with number (0-7) Deflcdchar 0 , 240 , 224 , 224 , 255 , 254 , 252 , 248 , 240 ' replace ? with number (0-7) Cls 'select data RAM Rem it is important that a CLS is following the deflcdchar statements because it will set the controller back in datamode Lcd Chr(0) ; Chr(1) 'print the special character '----------------- Now use an internal routine ------------ _temp1 = 1 'value into ACC !rCall _write_lcd 'put it on LCD End $LCDVFO Top Previous Next Action Instruct the compiler to generate very short Enable pulse for VFO displays. Syntax $LCDVFO Remarks VFO based displays need a very short Enable pulse. Normal LCD displays need a longer pulse. To support VFO displays this compiler directive has been added. The display need to be instruction compatible with normal HD44780 based text displays. Noritake is the biggest manufacturer of VFO displays. The $LCDVFO directive is intended to be used in combination with the LCD routines. ASM NONE See also NONE Example NONE $LIB Top Previous Next Action Informs the compiler about the used libraries. Syntax $LIB "libname1" [, "libname2"] Remarks Libname1 is the name of the library that holds ASM routines that are used by your program. More filenames can be specified by separating the names by a comma. The specified libraries will be searched when you specify the routines to use with the $EXTERNAL directive. The search order is the same as the order you specify the library names. The MCS.LBX will be searched last and is always included so you don't need to specify it with the $LIB directive. Because the MCS.LBX is searched last you can include duplicate routines in your own library. These routines will be used instead of the ones from the default MCS.LBX library. This is a good way when you want to enhance the MCS.LBX routines. Just copy the MCS.LIB to a new file and make the changes in this new file. When we make changes to the library your changes will be preserved. Creating your own LIB file A library file is a simple ASCII file. It can be created with the BASCOM editor, notepad or any other ASCII editor. When you use BASCOM, make sure that the LIB extension is added to the Options, Environment, Editor, "No reformat extension". This will prevent the editor to reformat the LIB file when you open it. The file must include the following header information. It is not used yet but will be later. copyright = Your name www = optional location where people can find the latest source email = your email address comment = AVR compiler library libversion = the version of the library in the format : 1.00 date = date of last modification statement = A statement with copyright and usage information The routine must start with the name in brackets and must end with the [END]. The following ASM routine example is from the MYLIB.LIB library. [test] Test: ldd r26,y+2 ; load address of X ldd r27,y+3 ld r24,x ; get value into r24 Inc r24 ; value + 1 St x,r24 ; put back ldd r26,y+0 ; address of Y ldd r27,y+1 st x,r24 ; store ret ; ready [END] After you have saved your library in the LIB subdirectory you must compile it with the LIB Manager. Or you can include it with the LIB extension in which case you don�t have to compile it. About the assembler. When you reference constants that are declared in your basic program you need to put a star(*) before the line. ' Basic Program CONST myconst = 7 ' asm lib * sbi portb, myconst By adding the *, the line will be compiled when the basic program is compiled. It will not be changed into object code in the LBX file. When you use constants you need to use valid BASIC constants: Ldi r24,12 Ldi r24, 1+1 Ldi r24, &B001 ; binary basic Ldi r24,0b001 ; binary Ldi r24,&HFF ; hex basic Ldi r24,$FF ; hex Ldi r24,0xFF ; hex Other syntax is NOT supported. See also $EXTERNAL Example $regfile = "m48def.dat" $crystal = 4000000 $baud = 19200 Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 'In order to let this work you must put the mylib.lib file in the LIB dir 'And compile it to a LBX '------------------------------------------------------------------------- 'define the used library $lib"mylib.lbx" 'you can also use the original ASM : '$LIB "mylib.LIB" 'also define the used routines $external Test 'this is needed so the parameters will be placed correct on the stack Declare Sub Test(byval X Asbyte , Y Asbyte) 'reserve some space Dim Z As Byte 'call our own sub routine Call Test(1 , Z) 'z will be 2 in the used example End $LOADER 2081 ENHANCED Top Previous Next Action Instruct the compiler to create a boot loader at the specified address. Can be used for all AVR that support a boot loader like ATMEGA and ATXMEGA chips. Syntax $LOADER = address Remarks address The address where the boot loader is located. You can find this address in the data sheet. In version 2081 a constant named _LOADER_PAGE is created that holds the 64 KB page number. A lot of AVR microcontrollers are configured such that it is possible to use a boot loader able to receive firmware updates and to reprogram the Flash memory on demand. These AVR which support boot loader have a so called boot section. Normally a chip will start at address 0 when it resets. This is also called the reset vector. Chips that have a boot section, split the flash memory in two parts. The boot section is a small part of the normal flash and by setting a fuse bit you select that the chip runs code at the boot sector when it resets instead of the normal reset vector. The Program Flash memory space of ATXMEGA chips is also divided into Application and Boot sections. Both sections have dedicated Lock Bits for setting restrictions on write or read/write operations. ATXMEGA Program Flash memory parts: 1. Application Section for application code 2. Application Table Section for application code or data storage 3. Boot Section for application code or bootloader code You need to set the fuse bits so the chip jump to the boot loader address at reset (BOOTRST) ! Some chips also have fuse bits to select the size of the boot loader (e.g. 1024 words, 2048 words, 4096 words) The boot loader start address depends also on the boot size. You can find following information in the data sheet of the device (example for ATMEGA644): Boot Size Boot Loader Flash Section Boot Reset Address (Start Boot Loader Section) 512 words 0x7E00 - 0x7FFF $loader = $7E00 1024 words 0x7C00 - 0x7FFF $loader = $7C00 2048 words 0x7800 - 0x7FFF $loader = $7800 4096 words 0x7000 - 0x7FFF $loader = $7000 For ATXMEGA chips like ATXMEGA32A4 the boot section is part of the Flash Program Memory. You can find following information in the data sheet of the ATXMEGA device under Flash Program Memory (example for ATxmega16A4 .....ATxmega128A4): Chip Boot Loader Flash Section Boot Reset Address (Start Boot Loader Section) ATxmega16A4 0x2000 - 0x7FFF $loader = &H2000 ATxmega32A4 0x4000 - 0x47FF $loader = &H4000 ATxmega64A4 0x8000 - 0x87FF $loader = &H8000 ATxmega128A4 0x10000 - 0x10FFF $loader = &H10000 An external programmer is needed to program the boot loader into the chip. After the fuse bits are set and the boot loader is programmed you do not need the external programmer anymore for this chip (except you want to change the fuse bits). The MCS boot loader sample is a serial boot loader that uses the serial port (USART). With ATXMEGA or with ATMEGA with more then one USART you can choose which USART (COM port) should be used with the boot loader. For example you can use COM7 with an ATXMEGA: Config Com7 = 57600 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 ' Open "COM7:" For Binary As #7 When using another UART as COM1 do not forget to add the Interface number (in this example #7) to all the Serial IO functions like Waitkey(#7) or Print #7 , Chr(bstatus); in the boot loader example The boot loader uses the X-modem checksum protocol to receive the data. (XModem protocol (packet size = 128)) Most terminal emulators can send X-modem checksum. The Boot loader sample can upload both normal flash programs and EEPROM images. The Boot loader sends a byte with value of 123 to the AVR Boot loader. This boot loader program then enter the boot loader or will jump to the reset vector (0000) to execute the normal flash program. When it receives 124 instead of 123, it will upload the EEPROM. When you select a BIN file the flash will be uploaded. When you select an EEP file, the EEPROM will be uploaded. The following sample is written so it supports all chips with a boot section. How you need to use this ATMEGA boot loader example program: 1. Uncomment the Chip type and Const Loaderchip you want to use (for example ATMEGA644) $regfile = "m644def.dat" '$regfile = "m644Pdef.dat" Const Loaderchip = 644 2. Double check the baud rate and COM port you want to use 3. Compile the boot loader example 4. Program it into the chip with an external programmer like AVR ISP MKII 5. Select MCS Bootloader from programmer (select the right COM Port and baud rate) 6. compile a new program or example for this chip 7. reset the chip Ways to reset the AVR chip: Hardware reset: 1. Hardware Reset switch/button to GND (manual) 2. MCS Bootloader can set and reset the DTR or RTS line of serial COM port which can be used to reset the AVR (automatic) Software Reset: 1. Reset with Watchdog Timer (e.g. setting the Watchdog to 16ms, start it and let it time out) 2. With GOTO command (e.g. when ATMEGA644 is used the boot loader start at $7c00 ($loader = $7c00). Then you can use: GOTO &H7c00 to jump to the boot loader start. 3. With ATXMEGA there is a special register to reset the ATXMEGA via software. See also topic ATXMEGA 4. With MCS Bootloader you can send one or several ASCII character to reset the chip like with string "boot_me". In this case the "boot_me" must be detected in your main application on the AVR and then use for example Watchdog or GOTO to reset the chip. The boot loader is written to work at a baud rate of 57600. This baud rate works for most chips that use the internal oscillator. But it is best to check it first with a simple program. When you use a crystal you might even use a higher baud rate. You can change this by changing the baud rate in the boot loader example (take care to use also the same baud rate in the boot loader application (e.g. MCS Bootloader) on the PC side) Now make a new test program and compile it. Press F4 to start the MCS bootloader. You now need to reset the chip so that it will start the boot loader section. The boot loader will send a byte with value of 123 and the Bascom boot loader receives this and thus starts the loader process. There will be a stand alone boot loader available too. And the sample will be extended to support other AVR chips with boot section too. There is a $BOOT directive too. It is advised to use $LOADER as it allows you to write the boot loader in BASIC. You can not use interrupts in your boot loader program as the interrupts will point to the reset vector which is located in the lower section of the flash. When you start to writing pages, you overwrite this part. Take care when Watchdog is enabled by fuse bits and using a boot loader. You need to reset or deactivate the Watchdog in the boot loader example otherwise the firmware upload could be terminated by watchdog reset ! If you want to analyze the MCU Control and Status Register to know which reset source caused the reset you need to save this register already in the boot loader example because this register will be cleared and it will be always 0 when you check it at start of your application. When you use a boot loader it will use space from the available flash memory. The compiler does not know if you use a boot loader or not. When your program exceeds the available space and runs into the boot sector space, it will overwrite the boot loader. The $LOADERSIZE directive will take the boot loader size into account so you will get an error when the target file gets too big. Encryption/Decryption with Bootloader: You can use for example AES or XTEA ( XTEADECODE, XTEAENCODE ) in combination with boot loader examples. There is an AES with boot loader and AVR-DOS example in the ...BASCOM-AVR\SAMPLES\boot folder (xmega_dos_boot_AES.zip). See also $BOOT , $LOADERSIZE, MCS Bootloader , CONFIG INTVECTORSELECTION , $BOOTVECTOR There is an example for ATMEGA chips and for ATXMEGA Chips: ATMEGA Example: '---------------------------------------------------------------- ' (c) 1995-2016, MCS ' Bootloader.bas ' This sample demonstrates how you can write your own bootloader ' in BASCOM BASIC ' VERSION 2 of the BOOTLOADER. The waiting for the NAK is stretched ' further a bug was resolved for the M64/M128 that have a big page size '----------------------------------------------------------------- 'This sample will be extended to support other chips with bootloader 'The loader is supported from the IDE $crystal = 8000000 '$crystal = 14745600 $baud = 57600 'this loader uses serial com 'It is VERY IMPORTANT that the baud rate matches the one of the boot loader 'do not try to use buffered com as we can not use interrupts 'possible return codes of the PC bootloader.exe ' -6005 Cancel requested ' -6006 Fatal time out ' -6007 Unrecoverable event during protocol ' -6008 Too many errors during protocol ' -6009 Block sequence error in Xmodem ' -6016 Session aborted '$regfile = "m8def.dat" 'Const Loaderchip = 8 '$regfile = "m168def.dat" 'Const Loaderchip = 168 '$regfile = "m16def.dat" 'Const Loaderchip = 16 '$regfile = "m32def.dat" 'Const Loaderchip = 32 '$regfile = "m88def.dat" 'Const Loaderchip = 88 '$regfile = "m162def.dat" 'Const Loaderchip = 162 '$regfile = "m8515.dat" 'Const Loaderchip = 8515 '$regfile = "m128def.dat" 'Const Loaderchip = 128 '$regfile = "m64def.dat" 'Const Loaderchip = 64 '$regfile = "m2561def.dat" 'Const Loaderchip = 2561 '$regfile = "m2560def.dat" 'Const Loaderchip = 2560 '$regfile = "m329def.dat" 'Const Loaderchip = 329 '$regfile = "m324pdef.dat" 'Const Loaderchip = 324 $regfile = "m644def.dat" '$regfile = "m644Pdef.dat" Const Loaderchip = 644 #if Loaderchip = 88 'Mega88 $loader = $c00 'this address you can find in the datasheet 'the loader address is the same as the boot vector address Const Maxwordbit = 5 Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 #endif #if Loaderchip = 168 'Mega168 $loader = $1c00 'this address you can find in the datasheet 'the loader address is the same as the boot vector address Const Maxwordbit = 6 Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 #endif #if Loaderchip = 32 ' Mega32 $loader = $3c00 ' 1024 words Const Maxwordbit = 6 'Z6 is maximum bit ' Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 #endif #if Loaderchip = 8 ' Mega8 $loader = $c00 ' 1024 words Const Maxwordbit = 5 'Z5 is maximum bit ' Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 #endif #if Loaderchip = 161 ' Mega161 $loader = $1e00 ' 1024 words Const Maxwordbit = 6 'Z6 is maximum bit ' #endif #if Loaderchip = 162 ' Mega162 $loader = $1c00 ' 1024 words Const Maxwordbit = 6 'Z6 is maximum bit ' Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 #endif #if Loaderchip = 8515 ' Mega8515 $loader = $c00 ' 1024 words Const Maxwordbit = 5 'Z6 is maximum bit ' Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Osccal = &HB3 ' the internal osc needed a new value #endif #if Loaderchip = 64 ' Mega64 $loader = $7c00 ' 1024 words Const Maxwordbit = 7 'Z7 is maximum bit ' Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 #endif #if Loaderchip = 128 ' Mega128 $loader = &HFC00 ' 1024 words Const Maxwordbit = 7 'Z7 is maximum bit ' Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 #endif #if Loaderchip = 2561 ' Mega2561 $loader = &H1FC00 ' 1024 words Const Maxwordbit = 7 'Z7 is maximum bit ' Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 #endif #if Loaderchip = 2560 ' Mega2560 $loader = &H1FC00 ' 1024 words Const Maxwordbit = 7 'Z7 is maximum bit ' Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 #endif #if Loaderchip = 16 ' Mega16 $loader = $1c00 ' 1024 words Const Maxwordbit = 6 'Z6 is maximum bit ' Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 #endif #if Loaderchip = 329 ' Mega32 $loader = $3c00 ' 1024 words Const Maxwordbit = 6 'Z6 is maximum bit ' Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 #endif #if Loaderchip = 324 ' Mega32 $loader = $3c00 ' 1024 words Const Maxwordbit = 6 'Z6 is maximum bit ' Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 #endif #if Loaderchip = 644 ' Mega644P $loader = $7c00 ' 1024 words Const Maxwordbit = 7 'Z7 is maximum bit ' Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 #endif Const Maxword =(2 ^ Maxwordbit) * 2 '128 Const Maxwordshift = Maxwordbit + 1 Const Cdebug = 0 ' leave this to 0 #if Cdebug Print Maxword Print Maxwordshift #endif 'Dim the used variables Dim Bstatus As Byte , Bretries As Byte , Bblock As Byte , Bblocklocal As Byte Dim Bcsum1 As Byte , Bcsum2 As Byte , Buf(128) As Byte , Csum As Byte Dim J As Byte , Spmcrval As Byte ' self program command byte value Dim Z As Long 'this is the Z pointer word Dim Vl As Byte , Vh As Byte ' these bytes are used for the data values Dim Wrd As Word , Page As Word 'these vars contain the page and word address Dim Bkind As Byte , Bstarted As Byte 'Mega 88 : 32 words, 128 pages Disable Interrupts 'we do not use ints 'Waitms 100 'wait 100 msec sec 'We start with receiving a file. The PC must send this binary file 'some constants used in serial com Const Nak = &H15 Const Ack = &H06 Const Can = &H18 'we use some leds as indication in this sample , you might want to remove it Config Pinb.2 = Output Portb.2 = 1 'the stk200 has inverted logic for the leds Config Pinb.3 = Output Portb.3 = 1 $timeout = 400000 'we use a timeout 'When you get LOADER errors during the upload, increase the timeout value 'for example at 16 Mhz, use 200000 Bretries = 5 'we try 5 times Testfor123: #if Cdebug Print "Try " ; Bretries Print "Wait" #endif Bstatus = Waitkey() 'wait for the loader to send a byte #if Cdebug Print "Got " #endif Print Chr(bstatus); If Bstatus = 123 Then 'did we received value 123 ? Bkind = 0 'normal flash loader Goto Loader Elseif Bstatus = 124 Then ' EEPROM Bkind = 1 ' EEPROM loader Goto Loader Elseif Bstatus <> 0 Then Decr Bretries If Bretries <> 0 Then Goto Testfor123 'we test again End If For J = 1 To 10 'this is a simple indication that we start the normal reset vector Toggle Portb.2 : Waitms 100 Next #if Cdebug Print "RESET" #endif Goto _reset 'goto the normal reset vector at address 0 'this is the loader routine. It is a Xmodem-checksum reception routine Loader: #if Cdebug Print "Clear buffer" #endif Do Bstatus = Waitkey() Loop Until Bstatus = 0 For J = 1 To 3 'this is a simple indication that we start the normal reset vector Toggle Portb.2 : Waitms 50 Next If Bkind = 0 Then Spmcrval = 3 : Gosub Do_spm ' erase the first page Spmcrval = 17 : Gosub Do_spm ' re-enable page End If Bretries = 10 'number of retries Do Bstarted = 0 ' we were not started yet Csum = 0 'checksum is 0 when we start Print Chr(nak); ' firt time send a nack Do Bstatus = Waitkey() 'wait for statuse byte Select Case Bstatus Case 1: ' start of heading, PC is ready to send Incr Bblocklocal 'increase local block count Csum = 1 'checksum is 1 Bblock = Waitkey() : Csum = Csum + Bblock 'get block Bcsum1 = Waitkey() : Csum = Csum + Bcsum1 'get checksum first byte For J = 1 To 128 'get 128 bytes Buf(j) = Waitkey() : Csum = Csum + Buf(j) Next Bcsum2 = Waitkey() 'get second checksum byte If Bblocklocal = Bblock Then 'are the blocks the same? If Bcsum2 = Csum Then 'is the checksum the same? Gosub Writepage 'yes go write the page Print Chr(ack); 'acknowledge Else 'no match so send nak Print Chr(nak); End If Else Print Chr(nak); 'blocks do not match End If Case 4: ' end of transmission , file is transmitted If Wrd > 0 And Bkind = 0 Then 'if there was something left in the page Wrd = 0 'Z pointer needs wrd to be 0 Spmcrval = 5 : Gosub Do_spm 'write page Spmcrval = 17 : Gosub Do_spm ' re-enable page End If ' Waitms 100 ' OPTIONAL REMARK THIS IF THE DTR SIGNAL ARRIVES TO EARLY Print Chr(ack); ' send ack and ready Portb.3 = 0 ' simple indication that we are finished and ok Waitms 20 Goto _reset ' start new program Case &H18: ' PC aborts transmission Goto _reset ' ready Case 123 : Exit Do 'was probably still in the buffer Case 124 : Exit Do Case Else Exit Do ' no valid data End Select Loop If Bretries > 0 Then 'attempte left? Waitms 1000 Decr Bretries 'decrease attempts Else Goto _reset 'reset chip End If Loop 'write one or more pages Writepage: If Bkind = 0 Then For J = 1 To 128 Step 2 'we write 2 bytes into a page Vl = Buf(j) : Vh = Buf(j + 1) 'get Low and High bytes ! lds r0, {vl} 'store them into r0 and r1 registers ! lds r1, {vh} Spmcrval = 1 : Gosub Do_spm 'write value into page at word address Wrd = Wrd + 2 ' word address increases with 2 because LS bit of Z is not used If Wrd = Maxword Then ' page is full Wrd = 0 'Z pointer needs wrd to be 0 Spmcrval = 5 : Gosub Do_spm 'write page Spmcrval = 17 : Gosub Do_spm ' re-enable page Page = Page + 1 'next page Spmcrval = 3 : Gosub Do_spm ' erase next page Spmcrval = 17 : Gosub Do_spm ' re-enable page End If Next Else 'eeprom For J = 1 To 128 Writeeeprom Buf(j) , Wrd Wrd = Wrd + 1 Next End If Toggle Portb.2 : Waitms 10 : Toggle Portb.2 'indication that we write Return Do_spm: Bitwait Spmcsr.0 , Reset ' check for previous SPM complete Bitwait Eecr.1 , Reset 'wait for eeprom Z = Page 'make equal to page Shift Z , Left , Maxwordshift 'shift to proper place Z = Z + Wrd 'add word ! lds r30,{Z} ! lds r31,{Z+1} #if _romsize > 65536 ! lds r24,{Z+2} ! sts rampz,r24 ' we need to set rampz also for the M128 #endif Spmcsr = Spmcrval 'assign register ! spm 'this is an asm instruction ! nop ! nop Return 'How you need to use this program: '1- compile this program '2- program into chip with sample elctronics programmer '3- select MCS Bootloader from programmers '4- compile a new program for example M88.bas '5- press F4 and reset your micro ' the program will now be uploaded into the chip with Xmodem Checksum ' you can write your own loader.too 'A stand alone command line loader is also available 'How to call the bootloader from your program without a reset ??? 'Do ' Print "test" ' Waitms 1000 ' If Inkey() = 27 Then ' Print "boot" ' Goto &H1C00 ' End If 'Loop 'The GOTO will do the work, you need to specify the correct bootloader address 'this is the same as the $LOADER statement. ATXMEGA Example: NOTICE that there are many Xmega processors and the page size differs. The example is for the xmega32A4 which uses MAXWORDBIT=7 Other chips require a different value. See the table after the example. '---------------------------------------------------------------- ' (c) 1995-2016, MCS ' BootloaderXmega32A4.bas ' This sample demonstrates how you can write your own bootloader ' in BASCOM BASIC for the XMEGA '----------------------------------------------------------------- 'The loader is supported from the IDE $crystal = 32000000 ' xmega128 is running on 32 MHz $regfile = "xm32a4def.dat" $lib "xmega.lib" ' add a reference to this lib 'first enabled the osc of your choice Config Osc = Disabled , 32mhzosc = Enabled 'internal 2 MHz and 32 MHz enabled 'configure the systemclock Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 ' we will use 32 MHz and divide by 1 to end up with 32 MHz $loader = &H4000 ' bootloader starts after the application Config Com1 = 57600 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 ' use USART C0 'COM0-USARTC0, COM1-USARTC2, COM2-USARTD0. etc. Config Portc.3 = Output 'define TX as output Config Pinc.2 = Input Const Maxwordbit = 7 ' Z7 is maximum bit ' Const Maxword =(2 ^ Maxwordbit) * 2 '128 Const Maxwordshift = Maxwordbit + 1 Const Cdebug = 0 ' leave this to 0 'Dim the used variables Dim Bstatus As Byte , Bretries As Byte , Bmincount As Byte , Bblock As Byte , Bblocklocal As Byte Dim Bcsum1 As Byte , Bcsum2 As Byte , Buf(128) As Byte , Csum As Byte Dim J As Byte , Spmcrval As Byte ' self program command byte value Dim Z As Long 'this is the Z pointer word Dim Vl As Byte , Vh As Byte ' these bytes are used for the data values Dim Wrd As Word , Page As Word 'these vars contain the page and word address Disable Interrupts 'we do not use ints 'We start with receiving a file. The PC must send this binary file 'some constants used in serial com Const Nak = &H15 Const Ack = &H06 Const Can = &H18 $timeout = 300000 'we use a timeout 'When you get LOADER errors during the upload, increase the timeout value 'for example at 16 Mhz, use 200000 Bretries = 5 : Bmincount = 3 'we try 10 times and want to get 123 at least 3 times Do Bstatus = Waitkey() 'wait for the loader to send a byte If Bstatus = 123 Then 'did we received value 123 ? If Bmincount > 0 Then Decr Bmincount Else Print Chr(bstatus); Goto Loader ' yes so run bootloader End If Else 'we received some other data If Bretries > 0 Then 'retries left? Bmincount = 3 Decr Bretries Else Rampz = 0 Goto Proces_reset 'goto the normal reset vector at address 0 End If End If Loop 'this is the loader routine. It is a Xmodem-checksum reception routine Loader: Do Bstatus = Waitkey() Loop Until Bstatus = 0 Spmcrval = &H20 : Gosub Do_spm ' erase all app pages Bretries = 10 'number of retries Do Csum = 0 'checksum is 0 when we start Print Chr(nak); ' firt time send a nack Do Bstatus = Waitkey() 'wait for statuse byte Select Case Bstatus Case 1: ' start of heading, PC is ready to send Incr Bblocklocal 'increase local block count Csum = 1 'checksum is 1 Bblock = Waitkey() : Csum = Csum + Bblock 'get block Bcsum1 = Waitkey() : Csum = Csum + Bcsum1 'get checksum first byte For J = 1 To 128 'get 128 bytes Buf(j) = Waitkey() : Csum = Csum + Buf(j) Next Bcsum2 = Waitkey() 'get second checksum byte If Bblocklocal = Bblock Then 'are the blocks the same? If Bcsum2 = Csum Then 'is the checksum the same? Gosub Writepage 'yes go write the page Print Chr(ack); 'acknowledge Else 'no match so send nak Print Chr(nak); End If Else Print Chr(nak); 'blocks do not match End If Case 4: ' end of transmission , file is transmitted If Wrd > 0 Then 'if there was something left in the page Wrd = 0 'Z pointer needs wrd to be 0 Spmcrval = &H24 : Gosub Do_spm 'write page End If Print Chr(ack); ' send ack and ready Waitms 20 Goto Proces_reset Case &H18: ' PC aborts transmission Goto Proces_reset ' ready Case 123 : Exit Do 'was probably still in the buffer Case 124 : Exit Do Case Else Exit Do ' no valid data End Select Loop If Bretries > 0 Then 'attempte left? Waitms 1000 Decr Bretries 'decrease attempts Else Goto Proces_reset 'reset chip End If Loop 'write one or more pages Writepage: For J = 1 To 128 Step 2 'we write 2 bytes into a page Vl = Buf(j) : Vh = Buf(j + 1) 'get Low and High bytes ! lds r0, {vl} 'store them into r0 and r1 registers ! lds r1, {vh} Spmcrval = &H23 : Gosub Do_spm 'write value into page at word address Wrd = Wrd + 2 ' word address increases with 2 because LS bit of Z is not used If Wrd = Maxword Then ' page is full Wrd = 0 'Z pointer needs wrd to be 0 Spmcrval = &H24 : Gosub Do_spm 'write page Page = Page + 1 'next page End If Next Return Do_spm: Z = Page 'make equal to page Shift Z , Left , Maxwordshift 'shift to proper place Z = Z + Wrd 'add word ! lds r30,{Z} ! lds r31,{Z+1} #if _romsize > 65536 ! lds r24,{Z+2} ! sts rampz,r24 ' we need to set rampz also for the M128 #endif Nvm_cmd = Spmcrval Cpu_ccp = &H9D ! spm 'this is an asm instruction Do_spm_busy: ! lds r23, NVM_STATUS ! sbrc r23,7 ;if busy bit is cleared skip next instruc tion ! rjmp do_spm_busy Return Proces_reset: Rampz = 0 Goto _reset 'start at address 0 PAGE SIZE Processor Pagesize Maxwordbit ATxmega128A1 512 8 ATxmega128A1U 512 8 ATxmega128A3 512 8 ATxmega128A3U 512 8 ATxmega128A4U 256 7 ATxmega128B1 256 7 ATxmega128B3 256 7 ATxmega128C3 512 8 ATxmega128D3 512 8 ATxmega128D4 256 7 ATxmega16A4 256 7 ATxmega16A4U 256 7 ATxmega16C4 256 7 ATxmega16D4 256 7 ATxmega16E5 128 6 ATxmega192A3 512 8 ATxmega192A3U 512 8 ATxmega192C3 512 8 ATxmega192D3 512 8 ATxmega256A3 512 8 ATxmega256A3B 512 8 ATxmega256A3BU 512 8 ATxmega256A3U 512 8 ATxmega256C3 512 8 ATxmega256D3 512 8 ATxmega32A4 256 7 ATxmega32A4U 256 7 ATxmega32C3 256 7 ATxmega32C4 256 7 ATxmega32D3 256 7 ATxmega32D4 256 7 ATxmega32E5 128 6 ATxmega384C3 512 8 ATxmega384D3 512 8 ATxmega64A1 256 7 ATxmega64A1U 256 7 ATxmega64A3 256 7 ATxmega64A3U 256 7 ATxmega64A4U 256 7 ATxmega64B1 256 7 ATxmega64B3 256 7 ATxmega64C3 256 7 ATxmega64D3 256 7 ATxmega64D4 256 7 ATxmega8E5 128 6 $LOADERSIZE Top Previous Next Action Instruct the compiler that a boot loader is used so it will not overwrite the boot space. Syntax $LOADERSIZE = size Remarks size The amount of space in bytes that is used by the boot loader. When you use a boot loader it will use space from the available flash memory. The compiler does not know if you use a boot loader or not. It also does not know how you have set the fuse bits, so it is impossible to know how big the bootloader size is. When your program exceeds the available space and runs into the boot sector space, it will overwrite the boot loader. The $loadersize directive will take the boot loader size into account so you will get an error when the target file gets too big. When you select the MCS boot loader as programmer the IDE also will take into account the specified boot loader size. The directive can be used when you have a different programmer selected. For example an external programmer that does not know about the boot size. Do not use this directive in the bootloader program itself. You will get an error 344 in that case. $LOADERSIZE is only intended to be used in normal applications. See also $LOADER , $BOOT ASM NONE Example NONE $MAP Top Previous Next Action Will generate label info in the report. Syntax $MAP Remarks The $MAP directive will put an entry for each line number with the address into the report file. This info can be used for debugging purposes with other tools. See also NONE ASM NONE Example $MAP The report file will not contain the following section : Code map -------------------------------------------------------------------------------- Line Address(hex) -------------------------------------------------------------------------------- 1 0 9 36 26 39 30 3B 31 3E 32 48 33 4B 36 50 37 56 42 5B 43 6C 44 7D 45 80 46 81 $NOCOMPILE Top Previous Next Action Instruct the compiler not to compile the file. Syntax $NOCOMPILE Remarks This looks like an odd directive. Since you can split your program in multiple files, and you can create configuration files, you might open a file and try to compile it. Only normal project files can be compiled and you will get a number of errors and also unwanted files like error, report, etc. To prevent that you compile a file that is intended to be included, you can insert the $NOCOMPILE directive. Then the file will only be compiled when it is called from your main file, or other include file. A file that is opened as thus the main file, and which includes the $NOCOMP directive, can not be compiled. The IDE will see it as a successful compilation. This is important for the Batch Compiler. See also Batch Compiler Example $NOCOMPILE $NOFRAMEPROTECT Top Previous Next Action This directive will disable interrupt frame protection. Syntax $NOFRAMEPROTECT Remarks See the new preferred switch : $FRAMEPROTECT See also $FRAMEPROTECT Example NONE $NOINIT Top Previous Next Action Instruct the compiler to generate code without initialization code. Syntax $NOINIT Remarks $NOINIT is only needed in rare situations. It will instruct the compiler not to add initialization code. But that means that you need to write your own code then. $NOINIT was added in order to support boot loaders. But the new $LOADER directive can better be used as it does not require special ASM knowledge. See also $LOADER Example NONE $NORAMCLEAR Top Previous Next Action Instruct the compiler to not generate initial RAM clear code. Syntax $NORAMCLEAR Remarks Normally the SRAM is cleared in the initialization code. When you don't want the SRAM to be cleared(set to 0) you can use this directive. Because all variables are automatically set to 0 or ""(strings) without the $NORAMCLEAR, using $NORAMCLEAR will set the variables to an unknown value. That is, the variables will probably set to FF but you cannot count on it. When you have a battery back upped circuit, you do not want to clear the RAM at start up. So that would be a situation when you could use $NORAMCLEAR. See also $NOINIT $NORAMPZ Top Previous Next Action This compiler directive disables RAMPZ clearing. Syntax $NORAMPZ Remarks Processors with more then 64 KB of memory need to set the RAMPZ register in order to point to the proper 64 KB page. If the RAMPZ register is used, it will be cleared when it is used for something different then accessing the flash. BASCOM uses the Z register to access flash memory or RAM memory. Since processors with external memory capability can access more then 64KB of RAM, the RAMPZ must be set/cleared when accessing this memory. Otherwise accessing the flash code could result in a change of RAMPZ, and after this, accessing the RAM would not point to the proper place in memory. But setting this register requires extra code. When your application just fitted into a M128 or M256 and you do not want this RAMPZ handling because your application works fine, then you can use this $NORAMPZ directive. To see if your processor See also NONE Example NONE $NOTRANSFORM Top Previous Next Action This option controls transformation of unsupported ASM mnemonics. Syntax $NOTRANSFORM ON|OFF Remarks By default, assembler mnemonics that are not supported for a chip or register are transformed into different assembler mnemonics. The IN and OUT instructions for example only work on hardware registers with an address lower then 64. Most PORT registers are located in this lower address space, but there are many chips that have more ports which are located in extended memory. For such chips, using a IN or OUT on an extended address would result in a failure. Thus the compiler changes IN into an LDS and an OUT into an STS. When a register is required, R23 will be used except for SBIS/SBIC, these instructions use R0 when required. When you develop some ASM code, you might want to get an error when you are using an instruction the wrong way. For this purpose you can turn off the transformation. $NOTRANSFORM ON will turn off the transformation. And with $NOTRANSFORM OFF you can turn it back on. You should only use this option in your own code. When you use it on your whole program, it will not compile since the bascom libraries which use CBI, SBI, SBIS, IN, OUT, etc. will use the transformation. See also NONE Example NONE $NOTYPECHECK Top Previous Next Action This directive will turn off type checking Syntax $NOTYPECHECK Remarks Type checking is performed on some operations. It is turned on by default. With the $NOTYPECHECK you can turn this feature off. See also $TYPECHECK Example NONE $PROJECTTIME Top Previous Next Action This directive will keep track of time you spend on the source. Syntax $PROJECTTIME Remarks Keeping track of project time is the only purpose of this directive. It will be ignored by the compiler. When the IDE finds the $PROJECTTIME directive, it will count the minutes you spend on the code. Each time you save the code, the updated value will be shown. The IDE will automatic insert the value after $PROJECTTIME. So how does this work? When you type, you start a timer. When there are no keystrokes for 2 minutes, this process stops. It is started automatic as soon as you start typing. So when you type a character each minute, each minute will be counted a a full minutes of work. The time is counted and shown in minutes. While you can edit the value in the source, it will be changed as soon as you save the source. See also NONE Example $PROJECTTIME $PROG Top Previous Next Action Directive to auto program the lock and fuse bits. Syntax $PROG LB, FB , FBH , FBX Syntax Xmega $PROG LB, F0 , F1 , F2 , F3 ,F4 , F5 Remarks While the lock and fuse bits make the AVR customizable, the settings for your project can give some problems. The $PROG directive will create a file with the project name and the PRG extension. Every time you program the chip, it will check the lock and fuse bit settings and will change them if needed. So in a new chip, the lock and fuse bits will be set automatically. A chip that has been programmed with the desired settings will not be changed. The programmer has an option to create the PRG file from the current chip settings. The LB, FH, FBH and FBX values are stored in hexadecimal format in the PRJ file. You may use any notation as long as it is a numeric constant. Some chips might not have a setting for FBH or FBX, or you might not want to set all values. In that case, do NOT specify the value. For example: $PROG &H20 ,,, This will only write the Lockbit settings. $PROG ,,&H30, This will only write the FBH settings. LB Lockbit settings FB Fusebit settings FBH Fusebit High settings FBX Extended Fusebit settings Sometimes the data sheet refers to the Fusebit as the Fusebit Low settings. The $PROG setting is only supported by the AVRISP, STK200/300, Sample Electronics and Universal MCS Programmer Interface. The USB-ISP programmer also supports the $PROG directive. When you select the wrong Fuse bit, you could lock your chip. For example when you choose the wrong oscillator option, it could mean that the micro expects an external crystal oscillator. But when you connect a simple crystal, it will not work. In these cases where you can not communicate with the micro anymore, the advise is to apply a clock signal to X1 input of the micro. You can then select the proper fuse bits again. When you set the Lock bits, you can not read the chip content anymore. Only after erasing the chip, it could be reprogrammed again. Once the lock bits and fuse bits are set, it is best to remark the $PROG directive. This because it takes more time to read and compare the bits every time. Xmega The Xmega has one lock byte and 6 fuse bytes. For an Xmega the Write PRG option will write the correct code. See also Programmers , $PROG $PROGRAMMER Top Previous Next Action Will set the programmer from the source code. Syntax $PROGRAMMER = number Remarks Number A numeric constant that identifies the programmer. The $PROGRAMMER directive will set the programmer just before it starts programming. When you press F4 to program a chip, the selected programmer will be made active. This is convenient when you have different project open and use different programmers. But it can also lead to frustration as you might think that you have the 'STK200' selected, and the directive will set it to USB-ISP. The following values can be used : Value Programmer 0 AVR-ISP programmer(old AN 910) 1 STK200/STK300 2 PG302 3 External programmer 4 Sample Electronics 5 Eddie Mc Mullen 6 KITSRUS K122 7 STK500 8 Universal MCS Interface 9 STK500 extended 10 Lawicel Bootloader 11 MCS USB 12 USB-ISP I 13 MCS Bootloader 14 Proggy 15 FLIP (Atmel) 16 USBprog Programmer/ AVR ISP mkII (Atmel) 17 Kamprog for AVR 18 MyAVR MKII/AVR910 19 USBASP 20 JTAG MKII 21 STK600 22 ARDUINO (using stk500v1 protocol) 23 ARDUINO V2 (using stk500v2 protocol) 24 MINI-MAX/AVR-C (BIPOM) 25 mySmart USB light STK500 mode See also $PROG ASM NONE Example $REGFILE $REDUCEIVR Top Previous Next Action This directive will inform the compiler to reduce the IVR (interrupt vector table) to the smallest possible size. Syntax $REDUCEIVR Remarks The flash memory of the processor always starts with the IVR (interrupt vector table). The user code is placed after this table. So what is this IVR ? This table contains an address for each interrupt. When an interrupt occurs, the processor will jump to a specific and fixed address in code memory. The address depends on the interrupt itself, and on the processor. For example the MEGA88 has 25 interrupt sources. You can find them in the dat file : INTname1=INT0,$001,EIMSK.INT0,EIFR.INTF0 INTname2=INT1,$002,EIMSK.INT1,EIFR.INTF1 INTname3=PCINT0,$003,PCICR.PCIE0,PCIFR.PCIF0 INTname4=PCINT1,$004,PCICR.PCIE1,PCIFR.PCIF1 INTname5=PCINT2,$005,PCICR.PCIE2,PCIFR.PCIF2 INTname6=WDT@WATCHDOG,$006,WDTCSR.WDIE,WDTCSR.WDIF INTname7=OC2A@COMPARE2A,$007,TIMSK2.OCIE2A,TIFR2.OCF2A INTname8=OC2B@COMPARE2B,$008,TIMSK2.OCIE2B,TIFR2.OCF2B INTname9=OVF2@TIMER2,$009,TIMSK2.TOIE2,TIFR2.TOV2 INTname10=ICP1@CAPTURE1,$00A,TIMSK1.TICIE1,TIFR1.ICF1 INTname11=OC1A@COMPARE1A,$00B,TIMSK1.OCIE1A,TIFR1.OCF1A INTname12=OC1B@COMPARE1B,$00C,TIMSK1.OCIE1B,TIFR1.OCF1B INTname13=OVF1@TIMER1,$00D,TIMSK1.TOIE1,TIFR1.TOV1 INTname14=OC0A@COMPARE0A,$00E,TIMSK0.OCIE0A,TIFR0.OCF0A INTname15=OC0B@COMPARE0B,$00F,TIMSK0.OCIE0B,TIFR0.OCF0B INTname16=OVF0@TIMER0,$010,TIMSK0.TOIE0,TIFR0.TOV0 INTname17=SPI,$011,SPCR.SPIE,SPSR.SPIF INTname18=URXC@SERIAL,$012,UCSR0B.RXCIE0,UCSR0A.RXC0 INTname19=UDRE,$013,UCSR0B.UDRIE0,UCSR0A.UDRE0 INTname20=UTXC,$014,UCSR0B.TXCIE0,UCSR0A.TXC0 INTname21=ADCC@ADC,$015,ADCSRA.ADIE,ADCSRA.ADIF INTname22=ERDY,$016,EECR.EERIE INTname23=ACI,$017,ACSR.ACIE,ACSR.ACI INTname24=TWI,$018,TWCR.TWIE,TWCR.TWINT INTname25=SPM,$019,SPMCSR.SPMIE You can see that INT0 comes first. And that the address is $001 which is &H0001. So when INT0 occurs, the processor will jump to address 1. When you did not define an ISR (ON INT0) , the compiler will insert a RETI instruction. So nothing bad will happen to your code. When you did define an ISR , the compiler will insert a JUMP to your interrupt routine. When your interrupt ends, the RETI will let the processor continue where it was when the interrupt occurred. In the example when we only use the ISR with the lowest address all other addresses in the table would get a RETI instruction. And the user code could start at &H1A (one address after $19). Now that is not so bad but there are also processors with bigger tables and with tables that require 2 words for a JUMP. You waste a lot of space this way. So what does $REDUCEIVR do? It will determine which interrupt you have used has the highest address. And it will use the address after that as the user code start. This means that if we use only INT0 and we use $REDUCEIVR, the user code will start at address &H2 ($2). So you will save a lot of code space this way. Ok so why isn't this enabled by default? There is a catch : when your code has an interrupt enabled and there is no matching ON the processor will jump into the user code and this will create a crash almost for sure. So our advise : use this when you understand what this option does, and use it when your application is finished. In any case, retest the complete application when the option is enabled. See also $LOADER , CONFIG INTVECTORSELECTION , $BOOTVECTOR Example $REDUCEIVR $REGFILE Top Previous Next Action Instruct the compiler to use the specified register file instead of the selected dat file. Syntax $REGFILE = "name" Remarks Name The name of the register file. The register files are stored in the BASCOM-AVR application directory and they all have the DAT extension. The register file holds information about the chip such as the internal registers and interrupt addresses. The register file info is derived from atmel definition files. The $REGFILE statement overrides the setting from the Options, Compiler, Chip menu. The settings are stored in a .CFG file. The $REGFILE directive must be the first statement in your program. It may not be put into an included file since only the main source file is checked for the $REGFILE directive. It is good practice to use the $REGFILE directive. It has the advantage that you can see at the source which chip it was written for. The $REGFILE directive is also needed when the PinOut viewer or the PDF viewer is used. The register files contain the hardware register names from the micro. They also contain the bit names. These are constants that you may use in your program. But the names can not be used to dim a variable for example. Example : DIM PORTA As Byte This will not work since PORTA is a register constant. See also $SWSTACK , $HWSTACK , $FRAMESIZE, Memory usage ASM NONE Example $REGFILE = "8515DEF.DAT" $RESOURCE Top Previous Next Action Instruct the compiler to use a special resource file for multi language support. Syntax $RESOURCE [DUMP] "lang1" [, "lang2"] $RESOURCE ON | OFF Remarks lang1 This is the name of the first and default language. You can add a maximum of 8 languages. The names will be used in the resource editor. But they are only intended as a reference. The resource names will not end up in your application. They are used for the column names in the resource editor. lang2 The second language. You can add multiple languages separated by a comma. The language must be specified within double quotes. ON This will turn on the languages resource handling. In some cases you need to turn the language handling ON or OFF which is explained later OFF This will turn OFF the language handling DUMP This mode will create a .BCS file which contains all used string constants Some applications require that the interface is available in multiple languages. You write your application the same way as you always do. When it is ready, you can add the $RESOURCE directive to make the application suited for multiple languages. The $RESOURCE option will generate a BYTE variable named LANGUAGE. You can change the value in your application. The compiler will take care that the proper string is shown. But first you need to translate the strings into the languages of your choice. For this purpose you can use the Resource Editor. The Resource Editor can import a BCS file (BASCOM String file) which contains the languages and the strings. You can then add a string for all languages. So first make sure your application works. Then compile using the $RESOURCE DUMP option. When you test the languages.bas sample the content will look like this : "English" , "Dutch" , "German" , "Italian" "Multi language test" "This" " is a test" "Name " "Hello " As you can see, the first line contains the languages. The other lines only contain a string. Each string is only stored once in BASCOM. So even while "Mark" can have multiple meanings, it will only end up once in the BCS file. After you have translated the strings, the content of the BCR (BASCOM Resource) file will look like : "English","Dutch","German","Italian" "This","Dit","Dies","Questo" "Name ","Naam","Name","Nome" "Multi language test","Meertalen test","","Test multilingua" "Hello ","Hallo","Hallo","Ciao" " is a test"," is een test","ist ein test","è un test" "mark","Mark","Marcus","Marco" You may edit this file yourself, using Notepad or you can use the Resource Editor. Untranslated strings will be stored as "". Untranslated strings will be shown in the original language ! Now recompile your project and the compiler will handle every string it will find in the resource file (BCR) in a special way. Strings that are not found in the BCR file, are not processed and handled like normal. For example when you have a PRINT "check this out" , and you did not put that in the BCR file, it will show the same no matter which value the LANGUAGE variable has. But for each string found in the BCR file, the compiler will show the string depending on the LANGUAGE variable. When one of the languages is not translated, it will show as the original language. When LANGUAGE is 0, it will show the first string (the string from the first column). When languages is 1, it will show the string from the second column, and so on. You must take care that the LANGUAGE variables has a valid value. So by switching/changing 1 variable, you can change the language in the entire application. Strings are used for PRINT, LCD and other commands. It will work on every string that is in the BCR file. But that also brings us to the next option. Image this code : If S = "mark" Then Print "we can not change names" End If As you can see, we use a string. The code will fail if the string is translated (and is different in each language). You can simply remove the this string from the Resource file. But when you also need the word "mark" in the interface, you have a problem. For this purpose you can turn off the resource handling using $RESOURCE OFF The compiler will then not process the code following the directive with the special resource handling. And when you are done, you can turn the resource handling on again using $RESOURCE ON. See also Resource Editor Example '------------------------------------------------------------------------------ ' language.bas ' (c) 1995-2016 , MCS Electronics 'This example will only work with the resource add on 'resources are only needed for multi language applications 'By changing the LANGUAGE variable all strings used will be shown in the proper language '------------------------------------------------------------------------------ $regfile = "m88def.dat" $crystal = 8000000 $baud = 19200 'a few steps are needed to create a multi language application 'STEP 1, make your program as usual 'STEP 2, generate a file with all string resources using the $RESOURCE DUMP directive '$resource Dump , "English" , "Dutch" , "German" , "Italian" 'we will use 4 languages 'STEP 3, compile and you will find a file with the BCS extesion 'STEP 4, use Tools, Resource Editor and inport the resources 'STEP 5, add languages, translate the original strings 'STEP 6, compile your program this time with specifying the languages without the DUMP option $resource "English" , "Dutch" , "German" , "Italian" 'this must be done before you use any other resource ! 'in this sample 4 languages are used 'this because all resources found are looked up in the BCR file(BasCom Resource) Dim S As String * 20 Dim B As Byte Print "Multi language test" Do Print "This" ; S = " is a test" : Print S Input "Name " , S Print "Hello " ; S 'now something to look out for ! 'all string data not found in the BCR file is not resourced. so there is no problem with the following: If S = "mark" Then Print "we can not change names" End If 'but if you want to have "mark" resourced for another sentence you have a problem. 'the solution is to turn off resourcing $resource Off Print "mark" If S = "mark" Then Print "we can not change names" End If $resource On Language = Language + 1 If Language > 3 Then Language = 0 Loop $ROMSTART new 2079 Top Previous Next Action Instruct the compiler to generate a hex/bin file that starts at the specified address. Syntax $ROMSTART = address Remarks Address The address where the code must start. By default the first address is 0. The $ROMSTART directive is an inheritance from BASCOM-8051. In the AVR it does not have any meaning. In the 8051 you can use and relocate external memory. This is not possible in the AVR and hence there is no practical usage. For a bootloader you can use the $LOADER directive. The $ROMSTART directive is still in the help because a future AVR processor might make the option useful. See also $LOADER ASM NONE Example $ROMSTART = &H4000 $SERIALINPUT Top Previous Next Action Specifies that serial input must be redirected. Syntax $SERIALINPUT = label Remarks Label The name of the assembler routine that must be called when a character is needed by the INPUT routine. The character must be returned in R24. With the redirection of the INPUT command, you can use your own input routines. This way you can use other devices as input devices. Note that the INPUT statement is terminated when a RETURN code (13) is received. By default when you use INPUT or INKEY(), the compiler will expect data from the COM port. When you want to use a keyboard or remote control as the input device you can write a custom routine that puts the data into register R24 once it needs this data. See also $SERIALOUTPUT Example '-------------------------------------------------------------------------------- 'name : $serialinput.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demonstrates $SERIALINPUT redirection of serial input 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no '-------------------------------------------------------------------------------- $regfile = "m48def.dat" 'define used crystal $crystal = 4000000 $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 'default use 10 for the SW stack $framesize = 40 'default use 40 for the frame space 'dimension used variables Dim S As String * 10 Dim W As Long 'inform the compiler which routine must be called to get serial characters $serialinput = Myinput 'make a never ending loop Do 'ask for name Input "name " , S Print S 'error is set on time out Print "Error " ; Err Loop End 'custom character handling routine 'instead of saving and restoring only the used registers 'and write full ASM code, we use Pushall and PopAll to save and restore 'all registers so we can use all BASIC statements '$SERIALINPUT requires that the character is passed back in R24 Myinput: Pushall 'save all registers W = 0 'reset counter Myinput1: Incr W 'increase counter ! Sbis USR, 7 ' Wait for character ! Rjmp myinput2 'no charac waiting so check again Popall 'we got something Err = 0 'reset error ! In _temp1, UDR ' Read character from UART Return 'end of routine Myinput2: If W > 1000000 Then 'with 4 MHz ca 10 sec delay ! rjmp Myinput_exit 'waited too long Else Goto Myinput1 'try again End If Myinput_exit: Popall 'restore registers Err = 1 'set error variable ! ldi R24, 13 'fake enter so INPUT will end Return $SERIALINPUT1 Top Previous Next Action Specifies that serial input of the second UART must be redirected. Syntax $SERIALINPUT1 = label Remarks Label The name of the assembler routine that must be called when a character is needed from the INPUT routine. The character must be returned in R24. With the redirection of the INPUT command, you can use your own input routines. This way you can use other devices as input devices. Note that the INPUT statement is terminated when a RETURN code (13) is received. By default when you use INPUT or INKEY(), the compiler will expect data from the COM2 port. When you want to use a keyboard or remote control as the input device you can write a custom routine that puts the data into register R24 once it asks for this data. See also $SERIALOUTPUT1 , $SERIALINPUT , $SERIALOUTPUT Example See the $SERIALINPUT sample $SERIALINPUT2LCD Top Previous Next Action This compiler directive will redirect all serial input to the LCD display instead of echo-ing to the serial port. Syntax $SERIALINPUT2LCD Remarks You can also write your own custom input or output driver with the $SERIALINPUT and $SERIALOUTPUT statements, but the $SERIALINPUT2LCD is handy when you use a LCD display. By adding only this directive, you can view all output form routines such as PRINT, PRINTBIN, on the LCD display. See also $SERIALINPUT , $SERIALOUTPUT , $SERIALINPUT1 , $SERIALOUTPUT1 Example $regfile = "m48def.dat" $crystal = 4000000 $baud = 19200 Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portc.7 , Rs = Portc.6 $serialinput2lcd Dim V As Byte Do Cls Input "Number " , V 'this will go to the LCD display Loop $SERIALOUTPUT Top Previous Next Action Specifies that serial output must be redirected. Syntax $SERIALOUTPUT = label Remarks Label The name of the assembler routine that must be called when a character is send to the serial buffer (UDR). The character is placed into R24. With the redirection of the PRINT and other serial output related commands, you can use your own routines. This way you can use other devices as output devices. See also $SERIALINPUT , $SERIALINPUT2LCD , $SERIALINPUT1 , $SERIALOUTPUT1 Example $regfile = "m48def.dat" $crystal = 4000000 $baud = 19200 Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 $serialoutput = Myoutput 'your program goes here Do Print "Hello" Loop End myoutput: 'perform the needed actions here 'the data arrives in R24 'just set the output to PORTB !outportb,r24 !ret $SERIALOUTPUT1 Top Previous Next Action Specifies that serial output of the second UART must be redirected. Syntax $SERIALOUTPUT1 = label Remarks Label The name of the assembler routine that must be called when a character is send to the serial buffer (UDR1). The character is placed into R24. With the redirection of the PRINT and other serial output related commands, you can use your own routines. This way you can use other devices as output devices. See also $SERIALINPUT1 , $SERIALINPUT , $SERIALINPUT2LCD , $SERIALOUTPUT Example See the $SERIALOUTPUT example $SIM Top Previous Next Action Instructs the compiler to generate empty wait loops for the WAIT and WAITMS statements. This to allow faster simulation. Syntax $SIM Remarks Simulation of a WAIT statement can take a long time especially when memory view windows are opened. The $SIM compiler directive instructs the compiler to not generate code for WAITMS and WAIT. This will of course allows faster simulation. When your application is ready you must remark the $SIM directive or otherwise the WAIT and WAITMS statements will not work as expected. When you forget to remove the $SIM option and you try to program a chip you will receive a warning that $SIM was used. See also NONE ASM NONE Example $regfile = "m48def.dat" $crystal = 4000000 $baud = 19200 Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 $sim Do Wait 1 Print "Hello" Loop $STACKDUMP Top Previous Next Action Makes the compiler hook up the reset vector and includes code, which allows to get a dump of the stack residing in SRAM. Syntax $stackdump Preface Using $stackdump presumes certain knowledge of assembler code, i.e. reading and understanding disassembled code. On the other hand it's possible that an user, who has little to no experience in assembly reading, simply uses $stackdump, while an assembly-experienced user evaluates the dumped result. This allows sharing of experience, knowledge and active debugging of difficult code via Internet, without having actual hardware available. Remarks Additional code in Bascom-Basic is used to put out the content of the saved stack to whatever target, in the provided example code the dump is written to the serial interface, however any other reasonable target for receiving the dump is feasible. For example, a dump can be saved to EEProm also, the user is free to modify the target himself. Function After each reset an AVR micrcontroller executes the reset-vector, the $stackdump code hooks this vector and executes a small routine, which saves a certain amount of stack to a protected memory range. This is possible, as SRAM memory keeps its content even after a reset. After saving the stack, a routine is executed which clears SRAM, excluding the previously saved range. In the following it's save to put out the saved stack content by regular Bascom code. Without $stackdump this can't be done, as a) the stack would be destroyed by normal SRam-clearing code, and b) because every Bascom-code modifies, i.e overwrite the stack itself. Usage Stack can contain two types of data, 1) data, i.e. saved registers and 2) return addresses, which were pushed on the stack by previous calls. The most interesting is the latter, as it can point to faulty code. If followed these return addresses (which of course needs also some guesswork to distinguish it apart from saved registers), it's possible to find out interrupting code, and this way difficult to find bugs. Options Depending whether the stack pointer is intact at reset, one of the two options can be used: Ignore_SP = 1 Ignore_SP = 0 If a hard-rest occurs, for example by a watchdog reset, the stack pointer is reset to its default values, and this way can't be used to determine the stack pointers last position. For this case Ignore_SP = 1 is useful. In this mode the amount of bytes given by Stck_siz_sav beginning from stack end is saved. This can be used for tracking down randomly occurring resets by whatever reasons. Be aware that without knowing the stack pointers last position, it's much harder to find out the last executed call, but it's still possible. In contrary, if a soft reset occurs, the stack pointer is likely intact and the the option Ignore_SP = 0 is useful. Here the stack is saved from the stack pointers last position to the amount of Stck_siz_sav bytes till ramend/stack-end. In case ram-end comes first, only the stack range between stack pointer and ram-end is saved. The method using Ignore_SP = 0 is useful to redirect any interrupt to the reset vector by writing: On interrupt_xy my_isr NOSAVE Enable interrupt_xy Enable Interrupts '... my_isr: !jmp 0 return If using an external interrupt, for example INT0 for my_isr, a signal on INT0 will create the stack dump, pointing to code executed at occurrence of the signal. This works like an on-chip hardware debugger. In certain chips a watchdog timer interrupt is available, this interrupt can be used and a watchdog timeout will then create a dump. Notice: Previous mentioned functionality for Ignore_SP = 0 needs enabled interrupts. In case these special, or also global interrupts get disabled by code, it will fail. But also a disabled interrupt can point to the source of a bug. Using Ignore_SP = 1 will work in any case, but with said restrictions. Closing note $stackdump can only increase the chance to trap down a nasty bug or do some special type debugging. It's for sure no cure-all type of tool. Because of certain restrictions given by AVR hardware it can't be universal. $SWSTACK Top Previous Next Action Sets the available space for the software stack. Syntax $SWSTACK = var Remarks Var A numeric decimal value. While you can configure the SW Stack in Options, Compiler, Chip, it is good practice to put the value into your code. This way you do no need the cfg(configuration) file. The $SWSTACK directive overrides the value from the IDE Options. It is important that the $SWSTACK directive occurs in your main project file. It may not be included in an $include file as only the main file is parsed for $SWSTACK. $SWSTACK only accepts numeric values. Software Stack stores the parameter addresses passed to a subroutine and LOCAL variable addresses. So the Software stack stores the addresses of variables where each passed variable and local variable use 2 bytes per respective addresses. When using SUB or FUNCTION there are 3 ways for parameters: · Using BYREF pass a variable by reference with its ADDRESS (so it is pointing to an existing variable which is already in SRAM) · Using BYVAL the value is stored in FRAME (during the SUB is processed) so it is pointing to the address in FRAME. · Using BYLABEL pass the address of a label When nothing is specified the parameter will be passed BYREF. See also $HWSTACK , $FRAMESIZE, Memory Usage For example if you have used 10 locals in a SUB and there are 3 parameters passed to it, you need: (10 * 2 Byte) + (3 * 2 Byte) = 26 Byte Software Stack. The following SUB need 10 Byte of Software Stack: 5* 2 Byte = 10 Byte So the software stack size can be calculated by taking the maximum number of parameter passed to a SUB routine, adding the number of LOCAL variables and multiplying the result by 2. To be safe, add 4 more bytes for internally used LOCAL variables. If you have several SUB or FUNCTIONS search for the SUB or FUNCTION with the most parameters and LOCAL variables and use that calculated maximum numbers for defining the Software Stack ($swstack). The Software Stack is growing top down (see picture) and start direct after the Hardware Stack. The Software Stack grows against the FRAME. Picture: Example Memory of ATXMEGA128A1 [****] Example $regfile = "xm128a1def.dat" $crystal = 32000000 '32MHz $hwstack = 64 $swstack = 128 $framesize = 288 Config Osc = Enabled , 32mhzosc = Enabled '32MHz 'configure the systemclock Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 '32MHz 'Config Interrupts Config Priority = Static , Vector = Application , Lo = Enabled 'Enable Lo Level Interrupts Config Com1 = 57600 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 Declare Sub My_sub() Call My_sub() End 'end program Sub My_sub() Local A1 As Byte , A2 As Byte , A3 As Byte , A4 As Byte , A5 As Byte Local S As String * 254 For A1 = 1 To 254 S = S + "1" Next A1 A1 = 1 A2 = 2 A3 = 3 A4 = 4 A5 = 5 Print A1 End Sub 'default use 40 for the frame space $TIMEOUT Top Previous Next Action Enable timeout on the hardware UART and software UART. Syntax $TIMEOUT = value Remarks Value A constant that fits into a LONG , indicating how much time must be waited before the waiting is terminated. All RS-232 serial statements and functions(except INKEY) that use the hardware UART or software UART, will halt the program until a character is received. Only with buffered serial input you can process your main program while the buffer receives data on the background. $TIMEOUT is an alternative for normal serial reception. It is not intended to be used with buffered serial reception. As of version 2077, the first (and only the first) UART supports the $TIMEOUT feature. When you assign a constant to $TIMEOUT, you actual assign a value to the internal created value named ___TIMEOUT. This value will be decremented in the routine that waits for serial data. When it reaches zero, it will terminate. So the bigger the value, the longer the wait time before the timeout occurs. The timeout is not in seconds or microseconds, it is a relative number. Only the speed of the oscillator has effect on the duration. And the value of the number of course. When the time out is reached, a zero/null will be returned to the calling routine. Waitkey() will return 0 when used with a byte. When you use INPUT with a string, the timeout will be set for every character. So when 5 characters are expected, and they arrive just before the timeout value is reached, it may take a long time until the code is executed. When the timeout occurs on the first character, it will return much faster. When you already sent data, this data will be returned. For example, "123" was sent but a RETURN was never sent, INPUT will return "123". While without the $TIMEOUT, INPUT will not return until a RETURN is received. When you activate $TIMEOUT, and your micro has two UARTS(Mega128 for example) it will be active for both UART0 and UART1. And for an ATMEGA2560 with 4 UARTS, it will be enabled for all 4 UARTS, but only when no serial input buffer is configured. $TIMEOUT is also supported by the software UART. In fact, when you enable it for the hardware UART, you enable it for the software UART as well. See Also INPUT , WAITKEY Example '----------------------------------------------------------------------------------------- 'name : timeout.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demonstration of the $timeout option 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no '----------------------------------------------------------------------------------------- $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space 'most serial communication functions and routines wait until a character 'or end of line is received. 'This blocks execution of your program. SOmething you can change by using buffered input 'There is also another option : using a timeout '$timeout Does Not Work With Buffered Serial Input Dim Sname As String * 10 Dim B As Byte Do $timeout = 1000000 Input "Name : " , Sname Print "Hello " ; Sname $timeout = 5000000 Input "Name : " , Sname Print "Hello " ; Sname Loop 'you can re-configure $timeout $TINY Top Previous Next Action Instruct the compiler to generate initialize code without setting up the stacks. Syntax $TINY Remarks The tiny11 for example is a powerful chip. It only does not have SRAM. BASCOM depends on SRAM for the hardware stack and software stack. When you like to program in ASM you can use BASCOM with the $TINY directive. Some BASCOM statements will also already work but the biggest part will not work. A future version will support a subset of the BASCOM statements and function to be used with the chips without SRAM. Note that the generated code is not yet optimized for the tiny parts. Some used ASM statements for example will not work because the chip does not support it. See also NONE ASM NONE Example $regfile = "attiny15.dat" $tiny $crystal = 1000000 $noramclear $hwstack = 0 $swstack = 0 $framesize = 0 Dim A As Iram Byte Dim B As Iram Byte A = 100 : B = 5 A = A + B End $TYPECHECK Top Previous Next Action This directive will turn on type checking Syntax $TYPECHECK Remarks Type checking is performed on some operations. It is turned on by default. With the $NOTYPECHECK you can turn this feature off. And with $TYPECHECK you can turn it on again. See also $NOTYPECHECK Example NONE $VERSION Top Previous Next Action This compiler directive stores version information. Syntax $VERSION V,S,R Remarks Version info is important information. If you need to maintain source code, it will make it easy to identify the code. $VERSION has 3 parameters. These must be numeric digits. Each time you compile your code, the release number is increased. You can use Version(2) to print this information. $version 1,2,3 will be printed as 1.2.3 The compiler will create three internal constants named _VERSION_MAJOR, _VERSION_MINOR and _VERSION_BUILD with the specified values. For example when $version is set to : $VERSION 1,2,3 _VERSION_MAJOR will become 1 , _VERSION_MINOR will become 2 and _VERSION_BUILD will become 3. See also VERSION Example $version 1,2,3 Print Version(2) $WAITSTATE Top Previous Next Action Compiler directive to activate external SRAM and to insert a WAIT STATE for a slower ALE signal. CONFIG XRAM should be used instead. Syntax $WAITSTATE Remarks The $WAITSTATE can be used to override the Compiler Chip Options setting. Wait states are needed for slow external components that can not handle the fast ALE signal from the AVR chip. See also $XA , CONFIG XRAM Example $WAITSTATE $XA Top Previous Next Action Compiler directive to activate external memory access. CONFIG XRAM should be used instead. Syntax $XA Remarks The $XA directive can be used to override the Compiler Chip Options setting. This way you can store the setting in your program code. It is strongly advised to do this. See also $WAITSTATE , CONFIG XRAM Example $XA $XRAMSIZE Top Previous Next Action Specifies the size of the external RAM memory. Syntax $XRAMSIZE = [&H] size Remarks Size A constant with the size of the external RAM memory chip. The size of the chip can be selected from the Options Compiler Chip menu. The $XRAMSIZE overrides this setting. It is important that $XRAMSTART precedes $XRAMSIZE See also $XRAMSTART , CONFIG XRAM Example '----------------------------------------------------------------------------------------- 'name : m128.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demonstrate using $XRAM directive 'micro : Mega128 'suited for demo : yes 'commercial addon needed : no '----------------------------------------------------------------------------------------- $regfile = "m128def.dat" ' specify the used micro $crystal = 1000000 ' used crystal frequency $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space $xramstart = &H1000 $xramsize = &H1000 Dim X As X $XRAMSTART Top Previous Next Action Specifies the location of the external RAM memory. Syntax $XRAMSTART = [&H]address Remarks Address The (hex)-address where the data is stored. Or the lowest address that enables the RAM chip. You can use this option when you want to run your code in systems with external RAM memory. Address must be a constant. By default the extended RAM will start after the internal memory so the lower addresses of the external RAM can't be used to store information. When you want to protect an area of the chip, you can specify a higher address for the compiler to store the data. For example, you can specify &H400. The first dimensioned variable will be placed in address &H400 and not in &H260. It is important that when you use $XRAMSTART and $XRAMSIZE that $XRAMSTART comes before $XRAMSIZE. See also $XRAMSIZE Example '----------------------------------------------------------------------------------------- 'name : m128.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demonstrate using $XRAM directive 'micro : Mega128 'suited for demo : yes 'commercial addon needed : no '----------------------------------------------------------------------------------------- $regfile = "m128def.dat" ' specify the used micro $crystal = 1000000 ' used crystal frequency $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space $xramstart = &H1000 $xramsize = &H1000 Dim X As X $XTEAKEY Top Previous Next Action This directive accepts a 16 byte XTEA key and informs the compiler to encrypt the binary image. Syntax $XTEAKEY 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 Remarks $XTEAKEY accepts 16 parameters. These are the 16 bytes which together form a 128 bit key. When your code is compiled, the resulting binary code will be encrypted with the provided key. A boot loader could then use XTEA and decrypt the binary file before writing to flash memory. The XTEADECODE statement can be used inside a boot loader to decrypt the encrypted blocks. The XTEA encoder uses 32 rounds. The same as used in the xtea.lib Only the binary image is encrypted, the HEX file is not encrypted! You can not simulate an encrypted program. Add this option when your project is ready. See also $AESKEY , XTEAENCODE , XTEADECODE Example NONE 1WIRE Top Previous Next 1WIRECOUNT Top Previous Next Action This statement reads the number of 1wire devices attached to the bus. Syntax var2 = 1WIRECOUNT() var2 = 1WIRECOUNT( port , pin) Remarks var2 A WORD variable that is assigned with the number of devices on the bus. port The PIN port name like PINB or PIND. pin The pin number of the port. In the range from 0-7. May be a numeric constant or variable. The variable must be of the type word or integer. You can use the 1wirecount() function to know how many times the 1wsearchNext() function should be called to get all the Id's on the bus. The 1wirecount function will take 4 bytes of SRAM. ___1w_bitstorage , Byte used for bit storage : lastdeviceflag bit 0 id_bit bit 1 cmp_id_bit bit 2 search_dir bit 3 ___1wid_bit_number, Byte ___1wlast_zero, Byte ___1wlast_discrepancy , Byte When there is no 1WIRE device on the bus, the ERR bit will be set. When devices are found, ERR will be cleared. ASM The following asm routines are called from mcs.lib. _1wire_Count : (calls _1WIRE, _1WIRE_SEARCH_FIRST , _1WIRE_SEARCH_NEXT) Parameters passed : R24 : pin number, R30 : port , Y+0,Y+1 : 2 bytes of soft stack, X : pointer to the frame space Returns Y+0 and Y+1 with the value of the count. This is assigned to the target variable. See also 1WWRITE , 1WRESET , 1WREAD , 1WSEARCHFIRST, 1WSEARCHNEXT , Using the 1wire protocol Example '-------------------------------------------------------------------------------- 'name : 1wireSearch.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demonstrates 1wsearch 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no '-------------------------------------------------------------------------------- $regfile = "m48def.dat" $crystal = 4000000 $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 'default use 10 for the SW stack $framesize = 40 'default use 40 for the frame space Config 1wire = Portb.0 'use this pin 'On the STK200 jumper B.0 must be inserted 'The following internal bytes are used by the scan routines '___1w_bitstorage , Byte used for bit storage : ' lastdeviceflag bit 0 ' id_bit bit 1 ' cmp_id_bit bit 2 ' search_dir bit 3 '___1wid_bit_number, Byte '___1wlast_zero, Byte '___1wlast_discrepancy , Byte '___1wire_data , string * 7 (8 bytes) '[DIM variables used] 'we need some space from at least 8 bytes to store the ID Dim Reg_no(8) As Byte 'we need a loop counter and a word/integer for counting the ID's on the bus Dim I As Byte , W As Word 'Now search for the first device on the bus Reg_no(1) = 1wsearchfirst() For I = 1 To 8 'print the number Print Hex(reg_no(i)); Next Print Do 'Now search for other devices Reg_no(1) = 1wsearchnext() For I = 1 To 8 Print Hex(reg_no(i)); Next Print Loop Until Err = 1 'When ERR = 1 is returned it means that no device is found anymore 'You could also count the number of devices W = 1wirecount() 'It is IMPORTANT that the 1wirecount function returns a word/integer 'So the result variable must be of the type word or integer 'But you may assign it to a byte or long too of course Print W 'as a bonus the next routine : ' first fill the array with an existing number Reg_no(1) = 1wsearchfirst() ' unremark next line to chance a byte to test the ERR flag 'Reg_no(1) = 2 'now verify if the number exists 1wverify Reg_no(1) Print Err 'err =1 when the ID passed n reg_no() does NOT exist ' optinal call it with pinnumber line 1wverify reg_no(1),pinb,1 'As for the other 1wire statements/functions, you can provide the port and pin number as anoption 'W = 1wirecount(pinb , 1) 'for example look at pin PINB.1 End 1WRESET Top Previous Next Action This statement brings the 1wire pin to the correct state, and sends a reset to the bus. Syntax 1WRESET 1WRESET PORT , PIN Remarks 1WRESET Reset the 1WIRE bus. The error variable ERR will return 1 if an error occurred Port The register name of the input port. Like PINB, PIND. Pin The pin number to use. In the range from 0-7. May be a numeric constant or variable. The global variable ERR is set when an error occurs. There is also support for multi 1-wire devices on different pins. To use this you must specify the port and pin that is used for the communication. The 1wreset, 1wwrite and 1wread statements will work together when used with the old syntax. And the pin can be configured from the compiler options or with the CONFIG 1WIRE statement. The syntax for additional 1-wire devices is : 1WRESET port , pin 1WWRITE var/constant ,bytes] , port, pin var = 1WREAD( bytes) , for the configured 1 wire pin var = 1WREAD(bytes, port, pin) ,for reading multiple bytes See also 1WREAD , 1WWRITE Example '-------------------------------------------------------------------------------- 'name : 1wire.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demonstrates 1wreset, 1wwrite and 1wread() 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no ' pull-up of 4K7 required to VCC from Portb.2 ' DS2401 serial button connected to Portb.2 '-------------------------------------------------------------------------------- $regfile = "m48def.dat" $crystal = 4000000 $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 'default use 10 for the SW stack $framesize = 40 'default use 40 for the frame space 'when only bytes are used, use the following lib for smaller code $lib "mcsbyte.lib" Config 1wire = Portb.0 'use this pin 'On the STK200 jumper B.0 must be inserted Dim Ar(8) As Byte , A As Byte , I As Byte Do Wait 1 1wreset 'reset the device Print Err 'print error 1 if error 1wwrite &H33 'read ROM command For I = 1 To 8 Ar(i) = 1wread() 'place into array Next 'You could also read 8 bytes a time by unremarking the next line 'and by deleting the for next above 'Ar(1) = 1wread(8) 'read 8 bytes For I = 1 To 8 Print Hex(ar(i)); 'print output Next Print 'linefeed Loop 'NOTE THAT WHEN YOU COMPILE THIS SAMPLE THE CODE WILL RUN TO THIS POINT 'THIS because of the DO LOOP that is never terminated!!! 'New is the possibility to use more than one 1 wire bus 'The following syntax must be used: For I = 1 To 8 Ar(i) = 0 'clear array to see that it works Next 1wreset Pinb , 2 'use this port and pin for the second device 1wwrite &H33 , 1 , Pinb , 2 'note that now the number of bytes must be specified! '1wwrite Ar(1) , 5,pinb,2 'reading is also different Ar(1) = 1wread(8 , Pinb , 2) 'read 8 bytes from portB on pin 2 For I = 1 To 8 Print Hex(ar(i)); Next 'you could create a loop with a variable for the bit number ! For I = 0 To 3 'for pin 0-3 1wreset Pinb , I 1wwrite &H33 , 1 , Pinb , I Ar(1) = 1wread(8 , Pinb , I) For A = 1 To 8 Print Hex(ar(a)); Next Print Next End 1WREAD Top Previous Next Action This statement reads data from the 1wire bus into a variable. Syntax var2 = 1WREAD( [ bytes] ) var2 = 1WREAD( bytes , port , pin) Remarks var2 Reads a byte from the bus and places it into variable var2. Optional the number of bytes to read can be specified. Port The PIN port name like PINB or PIND. Pin The pin number of the port. In the range from 0-7. Maybe a numeric constant or variable. Multi 1-wire devices on different pins are supported. To use this you must specify the port pin that is used for the communication. The 1wreset, 1wwrite and 1wread statements will work together when used with the old syntax. And the pin can be configured from the compiler options or with the CONFIG 1WIRE statement. The syntax for additional 1-wire devices is : 1WRESET port, pin 1WWRITE var/constant , bytes, port, pin var = 1WREAD(bytes, port, pin) for reading multiple bytes See also 1WWRITE , 1WRESET Example '-------------------------------------------------------------------------------- 'name : 1wire.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demonstrates 1wreset, 1wwrite and 1wread() 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no ' pull-up of 4K7 required to VCC from Portb.2 ' DS2401 serial button connected to Portb.2 '-------------------------------------------------------------------------------- $regfile = "m48def.dat" $crystal = 4000000 $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 'default use 10 for the SW stack $framesize = 40 'default use 40 for the frame space 'when only bytes are used, use the following lib for smaller code $lib "mcsbyte.lib" Config 1wire = Portb.0 'use this pin 'On the STK200 jumper B.0 must be inserted Dim Ar(8) As Byte , A As Byte , I As Byte Do Wait 1 1wreset 'reset the device Print Err 'print error 1 if error 1wwrite &H33 'read ROM command For I = 1 To 8 Ar(i) = 1wread() 'place into array Next 'You could also read 8 bytes a time by unremarking the next line 'and by deleting the for next above 'Ar(1) = 1wread(8) 'read 8 bytes For I = 1 To 8 Print Hex(ar(i)); 'print output Next Print 'linefeed Loop 'NOTE THAT WHEN YOU COMPILE THIS SAMPLE THE CODE WILL RUN TO THIS POINT 'THIS because of the DO LOOP that is never terminated!!! 'New is the possibility to use more than one 1 wire bus 'The following syntax must be used: For I = 1 To 8 Ar(i) = 0 'clear array to see that it works Next 1wreset Pinb , 2 'use this port and pin for the second device 1wwrite &H33 , 1 , Pinb , 2 'note that now the number of bytes must be specified! '1wwrite Ar(1) , 5,pinb,2 'reading is also different Ar(1) = 1wread(8 , Pinb , 2) 'read 8 bytes from portB on pin 2 For I = 1 To 8 Print Hex(ar(i)); Next 'you could create a loop with a variable for the bit number ! For I = 0 To 3 'for pin 0-3 1wreset Pinb , I 1wwrite &H33 , 1 , Pinb , I Ar(1) = 1wread(8 , Pinb , I) For A = 1 To 8 Print Hex(ar(a)); Next Print Next End 1WSEARCHFIRST Top Previous Next Action This statement reads the first ID from the 1wire bus into a variable(array). Syntax var2 = 1WSEARCHFIRST() var2 = 1WSEARCHFIRST( port , pin) Remarks var2 A variable or array that should be at least 8 bytes long that will be assigned with the 8 byte ID from the first 1wire device on the bus. port The PIN port name like PINB or PIND. pin The pin number of the port. In the range from 0-7. Maybe a numeric constant or variable. The 1wireSearchFirst() function must be called once to initiate the ID retrieval process. After the 1wireSearchFirst() function is used you should use successive function calls to the 1wSearchNext function to retrieve other ID's on the bus. A string can not be assigned to get the values from the bus. This because a null may be returned as a value and the null is also used as a string terminator. I would advice to use a byte array as shown in the example. The 1wirecount function will take 4 bytes of SRAM. ___1w_bitstorage , Byte used for bit storage : lastdeviceflag bit 0 id_bit bit 1 cmp_id_bit bit 2 search_dir bit 3 ___1wid_bit_number, Byte ___1wlast_zero, Byte ___1wlast_discrepancy , Byte ASM The following asm routines are called from mcs.lib. _1wire_Search_First : (calls _1WIRE, _ADJUST_PIN , _ADJUST_BIT_ADDRESS) Parameters passed : R24 : pin number, R30 : port , X : address of target array Returns nothing. See also 1WWRITE , 1WRESET , 1WREAD , 1WSEARCHNEXT, 1WIRECOUNT Example '-------------------------------------------------------------------------------- 'name : 1wireSearch.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demonstrates 1wsearch 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no '-------------------------------------------------------------------------------- $regfile = "m48def.dat" $crystal = 4000000 $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 'default use 10 for the SW stack $framesize = 40 'default use 40 for the frame space Config 1wire = Portb.0 'use this pin 'On the STK200 jumper B.0 must be inserted 'The following internal bytes are used by the scan routines '___1w_bitstorage , Byte used for bit storage : ' lastdeviceflag bit 0 ' id_bit bit 1 ' cmp_id_bit bit 2 ' search_dir bit 3 '___1wid_bit_number, Byte '___1wlast_zero, Byte '___1wlast_discrepancy , Byte '___1wire_data , string * 7 (8 bytes) '[DIM variables used] 'we need some space from at least 8 bytes to store the ID Dim Reg_no(8) As Byte 'we need a loop counter and a word/integer for counting the ID's on the bus Dim I As Byte , W As Word 'Now search for the first device on the bus Reg_no(1) = 1wsearchfirst() For I = 1 To 8 'print the number Print Hex(reg_no(i)); Next Print Do 'Now search for other devices Reg_no(1) = 1wsearchnext() For I = 1 To 8 Print Hex(reg_no(i)); Next Print Loop Until Err = 1 'When ERR = 1 is returned it means that no device is found anymore 'You could also count the number of devices W = 1wirecount() 'It is IMPORTANT that the 1wirecount function returns a word/integer 'So the result variable must be of the type word or integer 'But you may assign it to a byte or long too of course Print W 'as a bonus the next routine : ' first fill the array with an existing number Reg_no(1) = 1wsearchfirst() ' unremark next line to chance a byte to test the ERR flag 'Reg_no(1) = 2 'now verify if the number exists 1wverify Reg_no(1) Print Err 'err =1 when the ID passed n reg_no() does NOT exist ' optinal call it with pinnumber line 1wverify reg_no(1),pinb,1 'As for the other 1wire statements/functions, you can provide the port and pin number as anoption 'W = 1wirecount(pinb , 1) 'for example look at pin PINB.1 End 1WSEARCHNEXT Top Previous Next Action This statement reads the next ID from the 1wire bus into a variable(array). Syntax var2 = 1WSEARCHNEXT() var2 = 1WSEARCHNEXT( port , pin) Remarks var2 A variable or array that should be at least 8 bytes long that will be assigned with the 8 byte ID from the next 1wire device on the bus. Port The PIN port name like PINB or PIND. Pin The pin number of the port. In the range from 0-7. May be a numeric constant or variable. The 1wireSearchFirst() function must be called once to initiate the ID retrieval process. After the 1wireSearchFirst() function is used you should use successive function calls to the 1wireSearchNext function to retrieve other ID's on the bus. A string can not be assigned to get the values from the bus. This because a null may be returned as a value and the null is also used as a string terminator. I would advice to use a byte array as shown in the example. The 1wirecount function will take 4 bytes of SRAM. ___1w_bitstorage , Byte used for bit storage : lastdeviceflag bit 0 id_bit bit 1 cmp_id_bit bit 2 search_dir bit 3 ___1wid_bit_number, Byte ___1wlast_zero, Byte ___1wlast_discrepancy , Byte ASM The following asm routines are called from mcs.lib. _1wire_Search_Next : (calls _1WIRE, _ADJUST_PIN , _ADJUST_BIT_ADDRESS) Parameters passed : R24 : pin number, R30 : port , X : address of target array Returns nothing. See also 1WWRITE , 1WRESET , 1WREAD , 1WSEARCHFIRST, 1WIRECOUNT Example '-------------------------------------------------------------------------------- 'name : 1wireSearch.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demonstrates 1wsearch 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no '-------------------------------------------------------------------------------- $regfile = "m48def.dat" $crystal = 4000000 $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 'default use 10 for the SW stack $framesize = 40 'default use 40 for the frame space Config 1wire = Portb.0 'use this pin 'On the STK200 jumper B.0 must be inserted 'The following internal bytes are used by the scan routines '___1w_bitstorage , Byte used for bit storage : ' lastdeviceflag bit 0 ' id_bit bit 1 ' cmp_id_bit bit 2 ' search_dir bit 3 '___1wid_bit_number, Byte '___1wlast_zero, Byte '___1wlast_discrepancy , Byte '___1wire_data , string * 7 (8 bytes) '[DIM variables used] 'we need some space from at least 8 bytes to store the ID Dim Reg_no(8) As Byte 'we need a loop counter and a word/integer for counting the ID's on the bus Dim I As Byte , W As Word 'Now search for the first device on the bus Reg_no(1) = 1wsearchfirst() For I = 1 To 8 'print the number Print Hex(reg_no(i)); Next Print Do 'Now search for other devices Reg_no(1) = 1wsearchnext() For I = 1 To 8 Print Hex(reg_no(i)); Next Print Loop Until Err = 1 'When ERR = 1 is returned it means that no device is found anymore 'You could also count the number of devices W = 1wirecount() 'It is IMPORTANT that the 1wirecount function returns a word/integer 'So the result variable must be of the type word or integer 'But you may assign it to a byte or long too of course Print W 'as a bonus the next routine : ' first fill the array with an existing number Reg_no(1) = 1wsearchfirst() ' unremark next line to chance a byte to test the ERR flag 'Reg_no(1) = 2 'now verify if the number exists 1wverify Reg_no(1) Print Err 'err =1 when the ID passed n reg_no() does NOT exist ' optinal call it with pinnumber line 1wverify reg_no(1),pinb,1 'As for the other 1wire statements/functions, you can provide the port and pin number as anoption 'W = 1wirecount(pinb , 1) 'for example look at pin PINB.1 End 1WVERIFY Top Previous Next Action This verifies if an ID is available on the 1wire bus. Syntax 1WVERIFY ar(1) 1WVERIFY ar(1) , port, pin Remarks Ar(1) A byte array that holds the ID to verify. port The name of the PORT PINx register like PINB or PIND. pin The pin number in the range from 0-7. May be a numeric constant or variable. Returns ERR set to 0 when the ID is found on the bus otherwise it will be 1. ASM The following asm routines are called from mcs.lib. _1wire_Search_Next : (calls _1WIRE, _ADJUST_PIN , _ADJUST_BIT_ADDRESS) See also 1WWRITE , 1WRESET , 1WREAD , 1WSEARCHFIRST, 1WIRECOUNT Example '-------------------------------------------------------------------------------- 'name : 1wireSearch.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demonstrates 1wsearch 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no '-------------------------------------------------------------------------------- $regfile = "m48def.dat" $crystal = 4000000 $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 'default use 10 for the SW stack $framesize = 40 'default use 40 for the frame space Config 1wire = Portb.0 'use this pin 'On the STK200 jumper B.0 must be inserted 'The following internal bytes are used by the scan routines '___1w_bitstorage , Byte used for bit storage : ' lastdeviceflag bit 0 ' id_bit bit 1 ' cmp_id_bit bit 2 ' search_dir bit 3 '___1wid_bit_number, Byte '___1wlast_zero, Byte '___1wlast_discrepancy , Byte '___1wire_data , string * 7 (8 bytes) '[DIM variables used] 'we need some space from at least 8 bytes to store the ID Dim Reg_no(8) As Byte 'we need a loop counter and a word/integer for counting the ID's on the bus Dim I As Byte , W As Word 'Now search for the first device on the bus Reg_no(1) = 1wsearchfirst() For I = 1 To 8 'print the number Print Hex(reg_no(i)); Next Print Do 'Now search for other devices Reg_no(1) = 1wsearchnext() For I = 1 To 8 Print Hex(reg_no(i)); Next Print Loop Until Err = 1 'When ERR = 1 is returned it means that no device is found anymore 'You could also count the number of devices W = 1wirecount() 'It is IMPORTANT that the 1wirecount function returns a word/integer 'So the result variable must be of the type word or integer 'But you may assign it to a byte or long too of course Print W 'as a bonus the next routine : ' first fill the array with an existing number Reg_no(1) = 1wsearchfirst() ' unremark next line to chance a byte to test the ERR flag 'Reg_no(1) = 2 'now verify if the number exists 1wverify Reg_no(1) Print Err 'err =1 when the ID passed n reg_no() does NOT exist ' optional call it with pinnumber line 1wverify reg_no(1),pinb,1 'As for the other 1wire statements/functions, you can provide the port and pin number as anoption 'W = 1wirecount(pinb , 1) 'for example look at pin PINB.1 End 1WWRITE Top Previous Next Action This statement writes a variable to the 1wire bus. Syntax 1WWRITE var1 1WWRITE var1, bytes 1WWRITE var1 , bytes , port , pin Remarks var1 Sends the value of var1 to the bus. The number of bytes can be specified too but this is optional. bytes The number of bytes to write. Must be specified when port and pin are used. port The name of the PORT PINx register like PINB or PIND. pin The pin number in the range from 0-7. May be a numeric constant or variable. Multiple 1-wire devices on different pins are supported. To use this you must specify the port and pin that are used for the communication. The 1wreset, 1wwrite and 1wread statements will work together when used with the old syntax. And the pin can be configured from the compiler options or with the CONFIG 1WIRE statement. The syntax for additional 1-wire devices is : 1WRESET port , pin 1WWRITE var/constant, bytes, port , pin var = 1WREAD(bytes, port, pin) ,for reading multiple bytes See also 1WREAD , 1WRESET Example '-------------------------------------------------------------------------------- 'name : 1wire.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demonstrates 1wreset, 1wwrite and 1wread() 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no ' pull-up of 4K7 required to VCC from Portb.2 ' DS2401 serial button connected to Portb.2 '-------------------------------------------------------------------------------- $regfile = "m48def.dat" $crystal = 4000000 $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 'default use 10 for the SW stack $framesize = 40 'default use 40 for the frame space 'when only bytes are used, use the following lib for smaller code $lib "mcsbyte.lib" Config 1wire = Portb.0 'use this pin 'On the STK200 jumper B.0 must be inserted Dim Ar(8) As Byte , A As Byte , I As Byte Do Wait 1 1wreset 'reset the device Print Err 'print error 1 if error 1wwrite &H33 'read ROM command For I = 1 To 8 Ar(i) = 1wread() 'place into array Next 'You could also read 8 bytes a time by unremarking the next line 'and by deleting the for next above 'Ar(1) = 1wread(8) 'read 8 bytes For I = 1 To 8 Print Hex(ar(i)); 'print output Next Print 'linefeed Loop 'NOTE THAT WHEN YOU COMPILE THIS SAMPLE THE CODE WILL RUN TO THIS POINT 'THIS because of the DO LOOP that is never terminated!!! 'New is the possibility to use more than one 1 wire bus 'The following syntax must be used: For I = 1 To 8 Ar(i) = 0 'clear array to see that it works Next 1wreset Pinb , 2 'use this port and pin for the second device 1wwrite &H33 , 1 , Pinb , 2 'note that now the number of bytes must be specified! '1wwrite Ar(1) , 5,pinb,2 'reading is also different Ar(1) = 1wread(8 , Pinb , 2) 'read 8 bytes from portB on pin 2 For I = 1 To 8 Print Hex(ar(i)); Next 'you could create a loop with a variable for the bit number ! For I = 0 To 3 'for pin 0-3 1wreset Pinb , I 1wwrite &H33 , 1 , Pinb , I Ar(1) = 1wread(8 , Pinb , I) For A = 1 To 8 Print Hex(ar(a)); Next Print Next End ADR , ADR2 Top Previous Next Action Create label address. Syntax ADR label ADR2 label Remarks label The name of a label. The AVR uses WORD addresses. ADR will create the word address. To find a byte in memory, you need to multiply by 2. For this purpose ADR2 is available. It will create the address of the label multiplied by 2. Using ADR2 you can use tables. The sample program demonstrates this together with some more advanced ASM code. The sample includes ADR2.LIB. This lib contains a special version of _MoveConst2String . The normal routine in MCS.LIB will stop printing once a null byte (zero) is encountered that indicates the end of a string. But for the sample program, we may not change the address, so the address is restored when the null byte is found. See Also NONE Example '=============================================================================== ' This is an example of how to create an interactive menu system supporting ' sub-menus and support routines using the !ADR and !ADR2 statements '=============================================================================== $regfile = "M644def.dat" $crystal = 8000000 $hwstack = 64 ' specify the hardware stack depth $swstack = 64 ' specify the software stack depth $framesize = 64 ' specify the framesize (local stack depth) $lib "adr2.lib" '------------------------------------------------------------------------------- Dim Menupointer As Word Dim Actionpointer As Word Dim Entries As Byte Dim Dummy As Byte Dim Message As String * 32 Dim Local1 As Byte Dim Local_loop1 As Byte Const Menu_id = &HAA ' sub-menu ID byte Const Routine_id = &H55 ' service routine ID byte '------------------------------------------------------------------------------- Restore Main_menu ' point to the start of the 'main' menu ! sts {MenuPointer}, R8 ' } ! sts {MenuPointer + 1}, R9 ' } store the pointer to the start of the menu Display_new_menu: ! lds R8, {MenuPointer} ' } ! lds R9, {MenuPointer + 1} ' } restore the pointer to the start of the menu Read Entries ' get the number of entries in the menu including the title Print For Local_loop1 = 1 To Entries Read Message ' read the message Print Message ' send it to the console Next Read Dataptr ' get the pointer to the menu's action table ! sts {ActionPointer}, R8 ' } ! sts {ActionPointer + 1}, R9 ' } store the pointer to the start of the menu's action list Input "Entry ? " , Local1 ' ask the user which menu entry If Local1 = 0 Then ' is it valid ? Goto Display_new_menu ' if not, re-display the menu End If If Local1 => Entries Then ' is it valid ? Goto Display_new_menu ' if not, re-display the menu End If ! lds R8,{ActionPointer} ' } ! lds R9,{ActionPointer + 1} ' } restore the pointer to the menu's action list If Local1 <> 1 Then For Local_loop1 = 2 To Local1 ' ! ldI R30,4 ' } ! clr R1 ' } ! add R8,R30 ' } ! adc R9,R1 ' } Next ' } calculate the location of the selected entry's function ID End If Read Local1 ' get the menu entry's function ID Read Dummy ' to handle the uP expecting WORDS in DATA statements If Local1 = Menu_id Then ' did the user select an entry that points to another menu ? Read Dataptr ! sts {MenuPointer}, R8 ' } ! sts {MenuPointer + 1}, R9 ' } store the start of the menu Goto Display_new_menu End If Read Dataptr ' get the address of this entry's support routine ! movw R30,R8 ! icall ' pass control to the entry's support routine Goto Display_new_menu ' re-display the last menu displayed '------------------------------------------------------------------------------- ' Test support routines '------------------------------------------------------------------------------- Hello_message: Print Print "You asked to print 'Hello'" ' confirmation that Menu Entry 3 was selected Return 2nd_menu_1st_entry_routine: Print Print "You selected Entry 1 of the 2nd menu" ' confirmation that Menu Entry 1 was selected Return 2nd_menu_2nd_entry_routine: Print Print "You selected Entry 2 of the 2nd menu" ' confirmation that Menu Entry 2 was selected Return 3rd_menu_1st_entry_routine: Print Print "You selected Entry 1 of the 3rd menu" ' confirmation that Menu Entry 1 was selected Return 3rd_menu_2nd_entry_routine: Print Print "You selected Entry 2 of the 3rd menu" ' confirmation the Menu Entry 2 was selected Return End '=============================================================================== ' Data Statements '=============================================================================== $data '------------------------------------------------------------------------------- ' Main Menu '------------------------------------------------------------------------------- Main_menu: Data 4 ' number of entries in the menu including title Data "MAIN MENU" ' } menu title Data "1. Go to Menu 2" ' } 1st menu entry Data "2. Go to Menu 3" ' } 2nd menu entry Data "3. Print 'Hello' message" ' } 3rd menu entry Adr2 Mainmenu_supporttable ' point to this menu support table '------------------------------------------------------------------------------- Mainmenu_supporttable: Data Menu_id ' identify this menu entry as a menu Adr2 Second_menu ' address of next menu Data Menu_id ' identify this menu entry as a menu Adr2 Third_menu ' address of next menu Data Routine_id ' identify this menu entry as support routine Adr Hello_message ' address of the support routine '------------------------------------------------------------------------------- ' Second Menu '------------------------------------------------------------------------------- Second_menu: Data 4 ' number of entries in the menu Data "SECOND MENU" ' } menu title Data "1. 2nd Menu Entry #1" ' } 1st menu entry Data "2. 2nd Menu Entry #2" ' } 2nd menu entry Data "3. Go to previous menu" ' } 3rd menu entry Adr2 Secondmenu_supporttable ' point to this menu support table '------------------------------------------------------------------------------- Secondmenu_supporttable: Data Routine_id ' identify this menu entry as a support routine Adr 2nd_menu_1st_entry_routine ' support routine for 1st menu entry Data Routine_id ' identify this menu entry as a support routine Adr 2nd_menu_2nd_entry_routine ' support routine for 2nd menu entry Data Menu_id ' identify this menu entry as a menu Adr2 Main_menu ' support routine for 3rd menu entry '------------------------------------------------------------------------------- ' Third Menu '------------------------------------------------------------------------------- Third_menu: Data 4 ' number of entries in the menu Data "THIRD MENU" ' } menu title Data "1. 3rd Menu Entry #1" ' } 1st menu entry Data "2. 3rd Menu Entry #2" ' } 2nd menu entry Data "3. Go to previous menu" ' } 3rd menu entry Adr2 Thirdmenu_supporttable ' point to this menu support table '------------------------------------------------------------------------------- Thirdmenu_supporttable: Data Routine_id ' identify this menu entry as a support routine Adr 3rd_menu_1st_entry_routine ' support routine for 1st menu entry Data Routine_id ' identify this menu entry as a support routine Adr 3rd_menu_2nd_entry_routine ' support routine for 2nd menu entry Data Menu_id ' identify this menu entry as a menu Adr2 Main_menu ' support routine for 3rd menu entry AESDECRYPT Top Previous Next Action This statement of function uses the Xmega AES encryption engine to decrypt a block of data. Syntax AESDECRYPT key, var , size targ = AESDECRYPT ( key, var , size) Remarks key The name of a label that contains 16 bytes of key data. Or an array holding 16 bytes of key data. var A variable or array containing the data to be encrypted. When you use the statement, this variable will contain the encrypted data after the conversion. size The number of bytes to encrypt. Encryption is done with blocks of 16 bytes. So the size should be a multiple of 16. If you supply only 14 bytes this is ok too, but the result will still be 16 bytes. It is important that your array is big enough to hold the result. Without the full 16 byte result, you can not decrypt the data. targ In case you use the function, this variable will hold the result. This function only works for Xmega chips that have an AES encryption unit. 128 bit encryption is used. You can either use a label with a fixed key, or use a variable. You should use the same key data for encryption and decryption. See also AESENCRYPT , $AESKEY Example '---------------------------------------------------------------- ' (c) 1995-2016 MCS ' xm128-AES.bas ' This sample demonstrates the Xmega128A1 AES encryption/decryption '----------------------------------------------------------------- $regfile = "xm128a1def.dat" $crystal = 32000000 $hwstack = 64 $swstack = 40 $framesize = 40 'first enable the osc of your choice Config Osc = Enabled , 32mhzosc = Enabled 'configure the systemclock Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 Config Com1 = 38400 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 '$external _aes_enc Dim Key(16) As Byte ' room for key Dim Ar(34) As Byte Dim Arenc(34) As Byte Dim J As Byte Print "AES test" Restore Keydata For J = 1 To 16 ' load a key to memory Read Key(j) Next 'load some data For J = 1 To 32 ' fill some data to encrypt Ar(j) = J Next Aesencrypt Keydata , Ar(1) , 32 Print "Encrypted data" For J = 1 To 32 ' fill some data to encrypt Print Ar(j) Next Aesdecrypt Keydata , Ar(1) , 32 Print "Decrypted data" For J = 1 To 32 ' fill some data to encrypt Print Ar(j) Next Print "Encrypt function" Arenc(1) = Aesencrypt(keydata , Ar(1) , 32) For J = 1 To 32 ' fill some data to encrypt Print Ar(j) ; "-" ; Arenc(j) Next Print "Decrypt function" Ar(1) = Aesdecrypt(keydata , Arenc(1) , 32) For J = 1 To 32 Print J ; ">" ; Ar(j) ; "-" ; Arenc(j) Next End Keydata: Data 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 AESENCRYPT Top Previous Next Action This statement of function uses the Xmega AES encryption engine to encrypt a block of data. Syntax AESENCRYPT key, var , size targ = AESENCRYPT ( key, var , size) Remarks key The name of a label that contains 16 bytes of key data. Or an array holding 16 bytes of key data. var A variable or array containing the data to be encrypted. When you use the statement, this variable will contain the encrypted data after the conversion. size The number of bytes to encrypt. Encryption is done with blocks of 16 bytes. So the size should be a multiple of 16. If you supply only 14 bytes this is ok too, but the result will still be 16 bytes. It is important that your array is big enough to hold the result. Without the full 16 byte result, you can not decrypt the data. targ In case you use the function, this variable will hold the result. This function only works for Xmega chips that have an AES encryption unit. 128 bit encryption is used. You can either use a label with a fixed key, or use a variable. You should use the same key data for encryption and decryption. See also AESDECRYPT , $AESKEY Example '---------------------------------------------------------------- ' (c) 1995-2016, MCS ' xm128-AES.bas ' This sample demonstrates the Xmega128A1 AES encryption/decryption '----------------------------------------------------------------- $regfile = "xm128a1def.dat" $crystal = 32000000 $hwstack = 64 $swstack = 40 $framesize = 40 'first enable the osc of your choice Config Osc = Enabled , 32mhzosc = Enabled 'configure the systemclock Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 Config Com1 = 38400 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 '$external _aes_enc Dim Key(16) As Byte ' room for key Dim Ar(34) As Byte Dim Arenc(34) As Byte Dim J As Byte Print "AES test" Restore Keydata For J = 1 To 16 ' load a key to memory Read Key(j) Next 'load some data For J = 1 To 32 ' fill some data to encrypt Ar(j) = J Next Aesencrypt Keydata , Ar(1) , 32 Print "Encrypted data" For J = 1 To 32 ' fill some data to encrypt Print Ar(j) Next Aesdecrypt Keydata , Ar(1) , 32 Print "Decrypted data" For J = 1 To 32 ' fill some data to encrypt Print Ar(j) Next Print "Encrypt function" Arenc(1) = Aesencrypt(keydata , Ar(1) , 32) For J = 1 To 32 ' fill some data to encrypt Print Ar(j) ; "-" ; Arenc(j) Next Print "Decrypt function" Ar(1) = Aesdecrypt(keydata , Arenc(1) , 32) For J = 1 To 32 Print J ; ">" ; Ar(j) ; "-" ; Arenc(j) Next End Keydata: Data 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 ALIAS Top Previous Next Action Indicates that the variable can be referenced with another name. Syntax newvar ALIAS oldvar Remarks oldvar Name of the variable such as PORTB.1 newvar New name of the variable such as direction Aliasing port pins can give the pin names a more meaningful name. For example, when your program uses 4 different pins to control 4 different relays, you could name them portb.1, portb.2, portb.3 and portb.4. But it would be more convenient to refer to them as relais1, relais2, relais3 and realais4. When you later on change your PCB and decide that relays 4 must be connected to portD.4 instead of portb.4, you only need to change the ALIAS line, and not your whole program. See also CONST Example '------------------------------------------------------------------------------- 'copyright : (c) 1995-2016, MCS Electronics 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no 'purpose : demonstrates ALIAS '------------------------------------------------------------------------------- $regfile = "m48def.dat" $crystal = 4000000 ' 4 MHz crystal Const On = 1 Const Off = 0 Config Portb = Output Relais1 Alias Portb.1 Relais2 Alias Portb.2 Relais3 Alias Portd.5 Relais4 Alias Portd.2 Set Relais1 Relais2 = 0 Relais3 = On Relais4 = Off End ABS Top Previous Next Action Returns the absolute value of a numeric signed variable. Syntax var = ABS(var2) Remarks Var Variable that is assigned with the absolute value of var2. Var2 The source variable to retrieve the absolute value from. var : Integer , Long, Single or Double. var2 : Integer, Long, Single or Double. The absolute value of a number is always positive. See also NONE ASM Calls: _abs16 for an Integer and _abs32 for a Long Input: R16-R17 for an Integer and R16-R19 for a Long Output:R16-R17 for an Integer and R16-R19 for a Long Calls _Fltabsmem for a single from the fp_trig library. Example Dim a as Integer, c as Integer a =-1000 c = Abs(a) Print c End ACOS Top Previous Next Action Returns the arccosine of a float in radians. Syntax var = ACOS( x ) Remarks Var A floating point variable such as single or double, that is assigned with the ACOS of variable x. X The float to get the ACOS of. Input is valid from �1 to +1 and returns p to 0. If Input is < -1 than p and input is > 1 than 0 will returned. If Input is cause of rounding effect in float-operations a little bit over 1 or -1, the value for 1.0 (-1.0) will be returned. This is the reason to give the value of the limit-point back, if Input is beyond limit. Generally the user have to take care, that Input to this function lies within �1 to +1. All trig functions work with radians. Use deg2rad and rad2deg to convert between radians and angles. See Also RAD2DEG , DEG2RAD , COS , SIN , TAN , ATN , ASIN , ATN2 Example $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim S As Single , X As Single x= 0.5 : S = Acos(x) Print S End AND Top Previous Next Action This logical operator returns the AND of two numeric variables. Syntax target = source1 AND source2 Remarks The AND operator works on two bits. It returns a '1' if both inputs are '1'. A B R 0 0 0 0 1 0 1 0 0 1 1 1 The truth table above shows all possible values. A and B represent the 2 inputs. R is the Return or output value. As you can see, you will only get a '1' when both inputs are '1' It is like having 2 switches in series. You have to switch them both on in order to have a closed circuit. While you can use AND on bits, you can also perform the same operation on bytes, integers, etc. In such a case, all bits of the variables will be AND-ed. Example : Dim A as Byte, B as Byte, R as byte A=&B1100_0001 B=&B1001_0000 R=A AND B R=&B1000_0000 As you can see, only bit 7 of both variables is '1'. So in the result, only bit 7 is set. This makes the AND operation perfect for isolating or clearing bits. If you want a value to be in a range of say 0-7 you can set the value to 7 : result= var AND &B111 See also OR , XOR, NOT Example '-------------------------------------------------------------------------------- 'name : boolean.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demo: AND, OR, XOR, NOT, BIT, SET, RESET and MOD 'suited for demo : yes 'commercial add on needed : no 'use in simulator : possible '-------------------------------------------------------------------------------- 'This very same program example can be used in the Help-files for ' AND, OR, XOR, NOT, BIT, SET, RESET and MOD $baud = 19200 $crystal = 8000000 $regfile = "m88def.dat" $hwstack = 40 $swstack = 20 $framesize = 20 Dim A As Byte , B1 As Byte , C As Byte Dim Aa As Bit , I As Integer A = 5 : B1 = 3 ' assign values C = A And B1 ' and a with b Print "A And B1 = " ; C ' print it: result = 1 C = A Or B1 Print "A Or B1 = " ; C ' print it: result = 7 C = A Xor B1 Print "A Xor B1 = " ; C ' print it: result = 6 A = 1 C = Not A Print "c = Not A " ; C ' print it: result = 254 C = C Mod 10 Print "C Mod 10 = " ; C ' print it: result = 4 If Portb.1 = 1 Then 'test a bit from a PORT (which is not the same as testing the input state) Print "Bit set" Else Print "Bit not set" End If 'result = Bit not set Config Pinb.0 = Input : Portb.0 = 1 'configure as input pin Do Loop Until Pinb.0 = 0 ' repeat this loop until the logic level becomes 0 Aa = 1 'use this or .. Set Aa 'use the set statement If Aa = 1 Then Print "Bit set (aa=1)" Else Print "Bit not set(aa=0)" End If 'result = Bit set (aa=1) Aa = 0 'now try 0 Reset Aa 'or use reset If Aa = 1 Then Print "Bit set (aa=1)" Else Print "Bit not set(aa=0)" End If 'result = Bit not set(aa=0) C = 8 'assign variable to &B0000_1000 Set C 'use the set statement without specifying the bit Print C 'print it: result = 9 ; bit0 has been set B1 = 255 'assign variable Reset B1.0 'reset bit 0 of a byte variable Print B1 'print it: result = 254 = &B11111110 B1 = 8 'assign variable to &B00001000 Set B1.7 'set it Print B1 'print it: result = 9 = &B00001001 End ASIN Top Previous Next Action Returns the arcsine of a float in radians. Syntax var = ASIN( x ) Remarks Var A float variable such as single or double that is assigned with the ASIN of variable x. X The float to get the ASIN of. Input is valid from �1 to +1 and returns -p/2 to +p/2. If Input is < -1 than -p/2 and input is > 1 than p/2 will returned. If Input is cause of rounding effect in single-operations a little bit over 1 or -1, the value for 1.0 (-1.0) will be returned. This is the reason to give the value of the limit-point back, if Input is beyond limit. Generally the user have to take care, that Input to this function lies within �1 to +1. All trig functions work with radians. Use deg2rad and rad2deg to convert between radians and angles. See Also RAD2DEG , DEG2RAD , COS , SIN , TAN , ATN , ACOS , ATN2 Example $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim S As Single , X As Single X = 0.5 : S = Asin(x) Print S '0.523595867 End ATN Top Previous Next Action Returns the Arctangent of a floating point variable in radians. Syntax var = ATN( float ) Remarks Var A float variable that is assigned with the arctangent of variable float. float The float variable to get the arctangent of. All trig functions work with radians. Use deg2rad and rad2deg to convert between radians and angles. Floating point variables can be of the single or double data type. See Also RAD2DEG , DEG2RAD , COS , SIN , TAN , ATN2 Example $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim S As Single , X As Single S = Atn(1) * 4 Print S ' prints 3.141593 PI End ATN2 Top Previous Next Action ATN2 is a four-quadrant arc-tangent. While the ATN-function returns from -p/2 (-90°) to p/2 (90°), the ATN2 function returns the whole range of a circle from -p (-180°) to +p (180°). The result depends on the ratio of Y/X and the signs of X and Y. Syntax var = ATN2( y, x ) Remarks Var A floating point variable that is assigned with the ATN2 of variable y and x. X The float variable with the distance in x-direction. Y The float variable with the distance in y-direction Quadrant Sign Y Sign X ATN2 I + + 0 to p/2 II + - p/2 to p III - - -p/2 to -p IV - + 0 to �p/2 If you go with the ratio Y/X into ATN you will get same result for X greater zero (right side in coordinate system) as with ATN2. ATN2 uses X and Y and can give information of the angle of the point over 360° in the coordinates system. All trig functions work with radians. Use deg2rad and rad2deg to convert between radians and angles. See Also RAD2DEG , DEG2RAD , COS , SIN , TAN , ATN Example $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim S As Single , X As Single X = 0.5 : S = 1.1 S = Atn2(s , X) Print S ' prints 1.144164676 End CHECKFLOAT Top Previous Next Action This function validates the value of a floating point variable. Syntax targ = CHECKFLOAT(var [,option]) Remarks targ A numeric variable that will be assigned with the result of the validation. The following bits can be set: cBitInfinity = 0 cmBitInfinity = 1 ;(2 ^ cBitInfinity) cBitZero = 1 cmBitZero = 2 ;(2 ^ cBitZero) cBitNAN = 2 cmBitNAN = 4 ;(2 ^ cBitNAN) cBitSign = 7 cmBitSign = 128 ;(2 ^ cBitSign) The byte values are shown in italic. The bit constants are defined in the single and double libraries. var A floating point variable such as a single or double to validate. option This is an optional numeric constant that servers as a mask. This allows to test for makes it possible to test for a single error. A floating point value may contain an illegal value as the result of a calculation. These illegal values are NAN (not a number) and INFINITY. The two other tests which are performed are a test for zero, and a sign test. If the result bit 0 is '1' then the number is infinity. If the result bit 1 is '1' then the number is zero. If the result bit 2 is '1' then the number if NAN. If the result bit 7 is '1' then the number is negative. If you want to test only for NAN and INFINITY you can add the bits and pass this as the optional numeric mask. For NAN and INFINITY this would be 1+4=5 The resulting value will be AND-ed and if any of the two bits is set, the result will be non-zero, indicating an error. If both values are 0, the result will be zero. This functions works for both the double and single data types. For the single there is however a note. When you divide a number by a real 0, the result is a zero (0). In the double data type you actually get an INFinite number. For this reason the sample contains a trick with overlayed variables to test the function. See also NONE Example $regfile = "m2561def.dat" $crystal = 8000000 $hwstack = 64 $swstack = 64 $framesize = 64 $baud = 19200 $lib "single.lbx" Dim S1 As Single , S2 As Single , S3 As Single dim d1 as Double , d2 as Double , d3 as Double dim bCheck as Byte dim bs(4) as Byte at s3 overlay dim bd(8) as Byte at d3 overlay S1 = 0 : Bcheck = Checkfloat(s1) : Print Bin(bcheck) S1 = 0 : Bcheck = Checkfloat(s1 , 2) : Print Bin(bcheck) d1 = 1: d2 = 0 : d3 = d1 / d2 ' 1/0 should result in infinty Bcheck = Checkfloat(d3) : Print Bin(bcheck) Bcheck = Checkfloat(d3 , 5) : Print Bcheck ' test for infinity and nan d1 = -1 d3 = sqr(d1) ' should produce NAN Bcheck = Checkfloat(d3) : Print Bin(bcheck) ' single routines must be checked for returning IEEE-Rulues according values s1 = 1: s2 = 0 : s3 = s1 / s2 ' 1/0 should result in infinty Bcheck = Checkfloat(s3) : Print Bin(bcheck) s1 = -1 s3 = sqr(s1) ' should produce NAN Bcheck = Checkfloat(s3) : Print Bin(bcheck) ' now check with hard-coded values for singles bs(1) = &HFF: bs(2) = &HFF: bs(3) = &HFF: bs(4) = &H7F ' NAN Bcheck = Checkfloat(s3) : Print Bin(bcheck) bs(1) = &H00: bs(2) = &H00: bs(3) = &H80: bs(4) = &H7F ' infinity Bcheck = Checkfloat(s3) : Print Bin(bcheck) End COS Top Previous Next Action Returns the cosine of a floating point variable Syntax var = COS( float ) Remarks Var A numeric variable that is assigned with cosine of variable float. float The floating point variable to get the cosine of. All trig functions work with radians. Use deg2rad and rad2deg to convert between radians and angles. See Also RAD2DEG , DEG2RAD , ATN , SIN , TAN Example $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim S As Single , X As Single S = 0.5 : X = Tan(s) : Print X ' prints 0.546302195 S = 0.5 : X = Sin(s) : Print X ' prints 0.479419108 S = 0.5 : X = Cos(s) : Print X ' prints 0.877588389 End COSH Top Previous Next Action Returns the cosine hyperbole of a floating point variable Syntax var = COSH( float ) Remarks Var A numeric variable that is assigned with cosine hyperbole of variable float. float The single or double variable to get the cosine hyperbole of. All trig functions work with radians. Use deg2rad and rad2deg to convert between radians and angles. See Also RAD2DEG , DEG2RAD , ATN , COS , SIN , TANH , SINH Example Show sample DEG2RAD Top Previous Next Action Converts an angle in to radians. Syntax var = DEG2RAD( angle ) Remarks Var A numeric variable that is assigned with the radians of variable Source. angle The single or double variable to get the degrees of. All trig functions work with radians. Use deg2rad and rad2deg to convert between radians and angles. Radian is the ratio between the length of an arc and its radius. The radian is the standard unit of angular measure. You can find a good explanation at wikipedia. See Also RAD2DEG Example '------------------------------------------------------------------------------- 'copyright : (c) 1995-2016, MCS Electronics 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no 'purpose : demonstrates DEG2RAD function '------------------------------------------------------------------------------- Dim S As Single S = 90 S = Deg2Rad(s) Print S S = Rad2deg(s) Print S End EXP Top Previous Next Action Returns e( the base of the natural logarithm) to the power of a single or double variable. Syntax Target = EXP(source) Remarks Target The single or double that is assigned with the Exp() of the target. Source The source to get the Exp of. See also LOG , LOG10 Example '------------------------------------------------------------------------------- 'copyright : (c) 1995-2016, MCS Electronics 'micro : Mega88 'suited for demo : no, but without the DOUBLE, it works for DEMO too in M48 'commercial addon needed : no 'purpose : demonstrates EXP function '------------------------------------------------------------------------------- $regfile = "m88def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 40 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Dim X As Single X = Exp(1.1) Print X 'prints 3.004166124 X = 1.1 X = Exp(x) Print X 'prints 3.004164931 Dim D As Double D = Exp(1.1) Print D 'prints 3.00416602394643 D = 1.1 D = Exp(d) Print D 'prints 3.00416602394638 End FIX Top Previous Next Action Returns for values greater then zero the next lower value, for values less then zero the next upper value. Syntax var = FIX( x ) Remarks Var A single or double variable that is assigned with the FIX of variable x. X The floating point variable to get the FIX of. See Also INT , ROUND , SGN Example '----------------------------------------------------------------------------------------- 'name : round_fix_int.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demo : ROUND,FIX 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no '----------------------------------------------------------------------------------------- $regfile = "m48def.dat" ' specify the used micro $crystal = 4000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Dim S As Single , Z As Single For S = -10 To 10 Step 0.5 Print S ; Spc(3) ; Round(s) ; Spc(3) ; Fix(s) ; Spc(3) ; Int(s) Next End FRAC Top Previous Next Action Returns the fraction of a single. Syntax var = FRAC( single ) Remarks var A numeric single variable that is assigned with the fraction of variable single. single The single variable to get the fraction of. The fraction is the right side after the decimal point of a single. See Also INT Example '------------------------------------------------------------------------------- 'copyright : (c) 1995-2016, MCS Electronics 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no 'purpose : demonstrates FRAC function '------------------------------------------------------------------------------- $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 40 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Dim X As Single X = 1.123456 Print X Print Frac(x) End INT Top Previous Next Action Returns the integer part of a single or double. Syntax var = INT( source ) Remarks Var A numeric floating point variable that is assigned with the integer of variable source. Source The source floating point variable to get the integer part of. The fraction is the right side after the decimal point of a single. The integer is the left side before the decimal point. 1234.567 1234 is the integer part, .567 is the fraction The assigned variable must be a single or double. When you want to convert a floating point data type to an integer data type, just assign the variable to a variable of that type : someLong = someDouble See Also FRAC , FIX , ROUND Example '----------------------------------------------------------------------------------------- 'name : round_fix_int.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demo : ROUND,FIX 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no '----------------------------------------------------------------------------------------- $regfile = "m48def.dat" ' specify the used micro $crystal = 4000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Dim S As Single , Z As Single For S = -10 To 10 Step 0.5 Print S ; Spc(3) ; Round(s) ; Spc(3) ; Fix(s) ; Spc(3) ; Int(s) Next End LOG10 Top Previous Next Action Returns the base 10 logarithm of a floating point variable. Syntax Target = LOG10(source) Remarks Target The single or double that is assigned with the base 10 logarithm of single/double target. Source The source single or double to get the base 10 LOG of. See also EXP , LOG Example Show sample LOG Top Previous Next Action Returns the natural logarithm of a floating point variable. Syntax Target = LOG(source) Remarks Target The single or double that is assigned with the LOG() of single target. Source The source single or doubler to get the LOG of. See also EXP , LOG10 Example Show sample NOT Top Previous Next Action This logical operator returns the inversed value. Syntax target = NOT source2 Remarks The NOT operator inverts the input bit. When the bit is '0' it will return a '1'. And when the bit is '1' it will return a '0' A R 0 1 1 0 The truth table above shows the possible values. A represent the input. R is the Return or output value. While you can use NOT on bits, you can also perform the same operation on bytes, integers, etc. In such a case, all bits of the variables will be inverted. Example : Dim A as Byte, B as Byte, R as byte A=&B1100_0001 R=NOT A R=&B0011_1110 See also AND , XOR, OR Example '-------------------------------------------------------------------------------- 'name : boolean.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demo: AND, OR, XOR, NOT, BIT, SET, RESET and MOD 'suited for demo : yes 'commercial add on needed : no 'use in simulator : possible '-------------------------------------------------------------------------------- 'This very same program example can be used in the Help-files for ' AND, OR, XOR, NOT, BIT, SET, RESET and MOD $baud = 19200 $crystal = 8000000 $regfile = "m88def.dat" $hwstack = 40 $swstack = 20 $framesize = 20 Dim A As Byte , B1 As Byte , C As Byte Dim Aa As Bit , I As Integer A = 5 : B1 = 3 ' assign values C = A And B1 ' and a with b Print "A And B1 = " ; C ' print it: result = 1 C = A Or B1 Print "A Or B1 = " ; C ' print it: result = 7 C = A Xor B1 Print "A Xor B1 = " ; C ' print it: result = 6 A = 1 C = Not A Print "c = Not A " ; C ' print it: result = 254 C = C Mod 10 Print "C Mod 10 = " ; C ' print it: result = 4 If Portb.1 = 1 Then 'test a bit from a PORT (which is not the same as testing the input state) Print "Bit set" Else Print "Bit not set" End If 'result = Bit not set Config Pinb.0 = Input : Portb.0 = 1 'configure as input pin Do Loop Until Pinb.0 = 0 ' repeat this loop until the logic level becomes 0 Aa = 1 'use this or .. Set Aa 'use the set statement If Aa = 1 Then Print "Bit set (aa=1)" Else Print "Bit not set(aa=0)" End If 'result = Bit set (aa=1) Aa = 0 'now try 0 Reset Aa 'or use reset If Aa = 1 Then Print "Bit set (aa=1)" Else Print "Bit not set(aa=0)" End If 'result = Bit not set(aa=0) C = 8 'assign variable to &B0000_1000 Set C 'use the set statement without specifying the bit Print C 'print it: result = 9 ; bit0 has been set B1 = 255 'assign variable Reset B1.0 'reset bit 0 of a byte variable Print B1 'print it: result = 254 = &B11111110 B1 = 8 'assign variable to &B00001000 Set B1.7 'set it Print B1 'print it: result = 9 = &B00001001 End OR Top Previous Next Action This logical operator returns the OR of two numeric variables. Syntax target = source1 OR source2 Remarks The OR operator works on two bits. It returns a '1' if one of both inputs is '1'. A B R 0 0 0 0 1 1 1 0 1 1 1 1 The truth table above shows all possible values. A and B represent the 2 inputs. R is the Return or output value. As you can see, you will get a '1' when either or both inputs is '1' It is like having 2 switches in parallel. Both switches will create a closed circuit. While you can use OR on bits, you can also perform the same operation on bytes, integers, etc. In such a case, all bits of the variables will be OR-ed. Example : Dim A as Byte, B as Byte, R as byte A=&B1100_0001 B=&B1001_0000 R=A OR B R=&B1001_0001 See also AND , XOR, NOT Example '-------------------------------------------------------------------------------- 'name : boolean.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demo: AND, OR, XOR, NOT, BIT, SET, RESET and MOD 'suited for demo : yes 'commercial add on needed : no 'use in simulator : possible '-------------------------------------------------------------------------------- 'This very same program example can be used in the Help-files for ' AND, OR, XOR, NOT, BIT, SET, RESET and MOD $baud = 19200 $crystal = 8000000 $regfile = "m88def.dat" $hwstack = 40 $swstack = 20 $framesize = 20 Dim A As Byte , B1 As Byte , C As Byte Dim Aa As Bit , I As Integer A = 5 : B1 = 3 ' assign values C = A And B1 ' and a with b Print "A And B1 = " ; C ' print it: result = 1 C = A Or B1 Print "A Or B1 = " ; C ' print it: result = 7 C = A Xor B1 Print "A Xor B1 = " ; C ' print it: result = 6 A = 1 C = Not A Print "c = Not A " ; C ' print it: result = 254 C = C Mod 10 Print "C Mod 10 = " ; C ' print it: result = 4 If Portb.1 = 1 Then 'test a bit from a PORT (which is not the same as testing the input state) Print "Bit set" Else Print "Bit not set" End If 'result = Bit not set Config Pinb.0 = Input : Portb.0 = 1 'configure as input pin Do Loop Until Pinb.0 = 0 ' repeat this loop until the logic level becomes 0 Aa = 1 'use this or .. Set Aa 'use the set statement If Aa = 1 Then Print "Bit set (aa=1)" Else Print "Bit not set(aa=0)" End If 'result = Bit set (aa=1) Aa = 0 'now try 0 Reset Aa 'or use reset If Aa = 1 Then Print "Bit set (aa=1)" Else Print "Bit not set(aa=0)" End If 'result = Bit not set(aa=0) C = 8 'assign variable to &B0000_1000 Set C 'use the set statement without specifying the bit Print C 'print it: result = 9 ; bit0 has been set B1 = 255 'assign variable Reset B1.0 'reset bit 0 of a byte variable Print B1 'print it: result = 254 = &B11111110 B1 = 8 'assign variable to &B00001000 Set B1.7 'set it Print B1 'print it: result = 9 = &B00001001 End POWER Top Previous Next Action Returns the power of a single or double variable and its argument Syntax var = POWER( source, raise ) Remarks Var A numeric variable that is assigned with the power of variable source ^ raise. Source The single or double variable to get the power of. The POWER function works for positive floating point variables only. When you use a ^ b , the sign will be preserved. While Excel does not allow raising a negative single, QB does allow it. The Power functions uses less code compared with the code that is generated when you use ^ for floating point values. It is important that you use single variables for both single and raise. Constants are not accepted. In version 1.11.9.2 the power function is improved so that it returns the same result as Excel. Previously it returned the same number as QB/VB. For example : -2 ^ 2 would be returned as -4, but -2 ^ 3 would be returned as -8 which is wring since -2 ^ 3 = -2 x -2 x -2=4 x -2 = -8. Minus times a minutes makes a positive number. So it depends on the sign of the base and if the number of raise if even or odd. The exception handling was also improved. Base Raise Result 0 0 NAN NAN x NAN x NAN NAN Infinity x NAN x Infinity NAN 0 x<0 Infinity 0 x>0 0 x 0 1 x<0 x<>int(x) NAN See Also EXP ,LOG, LOG10 , SQR Example Show sample Example for Double Exceptions $regfile = "m128def.dat" $crystal = 4000000 Dim D1 As Double , D2 As Double , D3 As Double Dim dInf as Double, dNAN as Double d1 = -1: dNAN = log(d1) d1 = 1: d2 = 0: dInf = D1 / D2 Print "POWER() - Test" Print "==============" D1 = 0: D2 = 0: GoSub ShowPowerTest D1 = dNAN: D2 = 3: GoSub ShowPowerTest D1 = 3: D2 = dNAN: GoSub ShowPowerTest D1 = dInf: D2 = 4: GoSub ShowPowerTest D1 = 4: D2 = dInf: GoSub ShowPowerTest D1 = 0: D2 = -2: GoSub ShowPowerTest D1 = 0: D2 = 3: GoSub ShowPowerTest D1 = 5: D2 = 0: GoSub ShowPowerTest D1 = -2: D2 = -3.5: GoSub ShowPowerTest D1 = -2: D2 = 3.5: GoSub ShowPowerTest D1 = -2: D2 = -3: GoSub ShowPowerTest D1 = -2: D2 = -4: GoSub ShowPowerTest D1 = -2: D2 = -5: GoSub ShowPowerTest D1 = -2: D2 = 3: GoSub ShowPowerTest D1 = -2: D2 = 4: GoSub ShowPowerTest D1 = -2: D2 = 5: GoSub ShowPowerTest end ShowPowerTest: D3 = POWER(D1, D2) Print "POWER( " ; D1 ; " , " ; D2 ; ") = " ; D3 Return --------------------------Simulator Output ------------------- POWER() - Test ============== POWER( 0 , 0) = NAN POWER( NAN , 3) = NAN POWER( 3 , NAN) = NAN POWER( Infinity , 4) = NAN POWER( 4 , Infinity) = NAN POWER( 0 , -2) = Infinity POWER( 0 , 3) = 0 POWER( 5 , 0) = 1 POWER( -2 , -3.5) = NAN POWER( -2 , 3.5) = NAN POWER( -2 , -3) = -125E-3 POWER( -2 , -4) = 62.5E-3 POWER( -2 , -5) = -31.25E-3 POWER( -2 , 3) = -8 POWER( -2 , 4) = 16 POWER( -2 , 5) = -32 QSIN Top Previous Next Action Returns the sinus of an integer Syntax var = QSIN( source ) Remarks Var A numeric integer variable that is assigned with sinus of variable source. source The integer variable to get the sinus of. Integer SIN and COS use a lookup table to determine the Sinus or Co sinus. Qsin and Qcos are used by some of the FT800 routines. The sinus of angle α is shown above. At 0 degrees the value on the y-ax is 0 and at 90 degrees, the value is at its maximum on the Y-ax. In the first quadrant of the circle (1) sinus will have a positive number as a result. In quadrant 2 of the circle, the sinus goes from the maximum value down to 0 and the result is a positive number as well. In quadrant 3 and 4 of the circle, we will get a negative number as a result since the result is below the x-ax. The QSIN works with integers which have a range from -32768 to 32767. This means that for the quadrant 1 and 2 we can use a value between 0 and 32767. In degrees we would use a value between 0 and 180. This means that each degree has a value of 182 (32767/180). The negative values are reserved for quadrant 3 and 4. Instead of integers you can also use a word variable. The following simple sample will show the input and output values. Dim Iii As Integer , I2 As Integer , W As Word For W= 0 To 65535 Step 182 Iii = W ' for usage as an integer I2 = Qsin(iii) ' get the value of W/III Print W; " " ; Iii ; " " ; I2 Next This will give the output : W III QSIN 0 0 0 182 182 571 364 364 1143 546 546 1713 728 728 2284 910 910 2854 1092 1092 3423 1274 1274 3992 1456 1456 4558 1638 1638 5124 1820 1820 5687 --snip-- 15470 15470 32640 15652 15652 32685 15834 15834 32720 16016 16016 32745 16198 16198 32760 16380 16380 32766 16562 16562 32761 16744 16744 32746 16926 16926 32721 17108 17108 32687 17290 17290 32643 17472 17472 32588 17654 17654 32523 17836 17836 32448 18018 18018 32364 18200 18200 32270 18382 18382 32166 18564 18564 32053 18746 18746 31929 18928 18928 31796 19110 19110 31653 19292 19292 31500 19474 19474 31339 19656 19656 31166 19838 19838 30986 20020 20020 30794 20202 20202 30595 20384 20384 30386 20566 20566 30167 20748 20748 29939 20930 20930 29702 21112 21112 29456 21294 21294 29202 21476 21476 28938 21658 21658 28666 21840 21840 28384 22022 22022 28095 22204 22204 27796 22386 22386 27489 22568 22568 27173 22750 22750 26850 --snip-- 32214 32214 1738 32396 32396 1168 32578 32578 596 32760 32760 25 32942 -32594 -546 33124 -32412 -1118 33306 -32230 -1688 33488 -32048 -2259 33670 -31866 -2829 33852 -31684 -3398 --snip -- 48230 -17306 -32638 48412 -17124 -32683 48594 -16942 -32719 48776 -16760 -32744 48958 -16578 -32760 49140 -16396 -32766 49322 -16214 -32761 49504 -16032 -32747 49686 -15850 -32723 49868 -15668 -32688 50050 -15486 -32645 50232 -15304 -32590 50414 -15122 -32526 50596 -14940 -32452 50778 -14758 -32368 50960 -14576 -32275 51142 -14394 -32171 51324 -14212 -32058 51506 -14030 -31934 51688 -13848 -31802 51870 -13666 -31659 52052 -13484 -31507 52234 -13302 -31346 52416 -13120 -31174 52598 -12938 -30994 52780 -12756 -30803 52962 -12574 -30604 53144 -12392 -30395 --snip-- 63154 -2382 -7417 63336 -2200 -6859 63518 -2018 -6299 63700 -1836 -5737 63882 -1654 -5173 64064 -1472 -4608 64246 -1290 -4042 64428 -1108 -3473 64610 -926 -2904 64792 -744 -2334 64974 -562 -1764 65156 -380 -1193 65338 -198 -621 65520 -16 -50 When we feed the output in Excel we can create the graph above, showing a perfect sinus. See Also QCOS Example NONE QCOS Top Previous Next Action Returns the Co Sinus of an integer Syntax var = QCOS( source ) Remarks Var A numeric integer variable that is assigned with sinus of variable source. source The integer variable to get the Co Sinus of. Integer SIN and COS use a lookup table to determine the Sinus or Co sinus. Qsin and Qcos are used by some of the FT800 routines. See Also SIN Example NONE RAD2DEG Top Previous Next Action Converts a value from radians to degrees. Syntax var = RAD2DEG( Source ) Remarks Var A numeric variable that is assigned with the angle of variable source. Source The single or double variable to get the angle of. All trig functions work with radians. Use deg2rad and rad2deg to convert between radians and angles. See Also DEG2RAD Example '------------------------------------------------------------------------------- 'copyright : (c) 1995-2016, MCS Electronics 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no 'purpose : demonstrates DEG2RAD function '------------------------------------------------------------------------------- Dim S As Single S = 90 S = Deg2Rad(s) Print S S = Rad2deg(s) Print S End ROUND Top Previous Next Action Returns a value rounded to the nearest value. Syntax var = ROUND( x ) Remarks Var A single or double variable that is assigned with the ROUND of variable x. X The single or double to get the ROUND of. Round(2.3) = 2 , Round(2.8) = 3 Round(-2.3) = -2 , Round(-2.8) = -3 See Also INT , FIX , SGN Example '----------------------------------------------------------------------------------------- 'name : round_fix_int.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demo : ROUND,FIX 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no '----------------------------------------------------------------------------------------- $regfile = "m48def.dat" ' specify the used micro $crystal = 4000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Dim S As Single , Z As Single For S = -10 To 10 Step 0.5 Print S ; Spc(3) ; Round(s) ; Spc(3) ; Fix(s) ; Spc(3) ; Int(s) Next End SGN 2080 IMPROVED Top Previous Next Action Returns the sign of a numeric value. Syntax var = SGN( x ) Remarks Var A numeric variable that is assigned with the SGN() of variable x. X The numeric variable to get the sign of. For values < 0, -1 will be returned For 0, 0 will be returned For values >0, 1 will be returned While the SGN function can return a negative value, it can only do so for integers, longs, singles and doubles. When a byte, word or dword is passed, only 0 or 1 can be returned since these values do not contain a sign bit. When a byte,word or dword is passed, the returned value is a byte. When an integer is passed, the returned value is an integer. When a long is passed, the returned value is a long. When a single is passed, the returned value is a single. When a double is passed, the returned value is a double. See Also INT , FIX , ROUND Example Dim S As Single , X As Single , Y As Single X = 2.3 : S = Sgn(x) Print S X = -2.3 : S = Sgn(x) Print S End TANH Top Previous Next Action Returns the hyperbole of a floating point variable Syntax var = TANH( source ) Remarks Var A numeric variable that is assigned with hyperbole of variable source. Source The single or double variable to get the hyperbole of. All trig functions work with radians. Use deg2rad and rad2deg to convert between radians and angles. See Also RAD2DEG , DEG2RAD , ATN , COS , SIN , SINH , COSH Example Show sample TAN Top Previous Next Action Returns the tangent of a float Syntax var = TAN( source ) Remarks Var A numeric variable that is assigned with tangent of variable source. Source The single or double variable to get the tangent of. All trig functions work with radians. Use deg2rad and rad2deg to convert between radians and angles. See Also RAD2DEG , DEG2RAD , ATN , COS , SIN , ATN2 Example $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim S As Single , X As Single S = 0.5 : X = Tan(s) : Print X ' prints 0.546302195 S = 0.5 : X = Sin(s) : Print X ' prints 0.479419108 S = 0.5 : X = Cos(s) : Print X ' prints 0.877588389 End SQR Top Previous Next Action Returns the Square root of a variable. Syntax var = SQR( source ) Remarks var A numeric single or double variable that is assigned with the SQR of variable source. source The single or double variable to get the SQR of. When SQR is used with a single, the FP_TRIG library will be used. When SQR is used with bytes, integers, words and longs, the SQR routine from MCS.LBX will be used. See Also POWER Example $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 40 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Dim A As Single Dim B As Double A = 9.0 B = 12345678.123 A =Sqr(A) Print A ' prints 3.0 B = Sqr(b) Print B End SINH Top Previous Next Action Returns the sinus hyperbole of a float Syntax var = SINH( source ) Remarks Var A numeric variable that is assigned with sinus hyperbole of variable source. source The single or double variable to get the sinus hyperbole of. All trig functions work with radians. Use deg2rad and rad2deg to convert between radians and angles. See Also RAD2DEG , DEG2RAD , ATN , COS , SIN , TANH , COSH Example Show sample SIN Top Previous Next Action Returns the sine of a float Syntax var = SIN( source ) Remarks Var A numeric variable that is assigned with sinus of variable source. source The single or double variable to get the sinus of. All trig functions work with radians. Use deg2rad and rad2deg to convert between radians and angles. See Also RAD2DEG , DEG2RAD , ATN , COS Example $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim S As Single , X As Single S = 0.5 : X = Tan(s) : Print X ' prints 0.546302195 S = 0.5 : X = Sin(s) : Print X ' prints 0.479419108 S = 0.5 : X = Cos(s) : Print X ' prints 0.877588389 End XOR Top Previous Next Action This logical operator returns the XOR of two numeric variables. Syntax target = source1 XOR source2 Remarks The XOR operator works on two bits. It returns a '1' if both inputs are different. A B R 0 0 0 0 1 1 1 0 1 1 1 0 The truth table above shows all possible values. A and B represent the 2 inputs. R is the Return or output value. As you can see, you will get a '1' when both inputs differ. While you can use XOR on bits, you can also perform the same operation on bytes, integers, etc. In such a case, all bits of the variables will be XOR-ed. Example : Dim A as Byte, B as Byte, R as byte A=&B1100_0001 B=&B1001_0000 R=A XOR B R=&B0101_0001 See also AND , OR, NOT Example '-------------------------------------------------------------------------------- 'name : boolean.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demo: AND, OR, XOR, NOT, BIT, SET, RESET and MOD 'suited for demo : yes 'commercial add on needed : no 'use in simulator : possible '-------------------------------------------------------------------------------- 'This very same program example can be used in the Help-files for ' AND, OR, XOR, NOT, BIT, SET, RESET and MOD $baud = 19200 $crystal = 8000000 $regfile = "m88def.dat" $hwstack = 40 $swstack = 20 $framesize = 20 Dim A As Byte , B1 As Byte , C As Byte Dim Aa As Bit , I As Integer A = 5 : B1 = 3 ' assign values C = A And B1 ' and a with b Print "A And B1 = " ; C ' print it: result = 1 C = A Or B1 Print "A Or B1 = " ; C ' print it: result = 7 C = A Xor B1 Print "A Xor B1 = " ; C ' print it: result = 6 A = 1 C = Not A Print "c = Not A " ; C ' print it: result = 254 C = C Mod 10 Print "C Mod 10 = " ; C ' print it: result = 4 If Portb.1 = 1 Then 'test a bit from a PORT (which is not the same as testing the input state) Print "Bit set" Else Print "Bit not set" End If 'result = Bit not set Config Pinb.0 = Input : Portb.0 = 1 'configure as input pin Do Loop Until Pinb.0 = 0 ' repeat this loop until the logic level becomes 0 Aa = 1 'use this or .. Set Aa 'use the set statement If Aa = 1 Then Print "Bit set (aa=1)" Else Print "Bit not set(aa=0)" End If 'result = Bit set (aa=1) Aa = 0 'now try 0 Reset Aa 'or use reset If Aa = 1 Then Print "Bit set (aa=1)" Else Print "Bit not set(aa=0)" End If 'result = Bit not set(aa=0) C = 8 'assign variable to &B0000_1000 Set C 'use the set statement without specifying the bit Print C 'print it: result = 9 ; bit0 has been set B1 = 255 'assign variable Reset B1.0 'reset bit 0 of a byte variable Print B1 'print it: result = 254 = &B11111110 B1 = 8 'assign variable to &B00001000 Set B1.7 'set it Print B1 'print it: result = 9 = &B00001001 End AVR-DOS File I/O Top Previous Next BLOAD Top Previous Next Action Writes the Content of a File into SRAM Syntax BLoad sFileName, wSRAMPointer Remarks sFileName (String) Name of the File to be read wSRAMPointer (Word) Variable, which holds the SRAM Address to which the content of the file should be written This function writes the content of a file to a desired space in SRAM. A free handle is needed for this function. See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, LOF , EOF , FREEFILE , FILEATTR , SEEK , BSAVE , KILL , DISKFREE , DISKSIZE , GET , PUT , FILEDATE , FILETIME , FILEDATETIME , DIR , FILELEN , WRITE , INPUT ASM Calls _BLoad Input X: Pointer to string with filename Z: Pointer to Long-variable, which holds the start position of SRAM Output r25: Errorcode C-Flag: Set on Error Example ' THIS IS A CODE FRAGMENT, it needs AVR-DOS in order to work 'now the good old bsave and bload Dim Ar(100)as Byte , I Asbyte For I = 1 To 100 Ar(i) = I ' fill the array Next Wait 2 W = Varptr(ar(1)) Bsave"josef.img", W , 100 For I = 1 To 100 Ar(i) = 0 ' reset the array Next Bload "josef.img" , W ' Josef you are amazing ! For I = 1 To 10 Print Ar(i) ; " "; Next Print BSAVE Top Previous Next Action Save a range in SRAM to a File Syntax BSave sFileName, wSRAMPointer, wLength Remarks sFileName (String) Name of the File to be written wSRAMPointer (Word) Variable, which holds the SRAM Address, from where SRAM should be written to a File wLength (Word) Count of Bytes from SRAM, which should be written to the file This function writes a range from the SRAM to a file. A free file handle is needed for this function. See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, LOF , EOF , FREEFILE , FILEATTR , SEEK , BLOAD , KILL , DISKFREE , DISKSIZE , GET , PUT , FILEDATE , FILETIME , FILEDATETIME , DIR , FILELEN , WRITE , INPUT ASM Calls _BSave Input X: Pointer to string with filename Z: Pointer to Long-variable, which holds the start position of SRAM r20/r21: Count of bytes to be written Output r25: Errorcode C-Flag: Set on Error Example ' THIS IS A CODE FRAGMENT, it needs AVR-DOS in order to work 'now the good old bsave and bload Dim Ar(100)as Byte , I Asbyte For I = 1 To 100 Ar(i) = I ' fill the array Next Wait 2 W = Varptr(ar(1)) Bsave"josef.img", W , 100 For I = 1 To 100 Ar(i) = 0 ' reset the array Next Bload "josef.img" , W ' Josef you are amazing ! For I = 1 To 10 Print Ar(i) ; " "; Next Print CHDIR Top Previous Next Action This statement will change the current directory. Syntax CHDIR directory Remarks CHange DIRectory changes the current folder or directory. The directory name must be a valid and existing folder or directory. Like in DOS, you can use ".." to go back one directory. And you can use "\" to go to the root directory. You can not specify a path. You may can have multiple open files, and you could copy from one folder to another folder using the file handles. The DIR command and the OPEN command works in the current directory. IF you OPEN a file, the position (Sector# and position inside this sector) of the directory entry of the file is stored at the file-handle-part of that file. So you can move to another directory and OPEN there a second file an so on. In Short: Directory nesting is not limited and you can open files in multiple directories. See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, LOF , EOF , FREEFILE , FILEATTR , SEEK , BSAVE , BLOAD , KILL , DISKFREE , DISKSIZE , GET , PUT, FILELEN , FILEDATE , FILETIME , FILEDATETIME , WRITE , INPUT , DIR, MKDIR, RMDIR, NAME Example MKDIR "abc" CHDIR "abc" CLEARATTR new 2079 Top Previous Next Action Clears the file Attribute. Syntax CLEARATTR [sFile] , bFileAttribute Remarks sFile The name of the file (no wildcard) which attribute need to be cleared. You may also omit the name in which case the file will be used previous found by the DIR() function. bFileAttribute Numeric variable holding the attribute bits to clear. This functions clears the DOS file attributes. A file can have multiple attributes. You should not use attributes 8(Volume) and 16(Sub Directory) on a normal file. Return value DOS Attribute 1 Read Only 2 Hidden 4 System File 8 Volume Label 16 Sub Directory 32 Archive 64,128 reserved A file can have multiple bits set like 3 (hidden + read only). So you can clear multiple bits by combining the bits. When you specify the filename, make sure it does not have a wildcard. CLEARTTR does not support wildcards. When you omit the filename, the last found file from DIR() will be used for the operation. In VB, CLEARATTR expects a new value for the attribute which replaces the old attribute byte. In AVR-DOS you specify the bits to clear. So old attribute bits which are not altered are kept. In AVR-DOS you can also set the individual bits using the SETRATTR statement. See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, LOF , EOF , FREEFILE , SEEK , BSAVE , BLOAD , KILL , DISKFREE , DISKSIZE , GET , PUT, FILEDATE , FILETIME , FILEDATETIME , DIR , FILELEN, WRITE , INPUT , FILEATTR , SETATTR , GETATTR Example See SETATTR DIR Top Previous Next Action Returns the filename that matches the specified file mask. Syntax sFile = DIR(mask) sFile = DIR() Remarks SFile A string variable that is assigned with the filename. Mask A file mask with a valid DOS file mask like *.TXT Use *.* to select all files. The first function call needs a file mask. All other calls do not need the file mask. In fact when you want to get the next filename from the directory, you must not provide a mask after the first call. Dir() returns an empty string when there are no more files or when no file name is found that matches the mask. See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, LOF , EOF , FREEFILE , FILEATTR , SEEK , BSAVE , BLOAD , KILL , DISKFREE , DISKSIZE , GET , PUT, FILELEN , FILEDATE , FILETIME , FILEDATETIME , WRITE , INPUT , MKDIR, RMDIR , CHDIR ASM Calls _Dir ; with file mask _Dir0 ; without file mask Input X : points to the string with the mask Z : points to the target variable Output Partial Example 'Lets have a look at the file we created Print "Dir function demo" S = Dir("*.*") 'The first call to the DIR() function must contain a file mask ' The * means everything. ' While Len(s)> 0 ' if there was a file found Print S ;" ";Filedate();" ";Filetime();" ";Filelen() ' print file , the date the fime was created/changed , the time and the size of the file S = Dir()' get next Wend DISKFREE Top Previous Next Action Returns the free size of the Disk in KB. Syntax lFreeSize = DISKFREE() Remarks lFreeSize A Long Variable, which is assigned with the available Bytes on the Disk in Kilo Bytes. This functions returns the free size of the disk in KB. With the support of FAT32, the return value was changed from byte into KB. See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, LOF , EOF , FREEFILE , FILEATTR , SEEK , BSAVE , BLOAD , KILL , DISKSIZE , GET , PUT , FILEDATE , FILETIME , FILEDATETIME , DIR , FILELEN , WRITE , INPUT ASM Calls _GetDiskFreeSize Input none Output r16-r19: Long-Value of free Bytes Partial Example Dim Gbtemp1 As Byte ' scratch byte Gbtemp1 =Initfilesystem(1) ' we must init the filesystem once If Gbtemp1 > 0 Then Print#1 ,"Error "; Gbtemp1 Else Print#1 ," OK" Print "Disksize : ";Disksize() ' show disk size in bytes Print "Disk free: ";Diskfree() ' show free space too End If DISKSIZE Top Previous Next Action Returns the size of the Disk in KB. Syntax lSize = DISKSIZE() Remarks lSize A Long Variable, which is assigned with the capacity of the disk in Kilo Bytes This functions returns the capacity of the disk in KB. With the support of FAT32, the return value was changed from byte into KB. See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, LOF , EOF , FREEFILE , FILEATTR , SEEK , BSAVE , BLOAD , KILL , DISKFREE , GET , PUT , FILEDATE , FILETIME , FILEDATETIME , DIR , FILELEN , WRITE , INPUT ASM Calls _GetDiskSize Input none Output 16-r19: Long-Value of capacity in Bytes Partial Example Dim Gbtemp1 As Byte ' scratch byte Gbtemp1 = Initfilesystem(1) ' we must init the filesystem once If Gbtemp1 > 0 Then Print#1 ,"Error "; Gbtemp1 Else Print#1 ," OK" Print "Disksize : "; Disksize() ' show disk size in bytes Print "Disk free: "; Diskfree() ' show free space too End If DriveCheck Top Previous Next Action Checks the Drive, if it is ready for use Syntax bErrorCode = DRIVECHECK() Remarks bErrorCode A Byte Variable, which is assigned with the return value of the function This function checks the drive, if it is ready for use (for example, whether a compact flash card is inserted). The functions returns 0 if the drive can be used, otherwise an error code is returned. For Error code see section Error codes. See also DriveReset , DriveInit , DriveGetIdentity , DriveWriteSector , DriveReadSector ASM Calls _DriveCheck Input none Output r25: Errorcode C-Flag: Set on Error Partial Example Dim bError as Byte bError = DriveCheck() DriveGetIdentity Top Previous Next Action Returns the Parameter information from the Card/Drive Syntax bErrorCode = DRIVEGETIDENTIFY(wSRAMPointer) Remarks BErrorCode A Byte Variable, which is assigned with the error code of the function wSRAMPointer A Word Variable, which contains the SRAM address (pointer) , to which the information of the Drive should be written The Identify Drive Function returns the parameter information (512 Bytes) from the Compact Flash Memory Card/Drive and writes it to SRAM starting at the address, to which the content of the variable wSRAMPointer is pointing. This information are for example number of sectors of the card, serial number and so on. Refer to the Card/Drive manual for further information. The functions returns 0 if no error occurred. For Error code see section Error codes. Note: For meaning of wSRAMPointer see Note in DriveReadSector See also DriveCheck, DriveReset , DriveInit , DriveWriteSector , DriveReadSector ASM Calls _DriveGetIdentity Input Z: SRAM-Address of buffer *) Output r25: Errorcode C-Flag: Set on Error *) Please note: This is not the address of wSRAMPointer, it is its content, which is the starting-address of the buffer. Partial Example Dim bError as Byte Dim aBuffer(512) as Byte' Hold Sector to and from CF-Card Dim wSRAMPointer as Word' Address-Pointer for write ' give Address of first Byte of the 512 Byte Buffer to Word-Variable wSRAMPointer =VarPtr(aBuffer(1)) ' Now read the parameter Information from CF-Card bError = DriveGetIdentity( wSRAMPointer) DriveInit Top Previous Next Action Sets the AVR-Hardware (PORTs, PINs) attached to the Drive and resets the Drive. Syntax bErrorCode = DRIVEINIT() Remarks BErrorCode A Byte Variable, which is assigned with the error code of the function Set the Ports and Pins attaching the Drive for Input/Output and give initial values to the output-pins. After that the Drive is reset. Which action is done in this function depends of the drive and its kind of connection to the AVR. The functions returns 0 if no error occurred. For Error code see section Error codes. See also DriveCheck, DriveReset , DriveGetIdentity , DriveWriteSector , DriveReadSector, AVR-DOS File System ASM Calls _DriveInit Input none Output r25: Errorcode C-Flag: Set on Error Partial Example Dim bError as Byte bError = DriveInit() DriveReset Top Previous Next Action Resets the Drive. Syntax bErrorCode = DRIVERESET() Remarks BErrorCode A Byte Variable, which is assigned with the error code of the function This function resets the drive and brings it to an initial state. The functions returns 0 if no error occurred. For Error code see section Error codes. See also DriveCheck, DriveInit , DriveGetIdentity , DriveWriteSector , DriveReadSector ASM Calls _DriveReset Input none Output r25: Errorcode C-Flag: Set on Error Partial Example Dim bError as Byte bError = DriveReset() DriveReadSector Top Previous Next Action Read a Sector (512 Bytes) from the (Compact Flashcard) Drive Syntax bErrorCode = DRIVEREADSECTOR(wSRAMPointer, lSectorNumber) Remarks bErrorCode A Byte Variable, which is assigned with the error code of the function wSRAMPointer A Word Variable, which contains the SRAM address (pointer) , to which the Sector from the Drive should be written lSectorNumber A Long Variable, which give the sector number on the drive be transfer. Reads a Sector (512 Bytes) from the Drive and write it to SRAM starting at the address, to which the content of the variable wSRAMPointer is pointing. The functions returns 0 if no error occurred. For Error code see section Error codes. Note: wSRAMPointer is not the variable, to which the content of the desired drive-sector should be written, it is the Word-Variable/Value which contains the SRAM address of the range, to which 512 Bytes should be written from the Drive. This gives you the flexibility to read and write every SRAM-Range to and from the drive, even it is not declared as variable. If you know the SRAM-Address (from the compiler report) of a buffer you can pass this value directly, otherwise you can get the address with the BASCOM-function VARPTR (see example). See also DriveCheck, DriveReset , DriveInit , DriveGetIdentity , DriveWriteSector ASM Calls _DriveReadSector Input Z: SRAM-Address of buffer *) X: Address of Long-variable with sectornumber Output r25: Errorcode C-Flag: Set on Error This is not the address of wSRAMPointer, it is its content, which is the starting-address of the buffer. Partial Example Dim bError as Byte Dim aBuffer(512)as Byte' Hold Sector to and from CF-Card Dim wSRAMPointer as Word' Address-Pointer for write Dim lSectorNumber as Long' Sector Number ' give Address of first Byte of the 512 Byte Buffer to Word-Variable wSRAMPointer =VarPtr(aBuffer(1)) ' Set Sectornumber, sector 32 normally holds the Boot record sector of first partition lSectorNumber = 32 ' Now read in sector 32 from CF-Card bError = DriveReadSector( wSRAMPointer , lSectorNumber) ' Now Sector number 32 is in Byte-Array bBuffer DriveWriteSector Top Previous Next Action Write a Sector (512 Bytes) to the (Compact Flashcard) Drive Syntax bErrorCode = DRIVEWRITESECTOR(wSRAMPointer, lSectorNumber) Remarks bErrorCode A Byte Variable, which is assigned with the error code of the function wSRAMPointer A Word Variable, which contains the SRAM address (pointer), from which the Sector to the Drive should be written lSectorNumber A Long Variable, which give the sector number on the drive to transfer. Writes a Sector (512 Bytes) from SRAM starting at the address, to which the content of the variable wSRAMPointer is pointing to the Drive to sector number lSectornumber. The functions returns 0 if no error occurred. For Error code see section Error codes. For the meaning of wSRAMPointer see Note in DriveReadSector See also DriveCheck, DriveReset , DriveInit , DriveGetIdentity , DriveReadSector ASM Calls _DriveWriteSector Input Z: SRAM-Address of buffer *) X: Address of Long-variable with sectornumber Output r25: Errorcode C-Flag: Set on Error This is not the address of wSRAMPointer, it is its content, which is the starting-address of the buffer. Partial Example Dim bError as Byte Dim aBuffer(512) as Byte' Hold Sector to and from CF-Card Dim wSRAMPointer as Word' Address-Pointer for read Dim lSectorNumber as Long' Sector Number ' give Address of first Byte of the 512 Byte Buffer to Word-Variable wSRAMPointer =VarPtr(aBuffer(1)) ' Set Sectornumber lSectorNumber = 3 ' Now Write in sector 3 from CF-Card bError = DriveWriteSector( wSRAMPointer , lSectorNumber) EOF Top Previous Next Action Returns the End of File Status. Syntax bFileEOFStatus = EOF(#bFileNumber) Remarks bFileEOFStatus (Byte) A Byte Variable, which assigned with the EOF Status bFileNumber (Byte) Number of the opened file This functions returns information about the End of File Status Return value Status 0 NOT EOF 255 EOF In case of an error (invalid file number) 255 (EOF) is returned too. See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, LOF , FREEFILE , FILEATTR , SEEK , BSAVE , BLOAD , KILL , DISKFREE , DISKSIZE , GET , PUT , FILEDATE , FILETIME , FILEDATETIME , DIR , FILELEN , WRITE , INPUT ASM Calls _FileEOF Input r24: Filenumber Output r24: EOF Status r25: Error code C-Flag: Set on Error Partial Example Ff =Freefile()' get file handle Open "test.txt" For Input As #ff ' we can use a constant for the file too Print Lof(#ff); " length of file" Print Fileattr(#ff); " file mode" ' should be 1 for input Do LineInput #ff , S ' read a line ' line input is used to read a line of text from a file Print S ' print on terminal emulator Loop Until Eof(#ff)<> 0 'The EOF() function returns a non-zero number when the end of the file is reached 'This way we know that there is no more data we can read Close #ff FILEATTR Top Previous Next Action Returns the file open mode. Syntax bFileAttribut = FILEATTR(bFileNumber) Remarks bFileAttribut (Byte) File open mode, See table bFileNumber (Byte) Number of the opened file This functions returns information about the File open mode Return value Open mode 1 INPUT 2 OUTPUT 8 APPEND 32 BINARY See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, LOF , EOF , FREEFILE , SEEK , BSAVE , BLOAD , KILL , DISKFREE , DISKSIZE , GET , PUT, FILEDATE , FILETIME , FILEDATETIME , DIR , FILELEN, WRITE , INPUT , GETATTR ASM Calls _FileAttr Input r24: Filenumber Output 24: File open mode r25: Errorcode C-Flag: Set on Error Partial Example 'open the file in BINARY mode Open "test.biN" For Binary As #2 Print Fileattr(#2); " file mode" ' should be 32 for binary Put #2 , Sn ' write a single Put #2 , Stxt ' write a string Close #2 FILEDATE Top Previous Next Action Returns the date of a file Syntax sDate = FILEDATE () sDate = FILEDATE (file) Remarks Sdate A string variable that is assigned with the date. File The name of the file to get the date of. This function works on any file when you specify the filename. When you do not specify the filename, it works on the current selected file of the DIR() function. See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, LOF , EOF , FREEFILE , FILEATTR , SEEK , BSAVE , BLOAD , KILL , DISKFREE , DISKSIZE, GET , PUT, FILELEN , FILETIME , FILEDATETIME , DIR , WRITE , INPUT ASM Calls _FileDateS ; with filename _FileDateS0 ; for current file from DIR() Input X : points to the string with the mask Z : points to the target variable Output Partial Example Print "File demo" Print Filelen("josef.img");" length" ' length of file Print Filetime("josef.img");" time" ' time file was changed Print Filedate("josef.img");" date" ' file date FILEDATETIME Top Previous Next Action Returns the file date and time of a file Syntax Var = FILEDATETIME () Var = FILEDATETIME (file) Remarks Var A string variable or byte array that is assigned with the file date and time of the specified file File The name of the file to get the date time of. When the target variable is a string, it must be dimensioned with a length of at least 17 bytes. When the target variable is a byte array, the array size must be at least 6 bytes. When you use a numeric variable, the internal file date and time format will be used. See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, LOF , EOF , FREEFILE , FILEATTR , SEEK , BSAVE , BLOAD , KILL , DISKFREE , GET , PUT , FILELEN , FILEDATE , FILETIME , DIR , WRITE , INPUT ASM Calls _FileDateTimeS _FileDateTimeS0 Input Output Calls _FileDateTimeB _FileDateTimeB0 Input Output Example See fs_subfunc_decl_lib.bas in the samples dir. FILELEN Top Previous Next Action Returns the size of a file Syntax lSize = FILELEN () lSize = FILELEN (file) Remarks lSize A Long Variable, which is assigned with the file size in bytes of the file. File A string or string constant to get the file length of. This function works on any file when you specify the filename. When you do not specify the filename, it works on the current selected file of the DIR() function. See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, LOF , EOF , FREEFILE , FILEATTR , SEEK , BSAVE , BLOAD , KILL , DISKFREE , GET , PUT , FILEDATE , FILETIME , FILEDATETIME , DIR , WRITE , INPUT ASM Calls _FileLen Input Output Partial Example Print "File demo" Print Filelen("josef.img");" length" ' length of file Print Filetime("josef.img");" time" ' time file was changed Print Filedate("josef.img");" date" ' file date FILETIME Top Previous Next Action Returns the time of a file Syntax sTime = FILETIME () sTime = FILETIME (file) Remarks Stime A string variable that is assigned with the file time. File The name of the file to get the time of. This function works on any file when you specify the filename. When you do not specify the filename, it works on the current selected file of the DIR() function. See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, LOF , EOF , FREEFILE , FILEATTR , SEEK , BSAVE , BLOAD , KILL , DISKFREE , GET , PUT , FILELEN , FILEDATE , FILEDATETIME , DIR , WRITE , INPUT ASM Calls _FileTimeS ; with file param _FileTimeS0 ; current file Input X : points to the string with the mask Z : points to the target variable Output Example Print "File demo" Print Filelen("josef.img");" length" ' length of file Print Filetime("josef.img");" time" ' time file was changed Print Filedate("josef.img");" date" ' file date FLUSH Top Previous Next Action Write current buffer of File to Card and updates Directory Syntax FLUSH #bFileNumber FLUSH Remarks BFileNumber Filenumber, which identifies an opened file such as #1 or #ff This function writes all information of an open file, which is not saved yet to the Disk. Normally the Card is updated, if a file will be closed or changed to another sector. When no file number is specified, all open files will be flushed. Flush does not need additional buffers. You could use FLUSH to be absolutely sure that data is written to the disk. For example in a data log application which is updated infrequently. A power failure could result in a problem when there would be data in the buffer. See also INITFILESYSTEM , OPEN , CLOSE, PRINT, LINE INPUT, LOC, LOF , EOF , FREEFILE , FILEATTR , SEEK , BSAVE , BLOAD , KILL , DISKFREE , DISKSIZE , GET , PUT , FILEDATE , FILETIME , FILEDATETIME , DIR , FILELEN , WRITE , INPUT ASM Calls _FileFlush _FilesAllFlush Input r24: filenumber Output r25: Errorcode C-Flag: Set on Error Partial Example $include "startup.inc" 'open the file in BINARY mode Open "test.bin" For Binary As #2 Put #2 , B ' write a byte Put #2 , W ' write a word Put #2 , L ' write a long Ltemp = Loc(#2) + 1 ' get the position of the next byte Print Ltemp ;" LOC" ' store the location of the file pointer Print Lof(#2);" length of file" Print Fileattr(#2);" file mode" ' should be 32 for binary Put #2 , Sn ' write a single Put #2 , Stxt ' write a string Flush #2 ' flush to disk Close #2 FREEFILE Top Previous Next Action Returns a free Filenumber. Syntax bFileNumber = FREEFILE() Remarks bFileNumber A byte variable , which can be used for opening next file This function gives you a free file number, which can be used for file � opening statements. In contrast to VB this file numbers start with 128 and goes up to 255. Use range 1 to 127 for user defined file numbers to avoid file number conflicts with the system numbers from FreeFile() This function is implemented for compatility with VB. See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, LOF , EOF , FILEATTR , SEEK , BSAVE , BLOAD , KILL , DISKFREE , DISKSIZE , GET , PUT , FILEDATE , FILETIME , FILEDATETIME , DIR , FILELEN , WRITE , INPUT ASM Calls _GetFreeFileNumber Input none Output r24: Filenumber r25: Errorcode C-Flag: Set on Error Partial Example Ff =Freefile() ' get file handle Open"test.txt" For Input As #ff ' we can use a constant for the file too Print Lof(#ff);" length of file" Print Fileattr(#ff);" file mode" ' should be 1 for input Do LineInput #ff , S ' read a line ' line input is used to read a line of text from a file Print S ' print on terminal emulator Loop UntilEof(ff)<> 0 'The EOF() function returns a non-zero number when the end of the file is reached 'This way we know that there is no more data we can read Close #ff GETATTR Top Previous Next Action Returns the file Attribute. Syntax bFileAttribut = GETATTR([sFile]) Remarks bFileAttribut Numeric variable which is assigned with the file attribute. sFile The name of the file (no wildcard) to get the attribute from. You may also omit the name in which case the file will be used previous found by the DIR() function. This functions returns the DOS file attributes. A file can have multiple attributes. Return value DOS Attribute 1 Read Only 2 Hidden 4 System File 8 Volume Label 16 Sub Directory 32 Archive 64,128 reserved A file could have an attribute of 3 (hidden+ read only). See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, LOF , EOF , FREEFILE , SEEK , BSAVE , BLOAD , KILL , DISKFREE , DISKSIZE , GET , PUT, FILEDATE , FILETIME , FILEDATETIME , DIR , FILELEN, WRITE , INPUT , FILEATTR Partial Example 'open the file in BINARY mode Print Getattr("somefile.bin") INITFILESYSTEM Top Previous Next Action Initialize the file system Syntax bErrorCode = INITFILESYSTEM (bPartitionNumber) Remarks bErrorCode (Byte) Error Result from Routine, Returns 0 if no Error bPartitionNumber (Byte) Partition number on the Flashcard Drive (normally 1) Reads the Master boot record and the partition boot record (Sector) from the flash card and initializes the file system. This function must be called before any other file-system function is used. See also OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, LOF , EOF , FREEFILE , FILEATTR , SEEK , BSAVE , BLOAD , KILL , DISKFREE , DISKSIZE , GET , PUT , FILEDATE , FILETIME , FILEDATETIME , DIR , FILELEN , WRITE , INPUT, AVR-DOS File System ASM Calls _GetFileSystem Input r24: partitionnumber (1-based) Output r25: Errorcode C-Flag: Set on Error Partial Example Dim bErrorCode as Byte bErrorCode = InitFileSystem(1) If bErrorCode > 0 then Print "Error: "; bErrorCode Else Print "Filesystem successfully initialized" End If KILL Top Previous Next Action Delete a file from the Disk Syntax KILL sFileName Remarks sFileName A String variable or string expression, which denotes the file to delete This function deletes a file from the disk. A file in use can't be deleted. WildCards in Filename are not supported. Check the DOS-Error in variable gDOSError. See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, LOF , EOF , FREEFILE , FILEATTR , SEEK , BSAVE , BLOAD , DISKFREE , DISKSIZE , GET , PUT , FILEDATE , FILETIME , FILEDATETIME , DIR , FILELEN , WRITE , INPUT ASM Calls _DeleteFile Input X: Pointer to string with filename Output r25: Errorcode C-Flag: Set on Error Partial Example 'We can use the KILL statement to delete a file. 'A file mask is not supported Print "Kill (delete) file demo" Kill "test.txt" LINEINPUT Top Previous Next Action Read a Line from an opened File. Syntax LINEINPUT #bFileNumber, sLineText LINE_INPUT #bFileNumber, sLineText Remarks BfileNumber (Byte) File number, which identifies an opened file SlineText (String) A string, which is assigned with the next line from the file. Only valid for files opened in mode INPUT. Line INPUT works only with strings. It is great for working on text files. See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LOC, LOF , EOF , FREEFILE , FILEATTR , SEEK , BSAVE , BLOAD , KILL , DISKFREE , DISKSIZE , GET , PUT , FILEDATE , FILETIME , FILEDATETIME , DIR , FILELEN , WRITE , INPUT ASM Calls _FileLineInput Input r24: filenumber X: Pointer to String to be written from file r25: Stringlength Output r25: Errorcode C-Flag: Set on Error Example 'Ok we want to check if the file contains the written lines Ff = Freefile()' get file handle Open "test.txt" For Input As #ff ' we can use a constant for the file too Print Lof(#ff); " length of file" Print Fileattr(#ff); " file mode" ' should be 1 for input Do LineInput #ff , S ' read a line ' line input is used to read a line of text from a file Print S ' print on terminal emulator Loop Until Eof(ff)<> 0 'The EOF() function returns a non-zero number when the end of the file is reached 'This way we know that there is no more data we can read Close #ff LOC Top Previous Next Action Returns the position of last read or written Byte of the file Syntax lLastReadWritten = LOC (#bFileNumber) Remarks bFileNumber (Byte) File number, which identifies an opened file lLastReadWritten (Long) Variable, assigned with the Position of last read or written Byte (1-based) This function returns the position of the last read or written Byte. If an error occurs, 0 is returned. Check DOS-Error in variable gbDOSError. If the file position pointer is changed with the command SEEK, this function can not be used till the next read/write operation. This function differs from VB. In VB the byte position is divided by 128. See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOF , EOF , FREEFILE , FILEATTR , SEEK , BSAVE , BLOAD , KILL , DISKFREE , DISKSIZE , GET , PUT , FILEDATE , FILETIME , FILEDATETIME , DIR , FILELEN , WRITE , INPUT ASM Calls _FileLoc Input r24: filenumber X: Pointer to Long-variable, which gets th result Output r25: Errorcode C-Flag: Set on Error Example ' open the file in BINARY mode Open "test.bin" For Binary As #2 Put #2 , B ' write a byte Put #2 , W ' write a word Put #2 , L ' write a long Ltemp = Loc(#2)+ 1 ' get the position of the next byte Print Ltemp ;" LOC" ' store the location of the file pointer Print Lof(#2);" length of file" Print Fileattr(#2);" file mode" ' should be 32 for binary Put #2 , Sn ' write a single Put #2 , Stxt ' write a string Flush #2 ' flush to disk Close #2 LOF Top Previous Next Action Returns the length of the File in Bytes Syntax lFileLength = LOF (#bFileNumber) Remarks bFileNumber (Byte) Filenumber, which identifies an opened file LFileLength (Long) Variable, which assigned with the Length of the file (1-based) This function returns the length of an opened file. If an error occurs, 0 is returned. Check DOS-Error in variable gbDOSError. See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, EOF , FREEFILE , FILEATTR , SEEK , BSAVE , BLOAD , KILL , DISKFREE , DISKSIZE , GET , PUT , FILEDATE , FILETIME , FILEDATETIME , DIR , FILELEN , WRITE , INPUT ASM Calls _FileLOF Input r24: filenumber X: Pointer to Long-variable, which gets th result Output r25: Errorcode C-Flag: Set on Error Example ' open the file in BINARY mode Open "test.bin" For Binary As #2 Put #2 , B ' write a byte Put #2 , W ' write a word Put #2 , L ' write a long Ltemp = Loc(#2)+ 1 ' get the position of the next byte Print Ltemp ;" LOC" ' store the location of the file pointer Print Lof(#2);" length of file" Print Fileattr(#2);" file mode" ' should be 32 for binary Put #2 , Sn ' write a single Put #2 , Stxt ' write a string Flush #2 ' flush to disk Close #2 MKDIR Top Previous Next Action This statement creates a folder or directory in the current directory. Syntax MKDIR directory Remarks MaKeDIRectory creates a folder or directory in the current directory. The directory may not have a device name like COM1, LPT1, etc. The directory may also not have a name like ".." or "\" since these names are reserved. You can not create a directory using a path. MKDIR "test" ' ok MKDIR "test\abc" ' NOT OK MKDIR ".." ' NOT OK MKDIR "\" ' NOT OK MKDIR "test" : CHDIR "test" : MKDIR "abc" ' this would create test\abc See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, LOF , EOF , FREEFILE , FILEATTR , SEEK , BSAVE , BLOAD , KILL , DISKFREE , DISKSIZE , GET , PUT, FILELEN , FILEDATE , FILETIME , FILEDATETIME , WRITE , INPUT , DIR, RMDIR , CHDIR , NAME Example MKDIR "test" NAME Top Previous Next Action This AVR-DOS statement renames a file or directory name. Syntax NAME old AS new Remarks old The name of the file or folder that you want to rename. This file must exist in the current folder. new The new name of the file. The new file may not already exist. The current folder will be used. Both old and new must be valid file names and of the string data type. Constants are not allowed. See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, LOF , EOF , FREEFILE , FILEATTR , SEEK , BSAVE , BLOAD , KILL , DISKFREE , DISKSIZE , GET , PUT, FILELEN , FILEDATE , FILETIME , FILEDATETIME , WRITE , INPUT , DIR, MKDIR, RMDIR, CHDIR Example Old = "file1.txt" New = "fileNew.txt" NAME old AS new RMDIR Top Previous Next Action This statement removes the specified directory. Syntax RMDIR directory Remarks RMDIR (ReMove DIRectory) removes the specified directory or folder. The folder must exist. You may not use a path. While KILL is used to remove files, RMDIR is used to remove directories. You should remove all files before you remove the directory. See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, LOF , EOF , FREEFILE , FILEATTR , SEEK , BSAVE , BLOAD , KILL , DISKFREE , DISKSIZE , GET , PUT, FILELEN , FILEDATE , FILETIME , FILEDATETIME , WRITE , INPUT , DIR, MKDIR, CHDIR , NAME Example RMDIR "abc" SETATTR new 2079 Top Previous Next Action Sets the file Attribute. Syntax SETATTR [sFile ,] bFileAttribute Remarks sFile The name of the file (no wildcard) which attribute need to be set. You may also omit the name in which case the file will be used previous found by the DIR() function. bFileAttribute Numeric variable holding the attribute bits to set. This statement sets the DOS file attributes. A file can have multiple attributes. You should not use attributes 8(Volume) and 16(Sub Directory) on a normal file. Return value DOS Attribute 1 Read Only 2 Hidden 4 System File 8 Volume Label 16 Sub Directory 32 Archive 64,128 reserved A file can have multiple bits set like 3 (hidden + read only). So you can combine multiple bits to set multiple bits at once. When you specify the filename, make sure it does not have a wildcard. SETATTR does not support wildcards. When you omit the filename, the last found file from DIR() will be used for the operation. In VB, SETATTR expect a new value for the attribute which replaces the old attribute byte. In AVR-DOS you specify the bits to set. So old attributes are kept. In AVR-DOS you can also reset the individual bits using the CLEARATTR statement. See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, LOF , EOF , FREEFILE , SEEK , BSAVE , BLOAD , KILL , DISKFREE , DISKSIZE , GET , PUT, FILEDATE , FILETIME , FILEDATETIME , DIR , FILELEN, WRITE , INPUT , FILEATTR , CLEARATTR , GETATTR Example '------------------------------------------------------------------------------ ' simulate-AVR-DOS.bas ' simulate AVR-DOS using virtual XRAM drive ' '------------------------------------------------------------------------------ $regfile = "M128def.dat" $crystal = 16000000 ' Adjust HW Stack, Soft-Stack and Frame size to 128 minimum each!!! $hwstack=128 : $swstack=128 : $framesize=128 $xramsize = &H10000 'specify 64KB of XRAM for the file system $sim 'for simulation only ! $baud = 19200 Config Clock = Soft Enable Interrupts Config Date = Mdy , Separator = dot Dim Btemp1 As Byte ,battr1 as Byte, battr2 as Byte $include "Config_XRAMDrive.bas" ' Does drive init too $include "Config_AVR-DOS.BAS" Print "Wait for Drive" If Gbdriveerror = 0 Then Print "Init File System ... "; Btemp1 = Initfilesystem(1) ' Partition 1 ' use 0 for drive without Master boot record If Btemp1 <> 0 Then Print "Error: " ; Btemp1 ; " at Init file system" Else Print " OK" Print "Filesystem: " ; Gbfilesystem Print "FAT Start Sector: " ; Glfatfirstsector Print "Root Start Sector: " ; Glrootfirstsector Print "Data First Sector: " ; Gldatafirstsector Print "Max. Cluster Nummber: " ; Glmaxclusternumber Print "Sectors per Cluster: " ; Gbsectorspercluster Print "Root Entries: " ; Gwrootentries Print "Sectors per FAT: " ; Glsectorsperfat Print "Number of FATs: " ; Gbnumberoffats End If Else Print "Error during Drive Init: " ; Gbdriveerror End If Dim strDummy as String * 12 Dim Datei As String * 12 , Attribut As Byte Datei = "Test1.txt" Open Datei For Output As #11 Print #11 , "Testzeile1" Close #11 open "Test2.txt" For output as #11 Print #11, "Testzeile2" close #11 open "Test3.txt" for output as #11 Print #11, "Testzeile3" close #11 ' Set readonly Bit in Test1.txt Attribut = &B00000001 Setattr Datei , Attribut ' Reset Archib-Bit in test1.txt Attribut = &B00100000 clearattr Datei , Attribut ' Check for Filename with wildcard, which is not supported ' Set readonly Bit in Test1.txt Datei = "Test*.txt" Attribut = &B00000001 Setattr Datei , Attribut Print gbDOSError Datei = DIR("Test*.txt") Attribut = &B00000001 while Datei > "" SetAttr Attribut Datei = DIR() wend Datei = DIR("Test*.txt") Attribut = &B00100000 While Datei > "" battr1=Getattr() clearattr Attribut battr2=Getattr() print datei ;" "; battr1;" " ; battr2 Datei = DIR() wend End WRITE Top Previous Next Action Writes data to a sequential file Syntax WRITE #ch , data [,data1] Remarks Ch A channel number, which identifies an opened file. This can be a hard coded constant or a variable. Data , data1 A variable who�s content are written to the file. When you write a variables value, you do not write the binary representation but the ASCII representation. When you look in a file it contains readable text. When you use PUT, to write binary info, the files are not readable or contain unreadable characters. Strings written are surrounded by string delimiters "". Multiple variables written are separated by a comma. Consider this example : Dim S as String * 10 , W as Word S="hello" : W = 100 OPEN "test.txt" For OUTPUT as #1 WRITE #1, S , W CLOSE #1 The file content will look like this : "hello",100 Use INPUT to read the values from value. See also INITFILESYSTEM , OPEN , CLOSE, FLUSH , PRINT, LINE INPUT, LOC, LOF , EOF , FREEFILE , FILEATTR , SEEK , BSAVE , BLOAD , KILL , DISKFREE , GET , PUT , FILEDATE , FILETIME , FILEDATETIME , DIR , WRITE , INPUT ASM Calls _FileWriteQuotationMark _FileWriteDecInt _FileWriteDecByte _FileWriteDecWord _FileWriteDecLong _FileWriteDecSingle Input Z points to variable Output Partial Example Dim S As String * 10 , W As Word , L As Long S = "write" Open "write.dmo"for Output As #2 Write #2 , S , W , L ' write is also supported Close #2 Open "write.dmo"for Input As #2 Input #2 , S , W , L ' write is also supported Close #2 Print S ; " " ; W ; " " ; L BITWAIT Top Previous Next Action Wait until a bit is set or reset. Syntax BITWAIT x , SET/RESET Remarks X Bit variable or internal register like PORTB.x , where x ranges from 0-7. When using bit variables make sure that they are set/reset by software otherwise your program will stay in a loop. When you use internal registers that can be set/reset by hardware such as PINB.0 this doesn't apply since this state can change as a result from for example a key press. See also NONE ASM Calls: NONE Input: NONE Output: NONE Code : shown for address 0-31 label1: Sbic PINB.0,label2 Rjmp label1 Label2: Example $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim A As Bit Bitwait A , Set 'wait until bit a is set 'the code above will loop forever since the bit 'A' is not set in software 'it could be set in an ISR routine Bitwait Pinb.7 , Reset 'wait until bit 7 of Port B is 0. End BITS Top Previous Next Action Set all specified bits to 1. Syntax Var = Bits( b1 [,bn]) Remarks Var The BYTE/PORT variable that is assigned with the constant. B1 , bn A list of bit numbers that must be set to 1. While it is simple to assign a value to a byte, and there is special Boolean notation &B for assigning bits, the Bits() function makes it simple to assign a few bits. B = &B1000001 : how many zero�s are there? This would make it more readable : B = Bits(0, 6) You can read from the code that bit 0 and bit 6 are set to 1. It does not save code space as the effect is the same. It can only be used on bytes and port registers. Valid bits are in range from 0 to 7. See Also NBITS Example '-------------------------------------------------------------------------------- 'name : bits-nbits.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demo for Bits() AND Nbits() 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no 'use in simulator : possible '-------------------------------------------------------------------------------- $regfile = "m48def.dat" ' specify the used micro $crystal = 4000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Dim B As Byte 'while you can use &B notation for setting bits, like B = &B1000_0111 'there is also an alternative by specifying the bits to set B = Bits(0 , 1 , 2 , 7) 'set only bit 0,1,2 and 7 Print B 'and while bits() will set all bits specified to 1, there is also Nbits() 'the N is for NOT. Nbits(1,2) means, set all bits except 1 and 2 B = Nbits(7) 'do not set bit 7 Print B End BREAK Top Previous Next Action This statement will break the simulator/debugger. Syntax BREAK Remarks A number of new processors support the BREAK instruction. The break instruction will break execution of the simulator. This is support by the BASCOM simulator but also by Atmels Studio. Processors that do not support the BREAK instruction interpret the BREAK instruction as a NOP (no operation). So it is safe to use on all processors. The BREAK instruction uses 1 cycle just like the ASM NOP instruction. See also NOP Example NONE BYVAL Top Previous Next Action Specifies that a variable will be passed by value. Syntax Sub Test(BYVAL var) Remarks Var Variable name The default for passing variables to SUBS and FUNCTIONS, is by reference(BYREF). When you pass a variable by reference, the address is passed to the SUB or FUNCTION. When you pass a variable by Value, a temp variable is created on the frame and the address of the copy is passed. When you pass by reference, changes to the variable will be made to the calling variable. When you pass by value, changes to the variable will be made to the copy so the original value will not be changed. By default passing by reference is used. Note that calling by reference will generate less code. See also CALL , DECLARE , SUB , FUNCTION ASM NONE Example Declare Sub Test(Byval X As Byte, Byref Y As Byte, Z As Byte) CALL Top Previous Next Action Call and execute a subroutine. Syntax CALL Test [ (var1, var-n) ] Remarks Var1 Any BASCOM variable or constant. Var-n Any BASCOM variable or constant. Test Name of the subroutine. In this case Test. You can call sub routines with or without passing parameters. It is important that the SUB routine is DECLARED before you make the CALL to the subroutine. Of course the number of declared parameters must match the number of passed parameters. It is also important that when you pass constants to a SUB routine, you must DECLARE these parameters with the BYVAL argument. With the CALL statement, you can call a procedure or subroutine. For example: Call Test2 The call statement enables you to implement your own statements. You don't have to use the CALL statement: Test2 will also call subroutine test2 When you don't supply the CALL statement, you must leave out the parenthesis. So Call Routine(x,y,z) must be written as Routine x,y,x Unlike normal SUB programs called with the GOSUB statement, the CALL statement enables you to pass variables to a SUB routine that may be local to the SUB. By using CONFIG SUBMODE=NEW, you do not need to DECLARE each sub/function. See also DECLARE , SUB , EXIT , FUNCTION , LOCAL , CONFIG SUBMODE Example $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim A As Byte , B As Byte 'dimension some variables Declare Sub Test(b1 As Byte , Byval B2 As Byte) 'declare the SUB program A = 65 'assign a value to variable A Call Test(a , 5)'call test with parameter A and constant Test A , 5 'alternative call Print A 'now print the new value End Sub Test(b1 As Byte , Byval B2 As Byte) 'use the same variable names as 'the declared one Print B1 'print it Print Bcd(b2) B1 = 10 'reassign the variable B2 = 15 'reassign the variable End Sub One important thing to notice is that you can change b2 but that the change will not be reflected to the calling program! Variable A is changed however. This is the difference between the BYVAL and BYREF argument in the DECLARE ration of the SUB program. When you use BYVAL, this means that you will pass the argument by its value. A copy of the variable is made and passed to the SUB program. So the SUB program can use the value and modify it, but the change will not be reflected to the calling parameter. It would be impossible too when you pass a numeric constant for example. If you do not specify BYVAL, BYREF will be used by default and you will pass the address of the variable. So when you reassign B1 in the above example, you are actually changing parameter A. CHECKSUM CHECKSUMXOR Top Previous Next Action Returns a checksum of a string. Syntax PRINT Checksum(var) b = Checksum(var) b = ChecksumXOR(var) Remarks Var A string variable. B A numeric variable that is assigned with the checksum. The checksum is computed by counting all the bytes of the string variable. The checksumXOR is computed by Xor-ing all the bytes of the string variable. Checksums are often used with serial communication. The checksum is a byte checksum. The following VB code is equivalent : Dim Check as Byte Check = 0 For x = 1 To Len(s$) Check = check + ASC(mid$(s$,x,1)) Next The following VB code is equivalent for ChecksumXOR Dim Check as Byte Check = 0 For x = 1 To Len(s$) Check = check XOR ASC(mid$(s$,x,1)) Next See also CRC8 , CRC16 , CRC32 , CRC16UNI, CRCMB Example $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim S As String * 10 'dim variable S = "test" 'assign variable Print Checksum(s) 'print value (192) End CRC8 Top Previous Next Action Returns the CRC8 value of a variable or array. Syntax Var = CRC8( source , L) Remarks Var The variable that is assigned with the CRC8 of variable source. Source The source variable or first element of the array to get the CRC8 of. L The number of bytes to check. CRC8 is used in communication protocols to check if there are no transmission errors. The 1wire for example returns a CRC byte as the last byte from it�s ID. The code below shows a VB function of CRC8 Function Docrc8(s As String) As Byte Dim j As Byte Dim k As Byte Dim crc8 As Byte crc8 = 0 For m = 1 To Len(s) x = Asc(Mid(s, m, 1)) For k = 0 To 7 j = 1 And (x Xor crc8) crc8 = Fix(crc8 / 2) And &HFF x = Fix(x / 2) And &HFF If j <> 0 Then crc8 = crc8 Xor &H8C End If Next k Next Docrc8 = crc8 End Function When you want to use a different polynome, you can override the default by defining a constant named CRC8_POLY Const CRC8_POLY = &HAA 'use a different value Please notice that the CRC8 function is the CRC8-MAXIM function. It is primarily intended for the 1WIRE routines. There exist a lot of different CRC8 variants. They differ in the start value, the polynom , if the result is XOR-ed and if the data is reflected or not. Reflection means that data is flipped. (See FLIP) See also CHECKSUM , CRC16, CRC16UNI , CRC32 , TCPCHECKSUM , CRCMB ASM The following routine is called from mcs.lib : _CRC8 The routine must be called with Z pointing to the data and R24 must contain the number of bytes to check. On return, R16 contains the CRC8 value. The used registers are : R16-R19, R25. ;##### X = Crc8(ar(1) , 7) Ldi R24,$07 ; number of bytes Ldi R30,$64 ; address of ar(1) Ldi R31,$00 ; load constant in register Rcall _Crc8 ; call routine Ldi R26,$60 ; address of X St X,R16 ; store crc8 Example $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim Ar(10) As Byte Dim J As Byte Ar(1) = 1 Ar(2) = 2 Ar(3) = 3 J = Crc8(ar(1) , 3) 'calculate value which is 216 Print J End CRC8UNI Top Previous Next Action Returns the CRC value of a variable or array. Syntax Var = CRC8UNI( source , L) Remarks Var The variable that is assigned with the CRC8 of variable source. Source The source variable or first element of the array to get the CRC8 of. L The number of bytes to check. CRC is used in communication protocols to check if there are no transmission errors. The CRC8 function in BASCOM is mainly intended to be used with 1WIRE. The CRC8UNI uses the CCITT with polynome value 7. When you want to use a different polynome, you can override the default by defining a constant named CRC8_POLY Const CRC8_POLY = &HAA 'use a different value See also CHECKSUM , CRC16, CRC16UNI , CRC32 , TCPCHECKSUM , CRCMB , CRC8 Example '------------------------------------------------------------------------------ 'name : crc8-16-32.bas 'copyright : (c) 1995-2017, MCS Electronics 'purpose : demonstrates CRC 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no '------------------------------------------------------------------------------ $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Dim Ar(10) As Byte Dim J As Byte Dim W As Word Dim L As Long Dim S As String * 16 S = "123456789" Ar(1) = 1 Ar(2) = 2 Ar(3) = 3 J = Crc8(ar(1) , 3) 'calculate value which is 216 j = Crc8Uni(ar(1) , 3) 'calculate unsing CCITT which is 72 W = Crc16(ar(1) , 3) '24881 L = Crc32(ar(1) , 3) '1438416925 ' data , length, intial value , Poly, reflect input, reflect output Print Hex(Crc16Uni(S , 9 , 0 , &H1021 , 0 , 0)) 'CRC-CCITT (0x0000) 31C3 Print Hex(Crc16Uni(S , 9 , &HFFFF , &H1021 , 0 , 0)) 'CRC-CCITT (0xFFFF) 29B1 Print Hex(Crc16Uni(S , 9 , &H1D0F , &H1021 , 0 , 0)) 'CRC-CCITT (0x1D0F) E5CC Print Hex(Crc16Uni(S , 9 , 0 , &H8005 , 1 , 1)) 'crc16 BB3D Print Hex(Crc16Uni(S , 9 , &HFFFF , &H8005 , 1 , 1)) 'crc16-modbus 4B37 End CRC16 Top Previous Next Action Returns the CRC16 value of a variable or array. Syntax Var = CRC16( source , L) Remarks Var The variable that is assigned with the CRC16 of variable source. Should be a word or integer variable. Source The source variable or first element of the array to get the CRC16 value from. By default only normal RAM variables are supported. You can also use EEPROM memory when you add a constant to your project : Const CRC16_EEPROM=1 L The number of bytes to check. This can be a numeric constant , byte or word variable. The maximum size to check is 65535. CRC16 is used in communication protocols to check if there are no transmission errors. The 1wire for example returns a CRC byte as the last byte from it�s ID. Use CRC8 for the 1wire routines. There are a lot of different CRC16 routines. There is no real standard since the polynomial will vary from manufacture to manufacture. The equivalent code in VB is shown below. There are multiple ways to implement it in VB. This is one of them. VB CRC16 Sample Private Sub Command1_Click() Dim ar(10) As Byte Dim b As Byte Dim J As Integer ar(1) = 1 ar(2) = 2 ar(3) = 3 b = Docrc8(ar(), 3) ' call funciton Print b 'calculate value which is 216 J = CRC16(ar(), 3) ' call function Print J End Sub Function Docrc8(ar() As Byte, bts As Byte) As Byte Dim J As Byte Dim k As Byte Dim crc8 As Byte crc8 = 0 For m = 1 To bts x = ar(m) For k = 0 To 7 J = 1 And (x Xor crc8) crc8 = Fix(crc8 / 2) And &HFF x = Fix(x / 2) And &HFF If J <> 0 Then crc8 = crc8 Xor &H8C End If Next k Next Docrc8 = crc8 End Function '***************************************************************** Public Function CRC16(buf() As Byte, lbuf As Integer) As Integer Dim CRC1 As Long Dim b As Boolean CRC1 = 0 ' init CRC For i = 1 To lbuf ' for each byte CRC_MSB = CRC1 \ 256 crc_LSB = CRC1 And 255 CRC_MSB = CRC_MSB Xor buf(i) CRC1 = (CRC_MSB * 256) + crc_LSB For J = 0 To 7 Step 1 ' for each bit CRC1 = shl(CRC1, b) If b Then CRC1 = CRC1 Xor &H1021 Next J Next i CRC16 = CRC1 End Function 'Shift Left function Function shl(n As Long, ByRef b As Boolean) As Long Dim L As Long L = n L = L * 2 If (L > &HFFFF&) Then b = True Else b = False End If shl = L And &HFFFF& End Function See also CHECKSUM , CRC8, CRC16UNI , CRC32 , TCPCHECKSUM , CRCMB , CRC8UNI ASM The following routine is called from mcs.lib : _CRC16 The routine must be called with X pointing to the data. The soft stack �Y must contain the number of bytes to scan. On return, R16 and R17 contain the CRC16 value. The used registers are : R16-R19, R25. ;##### X = Crc16(ar(1) , 7) Ldi R24,$07 ; number of bytes St �y, R24 Ldi R26,$64 ; address of ar(1) Ldi R27,$00 ; load constant in register Rcall _Crc16 ; call routine Ldi R26,$60 ; address of X St X+,R16 ; store crc16 LSB St X , R17 ; store CRC16 MSB Example $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim Ar(10) As Byte Dim J As Byte Dim W As Word Dim L As Long Ar(1) = 1 Ar(2) = 2 Ar(3) = 3 J = Crc8(ar(1) , 3) 'calculate value which is 216 W = Crc16(ar(1) , 3) '24881 L = Crc32(ar(1) , 3) '494976085 End CRC16UNI Top Previous Next Action Returns the CRC16 value of a variable or array. Syntax Var = CRC16UNI( source ,length , initial, polynomial,refin,refout) Remarks var The variable that is assigned with the CRC16 of variable source. Should be a word or integer variable. source The source variable or first element of the array to get the CRC16 value from. length The number of bytes to check. initial The initial value of the CRC. This is usual 0 or &HFFFF. polynomial The polynomial value to use. refin Reflect the data input bits. Use 0 to disable this option. Use a non-zero value to enable this option. refout Reflect the data output. Use 0 to disable this option. Use a non-zero value to enable this option. CRC16 is used in communication protocols to check if there are no transmission errors. The 1wire for example returns a CRC byte as the last byte from it�s ID. Use CRC8 for the 1wire routines. There are a lot of different CRC16 routines. There is no real standard since the polynomial will vary from manufacture to manufacture. At http://www.ross.net/crc/download/crc_v3.txt you can find a great document about CRC calculation from Ross N. Williams. At the end you will find an example that is good for dealing with most CRC variations. The BASCOM CRC16UNI function is a conversion of this example. There is a difference however : The CRC16UNI function does not XOR the output bytes. This because most CRC functions XOR with 0. The example will show some of the most used combinations. See also CHECKSUM , CRC8, CRC16 , CRC32 , TCPCHECKSUM , CRCMB , CRC8UNI Example '------------------------------------------------------------------------------ 'name : crc8-16-32.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demonstrates CRC 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no '------------------------------------------------------------------------------ $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Dim Ar(10) As Byte Dim J As Byte Dim W As Word Dim L As Long Dim S As String * 16 S = "123456789" Ar(1) = 1 Ar(2) = 2 Ar(3) = 3 J = Crc8(ar(1) , 3) 'calculate value which is 216 W = Crc16(ar(1) , 3) '24881 L = Crc32(ar(1) , 3) '494976085 ' data , length, intial value , Poly, reflect input, reflect output Print Hex(crc16uni(s , 9 , 0 , &H1021 , 0 , 0)) 'CRC-CCITT (0x0000) 31C3 Print Hex(crc16uni(s , 9 , &HFFFF , &H1021 , 0 , 0)) 'CRC-CCITT (0xFFFF) 29B1 Print Hex(crc16uni(s , 9 , &H1D0F , &H1021 , 0 , 0)) 'CRC-CCITT (0x1D0F) E5CC Print Hex(crc16uni(s , 9 , 0 , &H8005 , 1 , 1)) 'crc16 BB3D Print Hex(crc16uni(s , 9 , &HFFFF , &H8005 , 1 , 1)) 'crc16-modbus 4B37 End CRC32 Top Previous Next Action Returns the CRC32 value of a variable. Syntax Var = CRC32( source , L) Remarks Var The LONG variable that is assigned with the CRC32 of variable source. Source The source variable or first element of the array to get the CRC 32 value from. L The number of bytes to check. This can be a word variable. CRC32 is used in communication protocols to check if there are no transmission errors. See also CHECKSUM , CRC8, CRC16 , CRC16UNI , TCPCHECKSUM , CRCMB , CRC8UNI Example $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim Ar(10) As Byte Dim J As Byte Dim W As Word Dim L As Long Ar(1) = 1 Ar(2) = 2 Ar(3) = 3 J = Crc8(ar(1) , 3) 'calculate value which is 216 W = Crc16(ar(1) , 3) '24881 L = Crc32(ar(1) , 3) '1438416925 End CRCMB Top Previous Next Action Returns the Modbus CRC value of a variable or array. Syntax Var = CRCMB( source , L) Remarks Var The variable that is assigned with the modbus checksum of variable source. This should be a word variable. Source The source variable or first element of the array to get the checksum of. L The number of bytes to check. CRC8 is used in communication protocols to check if there are no transmission errors. The Modbus checksum uses a different polynome. Modbus.lbx or modbus.lib need to be included in your project using the $LIB directive See also CHECKSUM , CRC16, CRC16UNI , CRC32 , TCPCHECKSUM , CRC8 , CRC8UNI Example $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim Ar(10) As Byte Dim W As Word Ar(1) = 1 Ar(2) = 2 Ar(3) = 3 W = CrcMB(ar(1) , 3) 'calculate value Print W End ASC Top Previous Next Action Assigns a numeric variable with the ASCII value of the first character of a string. Syntax var = ASC(string [,index]) Remarks Var Target numeric variable that is assigned. String String variable or constant from which to retrieve the ASCII value. Index An optional index value. The index has a range from 1 to the length of the string. When no index is provided, the default value 1 will be used. Note that only the first character of the string will be used. When the string is empty, a zero will be returned. ASCII stands for American Standard Code for Information Interchange. Computers can only understand numbers, so an ASCII code is the numerical representation of a character such as 'a' or '@' or an action of some sort. ASCII was developed a long time ago and now the non-printing characters are rarely used for their original purpose. Below is the ASCII character table and this includes descriptions of the first 32 non-printing characters. ASCII was actually designed for use with teletypes and so the descriptions are somewhat obscure. If someone says they want your CV however in ASCII format, all this means is they want 'plain' text with no formatting such as tabs, bold or underscoring - the raw format that any computer can understand. This is usually so they can easily import the file into their own applications without issues. Notepad.exe creates ASCII text, or in MS Word you can save a file as 'text only' Extended ASCII As people gradually required computers to understand additional characters and non-printing characters the ASCII set became restrictive. As with most technology, it took a while to get a single standard for these extra characters and hence there are few varying 'extended' sets. The most popular is presented below. See also CHR ASM NONE Example '------------------------------------------------------------------------------ 'name : asc.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demonstrates ASC function 'micro : Mega88 'suited for demo : yes 'commercial addon needed : no '------------------------------------------------------------------------------ $RegFile = "m88def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim A As Byte , S As String * 10 , idx as Byte Print "ASC demo" S = "ABC" A = Asc(s) Print A 'will print 65 print "test with index" a= asc(s,0) : print a 'invalid range will return 0 a= asc(s,2) : print a a= asc(s,100) : print a 'invalid range will return 0 End BCD Top Previous Next Action Converts a variable stored in BCD format into a string. Syntax PRINT BCD( var ) LCD BCD( var) Remarks Var Numeric variable to convert. When you want to use an I2C clock device which stores its values in BCD format you can use this function to print the value correctly. BCD() displays values with a leading zero. The BCD() function is intended for the PRINT/LCD statements. Use the MAKEBCD function to convert variables from decimal to BCD. Use the MAKEDEC function to convert variables from BCD to decimal. See also MAKEDEC , MAKEBCD ASM Calls: _BcdStr Input: X hold address of variable Output: R0 with number of bytes, frame with data. Example '-------------------------------------------------------------------------------- 'name : bcd.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demonstration of split and combine BCD Bytes 'suited for demo : yes 'commercial addon needed : no 'use in simulator : possible '-------------------------------------------------------------------------------- $regfile = "m48def.dat" ' specify the used micro $crystal = 4000000 ' used crystal frequency $baud = 19200 ' use baud rate Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space '=============================================================================== ' Set up Variables '=============================================================================== Dim A As Byte 'Setup A Variable Dim B As Byte 'Setup B Variable Dim C As Byte 'Setup C Variable A = &H89 '=============================================================================== ' Main '=============================================================================== Main: Print "Combined : " ; Hex(a) 'Print A '------------------------------------------------------------------------------- B = A And &B1111_0000 'Mask To Get Only High Nibble Of Byte Shift B , Right , 4 'Shift High Nibble To Low Nibble Position , Store As B C = A And &B0000_1111 'Mask To Get Only Low Nibble Of Byte , Store As C Print "Split : " ; B ; " " ; C 'Print B (High Nibble) , C(low Nibble) '------------------------------------------------------------------------------- Shift B , Left , 4 'Shift Data From Low Nibble Into High Nibble Position A = B + C 'Add B (High Nibble) And C(low Nibble) Together Print "Re-Combined: " ; Hex(a); " " ; Bcd(a) 'Print A (re -combined Byte) End 'End Program BIN Top Previous Next Action Convert a numeric variable into the binary string representation. Syntax Var = Bin(source) Remarks Var The target string that will be assigned with the binary representation of the variable source. Source The numeric variable that will be converted. The BIN() function can be used to display the state of a port. When the variable source has the value &B10100011 the string named var will be assigned with "10100011". It can be easily printed to the serial port. See also HEX , STR , VAL , HEXVAL , BINVAL ASM NONE Example $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim B As Byte ' assign value to B B = 45 Dim S As String * 10 'convert to string S = Bin(b) 'assign value to portb Portb = 33 Print Bin(portb) 'of course it also works for other numerics End BINVAL Top Previous Next Action Converts a string representation of a binary number into a number. Syntax var = Binval( s) Remarks Var A numeric variable that is assigned with the value of s. S Variable of the string type. Should contain only 0 and 1 digits. See also STR , HEXVAL , HEX , BIN , VAL Example $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim S As String * 8 S = "11001100" Dim B As Byte ' assign value to B B = Binval(s) Print B End BIN2GRAY Top Previous Next Action Returns the Gray-code of a variable. Syntax var1 = Bin2gray(var2) Remarks var1 Variable that will be assigned with the Gray code. var2 A variable that will be converted. Gray code is used for rotary encoders. Bin2gray() works with byte , integer, word and long variables. The data type of the variable that will be assigned determines if a byte, word or long conversion will be done. See also GRAY2BIN , ENCODER ASM Depending on the data type of the target variable the following routine will be called from mcs.lbx: _grey2Bin for bytes , _grey2bin2 for integer/word and _grey2bin4 for longs. Example '----------------------------------------------------------------------------------------- 'name : graycode.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : show the Bin2Gray and Gray2Bin functions 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no '----------------------------------------------------------------------------------------- $regfile = "m48def.dat" ' specify the used micro $crystal = 4000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space 'Bin2Gray() converts a byte,integer,word or long into grey code. 'Gray2Bin() converts a gray code into a binary value Dim B As Byte ' could be word,integer or long too Print "BIN" ; Spc(8) ; "GREY" For B = 0 To 15 Print B ; Spc(10) ; Bin2gray(b) Next Print "GREY" ; Spc(8) ; "BIN" For B = 0 To 15 Print B ; Spc(10) ; Gray2bin(b) Next End CHR Top Previous Next Action Convert a numeric variable or a constant to a string with a length of 1 character. The character represents the ASCII value of the numeric value. Syntax PRINT CHR(var) s = CHR(var) Remarks Var Numeric variable or numeric constant. S A string variable. When you want to print a character to the screen or the LCD display, you must convert it with the CHR() function. When you use PRINT numvar, the value will be printed. When you use PRINT Chr(numvar), the ASCII character itself will be printed. The Chr() function is handy in combination with the LCD custom characters where you can redefine characters 0-7 of the ASCII table. Since strings are terminated with a null byte which is the same as Chr(0) , you can not embed a Chr(0) into a string. When using Chr(0) with the LCD to display a customer character, use : LCD "tekst" ; chr(0) ; "more tekst" See also ASC Example '----------------------------------------------------------------------------------------- 'name : chr.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : shows how to use the CHR() and BCD() function and ' HEX() function in combination with a PRINT statement 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no '----------------------------------------------------------------------------------------- $regfile = "m48def.dat" ' specify the used micro $crystal = 4000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim K As Byte K = 65 Print K ; Chr(k) ; K ; Chr(66) ; Bcd(k) ; Hex(k) End FORMAT enhanced 2080 Top Previous Next Action Formats a numeric string. Syntax target = FORMAT(source, "mask") Remarks target The string that is assigned with the formatted string. source The source string that holds the number. mask The mask for formatting the string. When spaces are in the mask, leading spaces will be added when the length of the mask is longer than the source string. " " '8 spaces when source is "123" it will be " 123". When a + is in the mask (after the spaces) a leading + will be assigned when the number does not start with the - (minus) sign. "+" with number "123" will be "+123". When zero's are provided in the mask, the string will be filled with leading zero's. " +00000" with 123 will become " +00123" An optional decimal point can be inserted too: "000.00" will format the number 123 to "001.23" Combinations can be made but the order must be : spaces, + , 0 an optional point and zero's. In version 2080 the mask may be a variable as well. When you do not want to use the overhead of the single or double, you can use the LONG. You can scale the value by a factor for example 100. Then use FORMAT to show the value. For example : Dim L as Long, X as Long , Res as Long L = 1 X = 2 Res = L / X ' Now this would result in 0 because an integer or Long does not support floating point. ' But when you scale L with a factor 100, you get : L = 100 X = 2 Res = L / X '50 Now Res will be 50. To show it the proper way we can use FORMAT. Format works with strings so the variables need to be converted to string first. Dim S1 as string * 16 : s1 = Str(Res) Print Format(s1,"000.00") See also FUSING , STR Example '----------------------------------------------------------------------------------------- 'name : format.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demo : FORMAT 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no '----------------------------------------------------------------------------------------- $regfile = "m48def.dat" ' specify the used micro $crystal = 4000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Dim S As String * 10 Dim I As Integer S = "12345" S = Format(s , "+") Print S ' +12345 S = "123" S = Format(s , "00000") Print S ' 00123 S = "12345" S = Format(s , "000.00") Print S ' 123.45 S = "12345" S = Format(s , "+000.00") Print S ' +123.45 End FUSING Top Previous Next Action FUSING returns a formatted string of a single value. Syntax target = FUSING(source, "mask") Remarks target The string that is assigned with the formatted string. source The source variable of the type SINGLE that will be converted mask The mask for formatting the string. The mask is a string constant that always must start with #. After the decimal point you can provide the number of digits you want the string to have: #.### will give a result like 123.456. Rounding is used when you use the # sign. So 123.4567 will be converted into 123.457 When no rounding must be performed, you can use the & sign instead of the # sign. But only after the DP. #.&&& will result in 123.456 when the single has the value 123.4567 When the single is zero, 0.0 will be returned, no matter how the mask is set up. See also FORMAT , STR , CONFIG SINGLE Example '----------------------------------------------------------------------------------------- 'name : fusing.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demo : FUSING 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no '----------------------------------------------------------------------------------------- $regfile = "m48def.dat" ' specify the used micro $crystal = 4000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Dim S As Single , Z As String * 10 'now assign a value to the single S = 123.45678 'when using str() you can convert a numeric value into a string Z = Str(s) Print Z 'prints 123.456779477 Z = Fusing(s , "#.##") 'now use some formatting with 2 digits behind the decimal point with rounding Print Fusing(s , "#.##") 'prints 123.46 'now use some formatting with 2 digits behind the decimal point without rounding Print Fusing(s , "#.&&") 'prints 123.45 'The mask must start with #. 'It must have at least one # or & after the point. 'You may not mix & and # after the point. End GRAY2BIN Top Previous Next Action Returns the numeric value of a Gray code. Syntax var1 = GRAY2BIN(var2) Remarks var1 Variable that will be assigned with the binary value of the Grey code. var2 A variable in Grey format that will be converted. Gray code is used for rotary encoders. Gray2bin() works for byte, integer, word and long variables. See also BIN2GRAY ASM Depending on the data type of the target variable the following routine will be called from mcs.lbx: _Bin2grey for bytes , _Bin2Grey2 for integer/word and _Bin2grey4 for longs. Example '----------------------------------------------------------------------------------------- 'name : graycode.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : show the Bin2Gray and Gray2Bin functions 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no '----------------------------------------------------------------------------------------- $regfile = "m48def.dat" ' specify the used micro $crystal = 4000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space 'Bin2Gray() converts a byte,integer,word or long into grey code. 'Gray2Bin() converts a gray code into a binary value Dim B As Byte ' could be word,integer or long too Print "BIN" ; Spc(8) ; "GREY" For B = 0 To 15 Print B ; Spc(10) ; Bin2gray(b) Next Print "GREY" ; Spc(8) ; "BIN" For B = 0 To 15 Print B ; Spc(10) ; Gray2bin(b) Next End HEXVAL Top Previous Next Action Convert string representing a hexadecimal number into a numeric variable. Syntax var = HEXVAL( x ) Remarks Var The numeric variable that must be assigned. X The hexadecimal string that must be converted. In VB you can use the VAL() function to convert hexadecimal strings. But since that would require an extra test for the leading &H signs that are required in VB, a separate function was designed. The data may only contain hex decimal characters : 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,a,b,c,d,e,f. Other data will lead to conversion errors. If you need spaces to be filtered you can use the alternative library named hexval.lbx Include it to your code with $LIB "hexval.lbx" and the conversion routine from this library will be used instead of the one from mcs.lbx. The alternative library will also set the ERR flag if an illegal character is found. See also HEX , VAL , STR , BIN , BINVAL Example $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim L As Long Dim S As String * 8 Do Input "Hex value " , S L = Hexval(s) Print L ; Spc(3) ; Hex(l) Loop HEX Top Previous Next Action Returns a string representation of a hexadecimal number. Syntax var = HEX( x ) Remarks var A string variable. X A numeric variable of data type Byte, Integer, Word, Long, Single or Double. See also HEXVAL , VAL , STR , BIN , BINVAL Example $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim B As Byte , J As Integer , W As Word , L As Long B = 1 : J = &HF001 W = &HF001 L = W Print B ; Spc(3) ; Hex(b) Print J ; Spc(3) ; Hex(j) Print W ; Spc(3) ; Hex(w) Print L ; Spc(3) ; Hex(l) End MANCHESTERDEC 2082 NEW Top Previous Next Action This functions decodes a Manchester encoded word into a byte. Syntax target = ManChesterDec(source) Remarks target The byte variables that is assigned with the decoded Manchester value. source A Word variable containing the Manchester encoded value. Manchester encoding (also known as phase encoding) is a line code in which the encoding of each data bit is either low then high, or high then low, for equal time. It is a self-clocking signal with no DC component. Because each input bit is represented as 01 or 10, the resulting data is twice the size of the input data. Manchester encoding is used with RF and IR data transmission. When there is an error in the decoding, register R25 will be set to 255. See also MANCHESTERENC Example '-----------------------PROJECT------------------------------------------------ 'name ManchesterCoding.BAS 'copyright © 2018, MCS 'purpose DEMO MANCHESTER ENCODING and DECODING 'micro M1280 '---------------------------------------------------------------- $regfile = "m1280def.dat" ' specify the uC used $crystal = 32000000 ' Oscillator frequency $hwstack = 40 ' hardware stack $swstack = 40 ' software stack $framesize = 40 ' frame space Dim B As Byte , J As Byte , W As Word For J = 0 To 255 W = Manchesterenc(j) ' encode into manchester code whith results into a WORD B = Manchesterdec(w) ' decode it back If R25 <> 0 Then ' when an error occurs, register r25 is 255 Print "ERROR" End If Print J ; " " ; Hex(w) ; " " ; B Next MANCHESTERENC 2082 NEW Top Previous Next Action This functions encodes a byte into a Manchester encoded word. Syntax target = ManChesterEnc(source) Remarks target A variable with a minimum data length of 2 such as a word. source A byte containing the data to convert. Manchester encoding (also known as phase encoding) is a line code in which the encoding of each data bit is either low then high, or high then low, for equal time. It is a self-clocking signal with no DC component. Because each input bit is represented as 01 or 10, the resulting data is twice the size of the input data. Manchester encoding is used with RF and IR data transmission. See also MANCHESTERDEC Example '-----------------------PROJECT------------------------------------------------ 'name ManchesterCoding.BAS 'copyright © 2018, MCS 'purpose DEMO MANCHESTER ENCODING and DECODING 'micro M1280 '---------------------------------------------------------------- $regfile = "m1280def.dat" ' specify the uC used $crystal = 32000000 ' Oscillator frequency $hwstack = 40 ' hardware stack $swstack = 40 ' software stack $framesize = 40 ' frame space Dim B As Byte , J As Byte , W As Word For J = 0 To 255 W = Manchesterenc(j) ' encode into manchester code whith results into a WORD B = Manchesterdec(w) ' decode it back If R25 <> 0 Then ' when an error occurs, register r25 is 255 Print "ERROR" End If Print J ; " " ; Hex(w) ; " " ; B Next STR Top Previous Next Action Returns a string representation of a number. Syntax var = STR( x [,digits]) Remarks var A string variable. X A numeric variable. digits An options parameter, only allowed for singles and doubles. It specifies how many digits after the comma/point are used. When using with a single, you need to use : CONFIG SINGLE=SCIENTIFIC The string must be big enough to store the result. So if you have a string like this : Dim S as string * 4, and you use it on a single with the value 0.00000001 then there is not enough space in the string to hold the result. Strings that are assigned with Str() should be dimmed 16 characters long. You do not need to convert a variable into a string before you print it. When you use PRINT var, then you will get the same result as when you convert the numeric variable into a string, and print that string. The PRINT routine will convert the numeric variable into a string before it gets printed to the serial port. As the integer conversion routines can convert byte, integer, word and longs into a string it also means some code overhead when you do not use longs. You can include the alternative library named mcsbyte.lbx then. This library can only print bytes. There is also a library for printing integers and words only. This library is named mcsbyteint. When you use these libs to print a long you will get an error message. See also VAL , HEX , HEXVAL , MCSBYTE , BIN , STR2DIGITS , FUSING Difference with VB In VB STR() returns a string with a leading space. BASCOM does not return a leading space. Example Dim A As Byte , S As String * 10 A = 123 S = Str(a) Print S ' 123 'when you use print a, you will get the same result. 'but a string can also be manipulated with the string routines. End STR2DIGITS Top Previous Next Action This statement will convert a string into an array of binary numbers. Syntax STR2DIGITS s , ar(1) Remarks s A string variable that holds a number. For example "12345" ar(1) The first element of a byte array that will be assigned with the binary representation of the digits. After the conversion, the first element will be assigned with the number of processed digits. The next element will become the most right digit of the string, the last element will become the first character of the string. In this example with string "12345" ar(1) = 5 ar(2) = 5 ar(3) = 4 ar(4) = 3 ar(5) = 2 ar(6) = 1 Your array need to be big enough to hold all digits and the digit counter. You can convert a string into a number with VAL() and a number into a string with STR(). In some cases, it is required to have access to all the individual digits of a variable. While you can use a loop and MOD to get all digits, the STR2DIGITS will work for bytes, word, and longs. Non numeric digits will not be converted properly. For example, in a string "-0" , the 0 which is ASCII 48, will be converted into a 0. The - is 45 and will result in 45-48=-3, and in byte form : 253. The dot (.) will be converted into 254. See also STR , VAL Example '------------------------------------------------------------------------------- ' ARDUINO-Duemilanove.BAS ' Also tested with ARDUINO NANO V3.0 ' (c) 1995-2016, MCS Electronics ' This is a sample file for the Mega328P based ARDUINO board ' Select Programmer 'ARDUINO' , 57600 baud and the proper COM port '------------------------------------------------------------------------------- $regfile= "m328pdef.dat" ' used micro $crystal=16000000 ' used xtal $baud=19200 ' baud rate we want config clockdiv=1 ' either use this or change the divider fuse byte '------------------------------------------------------------------------------- dim w as word dim s as string * 6, ar(6) as byte config portb=output ' make portb an output do toggle portb ' toggle level waitms 1000 ' wait 1 sec print "Duemilanove" ' test serial com w=w+1 : s=str(w) ' convert w to a string str2digits s,ar(1) ' convert string into an array with binary numbers loop VAL Top Previous Next Action Converts a string representation of a number into a number. Syntax var = VAL( s) Remarks Var A numeric variable that is assigned with the value of s. S Variable of the string type. It depends on the variable type which conversion routine will be used. Single and Double conversion will take more code space. When you use INPUT, internal the compiler also uses the VAL routines. In order to safe code space, there are different conversion routines. For example BINVAL and HEXVAL are separate routines. While they could be added to the compiler, it would mean a certain overhead as they might never be needed. With strings as input or the INPUT statement, the string is dynamic and so all conversion routines would be needed. The VAL() conversion routine does not check for illegal characters. If you use them you get a wrong result or 0. If you want to check for illegal characters you can add a constant named _VALCHECK to your code with a value of 1. This will include some code that will set the internal ERR variable to 0 or 1. If illegal characters are found, ERR will return 1. Since VAL is used for the INPUT statement too, this will also work for the INPUT statement. See also STR , HEXVAL , HEX , BIN , BINVAL , STR2DIGITS Example $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Dim A As Byte , S As String * 10 S = "123" A = Val(s) 'convert string Print A ' 123 S = "12345678" Dim L As Long L = Val(s) Print L End Example2 $regfile = "m48def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Const _VALCHECK=1 ' TEST VAL() Dim A As Byte , S As String * 10 S = "123" A = Val(s) 'convert string Print A ; " ERR:" ; Err ' 123 S = "1234a5678" Dim L As Long L = Val(s) Print L ; " ERR:" ; Err End CAN Top Previous Next CANBAUD Top Previous Next Action Sets the baud rate of the CAN bus. Syntax CANBAUD = value Remarks All devices on the CAN bus need to have the same baud rate. The value must be a constant. The baud rate depends on the used crystal. The compiler uses the $CRYSTAL value to calculate the CAN baud rate. Higher baud rates require a higher system clock. See also CONFIG CANBUS , CONFIG CANMOB , CANRESET, CANCLEARMOB, CANCLEARALLMOBS, CANSEND, CANRECEIVE , CANID, CANSELPAGE, CANGETINTS Example Canbaud = 125000 ' use 125 KB CANGETINTS Top Previous Next Action Reads the CAN interrupt registers and store into the _CAN_MOBINTS word variable. Syntax CANGETINTS Remarks This statement is intended to be used in the CAN Interrupt routine. It will read the CAN interrupt registers and stores it into a word variable. Multiple Message Objects can cause an interrupt at the same time. This means that all message objects need to be checked for a possible interrupt. In the example this is done with a For Next loop. Cangetints ' read all the interrupts into variable _can_mobints For _can_int_idx = 0 To 14 ' for all message objects If _can_mobints._can_int_idx = 1 Then ' if this message caused an interrupt Canselpage _can_int_idx ' select message object The loop checks all bits and if a message object interrupt has been set, the message object will be selected with CANSELPAGE. See also CONFIG CANBUS , CONFIG CANMOB , CANBAUD, CANRESET, CANCLEARMOB, CANCLEARALLMOBS, CANSEND, CANRECEIVE , CANID, CANSELPAGE Example CANID Top Previous Next Action Returns the ID from the received CAN frame. Syntax value = CANID() Remarks The CANID function can return a 11 bit or 29 bit ID. You need to assign it to a WORD or DWORD variable. The CANID functions works at the current selected MOB and is typically used inside the CAN interrupt. See also CONFIG CANBUS , CONFIG CANMOB , CANBAUD, CANRESET, CANCLEARMOB, CANCLEARALLMOBS, CANSEND, CANRECEIVE , CANSELPAGE, CANGETINTS Example Dim _canid As Dword _canid = Canid() ' read the identifier CANCLEARALLMOBS Top Previous Next Action Clear all Message Objects. Syntax CANCLEARALLMOBS Remarks Use CANCLEARALLMOBS after you reset the CAN controller to set all registers in the proper state. All registers belonging to the MOB will be clear (set to 0). See also CONFIG CANBUS , CONFIG CANMOB , CANBAUD, CANRESET, CANCLEARMOB, CANSEND, CANRECEIVE , CANID, CANSELPAGE, CANGETINTS Example Canclearallmobs ' clear alle message objects CANCLEARMOB Top Previous Next Action Clears a Message Object. Syntax CANCLEARMOB ObjectNr Remarks The ObjectNr is the number of the Message Object you want to clear. This is a number in the range 0-14. A message object need to be cleared before it can be used. CONFIG CANMOB will clear the object by default. You can also use CANCLEARALLMOBS to clear all message objects. See also CONFIG CANBUS , CONFIG CANMOB , CANBAUD, CANRESET, CANCLEARALLMOBS, CANSEND, CANRECEIVE , CANID, CANSELPAGE, CANGETINTS Example CANRECEIVE Top Previous Next Action Receives data from a received CAN frame and stores it into a variable. Syntax numrec = CANRECEIVE(var [, bytes]) Remarks numrec Number of bytes received. var The variable into which the received data is stored. This must be a numeric variable or array. Version 2076 supports strings as well. bytes This is an optional parameter and specifies the number of bytes to retrieve. The compiler will use the data type of the variable to determine how many bytes need to be retrieved. So when you use a variable that was DIMensioned as a long, an attempt will be made to read 4 bytes. The CANRECEIVE function operates on the current selected Message Object which is selected with CANSELPAGE. The CANRECEIVE function is intended to be used inside the CAN interrupt routine. After you have retrieved the data from the received CAN frame, the Message Object is free to be used again. You MUST configure it again in order to receive a new interrupt. See also CONFIG CANBUS , CONFIG CANMOB , CANBAUD, CANRESET, CANCLEARMOB, CANCLEARALLMOBS, CANSEND, CANID, CANSELPAGE, CANGETINTS Example Breceived = Canreceive(porta) ' read the data and store in PORTA Print #2 , "Got : " ; Breceived ; " bytes" ' show what we received Print #2 , Hex(porta) Config Canmob = -1 , Bitlen = 11 , Msgobject = Receive , Msglen = 1 , Autoreply = Disabled , Clearmob = No ' reconfig with value -1 for the current MOB and do not set ID and MASK CANRESET Top Previous Next Action Reset the CAN controller. Syntax CANRESET Remarks CANRESET will reset the CAN controller. It is also reset when the processor is reset. See also CONFIG CANBUS , CONFIG CANMOB , CANBAUD, CANCLEARMOB, CANCLEARALLMOBS, CANSEND, CANRECEIVE , CANID, CANSELPAGE, CANGETINTS Example Canreset ' reset can controller CANSELPAGE Top Previous Next Action Selects the Message Object index or page. Syntax CANSELPAGE index Remarks All 15 message objects share the same registers. With CANSELPAGE you select the index of the MOB you want to access. The index is a constant or variable in the range of 0-14. You should save and restore the CANPAGE register when changing the index. This is shown in the CAN example. See also CONFIG CANBUS , CONFIG CANMOB , CANBAUD, CANRESET, CANCLEARMOB, CANCLEARALLMOBS, CANSEND, CANRECEIVE , CANID, CANGETINTS Example CANSEND Top Previous Next Action Puts the Message Object into Transmit mode and send out data. Syntax status = CANSEND(object, var[,bytes]) Remarks status The status of sending the frame. This should be 0 if there was no problem. If there is an error it will return 1 or higher. The return value is the CANSTMOB register content with the TX bit cleared. object The message object number in the range from 0-14. The MOB must have been configured into the DISABLED mode before CANSEND can be used. var A variable or array which content will be send. The data type of the variable will be used to determine the number of bytes to send. bytes This is an optional value. You can specify how many bytes must be transmitted. The CANSEND function will disable the TX interrupt and then polls the CANSTMOB register for a change of flags. The TX flag is cleared so that a successful transmission returns a 0. In case of ACK errors or other errors, a value other then 0 will be returned. Right after the status has changed, the TX and Error interrupt are enabled again and the CAN interrupt routine is executed. You need to reconfigure the MOB in all cases otherwise you can not send new data. See also CONFIG CANBUS , CONFIG CANMOB , CANBAUD, CANRESET, CANCLEARMOB, CANCLEARALLMOBS, CANRECEIVE , CANID, CANSELPAGE, CANGETINTS Example Have a look at CONFIG CANBUS for a full example. The code below only demonstrates that you MUST configure the MOB again in the interrupt routine. The code below is taken from the sample you find under CONFIG CANBUS Elseif Canstmob.6 = 1 Then 'transmission ready Config Canmob = -1 , Bitlen = 11 , Msgobject = Disabled , Msglen = 1 , Clearmob = No ' reconfig with value -1 for the current MOB and do not set ID and MASK Elseif Canstmob.0 = 1 Then 'ACK ERROR Config Canmob = -1 , Bitlen = 11 , Msgobject = Disabled , Msglen = 1 , Clearmob = No ' reconfig with value -1 for the current MOB and do not set ID and MASK CLEAR Top Previous Next Action Clear serial input or output buffer Syntax CLEAR bufname Remarks Bufname Serial buffer name to clear. SERIALIN, SERIALIN0 - COM1/UART0 input buffer SERIALIN1 - COM2/UART1 input buffer SERIALIN2 - COM3/UART2 input buffer SERIALIN3 - COM4/UART3 input buffer SERIALIN4 - COM5/UART4 input buffer SERIALIN5 - COM6/UART5 input buffer SERIALIN6 - COM7/UART6 input buffer SERIALIN7 - COM8/UART7 input buffer SERIALOUT,SERIALOUT0 - COM1/UART0 output buffer SERIALOUT1 - COM2/UART1 output buffer SERIALOUT2 - COM3/UART2 output buffer SERIALOUT3 - COM4/UART3 output buffer SERIALOUT4 - COM5/UART4 output buffer SERIALOUT5 - COM6/UART5 output buffer SERIALOUT6 - COM7/UART6 output buffer SERIALOUT7 - COM8/UART7 output buffer When you use buffered serial input or buffered serial output, you might want to clear the buffer. While you can make the head pointer equal to the tail pointer, an interrupt could be active which might result in an update of the buffer variables, resulting in an unexpected result. The CLEAR statement will reset the head and tail pointers of the ring buffer, and it will set the buffer count variable to 0. The buffer count variable is new and introduced in 1.11.8.3. It counts how many bytes are in the buffer. The internal buffercount variable is named _RS_BUFCOUNTxy , where X is R for Receive, and W for Write, and y is 0 for the first UART, and 1 for the second UART. See also CONFIG SERIALIN, CONFIG SERIALOUT ASM Calls _BUF_CLEAR from MCS.LIB Example CLEAR SERIALIN CLOCKDIVISION Top Previous Next Action Will set the system clock division available in some MEGA chips. Syntax CLOCKDIVISON = var Remarks Var Variable or numeric constant that sets the clock division. Valid values are from 2-129. A value of 0 will disable the division. On the MEGA 103 and 603 the system clock frequency can be divided so you can save power for instance. A value of 0 will disable the clock divider. The divider can divide from 2 to 127. So the other valid values are from 2 - 127. Some routines that rely on the system clock will not work proper anymore when you use the divider. WAITMS for example will take twice the time when you use a value of 2. Most new processors support a limited number of division factors which can be selected using CONFIG CLOCKDIV. See also POWERSAVE , CONFIG CLOCKDIV Example $regfile = "m103def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Clockdivision = 2 CLOSE Top Previous Next Action Closes an opened device. Syntax OPEN "device" for MODE As #channel CLOSE #channel Remarks Device The default device is COM1 and you don't need to open a channel to use INPUT/OUTPUT on this device. With the implementation of the software UART, the compiler must know to which pin/device you will send/receive the data. So that is why the OPEN statement must be used. It tells the compiler about the pin you use for the serial input or output and the baud rate you want to use. COMB.0:9600,8,N,2 will use PORT B.0 at 9600 baud with 2 stop bits. The format for COM1 is : COM1: Some chips have 2 UARTS. You can use COM2: to open the second HW UART. Other chips might have 4 or 8 UARTS. The format for the software UART is: COMpin:speed,8,N,stop bits[,INVERTED] Where pin is the name of the PORT-pin. Speed must be specified and stop bits can be 1 or 2. An optional parameter ,INVERTED can be specified to use inverted RS-232. Open "COMD.1:9600,8,N,1,INVERTED" For Output As #1 , will use pin PORTD.1 for output with 9600 baud, 1 stop bit and with inverted RS-232. MODE You can use BINARY or RANDOM for COM1 and COM2, but for the software UART pins, you must specify INPUT or OUTPUT. Channel The number of the channel to open. Must be a positive constant >0. The statements that support the device are PRINT , INPUT and INPUTHEX , INKEY, WAITKEY. Using CLOSE on a serial device is optional. Only a file as used with AVR-DOS requires a CLOSE. The best place for the CLOSE statement is at the end of your program. The INPUT statement in combination with the software UART, will not echo characters back because there is no default associated pin for this. For the AVR-DOS file system, you may place the CLOSE at any place in your program. This because the file system supports real file handles. For the UART, SPI or other devices, you do not need to close the device. Only AVR-DOS needs a CLOSE so the file will be flushed. See also OPEN , PRINT Example '----------------------------------------------------------------------------------------- 'name : open.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demonstrates software UART 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no '----------------------------------------------------------------------------------------- $regfile = "m48def.dat" ' specify the used micro $crystal = 10000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Dim B As Byte 'Optional you can fine tune the calculated bit delay 'Why would you want to do that? 'Because chips that have an internal oscillator may not 'run at the speed specified. This depends on the voltage, temp etc. 'You can either change $CRYSTAL or you can use 'BAUD #1,9610 'In this example file we use the DT006 from www.simmstick.com 'This allows easy testing with the existing serial port 'The MAX232 is fitted for this example. 'Because we use the hardware UART pins we MAY NOT use the hardware UART 'The hardware UART is used when you use PRINT, INPUT or other related statements 'We will use the software UART. Waitms 100 'open channel for output Open "comd.1:19200,8,n,1" For Output As #1 Print #1 , "serial output" 'Now open a pin for input Open "comd.0:19200,8,n,1" For Input As #2 'since there is no relation between the input and output pin 'there is NO ECHO while keys are typed Print #1 , "Number" 'get a number Input #2 , B 'print the number Print #1 , B 'now loop until ESC is pressed 'With INKEY() we can check if there is data available 'To use it with the software UART you must provide the channel Do 'store in byte B = Inkey(#2) 'when the value > 0 we got something If B > 0 Then Print #1 , Chr(b) 'print the character End If Loop Until B = 27 Close #2 Close #1 'OPTIONAL you may use the HARDWARE UART 'The software UART will not work on the hardware UART pins 'so you must choose other pins 'use normal hardware UART for printing 'Print B 'When you dont want to use a level inverter such as the MAX-232 'You can specify ,INVERTED : 'Open "comd.0:300,8,n,1,inverted" For Input As #2 'Now the logic is inverted and there is no need for a level converter 'But the distance of the wires must be shorter with this End COMPARE new 2080 Top Previous Next Action This function performs a byte compare on two variables. Syntax result = COMPARE( var1, var2, bytes) Remarks result A word variable that is assigned with the result of the function. When the 2 variables are equal, the value will be 0. When the 2 variables differ, the index is returned of the position that differs. var1 , var2 Any kind of variable like a long or string. Constants are not supported. Bytes The number of bytes to test. The maximum value must fit into a word. (65535). See also NONE Example '------------------------------------------------------------------------- 'name : compare.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demonstrates byte COMPARE function, written by MWS 'micro : Mega88 'suited for demo : yes 'commercial addon needed : no '------------------------------------------------------------------------- ' purpose: byte-wise compare ' arg Val1: first value to compare, type = don't care ' arg Val2: second value to compare, type = don't care ' arg BtComp: count of bytes to compare, can be a constant or a variable ' range is 1 to 65535 bytes ' result: zero if all bytes within range of BtComp are matching ' 1 up to BtComp if there's a miss, ' zero is used for signaling a comlete match, so Config Base has no effect ' 1 is always the first byte of the variable, whatever type of variable it is '------------------------------------------------------------------------- $regfile = "m328pdef.dat" $crystal = 16000000 $hwstack = 40 $swstack = 32 $framesize = 32 Const Testver = 2 ' edit for different tests 0,1 or 2 Dim Mmpos As Word ' dimension word var to hold the result, i.e. mismatch position Dim btt As Word ' bytes to test #if Testver = 0 Dim Val_a(8) As Byte ' byte array vs. byte array Dim Val_b(8) As Byte ' arrays are initialyzed 0 Btt = 8 Val_a(4) = 1 ' test it #elseif Testver = 1 Dim Val_a As Double ' Double vs. byte array Dim Val_b(8) As Byte Btt = 8 Val_b(2) = 1 ' test it #elseif Testver = 2 ' compare strings Dim Val_a As String * 16 Dim Val_b As String * 16 Btt = 12 Val_a = "Hello Bascom" Val_b = "Hello Bascon" ' find the mismatch #endif Mmpos = Compare(val_a , Val_b , Btt) If Mmpos > 0 Then Print "We have a miss at pos: " ; Mmpos Else Print "Match!" End If End CONFIGURATION Top Previous Next CONFIG Top Previous Next The CONFIG statement is used to configure the various hardware devices. DIRECTIVE RE-USABLE XMEGA ONLY CONFIG 1WIRE NO CONFIG ACXX YES X CONFIG ACI YES CONFIG ADC NO CONFIG ADCx YES X CONFIG ATEMU NO CONFIG BASE NO CONFIG BCCARD NO CONFIG CANBUS YES CONFIG CANMOB YES CONFIG CLOCK NO CONFIG CLOCKDIV YES CONFIG COM1 YES CONFIG COM2 also COM3 - COM8 YES CONFIG DAC YES X CONFIG DATE NO CONFIG DCF77 NO CONFIG DEBOUNCE NO CONFIG DMA YES X CONFIG DMACHx YES X CONFIG DMXSLAVE NO CONFIG DP NO CONFIG EDMA x CONFIG EDMAx x CONFIG EEPROM NO X CONFIG ERROR NO CONFIG EVENT_SYSTEM YES X CONFIG EXTENDED_PORT NO CONFIG FT800 2080 UPDATED NO CONFIG GRAPHLCD NO CONFIG HITAG NO CONFIG I2CBUS YES CONFIG I2CDELAY NO CONFIG I2CSLAVE NO CONFIG INPUT NO CONFIG INPUTBIN 2080 NEW NO CONFIG INTx YES CONFIG INTVECTORSELECTION YES CONFIG KBD NO CONFIG KEYBOARD NO CONFIG LCD NO CONFIG LCDBUS NO CONFIG LCDMODE NO CONFIG LCDPIN NO CONFIG OSC YES X CONFIG PORT YES CONFIG POWERMODE YES CONFIG POWER_REDUCTION NO X CONFIG PRIORITY YES X CONFIG PRINT NO CONFIG PRINTBIN NO CONFIG PS2EMU NO CONFIG RAINBOW 2079 NEW NO CONFIG RC5 NO CONFIG RND NO CONFIG SERIALIN NO CONFIG SERIALIN1 NO CONFIG SERIALIN2 NO CONFIG SERIALIN3 NO CONFIG SERIALOUT NO CONFIG SERIALOUT1 NO CONFIG SERIALOUT2 NO CONFIG SERIALOUT3 NO CONFIG SERVOS NO CONFIG SHIFTIN NO CONFIG SINGLE YES CONFIG SDA NO CONFIG SCL NO CONFIG SPI NO CONFIG SPIx YES X CONFIG SUBMODE NO CONFIG SYSCLOCK YES X CONFIG TCXX YES X CONFIG TCPIP NO CONFIG TWI YES CONFIG TWISLAVE NO CONFIG TWIxSLAVE NO x CONFIG TIMER0 YES CONFIG TIMER1 YES CONFIG TIMER2 and 3 YES CONFIG USB NO CONFIG USI NO CONFIG VPORT YES X CONFIG WATCHDOG YES CONFIG WAITSUART NO CONFIG X10 NO CONFIG XPIN YES CONFIG XRAM YES Some CONFIG directives are intended to be used once. Others can be used multiple times. For example you can specify that a port must be set to input after you have specified that it is used as an input. You cannot change the LCD pins during run time. In that case the last specification will be used or an error message will be displayed. Some Configuration commands are only available to the Xmega. An X in the 'Xmega Only' indicates that the command can only be used for an Xmega processor. CONFIG 1WIRE Top Previous Next Action Configure the pin to use for 1WIRE statements and override the compiler setting. Syntax CONFIG 1WIRE = pin [, extended=0|1] Remarks Pin The port pin to use such as PORTB.0 extended An optional constant value of 0 or 1. This is an optional parameter The CONFIG 1WIRE statement overrides the compiler setting. It is the preferred that you use it. This way the setting is stored in your source code. You can configure only one pin for the 1WIRE statements because the idea is that you can attach multiple 1WIRE devices to the 1WIRE bus. You can however use multiple pins and thus multiple busses. All 1wire commands and functions need the port and pin in that case. A CONFIG 1WIRE statement is not need in that case either. The 1wire commands and function will automatically set the DDR and PORT register bits to the proper state. You do not need to bring the pins into the right state yourself. It is important that you use a pull up resistor of 4K7 ohm on the 1wire pin(for 5V VCC). The pull up resistor of the AVR is not sufficient. Also notice that some 1wire chips also need +5V. 1 wire is just marketing since you need GND anyway. The least is 2 wires and typical you need 3 wires. Extended The extended option is only required when you use multiple busses/pins and if these pins mix normal and extended addresses. Let's clear that up. When the 1wire code was written in 1995 all the port addresses were normal I/O addresses. These are addresses that fit in the I/O space (address < &H60). To save code, register R31 was cleared in the library and the port register was passed in R30. When Atmel introduced the extended I/O registers with address >&HFF, it was possible to set R31 to a fixed value when the user port was an extended I/O address. But when you want to mix the addresses, there is no other way then to pass the word address of the I/O register to the library code. And that is exactly what EXTENDED=1 will do. It will use more code. This support was written for a customer that already made his PCB's. We do advise to use the same port when you use multiple pins. ATMEGA128 PORTF The ATMEGA128 PORTF is split up. Normally, the DDR, PIN and PORT registers are in the same order. For example : PORTB = &H18 , DDRB = &H17 and PINB = &H16 But PORTF in the MEGA128 is different : PINF = &H00 , PORTF = &H62 , DDRF = &H61 You need a special library named M128-1wire-PortF.lib for this processor and port. This library is fixed to portF See also 1WRESET , 1WREAD , 1WWRITE , 1WIRECOUNT , 1WRESET , 1WSEARCHFIRST , 1WSEARCHNEXT Example '-------------------------------------------------------------------------------- 'name : 1wire.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demonstrates 1wreset, 1wwrite and 1wread() 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no ' pull-up of 4K7 required to VCC from Portb.2 ' DS2401 serial button connected to Portb.2 '-------------------------------------------------------------------------------- $regfile = "m48def.dat" $crystal = 8000000 $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 'default use 10 for the SW stack $framesize = 40 'default use 40 for the frame space Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 'when only bytes are used, use the following lib for smaller code $lib "mcsbyte.lib" Config 1wire = Portb.0 'use this pin 'On the STK200 jumper B.0 must be inserted Dim Ar(8) As Byte , A As Byte , I As Byte Do Wait 1 1wreset 'reset the device Print Err 'print error 1 if error 1wwrite &H33 'read ROM command For I = 1 To 8 Ar(i) = 1wread() 'place into array Next 'You could also read 8 bytes a time by unremarking the next line 'and by deleting the for next above 'Ar(1) = 1wread(8) 'read 8 bytes For I = 1 To 8 Print Hex(ar(i)); 'print output Next Print 'linefeed Loop 'NOTE THAT WHEN YOU COMPILE THIS SAMPLE THE CODE WILL RUN TO THIS POINT 'THIS because of the DO LOOP that is never terminated!!! 'New is the possibility to use more than one 1 wire bus 'The following syntax must be used: For I = 1 To 8 Ar(i) = 0 'clear array to see that it works Next 1wreset Pinb , 2 'use this port and pin for the second device 1wwrite &H33 , 1 , Pinb , 2 'note that now the number of bytes must be specified! '1wwrite Ar(1) , 5,pinb,2 'reading is also different Ar(1) = 1wread(8 , Pinb , 2) 'read 8 bytes from portB on pin 2 For I = 1 To 8 Print Hex(ar(i)); Next 'you could create a loop with a variable for the bit number ! For I = 0 To 3 'for pin 0-3 1wreset Pinb , I 1wwrite &H33 , 1 , Pinb , I Ar(1) = 1wread(8 , Pinb , I) For A = 1 To 8 Print Hex(ar(a)); Next Print Next End Xmega Example '-------------------------------------------------------------------------------- 'name : XM128-1wire.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demonstrates 1wreset, 1wwrite and 1wread() 'micro : Xm128A1 'suited for demo : no 'commercial addon needed : no ' pull-up of 4K7 required to VCC from Portb.0 ' DS2401 serial button connected to Portb.0 '-------------------------------------------------------------------------------- $regfile = "xm128a1def.dat" $crystal = 32000000 $lib "xmega.lib" : $external _xmegafix_clear : $external _xmegafix_rol_r1014 $hwstack = 32 ' default use 32 for the hardware stack $swstack = 32 'default use 10 for the SW stack $framesize = 32 'default use 40 for the frame space 'First Enable The Osc Of Your Choice Config Osc = Enabled , 32mhzosc = Enabled 'configure the systemclock Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 'configure UART Config Com1 = 19200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 'configure 1wire pin Config 1wire = Portb.0 'use this pin Dim Ar(8) As Byte , A As Byte , I As Byte Print "start" A = 1wirecount() Print A ; " devices found" 'get first Ar(1) = 1wsearchfirst() For I = 1 To 8 'print the number Print Hex(ar(i)); Next Print Do 'Now search for other devices Ar(1) = 1wsearchnext() ' get next device For I = 1 To 8 Print Hex(ar(i)); Next Print Loop Until Err = 1 Waitms 2000 Do 1wreset 'reset the device Print Err 'print error 1 if error 1wwrite &H33 'read ROM command ' Ar(1) = 1wread(8) you can use this instead of the code below For I = 1 To 8 Ar(i) = 1wread() 'place into array Next For I = 1 To 8 Print Hex(ar(i)); 'print output Next Print 'linefeed Waitms 1000 Loop End CONFIG ACI Top Previous Next Action Configures the Analog Comparator. Syntax CONFIG ACI = ON|OFF, COMPARE = ON|OFF, TRIGGER=TOGGLE|RISING|FALLING Remarks ACI Can be switched on or off COMPARE Can be on or off. When switched ON, the TIMER1 in capture mode will trigger on ACI too. TRIGGER Specifies which comparator events trigger the analog comparator interrupts. See also NONE Example NONE CONFIG ACXX Top Previous Next Action Configures the Analog Comparator of the Xmega. Syntax CONFIG ACXX = state, TRIGGER=trigger, HISPEED=speed, HYSMODE=hys , MUXPLUS=mp , MUXMIN=mm , OUTPUT=otp , SCALE=scale , WINDOW=w , WINTMODE = wint Remarks ACXX The name of the Analog comparator : ACA0,ACA1, ACB0 or ACB1 Some XMEGA chips might not have (all) comparators. State ON or OFF. Select ON to turn the comparator on. By default it is off. HiSpeed When ENABLED, the comparator hi speed mode is activated. Default mode is DISABLED. Trigger Specifies which comparator event triggers the analog comparator interrupts. This options are : RISING, FALLING or BOTH / TOGGLE. Hysmode To prevent quick toggling, a hysteresis is built in. You can chose the mode : - OFF - SMALL - LARGE MuxPlus This option controls which pin is connected to the positive input of the comparator. Possible values : 0-7, DAC. When you chose 7, DAC will also be used. So 7 and DAC are equivalent. MuxMin This option controls which pin is connected to the negative input of the comparator. Possible values : 0-7, DAC, BANDGAP, SCALER. 0 - connects pin 0 1 - connects pin 1 2 - connects pin 3 ! 3 - connects pin 5 4 - connects pin 7 5 - connects the DAC output (same as DAC option) 6 - connects the BANDGAP voltage (same as BANDGAP option) 7 - connects the SCALER output (same as SCALE option) Output Enabled or Disabled (default). When the output is enabled, the output of the comparator is routed to pin 7 of the port. For ACA1 the output is routed to the AC1OUT pin if the Xmega supports this. Scale The input voltage of the negative mux pin can be scaled. The scale value must be in range from 0-63. The scale output voltage is calculated as : (vcc * (scale+1)) / 64 Thus a value of 63 would give VCC. And 32 would give vcc/2 Windows Enabled or Disabled (default). When enabled, the two comparators of the port (ACA0 + ACA1) or (ACB0 + ACB1) form a window discriminator so you can control if a voltage is in the range of the lower and upper comparator. WintMode The status register contains the window state. (bit 6 and 7). You can also fire an interrupt at one of the states: ABOVE : interrupt on signal above window INSIDE : interrupt on signal inside window BELOW : interrupt on signal below window OUTSIDE : interrupt on signal outside window A window is used in battery voltage meters. you could set the lower voltage to 12 V. And the upper voltage to 14 V. If the voltage is inside this window : >=12V and <=14V then the battery is OK. If the voltage is below the battery need to be charged. If the voltage is above the window the battery if fully charged. The mentioned values are just an example. See also NONE Example '----------------------------------------------------------------- ' (c) 1995-2016, MCS ' xm128-AC.bas ' This sample demonstrates the Analog Comparator '----------------------------------------------------------------- $regfile = "xm128a1def.dat" $crystal = 32000000 $hwstack = 64 $swstack = 64 $framesize = 64 'include the following lib and code, the routines will be replaced since they are a workaround $lib "xmega.lib" $external _xmegafix_clear $external _xmegafix_rol_r1014 'First Enable The Osc Of Your Choice , make sure to enable 32 KHz clock or use an external 32 KHz clock Config Osc = Enabled , 32mhzosc = Enabled 'configure the systemclock Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 Config Com1 = 19200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 'setup comparator pin 0 and pin 1 are the input of portA. Pin 7 is an output in this sample Config Aca0 = On , Hysmode = Small , Muxplus = 0 , Muxmin = 1 , Output = Enabled Do Print Bin(aca_status) Print Aca_status.4 ' output ac0 Waitms 1000 Loop CONFIG ADC Top Previous Next Action Configures the A/D converter. Syntax CONFIG ADC = single, PRESCALER = AUTO, REFERENCE = opt Remarks ADC Running mode. May be SINGLE or FREE. This is the converter mode and has nothing to do with single ended or differential input mode. PRESCALER A numeric constant for the clock divider. Use AUTO to let the compiler generate the best value depending on the XTAL REFERENCE The options depend on the used micro. Some chips like the M163 have additional reference options. In the definition files you will find : ADC_REFMODEL = x This specifies which reference options are available. The possible values are listed in the table below. Chip Modes ADC_REFMODEL 2233,4433,4434,8535,m103,m603, m128103 OFF AVCC 0 m165, m169, m325,m3250, m645, m6450, m329,m3290, m649, m6490,m48,m88,m168 OFF AVCC INTERNAL or INTERNAL_1.1 1 tiny15,tiny26 AVCC OFF INTERNAL INTERNALEXTCAP 2 tiny13 AVCC INTERNAL 3 tiny24,tiny44,tiny84 AVCC EXTERNAL or OFF INTERNAL or INTERNAL_1.1 4 m164,m324,m644,m640,m1280, m1281,m2561,m2560 AREF or OFF AVCC INTERNAL1.1 INTERNAL_2.56 5 tiny261,tiny461,tiny861, tiny25,tiny45,tiny85 AVCC EXTERNAL or OFF INTERNAL_1.1 INTERNAL_2.56_NOCAP INTERNAL_2.56_EXTCAP 7 CAN128, PWM2_3,USB1287, m128, m16, m163, m32, m323, m64 AREF or OFF AVCC INTERNAL or INTERNAL_2.56 8 You may also use VALUE=value When you use VALUE=value, you may specify any value. The disadvantage is that when you port your code from one chip to another it will not work. While the AREF, AVCC, etc. are all converted to the right settings, the value can not be converted. The AD converter is started automatic when you use the CONFIG ADC command. You can use STOP ADC and START ADC to disable and enable the power of the AD converter. The GETADC() function is intended to be used with the SINGLE running mode. This means that each time you call GETADC(), a conversion is started. If you use the free running mode, you need to retrieve the value from the AD converter yourself. For example by reading the internal ADC word variable. See also GETADC , CONFIG ADCx Example '-------------------------------------------------------------------------------- 'name : adc.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demonstration of GETADC() function for 8535 or M163 micro 'micro : Mega163 'suited for demo : yes 'commercial addon needed : no 'use in simulator : possible ' Getadc() will also work for other AVR chips that have an ADC converter '-------------------------------------------------------------------------------- $regfile = "m163def.dat" ' we use the M163 $crystal = 4000000 $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 'default use 10 for the SW stack $framesize = 40 'default use 40 for the frame space 'configure single mode and auto prescaler setting 'The single mode must be used with the GETADC() function 'The prescaler divides the internal clock by 2,4,8,16,32,64 or 128 'Because the ADC needs a clock from 50-200 KHz 'The AUTO feature, will select the highest clockrate possible Config Adc = Single , Prescaler = Auto 'Now give power to the chip Start Adc ' NOT required since it will start automatic 'With STOP ADC, you can remove the power from the chip 'Stop Adc Dim W As Word , Channel As Byte Channel = 0 'now read A/D value from channel 0 Do W = Getadc(channel) Print "Channel " ; Channel ; " value " ; W Incr Channel If Channel > 7 Then Channel = 0 Loop End 'The new M163 has options for the reference voltage 'For this chip you can use the additional param : 'Config Adc = Single , Prescaler = Auto, Reference = Internal 'The reference param may be : 'OFF : AREF, internal reference turned off 'AVCC : AVCC, with external capacitor at AREF pin 'INTERNAL : Internal 2.56 voltage reference with external capacitor ar AREF pin 'Using the additional param on chip that do not have the internal reference will have no effect. CONFIG ADCx Top Previous Next Action Configures the A/D converter of the Xmega. See also ATXMEGA for base info on ATXMEGA. Syntax CONFIG ADCA | ADCB = mode, CONVMODE=sign, RESOLUTION=res, DMA=dma, REFERENCE=ref,EVENT_MODE=evt, EVENT_CHANNEL=evtchan, PRESCALER=pre, BANDGAP=gap, TEMPREF=tref, SWEEP=sweep, CH0_GAIN=gain, CH0_INP= inp, MUX0=mux, CH1_GAIN=gain, CH1_INP= inp, MUX1=mux , CH2_GAIN=gain, CH2_INP= inp, MUX2=mux, CH3_GAIN=gain, CH3_INP= inp, MUX3=mux Remarks mode Running mode. May be SINGLE or FREE. sign The conversion mode. This can be SIGNED or UNSIGNED. When choosing SIGNED you should assign the result to an integer. When choosing UNSIGNED you should assign the result to a word. The default is UNSIGNED. When the ADC uses differential input, SIGNED mode must be used, when using single ended input both signed or UNSIGNED mode can be used. Note: · Conversion mode is configured for the whole ADC, not individually for each channel, which means that the ADC must be put in the signed mode even if only one of the channels uses differential inputs. · Negative values are not negative inputs on the IO pins, but higher voltage level on the negative input in respect to the positive input. Even though the resulting value can be negative. For example +1.4 V on negative Input and +0.3 V on positive input is OK. · Do not apply Voltages below GND or above VCC !! res The resolution of the conversion. Valid values are : - 8BIT - 12BIT. This is the default - LEFT12BIT. This will result in a left aligned 21 bit value. dma If you want to use the DMA channel, you can select which DMA channels must be used: - OFF (no DMA) - CH01 (channel 0 + 1) - CH012 (channel 0 + 1 + 2) - CH0123 (channel 0 + 1 + 2 + 3) ref Selects the reference to use. Valid options : - INT1V. For internal 1V reference - INTVCC. For internal voltage divided by 1.6 - AREFA. External reference from AREF pin on PORT A. - AREFB. External reference from AREF pin on PORT B. gap Enables the bangap reference. Use ENABLED or DISABLED. Setting this bit enables the bandgap to prepare for ADC measurement. Note that if any other functions are using the bandgap already, this bit does not need to be set. This could be when the internal 1V reference is used in ADC or DAC, or if the Brown-out Detector is enabled. tref Enables the temperature reference. Use ENABLED or DISABLED. Setting this bit enables the temperature reference to prepare for ADC measurement sweep Selects which channels are included in a sweep when a channel sweep is triggered by the event system or in the free running mode. Valid options : - CH0 : channel 0 included - CH01 : channel 0 and 1 included - CH012 : channel 0-2 included - CH0123 : all channels are included evtchan Event channel selection. This selects which channel should trigger which ADC channel. Valid options: - CH0123. Event channel 0, 1, 2, 3 as selected inputs - CH1234. Event channel 1, 2, 3, 4 as selected inputs - CH2345. Event channel 2,3, 4, 5 as selected inputs - CH3456. Event channel 3, 4, 5, 6 as selected inputs - CH4567. Event channel 4, 5, 6, 7 as selected inputs - CH456. Event channel 4, 5, 6 as selected inputs - CH67. Event channel 6 and 7 as selected inputs - CH7. Event channel 7 as selected input evt Event channel mode selection. This selects how many of the selected event channel are in use. Valid options: - NONE. Event system is not used - CH0. Event channel with the lowest number, defined by evtchan triggers conversion on channel 0 - CH01. Event channel with the two lowest numbers, defined by evtchan trigger conversion on channel 0 and 1 respectively - CH012. Event channel with the three lowest numbers, defined by evtchan trigger conversion on channel 0, 1 and 2 respectively - CH0123. Event channel defined by evtchan trigger conversion on channel 0, 1, 2 and 3 respectively - SWEEP. One sweep of all active ADC channels defined by SWEEP on incoming event channel with the lowest number, defined by evtchan - SYNCSWEEP. One sweep of all active ADC channels defined by SWEEP on incoming event channel with the lowest number, defined by evtchan. In addition, the conversion will be synchronized on event to ensure a very accurate timing for the conversion. pre Prescaler value. The prescaler divides the system clock and applies it to the A/D converter. Valid prescaler values : - 4, 8, 16, 32, 64, 128, 256 and 512 gain Each of the 4 channels can have a different gain. Valid values are : 1,2,4,8,16,32 and 64 inp Each of the 4 channels can have a different mode. The 4 modes are : - INTERNAL. For example for temperature measurement - SINGLE_ENDED. For measuring positive voltages - DIFF. For differential input without gain which allows to measure negative voltages. - DIFFWGAIN. Same as DIFF but with gain. mux Selects the MUX to use with the channel. This must be a numeric constant. The value depends on the mode. See details below under How to selcect the MUX to use with the channel. At run time you can change the ADCx_CHy_MUXCTRL register. Where x is A or B, and y is the channel 0-3. XMEGA chips are grouped into different families. For example the features of an A-family device differ from a B-family or D-family device. An example for a A-family device is ATXMEGA128A1. The following table show the differences of the different XMEGA families: AVR XMEGA A AVR XMEGA B AVR XMEGA D ADCA Yes Yes Yes ADCB Yes Yes - - Channel 0 Yes Yes Yes Channel 1 Yes - - - - Channel 2 Yes - - - - Channel 3 Yes - - - - Architecture Pipelined Cyclic Cyclic Max ADC frequency 2MHz 1.4Mhz 1.4MHz Single propagation ADC cycles number (12 bits) 7 7 7 Single propagation ADC cycles number (8 bits) 5 5 5 Max sample per second (12 bits) 2Msps 200Ksps 200Ksps ADC result to DMA Yes Yes - - SWEEP mode (channel sweep) Yes - - - - Number of Internal inputs 4 3 3 Internal inputs Temp, Vcc/10, Bandgap, DAC Temp, Vcc/10, Bandgap Temp, Vcc/10, Bandgap x 0.5 Gain - - Yes - - Voltage reference = INTVCC/2 - - Yes - - The XMEGA A-family ADC conversion block has a 12-stage pipelined architecture capable of sampling several signals almost parallel. There are four input selection multiplexers with individual configurations. The separate configuration settings for the four multiplexers can be viewed as virtual channels, with one set of result registers each, all sharing the same ADC conversion block. ADC overview of XMEGA AU (Xmega with USB): So with the pipelined structure, four basic elements (Virtual Channels) can be used at the same time. Each signal propagates through the 12-stage pipelined ADC Block (12-stage for 12-Bit), where one bit is converted at each stage. The propagation time for one single 12-Bit signal conversion through the pipeline is 7 ADC clock cycles for 12-bit conversions. If Gain is used the propagation time increases by one cycle. When free running mode is configured an ADC channel will continuously sample and do new conversions. 12-Bit = [MSB , Bit 10 , Bit 9 , Bit 8, Bit 7 , Bit 6, Bit 5, Bit 4, Bit 3, Bit 2, Bit 1, LSB] If 4 Virtual ADC Channels are used the pipelined architecture will work as following: ADC Clock Cycle 1: Start Ch0 without gain ADC Clock Cycle 2: Channel 0 MSB (Bit11) ADC Clock Cycle 3: Channel 0 Bit9, Channel 1 MSB ADC Clock Cycle 4: Channel 0 Bit7, Channel 1 Bit9, Channel 2 MSB ADC Clock Cycle 5: Channel 0 Bit5, Channel 1 Bit7, Channel 2 Bit9, Channel 3 MSB ADC Clock Cycle 6: Channel 0 Bit3, Channel 2 Bit5, Channel 2 Bit7, Channel 3 Bit9 ADC Clock Cycle 7: Channel 0 Bit1, Channel 2 Bit3, Channel 2 Bit5, Channel 3 Bit7 ADC Clock Cycle 8: Channel 0 LSB ADC Clock Cycle 9: Channel 0 conversion complete ...... ADC Clock Cycle 10 Channel 1 conversion complete .... .... ..... The even elements (0, 2, 4 �) of 12-stage pipelined ADC Block will be enabled during the high level of the ADC clock, and the odd elements (1, 3 , 5 �) of 12-stage pipelined ADC Block will be enabled during the low level of the ADC clock. After four ADC clock cycles all 4 ADC channels have done the first sample bit (the MSB). For further details see Atmel Application Notes and data sheets. If real simultaneous conversions are needed on different channels then you need to use 2 ADC's. For example Channel 0 of ADCA and Channel 0 of ADCB an A-family device can be measured absolute simultaneously. Selectable voltage input types: � Differential measurement without gain The ADC must be in signed mode when differential input is used Pin 0...Pin 7 can be selected as positive input Pin 0...Pin 3 can be sleected as negative input ' ' +--------------+ ' | | ' Pina.0 -----+ differnential| ' | without gain | ' | | ' Pina.1 -----+ ADC | ' | | ' +--------------+ ' · Differential measurement with gain The gain is selectable to 1/2x, 1x, 2x, 4x, 8x, 16x, 32x and 64x gain The ADC must be in signed mode when differential input is used Pin 0...Pin 7 can be selected as positive input Pin 4...Pin 7 can be sleected as negative input ' ' +--------------+ ' | | ' Pina.0 -----+ differnential| ' | with gain | ' | | ' Pina.4 -----+ ADC | ' | | ' +--------------+ ' � Single ended input (signed mode) The ADC is differential, so for single ended measurements the negative input is connected to a fixed internal value. The negative input is connected to internal ground (GND) in signed mode. ' ' +--------------+ ' | | ' Vinp -----+ single ended | ' | signed mode | ' | | ' GND -----+ ADC | ' | | ' +--------------+ ' · Single ended input (unsigned mode) In unsigned mode the negative input is connected to half of the voltage reference (Vref) voltage minus a fixed device specific negative offset The approximate value corresponding to ground is around 200. This value corresponds to the digital result of ΔV (0.05 * 4096). This value also depend on the selected voltage reference so you should measure the real value by first selecting the voltage reference. (ΔV = Vref * 0.05) How to measure the offset ? Connect the ADC input pin (Vinp) to GND and measure the offset. This is also called offset calibration. This value can be stored for example in EEPROM and is therefore available for all other measurements. See also example below. This offset calibration value is then subtracted to each ADC output The offset enables the ADC to measure for example zero crossing in unsigned mode. ' ' +--------------+ ' | | ' Vinp -----+ single ended | ' | unsigned mode| ' | | ' (Vref/2)-dV -----+ ADC | ' | | ' +--------------+ ' � Internal input The ADC is differential, so for single ended measurements the negative input is connected to a fixed internal value How to selcect the MUX to use with the channel Mux0 = &B0_0000_000 Bit 0...2 of MUX0 = MUX selection on negative ADC input (For internal or single-ended measurements, these bits are not in use.) Bit 3...6 of MUX0 = MUX selection on Positive ADC input Input mode = INTERNAL: MUX POSITIVE INPUT Group Configuration Description 0000 TEMP Temperature Reference 0001 Bandgap Bandgap voltage 0010 SCALEDVCC 1/10 scaled Vcc 0011 DAC DAC output For example: W = Getadc(adcb , 0 , &B0_0011_000) 'Measure DAC Another example: Ch0_gain = 1 , Ch0_inp = INTERNAL , Mux0 = &B0_0011_000 'configure MUX0 to measure internal DAC Input mode = SINGLE_ENDED, DIFF or DIFFWGAIN: MUX POSITIVE INPUT Group Configuration Description 0000 Pin0 ADC0 0001 Pin1 0010 Pin2 0011 Pin3 0100 Pin4 0101 Pin5 0110 Pin6 0111 Pin7 1000 Pin8 1001 Pin9 1010 Pin10 1011 Pin11 1100 Pin12 1101 Pin13 1110 Pin14 1111 Pin15 ADC15 Input mode = DIFF: MUX NEGATIVE INPUT Group Configuration Description 000 Pin0 ADC0 001 Pin1 010 Pin2 011 Pin3 ADC3 100 reserved reserved 101 GND 110 reserved reserved 111 INTGND inernal GND Input mode = DIFFWGAIN: MUX NEGATIVE INPUT Group Configuration Description 000 Pin4 ADC0 001 Pin5 010 Pin6 011 Pin7 ADC3 100 INTGND internal GND 101 reserved reserved 110 reserved reserved 111 GND GND Example: Ch1_gain = 1 , Ch1_inp = Diffwgain , Mux1 = &B0_0001_001 Positive Input = PIN1 Negative Input = PIN5 Calculation of ADC Value: G = Gain TOP with 12-bit resolution: · TOP value of a signed result is 2047 and the results will be in the range -2048 to +2047 (0xF800 - 0x07FF). This is 11-bit plus sign bit (+ or -). · TOP value of of an unsigned result is 4095 and the results will be in the range 0 to +4095 (0x0 - 0x0FFF). This is 12-bit. For single ended and internal measurements GAIN is always 1 and Vinp is internal Ground. In signed mode, negative and positive results are generated: Vinp and Vinn = the positive and negative inputs to the ADC ADC Resolution = ((Vinp - Vinn)/Vref) * G * (TOP + 1) Example for signed differential input (with gain): TOP = 2047 Vinp = +0.3V Vinn = +1.4V Vref = Vcc/1.6 = 3.3V/1.6 = 2.0625 G = 1 ADC Resolution = ((Vinp - Vinn)/Vref) * G * (TOP + 1) ADC Resolution = ((0.3 - 1.4)/2.0625) * 1 * (2047 + 1) ADC Resolution = - 1092 Example for unsigned single ended: TOP = 4095 Vinp = +1.0V Vref = 3.323Volt/1.6 = 2.076875 ΔV = Vref * 0.05 = 2.0625 * 0.05 = 103.1mV G = 1 ADC Resolution = ((Vinp - (-ΔV))/Vref) * G * (TOP + 1) ADC Resolution = ((1.0 + 0.103125)/2.076875) * 1 * (4095 + 1) ADC Resolution = 2175 The offset needs to be subtracted to get the right value. See also example below where the real ADC Resolution was output over terminal with the ATXMEGA256A3BU (Measure Offset in Single Ended Unsigned Mode). ADC Compare function Another feature of XMEGA ADC is a 12-bit compare function. The ADC compare register can hold a 12-bit value that represents a threshold voltage. Each ADC Channel can be configured to automatically compare its result with this compare value to give an interrupt or event only when the result is above or below the threshold. All four ADC Channels share the same compare register but you can decide which ADC channel is working in compare mode. For ADC A you need to set register ADCA_CMP and configure the interrupt. The used interrupt for this feature is the ADC conversion complete interrupt of the according channel which will (when configured in compare mode) only fire when the compare condition is met. To configure the interrupt for example for ADC A Channel 0 the register ADCA_CH0_INTCTRL need to be set to: · Compare Result Below Threshold · Compare Result Above Threshold instead of a conversion complete interrupt. ADC Calibration: The production signature row offers several bytes for ADC calibration. The ADC is calibrated during production testing, and the calibration value must be loaded from the signature row into the ADC registers (CAL registers). Register ADCA_CALL = Low Byte of calibration value Register ADCA_CALH = High Byte of calibration value The calibration corrects the capacitor mismatch of the switched capacitor technology. This ADC calibration value copy should be done in a setup routine before using the ADC. See also READSIG (reads a byte from the signature area in the XMEGA) ADC Clock Frequency The ADC clock need to be set within the recommended speed limits for the ADC module to guarantee correct operation. For example for a ATXMEGA A4U device the minimum is 100Khz and the maximum is 2MHz (for internal signals like internal temp the max. value is 125KHz). The ADC clock is derived from a prescaled version of the XMEGA peripheral clock which is set with the Prescaler value paramter. Don't confuse ADC Clock frequency with ADC conversion speed. So even if you set the ADC Clock frequency to 2MHz you can sample at a rate of for example 20KHz ! Because the maximum ADC Clock Frequency is 1/4 of the peripheral clock of an ATXMEGA you can not sample at a rate higher than one fourth of the system clock speed. Take care on the source impedance of the analog signal source. If the source impedance is too high, the internal sampling capacitor will not be charged to the correct level and the result will not be accurate. In Atmel application Note AVR1300 you find details regarding sample rate vs. source impedance of analog signal source. Additional Best Practise Some additional best practise to use ADC with XMEGA: · Switch off unused peripheral parts with CONFIG POWER_REDUCTION to eliminate noise. · Put the XMEGA in the �Idle� sleep mode directly after starting the ADC conversion to reduce noise from the CPU · Use the lowest gain possible to avoid amplifying external noise · Apply offset and gain calibration to the measurement External Voltage Reference (REFA and REFB) The internal reference voltages like INT1V is derived from the bandgap voltage. Parameter like gain error of bandgap voltage can be found in the device data sheet. An external voltage reference can be more accurate compared to the internal voltage reference but is depending on the external circuit. The max. voltage for external ref on REFA pin (with ADC A this is PINA.0) is Vrefmax = Vcc - 0.6V so with Vcc=3.3V this is 2.7V. And external Vref must be at least 1V. The external reference pin AREFA or AREFB is shared with the DAC module ! See also Atmel Application Note AVR1012: XMEGA A Schematic Checklist For example a reference diode (like LM336-2.5V) can be used or a shunt voltage reference like LM4040 as external reference. For Maximum Performance use Event System and DMA Controller combined with ADC See config DMA, config DMAchx, config Event_System See also GETADC , CONFIG ADC, ATXMEGA Example for Single Conversion: '-------------------------------------------------------------------------------- 'setup the ADC-A converter Config Adca = Single , Convmode = Unsigned , Resolution = 12bit , Dma = Off , Reference = Int1v , Event_mode = None , Prescaler = 32 , Ch0_gain = 1 , Ch0_inp = Single_ended , Mux0 = 0 'you can setup other channels as well W = Getadc(adca , 0) Example for Free Running Mode: 'Configure ADC of Port A in FREE running mode Config Adca = Free , Convmode = Signed , Resolution = 12bit , Dma = Off , _ Reference = Intvcc , Event_mode = None , Prescaler = 256 , Sweep = Ch01 , _ Ch0_gain = 1 , Ch0_inp = Diffwgain , Mux0 = &B00000000 , _ Ch1_gain = 1 , Ch1_inp = Diffwgain , Mux1 = &B00001001 ' With MuxX you can set the 4 MUX-Register ' ADCA_CH0_MUXCTRL (for Channel 0) ' ADCA_CH1_MUXCTRL (for Channel 1) ' ADCA_CH2_MUXCTRL (for Channel 2) ' ADCA_CH3_MUXCTRL (for Channel 3) ' Mux0 = &B00000000 means in Signed Mode: ' MUXPOS Bits = 000 --> Pin 0 is positive Input for Channel 0 ' MUXNEG Bits = 00 --> Pin 4 is negative Input for Channel 0 (Pin 4 because of Differential with gain) ' Mux1 = &B00001001 means in Signed Mode: ' MUXPOS Bits = 001 --> Pin 1 is positive Input for Channel 1 ' MUXNEG Bits = 01 --> Pin 5 is negative Input for Channel 1 (Pin 5 because of Differential with gain) Measure Offset in Single Ended Unsigned Mode: With this example we want to measure the offset in single ended unsigned mode and also the output of the internal 1.0 Voltage reference to DAC B PINB.2. Also the signature row with calibration byte is in the example. 1. With the used ATXMEGA256A3BU the voltage on DAC B was measured with an DMM and the value was: 1.014V 2. After changing the gain calibration register of DAC B Ch0 to DACB_GAINCAL = 160 then the DAC B Ch0 analog output value was the expected 1.000V 3. The offset in single ended unsigned mode is 208 4. Now we connect the DAC B output (Pinb.2) to ADC B input (Pinb.0): the ADC resolution is 2180 5. Vref = 3.323Volt/1.6 = 2.076875 (Vcc was also double checked by a DMM) 6. 2.076875/4095 = 507.1733822 µV 7. 2180* 507.1733822 µV = 1.1056379 V 8. So here we see the difference of the DAC output 1.000V to the measured value in single ended unsigned mode of 1.1056379 V is 0.10564 V 9. When we subtract now the offset from the measured result (2180 - 208 = 1972) we are getting closer to the DAC B output 10. 1972 * 507.1733822 µV = 1.0001V '( Single ended input (unsigned mode) In unsigned mode the negative input is connected to half of the voltage reference (Vref) voltage minus a fixed device specific negative offset The approximate value corresponding to ground is around 200. This value corresponds to the digital result of ?V (0.05 * 4096). This value also depend on the selected voltage reference so you should measure the real value by first selecting the voltage reference. (?V = Vref * 0.05) How to measure the offset ? Connect the ADC input pin (Vinp) to GND and measure the offset. This is also called offset calibration. This value can be stored for example in EEPROM and is therefore available for all other measurements. This offset calibration value is then subtracted to each ADC output The offset enables the ADC to measure for example zero crossing in unsigned mode. ') $regfile = "XM256A3BUDEF.DAT" $crystal = 32000000 '32MHz $hwstack = 64 $swstack = 40 $framesize = 80 Config Osc = Enabled , 32mhzosc = Enabled '32MHz 'configure the systemclock Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 Config Portr.0 = Output Led0 Alias Portr.0 'LED 0 Config Portr.1 = Output Led1 Alias Portr.1 'LED 1 Config Com5 = 57600 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 Open "COM5:" For Binary As #1 Dim B As Byte dim j as byte 'First print the complete signature row For J = 0 To 37 b = Readsig(j) : Print #1, j ;" = " ; b Next 'Read calibration bytes from Signature row 'ADCB B = Readsig(24) 'ADCB Calibration Byte 0 ADCB_CALL = b 'write the value to the register Print #1 , "DCB Calibration Byte 0 = " ; B B = Readsig(25) 'ADCB Calibration Byte 1 ADCB_CALH = b Print #1 , "DCB Calibration Byte 1 = " ; B 'DACB B = Readsig(32) 'DACB Calibration Byte 0 (DACBOFFCAL) DACB_CH0OFFSETCAL = b 'write to the DACB offset register Print #1 , "DACB Calibration Byte 0 = " ; B B = Readsig(33) 'DACB Calibration Byte 1 (DACBGAINCAL) DACB_GAINCAL = 160 Print #1 , "DACB Calibration Byte 1 = " ; B 'Configure the DAC output to output Config Dacb = Enabled , Io0 = Enabled , Channel = Single , Reference = Int1v , Interval = 64 , Refresh = 64 Dim W As Word '-------------------------------------------------------------------------------- 'setup the ADC-B converter (there is no DAC A on ATXMEGA256A3BU) Config Adcb = Single , Convmode = Unsigned , Resolution = 12bit , Dma = Off , Reference = Intvcc , Event_mode = None , Prescaler = 32 , _ Ch0_gain = 1 , Ch0_inp = Single_ended , Mux0 = &B00000000 'you can setup other channels as well Dacb0 = 4095 '1 V output on portb.2 Do Wait 1 'Connect PINB.0 with GND to measure the offset in unsigned mode W = Getadc(adcb , 0) 'Measure PINA.0 Print #1 , "W = " ; W Loop End 'end program Internal measure the DACB output with ADC B: For this example you do not need a connection from DACB output to ADC B. We use the internal DACB output and measure it with ADCB so the DACB must be configured to output also internal and the ADC B must be configured to measure from internal DAC. Don't forget to subtract the offset from the measured value as we use unsigned mode. $regfile = "XM256A3BUDEF.DAT" $crystal = 32000000 '32MHz $hwstack = 64 $swstack = 40 $framesize = 80 Config Osc = Enabled , 32mhzosc = Enabled '32MHz 'configure the systemclock Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 Config Portr.0 = Output Led0 Alias Portr.0 'LED 0 Config Portr.1 = Output Led1 Alias Portr.1 'LED 1 Config Com5 = 57600 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 Open "COM5:" For Binary As #1 Dim B As Byte dim j as byte 'First print the complete signature row For J = 0 To 37 b = Readsig(j) : Print #1, j ;" = " ; b Next 'Read calibration bytes from Signature row 'ADCB B = Readsig(24) 'ADCB Calibration Byte 0 ADCB_CALL = b 'write the value to the register Print #1 , "DCB Calibration Byte 0 = " ; B B = Readsig(25) 'ADCB Calibration Byte 1 ADCB_CALH = b Print #1 , "DCB Calibration Byte 1 = " ; B 'DACB B = Readsig(32) 'DACB Calibration Byte 0 (DACBOFFCAL) DACB_CH0OFFSETCAL = b 'write to the DACB offset register Print #1 , "DACB Calibration Byte 0 = " ; B B = Readsig(33) 'DACB Calibration Byte 1 (DACBGAINCAL) DACB_GAINCAL = b Print #1 , "DACB Calibration Byte 1 = " ; B 'Configure the DAC output to output Config Dacb = Enabled , Io0 = Enabled , Channel = Single ,INTERNAL_OUTPUT = enabled, Reference = Int1v , Interval = 64 , Refresh = 64 Dim W As Word '-------------------------------------------------------------------------------- 'setup the ADC-B converter (there is no DAC A on ATXMEGA256A3BU) 'For internal Measurements use Unsigned mode, 12 bit, Internal 1.00 V Reference Config Adcb = Single , Convmode = Unsigned , Resolution = 12bit , Dma = Off , Reference = Intvcc , Event_mode = None , Prescaler = 512 , _ Ch0_gain = 1 , Ch0_inp = INTERNAL , Mux0 = &B0_0011_000 'configure MUX0 to measure internal DAC Dacb0 = 4095 '1 V Do Wait 1 W = Getadc(adcb , 0 , &B0_0011_000) 'Measure DAC Print #1 , "W = " ; W Loop End 'end program CONFIG ATEMU Top Previous Next Action Configures the PS/2 keyboard data and clock pins. Syntax CONFIG ATEMU = int , DATA = data, CLOCK=clock [,INIT=VALUE] Remarks Int The interrupt used such as INT0 or INT1. DATA The pin that is connected to the DATA line. This must be the same pin as the used interrupt. CLOCK The pin that is connected to the CLOCK line. INIT An optional value that will identify the keyboard. By default or when omitted this is &HAB83. The code that identifies a keyboard. Some mother boards/BIOS seems to require the reverse &H83AB. By making it an option you can pass any possible value. The MSB is passed first, the LSB last. Male (Plug) Female (Socket) 5-pin DIN (AT/XT): 1 - Clock 2 - Data 3 - Not Implemented 4 - Ground 5 - +5v Male (Plug) Female (Socket) 6-pin Mini-DIN (PS/2): 1 - Data 2 - Not Implemented 3 - Ground 4 - +5v 5 - Clock 6 - Not Implemented Old PC�s are equipped with a 5-pin DIN female connector. Newer PC�s have a 6-pin mini DIN female connector. The male sockets must be used for the connection with the micro. Besides the DATA and CLOCK you need to connect from the PC to the micro, you need to connect ground. You can use the +5V from the PC to power your microprocessor. The config statement will setup an ISR that is triggered when the INT pin goes low. This routine you can find in the library. The ISR will retrieve a byte from the PC and will send the proper commands back to the PC. The SENDSCANKBD statement allows you to send keyboard commands. Note that unlike the mouse emulator, the keyboard emulator is also recognized after your PC has booted. The PS2 Keyboard and mouse emulator needs an additional commercial addon library. See also SENDSCANKBD Example '----------------------------------------------------------------------------------------- 'name : ps2_kbdemul.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : PS2 AT Keyboard emulator 'micro : 90S2313 'suited for demo : no, ADD ONE NEEDED 'commercial addon needed : yes '----------------------------------------------------------------------------------------- $regfile = "2313def.dat" ' specify the used micro $crystal = 4000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space $lib "mcsbyteint.lbx" ' use optional lib since we use only bytes 'configure PS2 AT pins Enable Interrupts ' you need to turn on interrupts yourself since an INT is used Config Atemu = Int1 , Data = Pind.3 , Clock = Pinb.0 ' ^------------------------ used interrupt ' ^----------- pin connected to DATA ' ^-- pin connected to clock 'Note that the DATA must be connected to the used interrupt pin Waitms 500 ' optional delay 'rcall _AT_KBD_INIT Print "Press t for test, and set focus to the editor window" Dim Key2 As Byte , Key As Byte Do Key2 = Waitkey() ' get key from terminal Select Case Key2 Case "t" : Waitms 1500 Sendscankbd Mark ' send a scan code Case Else End Select Loop Print Hex(key) Mark: ' send mark Data 12 , &H3A , &HF0 , &H3A , &H1C , &HF0 , &H1C , &H2D , &HF0 , &H2D , &H42 , &HF0 , &H42 ' ^ send 12 bytes ' m a r k CONFIG BASE Top Previous Next Action This option specifies the lower boundary of all arrays. Syntax CONFIG BASE= value Remarks By default the first element of an array starts at 1. With CONFIG BASE=0 you can override this default so that all arrays start at 0. In some cases it is simpler that elements start at 0. A constant named _BASE reflects the setting. You can not change the BASE at run time. When you change this setting in existing code, you need to alter your code. For example when you used this code: Dim a(10) as byte : a(10) = 10 And you set CONFIG BASE=0, it will mean that element 10 is invalid. While in QB an additional element is created, this is not a good idea in bascom because it will require more space. See also DIM Example CONFIG BASE=0 Dim ar(10) as byte , j as byte For j=0 to 9 'array uses element 0-9 ar(j)=j Next Example CONFIG BASE=1 Dim ar(10) as byte , j as byte For j=1 to 10 ' arrays uses element 1-10 ar(j)=j Next CONFIG BCCARD Top Previous Next Action Initializes the pins that are connected to the BasicCard. Syntax CONFIG BCCARD = port , IO=pin, RESET=pin Remarks Port The PORT of the micro that is connected to the BasicCard. This can be PORTB or PORTD and will depend on the used micro. IO The pin number that is connected to the IO of the BasicCard. Must be in the range from 0-7 RESET The pin number that is connected to the RESET of the BasicCard. Must be in the range from 0-7 The variables SW1, SW2 and _BC_PCB are automatically dimensioned by the CONFIG BCCARD statement. This statements uses BCCARD.LIB, a library that is available separately from MCS Electronics. See Also BCRESET , BCDEF , BCCALL Example '------------------------------------------------------------------------------ ' BCCARD.BAS ' This AN shows how to use the BasicCard from Zeitcontrol ' www.basiccard.com '------------------------------------------------------------------------------ 'connections: ' C1 = +5V ' C2 = PORTD.4 - RESET ' C3 = PIN 4 - CLOCK ' C5 = GND ' C7 = PORTD.5 - I/O ' /--------------------------------\ ' | | ' | C1 C5 | ' | C2 C6 | ' | C3 C7 | ' | C4 C8 | ' | | ' \--------------------------------/ ' ' '----------- configure the pins we use ------------ Config Bccard = PORTD , Io = 5 , Reset = 4 ' ^ PORTD.4 ' ^------------ PORTD.5 ' ^--------------------- PORT D 'Load the sample calc.bas into the basiccard ' Now define the procedure in BASCOM ' We pass a string and also receive a string Bcdef Calc(string) 'We need to dim the following variables 'SW1 and SW2 are returned by the BasicCard 'BC_PCB must be set to 0 before you start a session 'Our program uses a string to pass the data so DIM it Dim S As String * 15 'Baudrate might be changed $baud = 9600 ' Crystal used must be 3579545 since it is connected to the Card too $crystal = 3579545 'Perform an ATR Bcreset 'Now we call the procedure in the BasicCard 'bccall funcname(nad,cla,ins,p1,p2,PRM as TYPE,PRM as TYPE) S = "1+1+3" ' we want to calculate the result of this expression Bccall Calc(0 , &H20 , 1 , 0 , 0 , S) ' ^--- variable to pass that holds the expression ' ^------- P2 ' ^----------- P1 ' ^--------------- INS ' ^-------------------- CLA ' ^-------------------------- NAD 'For info about NAD, CLA, INS, P1 and P2 see your BasicCard manual 'if an error occurs ERR is set ' The BCCALL returns also the variables SW1 and SW2 Print "Result of calc : " ; S Print "SW1 = " ; Hex(sw1) Print "SW2 = " ; Hex(sw2) 'Print Hex(_bc_pcb) ' for test you can see that it toggles between 0 and 40 Print "Error : " ; Err 'You can call this or another function again in this session S = "2+2" Bccall Calc(0 , &H20 , 1 , 0 , 0 , S) Print "Result of calc : " ; S Print "SW1 = " ; Hex(sw1) Print "SW2 = " ; Hex(sw2) 'Print Hex(_bc_pcb) ' for test you can see that it toggles between 0 and 40 Print "Error : " ; Err 'perform another ATR Bcreset Input "expression " , S Bccall Calc(0 , &H20 , 1 , 0 , 0 , S) Print "Answer : " ; S '----and now perform an ATR as a function Dim Buf(25) As Byte , I As Byte Buf(1) = Bcreset() For I = 1 To 25 Print I ; " " ; Hex(buf(i)) Next 'typical returns : 'TS = 3B 'T0 = EF 'TB1 = 00 'TC1 = FF 'TD1 = 81 T=1 indication 'TD2 = 31 TA3,TB3 follow T=1 indicator 'TA3 = 50 or 20 IFSC ,50 =Compact Card, 20 = Enhanced Card 'TB3 = 45 BWT blocl waiting time 'T1 -Tk = 42 61 73 69 63 43 61 72 64 20 5A 43 31 32 33 00 00 ' B a s i c C a r d Z C 1 2 3 'and another test 'define the procedure in the BasicCard program Bcdef Paramtest(byte , Word , Long ) 'dim some variables Dim B As Byte , W As Word , L As Long 'assign the variables B = 1 : W = &H1234 : L = &H12345678 Bccall Paramtest(0 , &HF6 , 1 , 0 , 0 , B , W , L) Print Hex(sw1) ; Spc(3) ; Hex(sw2) 'and see that the variables are changed by the BasicCard ! Print B ; Spc(3) ; Hex(w) ; " " ; Hex(l) 'try the echotest command Bcdef Echotest(byte) Bccall Echotest(0 , &HC0 , &H14 , 1 , 0 , B) Print B End 'end program CONFIG CANBUSMODE Top Previous Next Action Configures the CAN bus mode. Syntax CONFIG CANBUSMODE =mode Remarks mode The CAN bus can be set to 3 different modes. - ENABLED : TxCAN and RxCAN are enabled. - STANDBY : TxCAN is recessive and the receiver is disabled. The registers and mobs can be accessed. - LISTENING : This mode is transparant for the CAN channel. It enables a hardware loop[ back from the internal TxCAN to the RxCAN. It provides a recessive level on the TxCAN output pin. It does NOT disable the RxCAN pin. The CAN commands are intended for the AVR processor AT90CANXXX series. You need to terminate the bus with 120 ohm at both ends. Your code always need a number of statements. The best solution is to use the can-elektor.bas sample to get started. CANRESET Will reset the CAN controller. Use this only once. CANCLEARALLMOBS Will clear all message objects. This is best to be done right after the CANRESET. CANBAUD All devices on the bus need to have the same baud rate. Set the BAUD right after you have cleared all objects. CONFIG CANBUSMODE Now you chose the mode the bus will work in. This is ENABLED in most cases. CONFIG CANMOB Here you define the properties of each Message Object. This need to be done only once. But after the message object has been used, you need to configure it again so the new MOB can be used again. CANGIE , ON CAN_IT Since the interrupt TX, RX and ERR interrupts are used you need to assign a value of &B10111000 to CANGIE. You also need to assign an interrupt routine to the CANIT interrupt. In the main code you can send data using CANSEND. The interrupt routine. The CANPAGE register is saved into the _CAN_PAGE variable. This is required since the interrupt may not change the CANPAGE register. Then CANGETINTS is used to retreive all message object interrupt flags. The value is stored in _CAN_MOBINTS. Since multiple Message Objects can cause an interrupt we check all message objects with a For.. Next loop to test all bits. If the bit is set, the Message Object is selected with CANSELPAGE. Then the CANSTMOB register is tested for a number of bits/flags. If bit 5 is set, it means that a frame was received. For the demo the ID is read with CANID. The CANRECEIVE function reads the data from the frame into a variable. In the example the variable is a PORT which will change value depending on the receive data byte. After this the CONFIG CANMOB is used with a value of -1 to indicate that the operation must be done on the current selected MOB. The object is put back into receive mode. If bit 6 is set it means that data was transmitted with success. Again, we use CONFIG CANMOB so the object can be used again. For transmitting we put the object into DISABLED mode. And lastly we test bit 0, the MOB error bit. It if was set it means there was an error when data was sent using CANSEND. We must use CONFIG CANMOB so the MOB can be used again. We must clear the CANSIT1 and CANSIT2 flag registers before we exit the interrupt routine. We also need to reset the interrupt flags in CANGIT. This is done by writing the same value back to CANGIT. A one will clear the flag if it was set. Last we restore the CANPAGE register by writing _CAN_PAGE back to it. While the interrupt routine shows some PRINT statements, it is not a good idea to print inside the/a interrupt routine. You should keep the delay as short as possible otherwise you might not be able to process all CAN frames. As you can see in the sample, the MOB's are configured at the start AND once they are used so they can be re-used. In the example all lines are important except for the PRINT lines. See also CONFIG CANMOB , CANBAUD, CANRESET, CANCLEARMOB, CANCLEARALLMOBS, CANSEND, CANRECEIVE , CANID, CANSELPAGE, CANGETINTS Example '------------------------------------------------------------------------ ' CAN-Elektor.bas ' bascom-avr demo for Auto-CANtroller board '------------------------------------------------------------------------ $regfile = "m32can.dat" ' processor we use $crystal = 12000000 ' Crystal 12 MHz $hwstack = 64 $swstack = 32 $framesize = 40 '$prog &HFF , &HCF , &HD9 , &HFF ' generated. Take care that the chip supports all fuse bytes. Config Porta = Output ' LED Config Portc = Input ' DIP switch Portc = 255 ' activate pull up Config Com2 = 19200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Open "COM2:" For Binary As #2 Dim _canpage As Byte , _canid As Dword , _can_int_idx As Byte , _can_mobints As Word Dim Breceived As Byte , Bok As Byte , Bdil As Byte On Can_int Can_int ' define the CAN interrupt Enable Interrupts ' enable interrupts Canreset ' reset can controller Canclearallmobs ' clear alle message objects Canbaud = 125000 ' use 125 KB Config Canbusmode = Enabled ' enabled,standby,listening Config Canmob = 0 , Bitlen = 11 , Idtag = &H0120 , Idmask = &H0120 , Msgobject = Receive , Msglen = 1 , Autoreply = Disabled 'first mob is used for receiving data Config Canmob = 1 , Bitlen = 11 , Idtag = &H0120 , Msgobject = Disabled , Msglen = 1 ' this mob is used for sending data Cangie = &B10111000 ' CAN GENERAL INTERRUPT and TX and RX and ERR Print #2 , "Start" Do If Pinc <> Bdil Then ' if the switch changed Bdil = Pinc ' save the value Bok = Cansend(1 , Pinc) ' send one byte using MOB 1 Print #2 , "OK:" ; Bok ' should be 0 if it was send OK End If Loop '*********************** CAN CONTROLLER INTERRUPT ROUTINE ********************** 'multiple objects can generate an interrupt Can_int: _canpage = Canpage ' save can page because the main program can access the page too Cangetints ' read all the interrupts into variable _can_mobints For _can_int_idx = 0 To 14 ' for all message objects If _can_mobints._can_int_idx = 1 Then ' if this message caused an interrupt Canselpage _can_int_idx ' select message object If Canstmob.5 = 1 Then ' we received a frame _canid = Canid() ' read the identifier Print #2 , Hex(_canid) Breceived = Canreceive(porta) ' read the data and store in PORTA Print #2 , "Got : " ; Breceived ; " bytes" ' show what we received Print #2 , Hex(porta) Config Canmob = -1 , Bitlen = 11 , Msgobject = Receive , Msglen = 1 , Autoreply = Disabled , Clearmob = No ' reconfig with value -1 for the current MOB and do not set ID and MASK Elseif Canstmob.6 = 1 Then 'transmission ready Config Canmob = -1 , Bitlen = 11 , Msgobject = Disabled , Msglen = 1 , Clearmob = No ' reconfig with value -1 for the current MOB and do not set ID and MASK Elseif Canstmob.0 = 1 Then 'ack error when sending data 'transmission ready Print #2 , "ERROR:" ; Hex(canstmob) Config Canmob = -1 , Bitlen = 11 , Msgobject = Disabled , Msglen = 1 , Clearmob = No End If End If Next Cangit = Cangit ' clear interrupt flags Canpage = _canpage ' restore page Return CONFIG CANMOB Top Previous Next Action Configures one of the 15 CAN Message OBjects. Syntax CONFIG CANMOB=mob,BITLEN=bitlen,IDTAG=tag,IDMASK=mask,MSGOBJECT=mode,MSGLEN=msglen,AUTOREPLY=reply , CLEARMOB=clrmob Remarks mob The mob(message object) is a number or variable with a range from 0-14. Number 15 is reserved by Atmel. There are 15 message objects you can use but only one set of registers. The CANPAGE register is used to select the proper MOB. This is all handled by the compiler. Internally, the mob you pass will set the CANPAGE register. When you use a value of -1 , the configuration is done on the current selected MOB (or CANPAGE). A reconfigure does not need to set the IDTAG and IDMASK again. While you can use a constant or variable, you can not use a variable with a value of -1 to reconfigure the mob. A reconfigure requires a constant of -1. bitlen The CAN controller supports CAN messages with 11 bit ID's and with 29 bit ID's. And ID is an identifier. The lowest ID has the highest priority. Using 11 bit ID's has the advantage that it takes less time and as a result, you could send more messages. Just like with traffic, the bus capacity is limited. The baud rate and the message length all play a role. Valid values are 11 and 29. You can use a constant or variable. Using variables will increase code. idtag The IDTAG is the identifier you assign to the message object. When the MOB is used for transmitting, the IDTAG is used for the CAN ID. When the MOB is used for receiving, the IDTAG is used as a filter. Each time a message is sent or received, an interrupt is generated. This will interrupt the main process. For efficient usage, you need to set the IDTAG to filter only the ID's of interest. The IDMASK can be used together with the IDTAG to create a range. You can use a constant or variable to define the IDTAG. Using a variable will increase code. mask The IDMASK is only used when the MOB is used in receiving mode. It must be used together with IDTAG to create a range where the MOB will respond to. The following examples are for CAN rev A with 11 bit ID's. Example 1: you only want to filter ID &H0317. In this case you set the IDTAG to &H317. The IDMASK need to be set to &HFFFF in this case. A '1' for a bit in IDMASK means that the corresponding '1' in IDTAG is checked. When set a bit in IDMASK to '0' it means the corresponding bit in IDTAG can have any value. Full filtering: to accept only ID = 0x317 in part A. - ID MSK = 111 1111 1111 b - ID TAG = 011 0001 0111 b Example 2: you want to filter ID &H310-&H317. You can set the IDTAG to &H310 and the IDMASK to &HFFF8. The last 3 bits are set to 0 this way which means that &H310 is valid, but so is &H311, &H312, etc. Partial filtering: to accept ID from 0x310 up to 0x317 in part A. - ID MSK = 111 1111 1000 b - ID TAG = 011 0001 0xxx b Example 3: you want to filter from &H0000 to &H7FF. This means you need to respond to all messages. The IDMASK need to be set to 0. It will not matter to which value you set IDTAG since all 11 bits of IDMASK are set to 0. No filtering: to accept all ID from 0x000 up to 0x7FF in part A. - ID MSK = 000 0000 0000 b - ID TAG = xxx xxxx xxxx b You can use a constant or variable to define the IDMASK. Using a variable will increase code. mode The mode in which the MOB will be used. - DISABLED (0). The MOB is free to be used. - TRANSMIT (1). The MOB data will be transmitted. - RECEIVE (2). The MOB will wait for a message that matches the ID and MASK. - RECEIVE_BUFFERED (3). This mode can be used to receive multiple frames. The CANSEND function will use the TRANSMIT mode. You should chose the DISABLED mode when configuring the MOB for transmission. Instead of the mentioned parameter names, you can also use a variable to set the mode. This variable must have a value between 0 and 3. msglen This is the message length of the message in bytes. In receive mode you set it to the number of bytes you expect. The CANRECEIVE function will return the number of bytes read. When the MOB is used for transmitting, it will define the length of the data. The length can also be 0 to send frames without data. The msglen can be a constant or variable. The maximum number of bytes that can be sent or received is 8. reply This option can set ENABLED or DISABLED. If you use a variable, a 0 will disable auto reply, a 1 will enable auto reply. Auto reply can be used to reply to a remote frame. A remote frame is a frame without data. Since a remote frame has no data, you can reuse the MOB to send data as a reply to a remote frame. clrmob By default all registers of a MOB are cleared when you configure the MOB. When you reconfigure the MOB, or want to respond to an auto reply, you do not want to clear the MOB. In such a case you can use CLEARMOB=NO to prevent clearing of the registers. While CONFIG CANMOB can dynamically set up the MOB (using variables instead of constants), it will increase code. So use a constant if possible. See also CONFIG CANBUSMODE , CANBAUD, CANRESET, CANCLEARMOB, CANCLEARALLMOBS, CANSEND, CANRECEIVE , CANID, CANSELPAGE, CANGETINTS Example Config Canmob = 0 , Bitlen = 11 , Idtag = &H0120 , Idmask = &H0120 , Msgobject = Receive , Msglen = 1 , Autoreply = Disabled 'first mob is used for receiving data Config Canmob = 1 , Bitlen = 11 , Idtag = &H0120 , Msgobject = Disabled , Msglen = 1 ' this mob is used for sending data Config Canmob = -1 , Bitlen = 11 , Msgobject = Disabled , Msglen = 1 , Clearmob = No ' reconfig with value -1 for the current MOB and do not set ID and MASK CONFIG CLOCK Top Previous Next Action Configures the timer to be used for the Time$ and Date$ variables. Syntax CONFIG CLOCK = soft | USER [, GOSUB = SECTIC] [,RTC=rtc] [,RTC32=rtc32] [,RTC=rtc] [,RTC32=rtc32] is only for ATXMEGA devices. Remarks Soft Use SOFT for using the software based clock routines. You need to add an ENABLE INTERRUPTS statement to your code since the SOFT mode uses the timer in interrupt mode. The timer interrupt is enabled automatic but the global interrupt you need to enable yourself. While the compiler could enable the global interrupt automatic, you would not have control anymore when it is enabled when using multiple interrupts. In general you enable global interrupts after all interrupts are setup. For the SOFT mode you need to connect a special low frequency crystal with a value of 32768 Hz to the ASYNC TIMER oscillator pins. Use USER to write/use your own code in combination with an I2C clock chip for example. Sectic This option allows to jump to a user routine with the label sectic. Since the interrupt occurs every second you may handle various tasks in the sectic label. It is important that you use the name SECTIC and that you return with a RETURN statement from this label. The usage of the optional SECTIC routine will use 30 bytes of the hardware stack. This option only works with the SOFT clock mode. It does not work in USER mode. [, GOSUB = SECTIC] is only for SOFT mode. RTC This option is only available for processors with an RTC (XMEGA). This option sets the RTC clock source. Valid parameters are : 1KHZ_INT32KHZ_ULP 1 kHz from internal 32 kHz ULP 1KHZ_32KHZ_CRYSTOSC 1 kHz from 32 kHz Crystal Oscillator on TOSC 1KHZ_INT32KHZ_RCOSC 1 kHz from internal 32 kHz RC Oscillator 32KHZ_32KHZ_CRYSTOSC 32 kHz from 32 kHz Crystal Oscillator on TOSC The 1KHz clocks will load the PER register with 1000-1 and the 32 KHz clock will load PER with a value of 32768-1. The overflow mode is used and you can use the compare overflow if required. Do not forget to enable the 32 KHz oscillator and the interrupts as shown in the Xmega example. RTC32 This option is available for few XMEGA chips. You can use it instead of the RTC. In fact when a processor has an RTC32, it does not have an RTC. You can not use both RTC and RTC32 together. RTC32 only accepts one value : 1KHZ_32KHZ_CRYSTOSC This also means that you must use/connect an external 32 KHz crystal. When you use the RTC32, the battery back register VBAT_CTRL is initialized and setup. HIGHESR This option is available for few XMEGA chips which have RTC32 hardware. This option will set HIGH ESR mode when a value of '1' is selected. By default this option is 0/off. HIGH ESR consumes more power. When you use the CONFIG CLOCK (in soft or user mode) directive the compiler will DIM the following BYTE variables automatic : _sec _min _hour _day _month _year The DATETIME library will also be included by the compiler. For this reason it is important that you use CONFIG CLOCK when you use any of the date time functions. The variables Time$ and Date$ will also be dimensioned. These are special variables since they are treated different. See TIME$ and DATE$. Following a way to set Time$ and Date$ : Date$ = "11/11/00" Time$ = "02:20:00" You can change the date format by using: Config Date = Mdy , Separator = "/" ' ANSI-Format See CONFIG DATE The _sec, _min and other internal variables can be changed by the user too. But of course changing their values will change the Time$ and Date$ variables. The compiler also creates an ISR that gets updated once a second. This works for AVR chips which can be asynchronously clocked from the TOSC1/2 pins. TOSC1 = Timer Oscillator Pin 1 TOSC2 = Timer Oscillator Pin 2 For example the Timer/Counter 2 of an ATMEGA16 can be used as a Real Time Counter (RTC). The Timer/Counter 2 will then be asynchronously clocked from the TOSC Pin's. The Timer/Counter 2 can NOT be used for other tasks when configured in asynchronous mode. Notice that you need to connect a 32768 Hz crystal in order to use the timer in async mode, the mode that is used for the clock timer in SOFT mode. You also need to enable interrupts because of the interrupt service routine. When you choose the USER option, only the internal variables are created (like _sec , _min , _hour....). With the USER option you need to write the clock code yourself (so the USER need to update for example the System Second or Secofday). This means the one second clock must be generated by a "USER" source like a Timer which use the internal clock or an XTAL depending on the Xtal configuration. There are so called "AVR Timer Calculator" online available where you input the clock frequency from xtal, which Timer you use (8 or 16 Bit) and the period you want to achieve (like 1 second or 1000ms) than it will give you number which you need to configure the timer. You also configure the interrupt of the timer and then the program will jump to the timer interrupt routine where you can set the new system second. Config Clock = User 'Use USER to write/use your own code You also need to include the following labels with config clock = user: Getdatetime: 'called when date or time is read Return Setdate: 'called when date$ is set Return Settime: 'scanned when time$ is set Return Example for config clock = user in Bascom-Simulator Following example use $sim so it can be used in Bascom-Simulator. It uses config clock in user mode. The second tick is generated by Timer1 and the time updated in the Timer interrupt service routine. You can run this example direct in Bascom Simulator and you need to CLICK ON RUN BUTTON (in the simulator) go to Interrupts Tab and hit the OVF1 BUTTON to simulate an Timer interrupt. Then you will see how the program jump to the interrupt service routine and updates the time !! The Simulator output give you following: 01.09.09 00:00:01 00:00:02 00:00:03 00:00:04 00:00:05 00:00:06 00:00:07 That's it ! $regfile = "m16def.dat" $crystal = 12000000 $hwstack = 80 $swstack = 80 $framesize = 80 $baud = 19200 $sim 'ONLY FOR SIMULATOR MODE !!!! Dim second_tick As Long Config Clock = User 'Use USER to write/use your own code Config Date = Dmy , Separator = . 'Day.Month.Year Config Timer1 = Timer , Prescale = 256 On Timer1 Timer_irq Const Timer_preload = 18661 'Timervorgabe für Sekunden Takt Enable Timer1 Enable Interrupts Date$ = "01.09.09" Time$ = "00:00:00" Print Date$ Do !NOP Loop End 'end program Timer_irq: 'Timer1 IRQ (once per second) Incr Second_tick Time$ = Time(second_tick) Timer1 = Timer_preload Print Time$ 'only for Bascom-Simulator Return Settime: Return Getdatetime: Return Setdate: Return Using a DS1307 with config clock See the datetime_test1.bas example from the SAMPLES\DATETIME folder that shows how you can use a DS1307 clock chip for the date and time generation. See also example below ! Using config clock with ATXMEGA With ATXMEGA there are devices with 16-Bit RTC like ATXMEGA128A1 and 32-Bit RTC like ATXMEGA256A3B or ATXMEGA256A3BU. ATXMEGA with 16-Bit RTC: · Can be used with one of the two internal RC oscillator options or external 32.768kHz crystal oscillator · The internal 32 kHz Ultra Low Power (ULP) is a very low power clock source, and it is not designed for high accuracy. · If you want to use the internal 32Khz RC oscillator you need to enable it with config osc Config Osc = Disabled , 32mhzosc = Enabled , 32khzosc = Enabled ATXMEGA with 32-Bit RTC (for example ATXMEGA256A3B or ATXMEGA256A3BU): · An external 32.768kHz crystal oscillator must be used as the clock source · The 32-Bit RTC is combined with a Battery Backup System Numeric Values to calculate with Date and Time: · SecOfDay: (Type LONG) Seconds elapsed since Midnight. 00:00:00 start with 0 to 85399 at 23:59:59. · SysSec: (Type LONG) Seconds elapsed since begin of century (at 2000-01-01!). 00:00:00 at 2000-01-01 start with 0 to 2147483647 (overflow of LONG-Type) at 2068-01-19 03:14:07 · DayOfYear: (Type WORD) Days elapsed since first January of the current year. · First January start with 0 to 364 (365 in a leap year) · SysDay: (Type WORD) Days elapsed since begin of century (at 2000-01-01!). 2000-01-01 starts with 0 to 36524 at 2099-12-31 · DayOfWeek: (Type Byte) Days elapsed since Monday of current week. Monday start with 0 to Sunday = 6 With the numeric type calculations with Time and date are possible. Type 1 (discrete Bytes) and 2 (Strings) can be converted to an according numeric value. Than Seconds (at SecOfDay and SysSec) or Days (at DayOfYear, SysDay), can be added or subtracted. The Result can be converted back. See also TIME$ , DATE$ , CONFIG DATE, Memory usage, Date and Time Routines ASM The following ASM routines are called from datetime.lib _soft_clock. This is the ISR that gets called once per second. Example 1 '----------------------------------------------------------------------------------------- 'name : megaclock.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : shows the new TIME$ and DATE$ reserved variables 'micro : Mega103 'suited for demo : yes 'commercial addon needed : no '----------------------------------------------------------------------------------------- $regfile = "m103def.dat" ' specify the used micro $crystal = 4000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space 'With the 8535 and timer2 or the Mega103 and TIMER0 you can 'easily implement a clock by attaching a 32768 Hz xtal to the timer 'And of course some BASCOM code 'This example is written for the STK300 with M103 Enable Interrupts '[configure LCD] $lcd = &HC000 'address for E and RS $lcdrs = &H8000 'address for only E Config Lcd = 20 * 4 'nice display from bg micro Config Lcdbus = 4 'we run it in bus mode and I hooked up only db4-db7 Config Lcdmode = Bus 'tell about the bus mode '[now init the clock] Config Date = Mdy , Separator = / ' ANSI-Format Config Clock = Soft 'this is how simple it is 'The above statement will bind in an ISR so you can not use the TIMER anymore! 'For the M103 in this case it means that TIMER0 can not be used by the user anymore 'assign the date to the reserved date$ 'The format is MM/DD/YY Date$ = "11/11/00" 'assign the time, format in hh:mm:ss military format(24 hours) 'You may not use 1:2:3 !! adding support for this would mean overhead 'But of course you can alter the library routines used Time$ = "02:20:00" '--------------------------------------------------- 'clear the LCD display Cls Do Home 'cursor home Lcd Date$ ; " " ; Time$ 'show the date and time Loop 'The clock routine does use the following internal variables: '_day , _month, _year , _sec, _hour, _min 'These are all bytes. You can assign or use them directly _day = 1 'For the _year variable only the year is stored, not the century End Xmega Sample '---------------------------------------------------------------- ' (c) 1995-2016, MCS ' xm128-RTC.bas ' This sample demonstrates the Xmega128A1 RTC '----------------------------------------------------------------- $regfile = "xm128a1def.dat" $crystal = 32000000 $hwstack = 64 $swstack = 64 $framesize = 64 Config Portb = Output 'First Enable The Osc Of Your Choice , make sure to enable 32 KHz clock or use an external 32 KHz clock Config Osc = Enabled , 32mhzosc = Enabled , 32khzosc = Enabled ' For the CLOCK we use the RTC so make sure the 32 KHZ osc is enabled!!! 'configure the systemclock Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 Config Com1 = 19200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 Open "COM1:" For Binary As #1 Config Clock = Soft , Rtc = 1khz_int32khz_ulp ' we select the internal 1 KHz clock from the 32KHz internal oscillator 'the following clocks can be used to clock the RTC ' 1KHZ_INT32KHZ_ULP 1 kHz from internal 32 kHz ULP ' 1KHZ_32KHZ_CRYSTOSC 1 kHz from 32 kHz Crystal Oscillator on TOSC ' 1KHZ_INT32KHZ_RCOSC 1 kHz from internal 32 kHz RC Oscillator ' 32KHZ_32KHZ_CRYSTOSC 32 kHz from 32 kHz Crystal Oscillator on TOSC Config Priority = Static , Vector = Application , Lo = Enabled ' the RTC uses LO priority interrupts so these must be enabled !!! Enable Interrupts ' as usual interrupts must be enabled Do Print Time$ ' print the time Waitms 1000 Loop 'TO USE THE SECTIC in the sample you must use GOSUB=SECTIC in CONFIG CLOCK !!! Sectic: Toggle Portb 'optional toggle some leds when using the gosub=sectic option Return Example 2 $regfile = "m128def.dat" $hwstack = 80 $swstack = 80 $framesize = 160 $crystal = 8000000 $baud = 19200 Enable Interrupts '[now init the clock] Config Date = Mdy , Separator = / ' ANSI-Format Config Clock = Soft 'this is how simple it is 'The above statement will bind in an ISR so you can not use the TIMER anymore! 'assign the date to the reserved date$ 'The format is MM/DD/YY Date$ = "11/11/05" 'assign the time, format in hh:mm:ss military format(24 hours) 'You may not use 1:2:3 !! adding support for this would mean overhead 'But of course you can alter the library routines used Time$ = "23:59:50" Do Waitms 500 Print Date$ ; Spc(3) ; Time$ Loop Example 3 (using DS1307 with Config clock) '------------------------------------------------------------------------------- ' DateTime_test.bas ' This sample show how to use the Date-Time routines from the DateTime.Lib ' written by Josef Franz Vögel '------------------------------------------------------------------------------- $regfile = "m328pdef.dat" $crystal = 12e6 '16MHz $hwstack = 80 $swstack = 80 $framesize = 160 Const Clockmode = 1 'use i2c for the clock #if Clockmode = 1 Config Clock = Soft ' we use build in clock Disable Interrupts #else Config Clock = User ' we use I2C for the clock 'configure the scl and sda pins (using software I2C routines) Config Sda = Portd.6 Config Scl = Portd.5 I2cinit 'address of ds1307 Const Ds1307w = &HD0 ' Addresses of Ds1307 clock Const Ds1307r = &HD1 #endif 'configure the date format Config Date = Ymd , Separator = - ' ANSI-Format 'This sample does not have the clock started so interrupts are not enabled ' Enable Interrupts 'dim the used variables Dim Lvar1 As Long Dim Mday As Byte Dim Bweekday As Byte , Strweekday As String * 10 Dim Strdate As String * 8 Dim Strtime As String * 8 Dim Bsec As Byte , Bmin As Byte , Bhour As Byte Dim Bday As Byte , Bmonth As Byte , Byear As Byte Dim Lsecofday As Long Dim Wsysday As Word Dim Lsyssec As Long Dim Wdayofyear As Word ' =================== DayOfWeek ============================================= ' Example 1 with internal RTC-Clock _day = 4 : _month = 11 : _year = 2 ' Load RTC-Clock for example - testing Bweekday = Dayofweek() Strweekday = Lookupstr(bweekday , Weekdays) Print "Weekday-Number of " ; Date$ ; " is " ; Bweekday ; " = " ; Strweekday ' Example 2 with defined Clock - Bytes (Day / Month / Year) Bday = 26 : Bmonth = 11 : Byear = 2 Bweekday = Dayofweek(bday) Strweekday = Lookupstr(bweekday , Weekdays) Strdate = Date(bday) Print "Weekday-Number of Day=" ; Bday ; " Month=" ; Bmonth ; " Year=" ; Byear ; " is " ; Bweekday ; " (" ; Date(bday) ; ") = " ; Strweekday ' Example 3 with System Day Wsysday = 2000 ' that is 2005-06-23 Bweekday = Dayofweek(wsysday) Strweekday = Lookupstr(bweekday , Weekdays) Print "Weekday-Number of System Day " ; Wsysday ; " (" ; Date(wsysday) ; ") is " ; Bweekday ; " = " ; Strweekday ' Example 4 with System Second Lsyssec = 123456789 ' that is 2003-11-29 at 21:33:09 Bweekday = Dayofweek(lsyssec) Strweekday = Lookupstr(bweekday , Weekdays) Print "Weekday-Number of System Second " ; Lsyssec ; " (" ; Date(lsyssec) ; ") is " ; Bweekday ; " = " ; Strweekday ' Example 5 with Date-String Strdate = "04-11-02" ' we have configured Date in ANSI Bweekday = Dayofweek(strdate) Strweekday = Lookupstr(bweekday , Weekdays) Print "Weekday-Number of " ; Strdate ; " is " ; Bweekday ; " = " ; Strweekday ' ================= Second of Day ============================================= ' Example 1 with internal RTC-Clock _sec = 12 : _min = 30 : _hour = 18 ' Load RTC-Clock for example - testing Lsecofday = Secofday() Print "Second of Day of " ; Time$ ; " is " ; Lsecofday ' Example 2 with defined Clock - Bytes (Second / Minute / Hour) Bsec = 20 : Bmin = 1 : Bhour = 7 Lsecofday = Secofday(bsec) Print "Second of Day of Sec=" ; Bsec ; " Min=" ; Bmin ; " Hour=" ; Bhour ; " (" ; Time(bsec) ; ") is " ; Lsecofday ' Example 3 with System Second Lsyssec = 1234456789 Lsecofday = Secofday(lsyssec) Print "Second of Day of System Second " ; Lsyssec ; "(" ; Time(lsyssec) ; ") is " ; Lsecofday ' Example 4 with Time - String Strtime = "04:58:37" Lsecofday = Secofday(strtime) Print "Second of Day of " ; Strtime ; " is " ; Lsecofday ' ================== System Second ============================================ ' Example 1 with internal RTC-Clock ' Load RTC-Clock for example - testing _sec = 17 : _min = 35 : _hour = 8 : _day = 16 : _month = 4 : _year = 3 Lsyssec = Syssec() Print "System Second of " ; Time$ ; " at " ; Date$ ; " is " ; Lsyssec ' Example 2 with with defined Clock - Bytes (Second, Minute, Hour, Day / Month / Year) Bsec = 20 : Bmin = 1 : Bhour = 7 : Bday = 22 : Bmonth = 12 : Byear = 1 Lsyssec = Syssec(bsec) Strtime = Time(bsec) Strdate = Date(bday) Print "System Second of " ; Strtime ; " at " ; Strdate ; " is " ; Lsyssec ' Example 3 with System Day Wsysday = 2000 Lsyssec = Syssec(wsysday) Print "System Second of System Day " ; Wsysday ; " (" ; Date(wsysday) ; " 00:00:00) is " ; Lsyssec ' Example 4 with Time and Date String Strtime = "10:23:50" Strdate = "02-11-29" ' ANSI-Date Lsyssec = Syssec(strtime , Strdate) Print "System Second of " ; Strtime ; " at " ; Strdate ; " is " ; Lsyssec ' 91880630 ' ==================== Day Of Year ========================================= ' Example 1 with internal RTC-Clock _day = 20 : _month = 11 : _year = 2 ' Load RTC-Clock for example - testing Wdayofyear = Dayofyear() Print "Day Of Year of " ; Date$ ; " is " ; Wdayofyear ' Example 2 with defined Clock - Bytes (Day / Month / Year) Bday = 24 : Bmonth = 5 : Byear = 8 Wdayofyear = Dayofyear(bday) Print "Day Of Year of Day=" ; Bday ; " Month=" ; Bmonth ; " Year=" ; Byear ; " (" ; Date(bday) ; ") is " ; Wdayofyear ' Example 3 with Date - String Strdate = "04-10-29" ' we have configured ANSI Format Wdayofyear = Dayofyear(strdate) Print "Day Of Year of " ; Strdate ; " is " ; Wdayofyear ' Example 4 with System Second Lsyssec = 123456789 Wdayofyear = Dayofyear(lsyssec) Print "Day Of Year of System Second " ; Lsyssec ; " (" ; Date(lsyssec) ; ") is " ; Wdayofyear ' Example 5 with System Day Wsysday = 3000 Wdayofyear = Dayofyear(wsysday) Print "Day Of Year of System Day " ; Wsysday ; " (" ; Date(wsysday) ; ") is " ; Wdayofyear ' =================== System Day ====================================== ' Example 1 with internal RTC-Clock _day = 20 : _month = 11 : _year = 2 ' Load RTC-Clock for example - testing Wsysday = Sysday() Print "System Day of " ; Date$ ; " is " ; Wsysday ' Example 2 with defined Clock - Bytes (Day / Month / Year) Bday = 24 : Bmonth = 5 : Byear = 8 Wsysday = Sysday(bday) Print "System Day of Day=" ; Bday ; " Month=" ; Bmonth ; " Year=" ; Byear ; " (" ; Date(bday) ; ") is " ; Wsysday ' Example 3 with Date - String Strdate = "04-10-29" Wsysday = Sysday(strdate) Print "System Day of " ; Strdate ; " is " ; Wsysday ' Example 4 with System Second Lsyssec = 123456789 Wsysday = Sysday(lsyssec) Print "System Day of System Second " ; Lsyssec ; " (" ; Date(lsyssec) ; ") is " ; Wsysday ' =================== Time ================================================ ' Example 1: Converting defined Clock - Bytes (Second / Minute / Hour) to Time - String Bsec = 20 : Bmin = 1 : Bhour = 7 Strtime = Time(bsec) Print "Time values: Sec=" ; Bsec ; " Min=" ; Bmin ; " Hour=" ; Bhour ; " converted to string " ; Strtime ' Example 2: Converting System Second to Time - String Lsyssec = 123456789 Strtime = Time(lsyssec) Print "Time of Systemsecond " ; Lsyssec ; " is " ; Strtime ' Example 3: Converting Second of Day to Time - String Lsecofday = 12345 Strtime = Time(lsecofday) Print "Time of Second of Day " ; Lsecofday ; " is " ; Strtime ' Example 4: Converting System Second to defined Clock - Bytes (Second / Minute / Hour) Lsyssec = 123456789 Bsec = Time(lsyssec) Print "System Second " ; Lsyssec ; " converted to Sec=" ; Bsec ; " Min=" ; Bmin ; " Hour=" ; Bhour ; " (" ; Time(lsyssec) ; ")" ' Example 5: Converting Second of Day to defined Clock - Bytes (Second / Minute / Hour) Lsecofday = 12345 Bsec = Time(lsecofday) Print "Second of Day " ; Lsecofday ; " converted to Sec=" ; Bsec ; " Min=" ; Bmin ; " Hour=" ; Bhour ; " (" ; Time(lsecofday) ; ")" ' Example 6: Converting Time-string to defined Clock - Bytes (Second / Minute / Hour) Strtime = "07:33:12" Bsec = Time(strtime) Print "Time " ; Strtime ; " converted to Sec=" ; Bsec ; " Min=" ; Bmin ; " Hour=" ; Bhour ' ============================= Date ========================================== ' Example 1: Converting defined Clock - Bytes (Day / Month / Year) to Date - String Bday = 29 : Bmonth = 4 : Byear = 12 Strdate = Date(bday) Print "Dat values: Day=" ; Bday ; " Month=" ; Bmonth ; " Year=" ; Byear ; " converted to string " ; Strdate ' Example 2: Converting from System Day to Date - String Wsysday = 1234 Strdate = Date(wsysday) Print "System Day " ; Wsysday ; " is " ; Strdate ' Example 3: Converting from System Second to Date String Lsyssec = 123456789 Strdate = Date(lsyssec) Print "System Second " ; Lsyssec ; " is " ; Strdate ' Example 4: Converting SystemDay to defined Clock - Bytes (Day / Month / Year) Wsysday = 2000 Bday = Date(wsysday) Print "System Day " ; Wsysday ; " converted to Day=" ; Bday ; " Month=" ; Bmonth ; " Year=" ; Byear ; " (" ; Date(wsysday) ; ")" ' Example 5: Converting Date - String to defined Clock - Bytes (Day / Month / Year) Strdate = "04-08-31" Bday = Date(strdate) Print "Date " ; Strdate ; " converted to Day=" ; Bday ; " Month=" ; Bmonth ; " Year=" ; Byear ' Example 6: Converting System Second to defined Clock - Bytes (Day / Month / Year) Lsyssec = 123456789 Bday = Date(lsyssec) Print "System Second " ; Lsyssec ; " converted to Day=" ; Bday ; " Month=" ; Bmonth ; " Year=" ; Byear ; " (" ; Date(lsyssec) ; ")" ' ================ Second of Day elapsed Lsecofday = Secofday() _hour = _hour + 1 Lvar1 = Secelapsed(lsecofday) Print Lvar1 Lsyssec = Syssec() _day = _day + 1 Lvar1 = Syssecelapsed(lsyssec) Print Lvar1 Looptest: ' Initialising for testing _day = 1 _month = 1 _year = 1 _sec = 12 _min = 13 _hour = 14 Do If _year > 50 Then Exit Do End If _sec = _sec + 7 If _sec > 59 Then Incr _min _sec = _sec - 60 End If _min = _min + 2 If _min > 59 Then Incr _hour _min = _min - 60 End If _hour = _hour + 1 If _hour > 23 Then Incr _day _hour = _hour - 24 End If _day = _day + 1 If _day > 28 Then Select Case _month Case 1 Mday = 31 Case 2 Mday = _year And &H03 If Mday = 0 Then Mday = 29 Else Mday = 28 End If Case 3 Mday = 31 Case 4 Mday = 30 Case 5 Mday = 31 Case 6 Mday = 30 Case 7 Mday = 31 Case 8 Mday = 31 Case 9 Mday = 30 Case 10 Mday = 31 Case 11 Mday = 30 Case 12 Mday = 31 End Select If _day > Mday Then _day = _day - Mday Incr _month If _month > 12 Then _month = 1 Incr _year End If End If End If If _year > 99 Then Exit Do End If Lsecofday = Secofday() Lsyssec = Syssec() Bweekday = Dayofweek() Wdayofyear = Dayofyear() Wsysday = Sysday() Print Time$ ; " " ; Date$ ; " " ; Lsecofday ; " " ; Lsyssec ; " " ; Bweekday ; " " ; Wdayofyear ; " " ; Wsysday Loop End 'only when we use I2C for the clock we need to set the clock date time #if Clockmode = 0 'called from datetime.lib Dim Weekday As Byte Getdatetime: I2cstart ' Generate start code I2cwbyte Ds1307w ' send address I2cwbyte 0 ' start address in 1307 I2cstart ' Generate start code I2cwbyte Ds1307r ' send address I2crbyte _sec , Ack I2crbyte _min , Ack ' MINUTES I2crbyte _hour , Ack ' Hours I2crbyte Weekday , Ack ' Day of Week I2crbyte _day , Ack ' Day of Month I2crbyte _month , Ack ' Month of Year I2crbyte _year , Nack ' Year I2cstop _sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour) _day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year) Return Setdate: _day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year) I2cstart ' Generate start code I2cwbyte Ds1307w ' send address I2cwbyte 4 ' starting address in 1307 I2cwbyte _day ' Send Data to SECONDS I2cwbyte _month ' MINUTES I2cwbyte _year ' Hours I2cstop Return Settime: _sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour) I2cstart ' Generate start code I2cwbyte Ds1307w ' send address I2cwbyte 0 ' starting address in 1307 I2cwbyte _sec ' Send Data to SECONDS I2cwbyte _min ' MINUTES I2cwbyte _hour ' Hours I2cstop Return #endif Weekdays: Data "Monday" , "Tuesday" , "Wednesday" , "Thursday" , "Friday" , "Saturday" , "Sunday" CONFIG CLOCKDIV Top Previous Next Action Sets the clock divisor. Syntax CONFIG CLOCKDIV = constant Remarks constant The clock division factor to use. Possible values are 1 , 2 , 4 , 8 ,16 , 32 ,64 , 128 and 256. The options to set the clock divisor is available in most new chips. Under normal conditions the clock divisor is one. Thus an oscillator value of 8 MHz will result in a system clock of 8 MHz. With a clock divisor of 8, you would get a system clock of 1 MHz. Low speeds can be used to generate an accurate system frequency and for low power consumption. Some chips have a 8 or 16 division enabled by default by a fuse bit. You can then reprogram the fuse bit or you can set the divisor from code. When you set the clock divisor take care that you adjust the $CRYSTAL directive also. $CRYSTAL specifies the clock frequency of the system. So with 8 MHz clock and divisor of 8 you would specify $CRYSTAL = 1000000. Some older chips use a different method for clock division. These chips do not support CONFIG CLOCK but they might support CLOCKDIVSION. See also $CRYSTAL , CLOCKDIVISION Example CONFIG CLOCKDIV = 8 'we divide 8 MHz crystal clock by 8 resulting in 1 MHz speed CONFIG COM1 Top Previous Next Action Configures the UART of AVR chips that have an extended UART like the M8. Syntax CONFIG COM1 = baud , synchrone=0|1,parity=none|disabled|even|odd,stopbits=1|2,databits=4|6|7|8|9,clockpol=0|1 Remarks baud Baud rate to use. Use 'dummy' to leave the baud rate at the $baud value. synchrone 0 for asynchrone operation (default) and 1 for synchrone operation. Parity None, disabled, even or odd Stopbits The number of stop bits : 1 or 2 Databits The number of data bits : 4,5,7,8 or 9. Clockpol Clock polarity. 0 or 1. Note that not all AVR chips have the extended UART. Most AVR chips have a UART with fixed communication parameters. These are : No parity, 1 stop bit, 8 data bits. Normally you set the BAUD rate with $BAUD or at run time with BAUD. You may also set the baud rate when you open the COM channel. It is intended for the Mega2560 that has 4 UARTS and it is simpler to specify the baud rate when you open the channel. It may also be used with the first and second UART but it will generate additional code since using the first UART will always result in generating BAUD rate init code. See Also CONFIG COM2 , CONFIG COMx Example '----------------------------------------------------------------------------------------- 'name : 'copyright : (c) 1995-2016, MCS Electronics 'purpose : test for M128 support in M128 mode 'micro : Mega128 'suited for demo : yes 'commercial addon needed : no '----------------------------------------------------------------------------------------- $regfile = "m128def.dat" ' specify the used micro $crystal = 4000000 ' used crystal frequency $baud = 19200 ' use baud rate $baud1 = 19200 $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space 'By default the M128 has the M103 compatibility fuse set. Set the fuse to M128 'It also runs on a 1 MHz internal oscillator by default 'Set the internal osc to 4 MHz for this example DCBA=1100 'use the m128def.dat file when you wanto to use the M128 in M128 mode 'The M128 mode will use memory from $60-$9F for the extended registers 'Since some ports are located in extended registers it means that some statements 'will not work on these ports. Especially statements that will set or reset a bit 'in a register. You can set any bit yourself with the PORTF.1=1 statement for example 'But the I2C routines use ASM instructions to set the bit of a port. These ASM instructions may 'only be used on port registers. PORTF and PORTG will not work with I2C. 'The M128 has an extended UART. 'when CONFIG COMx is not used, the default N,8,1 will be used Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Config Com2 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 'try the second hardware UART Open "com2:" For Binary As #1 'try to access an extended register Config Portf = Output 'Config Portf = Input Print "Hello" Dim B As Byte Do Input "test serial port 0" , B Print B Print #1 , "test serial port 2" Loop Close #1 End CONFIG COM2 Top Previous Next Action Configures the UART of AVR chips that have a second extended UART like the M128. Syntax CONFIG COM2 = baud , synchrone=0|1,parity=none|disabled|even|odd,stopbits=1|2,databits=4|6|7|8|9,clockpol=0|1 Remarks baud Baud rate to use. Use 'dummy' to leave the baud rate at the $baud1 value. synchrone 0 for asynchrone operation (default) and 1 for synchrone operation. Parity None, disabled, even or odd Stopbits The number of stopbits : 1 or 2 Databits The number of databits : 4,5,7,8 or 9. Clockpol Clock polarity. 0 or 1. Normally you set the BAUD rate with $BAUD or at run time with BAUD. You may also set the baud rate when you open the COM channel. It is intended for the Mega2560 that has 4 UARTS and it is simpler to specify the baud rate when you open the channel. It may also be used with the first and second UART but it will generate additional code since using the first or second UART will always result in generating BAUD rate init code. Note that not all AVR chips have the extended UART. Most AVR chips have a UART with fixed communication parameters. They are : No parity, 1 stopbit, 8 data bits. See Also CONFIG COM1 , CONFIG COMx Example '----------------------------------------------------------------------------------------- 'name : 'copyright : (c) 1995-2016, MCS Electronics 'purpose : test for M128 support in M128 mode 'micro : Mega128 'suited for demo : yes 'commercial addon needed : no '----------------------------------------------------------------------------------------- $regfile = "m128def.dat" ' specify the used micro $crystal = 4000000 ' used crystal frequency $baud = 19200 ' use baud rate $baud1 = 19200 $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space 'By default the M128 has the M103 compatibility fuse set. Set the fuse to M128 'It also runs on a 1 MHz internal oscillator by default 'Set the internal osc to 4 MHz for this example DCBA=1100 'use the m128def.dat file when you wanto to use the M128 in M128 mode 'The M128 mode will use memory from $60-$9F for the extended registers 'Since some ports are located in extended registers it means that some statements 'will not work on these ports. Especially statements that will set or reset a bit 'in a register. You can set any bit yourself with the PORTF.1=1 statement for example 'But the I2C routines use ASM instructions to set the bit of a port. These ASM instructions may 'only be used on port registers. PORTF and PORTG will not work with I2C. 'The M128 has an extended UART. 'when CONFIG COMx is not used, the default N,8,1 will be used Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Config Com2 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 'try the second hardware UART Open "com2:" For Binary As #1 'try to access an extended register Config Portf = Output 'Config Portf = Input Print "Hello" Dim B As Byte Do Input "test serial port 0" , B Print B Print #1 , "test serial port 2" Loop Close #1 End CONFIG COMx Top Previous Next Action Configures the UART of AVR chips that have an extended UART like the M2560. Syntax CONFIG COMx = baud , synchrone=0|1,parity=none|disabled|even|odd,stopbits=1|2,databits=4|6|7|8|9,clockpol=0|1 Syntax Xmega CONFIG COMx = baud , Mode=mode, Parity=parity, Stopbits=stopbits, Databits=databits Remarks COMx The COM port to configure. Value in range from 1-4 baud Baud rate to use. synchrone 0 for asynchrone operation (default) and 1 for synchrone operation. Parity None, disabled, even or odd Stopbits The number of stop bits : 1 or 2 Databits The number of data bits : 4,5,7,8 or 9. Clockpol Clock polarity. 0 or 1. Note that not all AVR chips have the extended UART. Most AVR chips have a UART with fixed communication parameters. These are : No parity, 1 stopbit, 8 data bits. The Mega2560 does support 4 UART's. Remarks Xmega COMx The COM port to configure. Value in range from 1-8 baud Baud rate to use. If the baud rate can be generated accurately depends on the system clock. mode The USART mode, this can be : - ASYNCHRONEOUS or 0 (default) for asynchronous operation. - SYNCHRONEOUS or 1 , for synchronous operation. - IRDA or IRCOM for IRDA operation - SPI or MSPI for operation as SPI controller Parity None, disabled, even or odd Stopbits The number of stop bits : 1 or 2 Databits The number of data bits : 5,6,7,8 or 9. In the Xmega the registers have a fixed offset. This allows to use dynamic UARTS : you can change settings at run time by using a variable. This will use some more code when using just one UART but will save code when using multiple UARTS because you need only one copy of the code. In the Xmega you MUST use CONFIG COM before you can use the UART. The CONFIG commands makes a call to _INIT_XMEGA_UART where the various parameters are passed to setup the UART. You also need to specify the baud rate. Do not use $BAUD. The CLOCKPOL for the SPI mode has been removed, it will be added to a configuration command for the SPI. The CONFIG COM will set the TX pin to output mode. This are the following pins : UART TX pin RX pin BAUD COM1 - UART_C0 PORTC.3 PORTC.2 BAUD COM2 - UART_C1 PORTC.7 PORTC.6 BAUD1 COM3 - UART_D0 PORTD.3 PORTD.2 BAUD2 COM4 - UART_D1 PORTD.7 PORTD.6 BAUD3 COM5 - UART_E0 PORTE.3 PORTE.2 BAUD4 COM6 - UART_E1 PORTE.7 PORTE.6 BAUD5 COM7 - UART_F0 PORTF.3 PORTF.2 BAUD6 COM8 - UART_F1 PORTF.7 PORTF.6 BAUD7 In IRDA mode, depending on the module you use, it might be necessary to invert the logic level of the TX pin with CONFIG XPIN. For example when COM1 is used for the IRDA module, you would use : CONFIG XPIN=PORTC.3, INVERTIO=ENABLED It is important that you specify all parameters of CONFIG COM. Do not omit one. See Also CONFIG COM1 , CONFIG COM2 Example '----------------------------------------------------------------------------------------- 'name : 'copyright : (c) 1995-2016, MCS Electronics 'purpose : test for M2560 support 'micro : Mega2560 'suited for demo : yes 'commercial addon needed : no '----------------------------------------------------------------------------------------- $regfile = "m2560def.dat" ' specify the used micro $crystal = 8000000 ' used crystal frequency $hwstack = 40 ' default use 32 for the hardware stack $swstack = 40 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space 'The M128 has an extended UART. 'when CO'NFIG COMx is not used, the default N,8,1 will be used Config Com1 = 19200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Config Com2 = 19200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Config Com3 = 19200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Config Com4 = 19200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 'Open all UARTS Open "com2:" For Binary As #1 Open "Com3:" For Binary As #2 Open "Com4:" For Binary As #3 Print "Hello" 'first uart Dim B As Byte Dim Tel As Word Do Incr Tel Print Tel ; " test serial port 1" Print #1 , Tel ; " test serial port 2" Print #2 , Tel ; " test serial port 3" Print #3 , Tel ; " test serial port 4" B = Inkey(#3) If B <> 0 Then Print #3 , B ; " from port 4" End If Waitms 500 Loop Close #1 Close #2 Close #3 End CONFIG DACx Top Previous Next Action This statement configures the DACA or DACB in the Xmega. Syntax CONFIG DACx=dac, IO0=IO0, IO1=IO1, INTERNAL_OUTPUT =INTOTP, CHANNEL=channel, TRIGGER_CH0=trig0, TRIGGER_CH1=trig1, REFERENCE=ref, LEFT_ADJUSTED=adjusted, EVENT_CHANNEL=event, INTERVAL=interval, REFRESH=refresh Remarks DACX Chose either DACA or DACB. DACA is connected to PORTA. DACB is connected to PORTB. dac ENABLED or DISABLED. Chose ENABLED to enable the DAC. IO0 ENABLED or DISABLED. Chose ENABLED to enable output 0. Each DAC has 2 outputs. When multiple outputs are used, the DAC is using S&H. IO1 ENABLED or DISABLED. Chose ENABLED to enable output 1. Intotp ENABLED or DISABLED. Chose ENABLED to enable the internal output. Channel SINGLE or DUAL. If both outputs are used, you need to enable the second output with IO1. Trig0 ENABLED or DISABLED. Chose ENABLED to enable the trigger of channel 0. Trig1 ENABLED or DISABLED. Chose ENABLED to enable the trigger of channel 1. Ref The DAC needs a stable voltage reference. You can chose one of the following: - INT1V. This will select the internal 1V reference - AVCC. This will use AVCC as reference. - AREFA. This will use AREFA as reference. - AREFB. This will use AREFB as reference. The output of the DAC can never be higher then the voltage reference. When you chose INT1V, the output is from 0-1V in 4096 steps. Adjusted ENABLED or DISABLED. By default the DAC output is right adjusted (this means the first 8 Bit are in the Low Byte and the following 4 Bit in the High Byte of the 16-bit Register). You can left alight the result. Event The event channel to use for the event system. Interval The minimum interval between 2 conversions. This is a value of : 1,2,4,8,16,32,64 or 128. The default in the register is 64. A value of 64 will give an interval of 64 clock cycles. The value is set in clock cycles and the time in µ Second depend on the CLKper (Peripheral Clock) setting. The minimum in SINGLE Channel mode is 1µS (1M conversions per seconds). The minimum in DUAL Channel mode (S/H mode) should no be below 1.5µS (666K conversions per second). In DUAL Channel mode the 50% increase of peripheral clock cycles is AUTOMATICALLY added by the XMEGA chip. Refresh The DAC channel refresh timing. This is the interval refresh time in DUAL channel mode. Possible values: OFF 16, 32, 128, 256, 512, 1014, 2048, 4096, 8192, 16384, 32768, 65536. A value of 16 means an interval of 16 clock cycles. The default loaded is 64. Note: Higher refresh rates causes higher power consumption. Manual conversions or Events between the refresh intervals do NOT affect the refresh intervals. This means the channels will be refreshed at a constant timing even when the data register are for example updated in between. The DAC data register is available in the DACA0, DACA1 and DACB0 and DACB1 variables. The DAC module can output conversion rates up to 1 M conversions per second with a resolution of 12 bits. A DAC conversion can be triggered by: · writing to the DAC data register (DACA0, DACA1 and DACB0 and DACB1) · an Event over Event System (when configured to trigger from Event system the DAC data register can be updated several times without triggering an conversion. In case of an Event the latest value in the DAC data register will be used for conversion) Trigger mode can be different between DAC Channels. For example DAC Channel 0 can be setup to work with Events while Channel 1 can be configured to start conversion when DAC data register is updated. How to handle the two Data Channels with one conversion Block: ' +-----------+ +------------------+ ' | Channel 0 | -------->| |-----> Out 0 ' +-----------+ | CONVERSION BLOCK | ' +-----------+ | | ' | Channel 1 | -------->| |-----> Out 1 ' +-----------+ +------------------+ ' | ' | ' Event System The fact that there are two data channels but one conversion block it needs to be configured by CHANNEL. · If Channel is SINGLE: Channel 0 is used in continuous-drive output mode and Channel 0 is then always connected to conversion block. · If Channel is DUAL: Both channels work in Sample and Hold (S/H) mode. The Sample and Hold keep the DAC output values during a conversion of the other channel. To refresh the output value in DUAL channel mode the refresh timing can be set. What can you drive with the XMEGA DAC outputs ? - The ouputs can drive loads of 1KOhm or capacitive loads of 100pF It is possible to use the XMEGA DMA Controller to output data on DAC Channels. See CONFIG DMACHx, CONFIG DMA See also Example Nr 2 below. Calibration of DAC: To Calibrate to DAC you can use the values from the signature row or you can change manual the Dacb_ch0offsetcal and Dacb_gaincal register. For example for using signature row for DACB Ch0 this is: 'DACB B = Readsig(32) 'DACB Calibration Byte 0 (DACBOFFCAL) Dacb_ch0offsetcal = B 'write to the DACB offset register Print #1 , "DACB Calibration Byte 0 = " ; B B = Readsig(33) 'DACB Calibration Byte 1 (DACBGAINCAL) Dacb_gaincal = B Print #1 , "DACB Calibration Byte 1 = " ; B See also Atmel Application Note AVR1301 for further details. See also START , STOP, CONFIG EVENT_SYSTEM Example Nr 1: (For another example see also the example xm128a1.bas from the samples\chips folder) $regfile = "xm256a3bdef.dat" $crystal = 32000000 '32MHz $hwstack = 64 $swstack = 40 $framesize = 40 Config Osc = Disabled , 32mhzosc = Enabled '32MHz 'configure the systemclock Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 Config Com7 = 57600 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 'Portf.2 and Portf.3 is COM7 Open "COM7:" For Binary As #1 Dim Var As Byte Config Portf.0 = Output Led1 Alias Portf.0 Config Portf.1 = Output Led2 Alias Portf.1 Config Dacb = Enabled , Io0 = Enabled , Channel = Single , Reference = Int1v , Interval = 64 , Refresh = 64 Dacb0 = 4095 '1 V output on portb.2 'Start Dacb ' to enable it 'Stop Dacb ' to disable it Do Incr Var Waitms 500 Dacb0 = 4095 '1 V output on portb.2 Set Led1 Reset Led2 Waitms 500 Reset Led1 Dacb0 = 0 '0 V output on portb.2 Set Led2 Print #1 , "Tick " ; Var Loop End 'end program Example Nr 2 (Ouput an Array of data from SRAM to DAC B over DMA): (This example is generating an sawtooth wave on DAC B Channel 0 = Portb.2 on ATXMEGA256A3B) ' Ouput an Array of data from SRAM to DAC B over DMA ' Timing: Timer/Counter TC0 feed the Event Channel 0 ' Event Channel 0 feed the DAC B Channel 0 ' Array Channel_0(1) is a word array filled with values ' DMA Channel 0 start at Channel_0(1) and increment until 8192 Byte (= 2*4096). After the DMA transaction the source address will be reloaded ' The destination address is the data register of DAC B Channel 0 and is incrementd once (to update the Low Byte and High Byte of the 12-Bit output value) 'Frequency of output signal = 32MHz/32 = 1MHz --> 1MHz/4096 (Sample_Count) = appx. 244Hz $regfile = "xm256a3bdef.dat" $crystal = 32000000 '32MHz $hwstack = 64 $swstack = 40 $framesize = 40 Config Osc = Disabled , 32mhzosc = Enabled '32MHz 'configure the systemclock Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 Config Priority = Static , Vector = Application , Lo = Enabled Config Com7 = 57600 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 'Portf.2 and Portf.3 is COM7 Open "COM7:" For Binary As #1 Print #1 , Print #1 , "Start DAC B Channel 0 over DMA Example" Dim Var As Byte Config Portf.0 = Output Led1 Alias Portf.0 Config Portf.1 = Output Led2 Alias Portf.1 Const Sample_count = 4096 'Number of 12-Bit Samples (Measurement Values) Dim Channel_0(sample_count) As Word 'Array Dim Dma_ready As Bit Dim Dma_channel_0_error As Bit Enable_dmach0 Alias Dma_ch0_ctrla.7 'Enable DMA Channel 0 Dim I As Word For I = 1 To 4096 'From 0V .....3.3Volt (with Reference = avcc) Channel_0(i) = I 'Generate a Sawtooth wave Next Config Tcc0 = Normal , Prescale = 1 'Setup Timer/Counter TC0 in nomal mode , Prescale = 1 --> no prescaler Tcc0_per = 31 '31 --> 32MHz/32 = 1MHz Config Event_system = Dummy , Mux0 = Tcc0_ovf 'TCC 0 overflow --> Event Channel 0 ' The xm256a3bd only have one DAC (DAC B) Config Dacb = Enabled , Io0 = Enabled , Channel = Single , Trigger_ch0 = Enabled , Event_channel = 0 , Reference = Avcc , Interval = 4 , Refresh = 16 ' DAC B Channel 0 is triggered by Event Channel 0 ' DMA Interrupt On Dma_ch0 Dma_ch0_int 'Interrupt will be enabled with Tci = XX in Config DMAX Config Dma = Enabled , Doublebuf = Disabled , Cpm = Rr ' enable DMA, Double Buffer disabled ' DMA Channel 0 is used here Config Dmach0 = Enabled , Burstlen = 2 , Chanrpt = Enabled , Tci = Lo , Eil = Lo , Singleshot = Enabled , _ Sar = Transaction , Sam = Inc , Dar = Burst , Dam = Inc , Trigger = &H25 , Btc = 8192 , Repeat = 0 , Sadr = Varptr(channel_0(1)) , Dadr = Varptr(dacb_ch0datal) ' Trigger = &H25 (DAC B Base Level Trigger) + Channel 0 = &H00 --> &H25 ' Burstlen is 2 byte because the DAC output value is a 12-Bit value you need to transfer 2 byte ' Source address (the array) is incremented until all bytes transfered (8192 byte) ' Destination address (DAC B Channel 0) is incremented once to transfer the low byte and high byte of the 12-bit value ' BTC = 8192 BYTE (needed to transfer the 4096 word) ' Reapeat = 0 --> repeat forever Enable Interrupts 'Frequency of output signal = 32MHz/32 = 1MHz --> 1MHz/4096 (Sample_Count) = appx. 244Hz Do Loop End 'end program '----------------------[Interrupt Service Routines]----------------------------- ' Dma_ch0_int is for DMA Channel ERROR Interrupt A N D for TRANSACTION COMPLETE Interrupt ' Which Interrupt fired must be checked in Interrupt Service Routine Dma_ch0_int: If Dma_intflags.0 = 1 Then 'Channel 0 Transaction Interrupt Flag Set Dma_intflags.0 'Clear the Channel 0 Transaction Complete flag Set Dma_ready End If If Dma_intflags.4 = 1 Then 'Channel 0 ERROR Flag Set Dma_intflags.4 'Clear the flag Set Dma_channel_0_error 'Channel 0 Error End If Return CONFIG DATE Top Previous Next Action Configure the Format of the Date String for Input to and Output from BASCOM � Date functions Syntax CONFIG DATE = DMY , Separator = char Remarks DMY The Day, month and year order. Use DMY, MDY or YMD. Char The character used to separate the day, month and year. Old syntax : / , - or . (dot). Preferred new syntax : MINUS, SLASH or DOT. Example: Config Date = DMY, SEPARATOR=MINUS The following table shows the common formats of date and the associated statements. Country Format Statement American mm/dd/yy Config Date = MDY, Separator = SLASH ANSI yy.mm.dd Config Date = YMD, Separator = DOT Britisch/French dd/mm/yy Config Date = DMY, Separator = SLASH German dd.mm.yy Config Date = DMY, Separator = DOT Italian dd-mm-yy Config Date = DMY, Separator = MINUS Japan/Taiwan yy/mm/dd Config Date = YMD, Separator = SLASH USA mm-dd-yy Config Date = MDY, Separator = MINUS When you live in Holland you would use : CONFIG DATE = DMY, separator = MINUS This would print 24-04-02 for 24 November 2002. When you line in the US, you would use : CONFIG DATE = MDY , separator = SLASH This would print 04/24/02 for 24 November 2002. See also CONFIG CLOCK , DATE TIME functions , DayOfWeek , DayOfYear , SecOfDay , SecElapsed , SysDay , SysSec , SysSecElapsed , Time , Date Example '----------------------------------------------------------------------------------------- 'name : megaclock.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : shows the new TIME$ and DATE$ reserved variables 'micro : Mega103 'suited for demo : yes 'commercial addon needed : no '----------------------------------------------------------------------------------------- $regfile = "m103def.dat" ' specify the used micro $crystal = 4000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space 'With the 8535 and timer2 or the Mega103 and TIMER0 you can 'easily implement a clock by attaching a 32768 Hz xtal to the timer 'And of course some BASCOM code 'This example is written for the STK300 with M103 Enable Interrupts '[configure LCD] $lcd = &HC000 'address for E and RS $lcdrs = &H8000 'address for only E Config Lcd = 20 * 4 'nice display from bg micro Config Lcdbus = 4 'we run it in bus mode and I hooked up only db4-db7 Config Lcdmode = Bus 'tell about the bus mode '[now init the clock] Config Date = Mdy , Separator = SLASH ' ANSI-Format Config Clock = Soft 'this is how simple it is 'The above statement will bind in an ISR so you can not use the TIMER anymore! 'For the M103 in this case it means that TIMER0 can not be used by the user anymore 'assign the date to the reserved date$ 'The format is MM/DD/YY Date$ = "11/11/00" 'assign the time, format in hh:mm:ss military format(24 hours) 'You may not use 1:2:3 !! adding support for this would mean overhead 'But of course you can alter the library routines used Time$ = "02:20:00" '--------------------------------------------------- 'clear the LCD display Cls Do Home 'cursor home Lcd Date$ ; " " ; Time$ 'show the date and time Loop 'The clock routine does use the following internal variables: '_day , _month, _year , _sec, _hour, _min 'These are all bytes. You can assign or use them directly _day = 1 'For the _year variable only the year is stored, not the century End CONFIG DCF77 Top Previous Next Action Instruct the compiler to use DCF-77 radio signal to get atom clock precision time Syntax CONFIG DCF77 = pin , timer = timer [ INVERTED=inv, CHECK=check, UPDATE=upd, UPDATETIME=updtime , TIMER1SEC=tmr1sec, SWITCHPOWER=swpwr, POWERPIN=pin, POWERLEVEL = pwrlvl , SECONDTICKS=sectick ,DEBUG=dbg , GOSUB = Sectic , PULSE=pulse ] Remarks PIN The input pin that is connected to the DCF-77 signal. This can be any micro processor pin that can be used as an input. TIMER The timer that is used to generate the compare interrupts, needed to determine the level of the DCF signal. Supported timers are : TIMER1. For Xmega : TCC0,TCC1,TCE0,TCE1,TCD0,TCD1,TCF0,TCF1 Xmega needs the MED priority set with CONFIG PRIORITY because the MED priority is used for the timer interrupt. INVERTED This value is 0 by default. When you specify 1, the compiler will assume you use an inverted DCF signal. Most DCF-77 receivers have a normal output and an inverted output. CHECK Check is 1 by default. The possible values are : 0 - The DCF-77 parity bits are checked. No other checks are performed. Use it when you have exceptional signal strength 1 - The received minutes are compared with the previous received minutes. And the difference must be 1. 2 - All received values(minutes, hours, etc. ) are compared with their previous received values. Only the minutes must differ with 1, the other values must be exactly the same. This value uses more internal ram but it gives the best check. Use this when you have bad signal reception. UPDATE Upd determines how often the internal date/time variables are updated with the DCF received values. The default value is 0. There are 3 possible values : 0 - Continuous update. The date and time variables are updated every time the correct values have been received 1 - Hourly update. The date and time variables are updated once an hour. 2- Daily update. The date and time variables are updated once a day. The UPDATE value also determines the maximum value of the UPDATETIME option. UPDATETIME This value depends on the used UPDATE parameter. When UPDATE is 1, the value must be in the range from 0-59. Start every hour at this minute with the new update. When UPDATE is 2, the value must be in the range from 0-23. Start every day at this hour with the new update. The default is 0. TIMER1SEC 16 bit timers with the right crystal value can generate a precise interrupt that fires every second. This can be used to synchronize only once a day or hour with the DCF values. The remaining time, the 1-sec interrupt will update the soft clock. By default this value is 0. SWITCHPOWER This option can be used to turn on/off the DCF-77 module with the control of a port pin. The default is 0. When you specify a value of 1, the DCF receiver will be switched off to save power, as soon as the clock is synchronized. POWERPIN The name of a pin like pinB.2 that will be used to turn on/off the DCF module. POWERLEVEL This option controls the level of the output pin that will result in a power ON for the module. 0 - When a logic 0 is applied to the power pin, the module is ON. 1 - When a logic 1 is applied to the power pin, the module is ON. Use a transistor to power the module. Do not power it from a port PIN directly. When you do power from a pin, make sure you sink the current. Ie : connect VCC to module, and GND of the module to ground. A logic 0 will then turn on the module. SECONDTICKS The number of times that the DCF signal state is read. This is the number of times per second that the interrupt is executed. This value is calculated by the compiler. The highest possible timer pre scale value is used and the lowest possible number of times that the interrupt is executed. This gives least impact on your main application. You can override the value by defining your own value. For example when you want to run some own code in the interrupt and need it to execute more often. DEBUG Optional value to fill 2 variables with debug info. DEBUG is on when a value of 1 is specified. By default, DEBUG is off. This has nothing to do with other DEBUG options of the compiler, it is only for the DCF77 code! When 1 is specified the compiler will create 2 internal variable named : bDCF_Pause and bDCF_Impuls. These values contain the DCF pulse length of the pause and the impulse. In the sample these values are printed. GOSUB The Sectic option will call a label in the main program every second. You have to insert this label yourself. You must also end it with a RETURN. The option is the same as used with CONFIG CLOCK PULSE This is an optional parameter that sets the pulse time in mS. The default is 150. When you have hardware that requires a shorter or longer pulse you can try a slightly higher or lower value. At all times you should use a value between 100 and 200 where 150 would be the optimum value. The DCF decoding routines use a status byte. This byte can be examined as in the example. The bits have the following meaning. Bit Explanation 0 The last reading of the DCF pin. 1 This bit is reserved. 2 This Bit is set, if after a complete time-stamp at second 58 the time-stamp is checked and it is OK. If after a minute mark (2 sec pause) this bit is set, the time from the DCF-Part is copied to the Clock-Part and this bit reset too. Every second mark also resets this bit. So time is only set, if after second 58 a minute mark follows. Normally this bit is only at value 1 from Second 58 to second 60/00. 3 This Bit indicates, that the DCF-Part should be stopped, if time is set. (at the option of updating once per hour or day). 4 This Bit indicated that the DCF-Part is stopped. 5 This bit indicates, that the CLOCK is configured the way, that during DCF-Clock is stopped, there is only one ISR-Call in one second. 6 This Bit determines the level of the DCF input-pin at the pulse (100/200 mSec part). 7 This bit indicates, that the DCF-Part has set the time of the Clock-part. See Also DCF77TIMEZONE You can read the Status-Bit 7 (DCF_Status.7), to check whether the internal clock was synchronized by the DCF-Part. You can also reset this Bit with RESET DCF_Status.7. The DCF-Part will set this bit again, if a valid time-stamp is received. You can read all other bits, but don�t change them. The DCF-77 signal is broadcasted by the German Time and Frequency department. The following information is copied from : http://www.ptb.de/en/org/4/44/_index.htm The main task of the department time and frequency is the realization and dissemination of the base unit time (second) and the dissemination of the legal time in the Federal Republic of Germany. The second is defined as the duration of 9 192 631 770 periods of the radiation corresponding to the transition between the two hyper fine levels of the ground state of the cesium-133 atom. For the realization and dissemination of the unit of time, the department develops and operates cesium atomic clocks as primary standards of time and frequency. In the past decades, these, as the worldwide most accurate atomic clocks, have contributed to the international atomic time scale (TAI) and represent the basis for the legal time in Germany. Dissemination of the legal time to the various users in industry, society, and research is performed via satellite, via a low frequency transmitter DCF77 and via an internet- and telephone service. The department participates in the tests for the future European satellite navigation system �Galileo�. Presently the primary clocks realizing the time unit are augmented by Cs clocks with laser cooled atoms (�Cs-fountain clocks�) whose accuracy presently exceeds the clocks with thermal beams by a factor of 10 (frequency uncertainty of 1 . 10-15). Future atomic clocks will most likely be based on atomic transitions in the optical range of single stored ions. Such standards are presently being developed along with the means to relate their optical frequencies without errors to radio-frequencies or 1 second pulsed. As one may expect transitions in nuclei of atoms to be better shielded from environmental perturbations than electron-shell transitions which have been used so far as atomic clock references, the department attempts to use an optical transition in the nucleus of 229Th for a future generation of atomic clocks. The work of the department is complemented by research in nonlinear optics (Solitons) and precision time transfer techniques, funded in the frame of several European projects and by national funding by Deutsche Forschungsgemeinschaft particularly in the frame of Sonderforschungsbereich 407 jointly with Hannover University. The following information is copied from wikipedia : http://en.wikipedia.org/wiki/DCF77 The signal can be received in this area: DCF77 is a long wave time signal and standard-frequency radio station. Its primary and backup transmitter are located in Mainflingen, about 25 km south-east of Frankfurt, Germany. It is operated by T-Systems Media Broadcast, a subsidiary of Deutsche Telekom AG, on behalf of the Physikalisch-Technische Bundesanstalt, Germany's national physics laboratory. DCF77 has been in service as a standard-frequency station since 1959; date and time information was added in 1973. The 77.5 kHz carrier signal is generated from local atomic clocks that are linked with the German master clocks in Braunschweig. With a relatively-high power of 50 kW, the station can be received in large parts of Europe, as far as 2000 km from Frankfurt. Its signal carries an amplitude-modulated, pulse-width coded 1 bit/s data signal. The same data signal is also phase modulated onto the carrier using a 511-bit long pseudo random sequence (direct-sequence spread spectrum modulation). The transmitted data repeats each minute Map showing the range of the DCF77 signal. Map showing the range of the DCF77 signal. * the current date and time; * a leap second warning bit; * a summer time bit; * a primary/backup transmitter identification bit; * several parity bits. Since 2003, 14 previously unused bits of the time code have been used for civil defence emergency signals. This is still an experimental service, aimed to replace one day the German network of civil defense sirens. The call sign stands for D=Deutschland (Germany), C=long wave signal, F=Frankfurt, 77=frequency: 77.5 kHz. It is transmitted three times per hour in morse code. Radio clocks have been very popular in Europe since the late 1980s and most of them use the DCF77 signal to set their time automatically. For further reference see wikipedia, a great on line information resource. The DCF library parameters state diagram looks as following: If the SECTIC option is used, the Sectic Interrupt routine should not need more time, than to the next timer interrupt. If you use a timer for dcf (and softclock) usually with 40 tics per second, the Sectic routine should take only less than 25msec. If the Sectic routines needs more than this limit, you will lose accuracy of the softclock time (especially during the time, where the clock is not synchronized by DCF) and also measurement of the length of the DCF-pulses. If the SECTIC routine needs more time than the short DCF-pulse (100ms, with some instability in DCF-receiver may be 80ms) you will lose synchronization with the DCF-signal. It is the principle of the DCF-routine, that the timer-interrupt measures the DCF-Pulse length and if you need more time in the interrupt routine as the duration from one timer interrupt to the next, you will get a problem. Thus keep the SECTIC routine as short as possible and set a flag in the SECTIC routine, which is checked in a loop of the main-program. See also CONFIG DATE ASM _DCF77 from DCF77.LBX is included by the compiler when you use the CONFIG statement. Example $regfile = "M88def.dat" $crystal = 8000000 $hwstack = 128 $swstack = 128 $framesize = 128 $baud = 19200 'Config Dcf77 = Pind.2 , Debug = 1 , Inverted = 0 , Check = 2 , Update = 0 , Updatetime = 30 , Switchpower = 0 , Secondticks = 50 , Timer1sec = 1 , Powerlevel = 1 , Timer = 1 Config Dcf77 = Pind.2 , Timer = 1 , Timer1sec = 1 , Debug = 1 Enable Interrupts Config Date = Dmy , Separator = . Dim I As Integer Dim Sec_old As Byte , Dcfsec_old As Byte Sec_old = 99 : Dcfsec_old = 99 ': DCF_Debug_Timer = 0 ' Testroutine für die DCF77 Clock Print "Test DCF77 Version 1.00" Do For I = 1 To 78 Waitms 10 If Sec_old <> _sec Then Exit For End If If Dcfsec_old <> Dcf_sec Then Exit For End If Next Waitms 220 Sec_old = _sec Dcfsec_old = Dcf_sec Print Time$ ; " " ; Date$ ; " " ; Time(dcf_sec) ; " " ; Date(dcf_day) ; " " ; Bin(dcf_status) ; " " ; Bin(dcf_bits) ; " " ; Bdcf_impuls ; " " ; Bdcf_pause Loop End CONFIG DEBOUNCE Top Previous Next Action Configures the delay time for the DEBOUNCE statement. Syntax CONFIG DEBOUNCE = time Remarks Time A numeric constant which specifies the delay time in mS. The maximum delay is 65535. When debounce time is not configured, 25 mS will be used as a default. See also DEBOUNCE Example '----------------------------------------------------------------------------------------- 'name : deboun.bas 'copyright : (c) 1995-2016, MCS Electronics 'purpose : demonstrates DEBOUNCE 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no '----------------------------------------------------------------------------------------- $regfile = "m48def.dat" ' specify the used micro $crystal = 4000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Debounce = 30 'when the config statement is not used a default of 25mS will be used 'Debounce Pind.0 , 1 , Pr 'try this for branching when high(1) Debounce Pind.0 , 0 , Pr , Sub Debounce Pind.0 , 0 , Pr , Sub ' ^----- label to branch to ' ^---------- Branch when P1.0 goes low(0) ' ^---------------- Examine P1.0 'When Pind.0 goes low jump to subroutine Pr 'Pind.0 must go high again before it jumps again 'to the label Pr when Pind.0 is low Debounce Pind.0 , 1 , Pr 'no branch Debounce Pind.0 , 1 , Pr 'will result in a return without gosub End Pr: Print "PIND.0 was/is low" Return CONFIG DMA Top Previous Next Action Configures the direct memory access (DMA) module of the XMEGA. Syntax CONFIG DMA=enabled|disabled, DOUBLEBUF=db, CPM=cpm Remarks DMA By default the DMA is disabled. Use ENABLED to enable the module. db DOUBLE BUFFER This options will set the double buffer mode. By default is is DISABLED. To allow for continuous transfer, two channels can be interlinked so that the second takes over the transfer when the first is finished and vice versa. This is called double buffering. When a transmission is completed for the first channel, the second channel is enabled. When a request is detected on the second channel, the transfer starts and when this is completed the first channel is enabled again Modes : - DISABLED : No double buffer enabled - CH01 : Double buffer enabled on channel0/1 - CH23 : Double buffer enabled on channel2/3 - CH01CH23 : Double buffer enabled on channel0/1 and channel2/3 cpm Channel Priority Mode If several channels request data transfer at the same time a priority scheme is available to determine which channel is allowed to transfer data. Application software can decide whether one or more channels should have a fixed priority or if a round robin scheme should be used. A round robin scheme means that the channel that last transferred data will have the lowest priority Modes : RR : Round Robin CH0RR123 : Channel0 > Round Robin (Channel 1, 2 and 3) CH01RR23 : Channel0 > Channel1 > Round Robin (Channel 2 and 3) CH0123 : Channel0 > Channel1 > Channel2 > Channel3 You also need to set the individual DMA channels using CONFIG DMACHx. See also CONFIG DMACHx , START DMACHx , CONFIG EDMA , CONFIG EDMAx Example See CONFIG DMACHx CONFIG DMACHx Top Previous Next Action Configures the direct memory access (DMA) channel of the XMEGA. Syntax CONFIG DMACHx=enabled|disabled,BURSTLEN=bl, CHANRPT=chrpt, CTR=ctr, SINGLESHOT=ss, TCI=tci, EIL=eil,SAR=sar, SAM=sam,DAR=dar,DAM=dam, TRIGGER,trig, BTC=btc, REPEAT=rpt,SADR=sadr, DADR=dadr Remarks In order to understand the various options better, we first have a better look at DMA. Normally, when you want to transfer data, the processor need to execute a number of operations. The BASCOM MEMCOPY for example will use processor instructions like LD (load data) and ST(store data) in a loop. If you want to clear 32KB of memory you need at least 32 K instructions. This will consume time, and all this time the processor can not handle other tasks. In a PC, you do not want to use the processor to be busy when you load a file from disk. The DMA controller will handle this. It can move blocks of memory between devices. You can also send for example an array in SRAM to an USART over DMA so the processor will not be busy handling the transfer from the Array to the USART. See also the example below. There is also an example to receive bytes over USART to SRAM in the Bascom-AVR/Samples folders. Before CONFIG DMACHx can be used you need to use Config Dma (CONFIG_DMA) DMA Transaction A complete DMA read and write operation between memories and/or peripherals is called a DMA transaction. A transaction is done in data blocks and the size of the transaction (number of bytes to transfer) is selectable from software and controlled by the block size and repeat counter settings. Each block transfer is divided into smaller bursts Block Transfer and Repeat The size of the block transfer is set by the Block Transfer Count Register, and can be anything from 1 byte to 64 KBytes. A repeat counter can be enabled to set a number of repeated block transfers before a transaction is complete. The repeat is from 1 to 255 and unlimited repeat count can be achieved by setting the repeat count to zero. Burst Transfer As the AVR CPU and DMA controller use the same data buses a block transfer is divided into smaller burst transfers. The burst transfer is selectable to 1, 2, 4, or 8 bytes. This means that, if the DMA acquires a data bus and a transfer request is pending it will occupy the bus until all bytes in the burst transfer is transferred. A bus arbiter controls when the DMA controller and the AVR CPU can use the bus. The CPU always has priority, so as long as the CPU request access to the bus, any pending burst transfer must wait. The CPU requests bus access when it executes an instruction that write or read data to SRAM, I/O memory, EEPROM and the External Bus Interface DMACHx There are 4 DMA channels numbered 0-3. By default these DMA channels are disabled. Use ENABLED to enable the channel. bl BURSTLEN Each DMA channel has an internal transfer buffer that is used for 2, 4 and 8 byte burst transfers. When a transfer is triggered, a DMA channel will wait until the transfer buffer contains two bytes before the transfer starts. For 4 or 8 byte transfer, any remaining bytes is transferred as soon as they are ready for a DMA channel. The buffer is used to reduce the time the DMA controller occupy the bus. Options : - 1 : 1 byte burst mode - 2 : 2 byte burst mode - 4 : 4 byte burst mode - 8 : 8 byte burst mode chanrpt Channel Repeat Setting this bit enables the repeat mode. In repeat mode, this bit is cleared by hardware in the beginning of the last block transfer. The REPCNT register should be configured before setting the REPEAT bit. When using the CONFIG command, the compiler will handle this. Options : Enabled : enabled repeat mode Disabled : disabled repeat mode ctr DMA Channel Transfer Request Setting this bit requests a data transfer on the DMA Channel. This bit is automatically cleared at the beginning of the data transfer Options : Enabled : request transfer ss DMA Channel Single Shot Data transfer Setting this bit enables the single shot mode. The channel will then do a burst transfer of BL bytes on the transfer trigger. This bit can not be changed if the channel is busy. Options : Enabled : enable SS mode. tci DMA Channel Transaction Complete Interrupt Level The interrupt can be turned OFF, or be given a priority LO, MED or HI eil DMA Channel Error Interrupt Level The interrupt can be turned OFF, or be given a priority LO, MED or HI sar Source Address Reload The channel source address can be reloaded the following way: NONE : No reload performed. BLOCK : DMA source address register is reloaded with initial value at end of each block transfer. BURST : DMA source address register is reloaded with initial value at end of each burst transfer. TRANSACTION : DMA source address register is reloaded with initial value at end of each transaction. sam Source Address Mode The address can be altered the following way : FIXED : The address remains the same. INC : The address is incremented by one DEC : The address is decremented by one If you want to write to a PORT, for example to generate a wave, you would chose FIXED. But if you want to move a block of memory, you want to use INC so the the source address is increased after each byte. dar Channel Destination Address Reload The channel destiny address can be reloaded the following way: NONE : No reload performed. BLOCK : DMA destiny address register is reloaded with initial value at end of each block transfer. BURST : DMA destiny address register is reloaded with initial value at end of each burst transfer. TRANSACTION : DMA destiny address register is reloaded with initial value at end of each transaction. dam Destiny Address Mode The address can be altered the following way : FIXED : The address remains the same. INC : The address is incremented by one DEC : The address is decremented by one If you want to write to a PORT, for example to generate a wave, you would chose FIXED. But if you want to move a block of memory, you want to use INC so the the source address is increased after each byte. In case of an byte array it would start with array(1) and the next byte would be array(2) which will be transferred and so on. trigger Trigger Source Select The trigger selected which device triggers the DMA transfer. A zero (0) will disable a trigger. You can manual start a DATA TRANSFER with START DMACHx statement. You can find the hardware trigger values in the datasheet. For example, EVENTSYS channel 0 would be 1. And EVENSTYS channel 1 would be 1. In case of for example an USART you need to add the base value and add an offset. Example: Base value for USARTC0 is &H4B Offset for (RXC) Receive complete is &H00 Offset for (DRE) Data Register Empty is &H01 So when you want to use the DRE the trigger is &H4B + &H01 = &H4C btc Block Transfer Count The BTC represents the 16-bit value TRFCNT. Which also means the max value is 64Kbyte. TRFCNT defines the number of bytes in a block transfer. The value of TRFCNT is decremented after each byte read by the DMA channel. When TRFCNT reaches zero, the register is reloaded with the last value written to it. When repeat is 1, this is the total amount of bytes to send in the DMA transaction. repeat Repeat Counter Register REPCNTcounts how many times a block transfer is performed. For each block transfer this register will be decremented. Unlimited repeat is activated by setting this register to 0. sadr Source Address This is the address of the DMA source. For example, the address of a variable. Or the address of a register. Use VARPTR() to find the address of a variable. For example if the source address is an array: sadr = varptr(ar(1)) For example if the source address is an hardware address like from an USART: sadr = Varptr(usarte0_data) or ADC A Channel 0: Sadr = Varptr(adca_ch0_res) dadr Destination Address The destiny address. This can be also for example an array in SRAM: dadr = varptr(dest(1)) This can be also for example a hardware recourse like USART: Dadr = Varptr(usarte0_data) or for example for DAC B Channel 0: Dadr = Varptr(dacb_ch0datal) After you have configured the DMA channel, you can start the transfer with the START DMACHx statement. This will write the TRFREQ bit in the CTRLA register. Setting the TRFREQ Bit (DMA Channel Transfer Request) requests a DATA TRANSFER on the DMA channel. Setting this bit requests a data transfer on the DMA Channel. This bit is automatically cleared at the beginning of the data transfer. To enable the DMA Channel you need to set the Dma_chX_ctrla.7 bit. For example for DMA Channel 0 this is Set Dma_ch0_ctrla.7 Setting this bit enables the DMA channel. This bit is automatically cleared when the transaction is completed. See also CONFIG DMA , START DMACHx, ATXMEGA , CONFIG EDMA , CONFIG EDMAx Example (copy SRAM Array to another SRAM Array over DMA): '---------------------------------------------------------------- ' (c) 1995-2016, MCS ' xm128A1-DMA.bas ' This sample demonstrates DMA with an Xmega128A1 '----------------------------------------------------------------- $regfile = "xm128a1def.dat" $crystal = 32000000 $hwstack = 64 $swstack = 40 $framesize = 40 'first enable the osc of your choice Config Osc = Enabled , 32mhzosc = Enabled 'configure the systemclock Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 Config Com1 = 38400 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 dim ar(100) as byte, dest(100) as byte,j as byte ,w as word for j=1 to 100 ar(j)=j ' create an array and assign a value next print "DMA DEMO" config dma= enabled, doublebuf=disabled,cpm = RR ' enable DMA 'you can configure 4 DMA channels config dmach0=enabled ,burstlen=8,chanrpt=enabled, tci=off,eil=off, sar=none,sam=inc,dar=none,dam=inc ,trigger=0,btc=100 ,repeat =1,sadr=varptr(ar(1)),dadr=varptr(dest(1)) start dmach0 ' this will do a manual/software DMA transfer, when trigger<>0 you can use a hardware event as a trigger source for j=1 to 50 print j;"-";ar(j);"-";dest(j) ' print the values next end Example (send an array to USART over DMA): 'Terminal Output of following example: '( ----- Array to USART over DMA ----- Hello Bascom Hello XMEGA ') $regfile = "xm128a1def.dat" $crystal = 32000000 $hwstack = 64 $swstack = 40 $framesize = 40 'first enable the osc of your choice Config Osc = Enabled , 32mhzosc = Enabled 'configure the systemclock Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 Config Priority = Static , Vector = Application , Lo = Enabled ' DMA Interrupt On Dma_ch0 Dma_ch0_int 'Interrupt will be enabled with Tci = XX in Config DMAX Config Com5 = 38400 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 Open "COM5:" For Binary As #5 Dim My_array(15) As Byte Dim My_string As String * 14 At My_array(1) Overlay Dim Dma_ready As Bit Dim Dma_channel_0_error As Bit Enable_dmach0 Alias Dma_ch0_ctrla.7 'Enable DMA Channel 0 Print #5 , Print #5 , "----- Array to USART over DMA -----" Print #5 , Config Dma = Enabled , Doublebuf = Disabled , Cpm = Rr ' enable DMA 'configure DMA channel Config Dmach0 = Disabled , Burstlen = 1 , Chanrpt = Disabled , Tci = Lo , Eil = Off , Singleshot = Enabled , Sar = Transaction , _ Sam = Inc , Dar = None , Dam = Fixed , Trigger = &H8C , Btc = 14 , Repeat = 0 , Sadr = Varptr(my_array(1)) , Dadr = Varptr(usarte0_data) ' BURSTLEN = 1 ' Tci = Lo , Eil = Off --> enable TRANSACTION COMPLETE Interrupt ' Singleshot = Enabled --> Setting this bit enables the single shot mode. ' The channel will then do a burst transfer of BL bytes on the transfer trigger. ' SAR (Source Address Reload) = After each transaction ' SAM = inc --> source address is increased after each byte ' DAR = NONE --> No reload performed ' DAM (Destiny Address Mode) --> Fixed --> The address remains the same ' Trigger = &H8C --> Base Value of USARTE0 = &H8B + Offset for DRE (Data Register Empty)= 1 --> &H8C ' BTC = 14 --> Block Transfer Count is 14 Byte ' We start with Dmach0 = Disabled --> will be enabled when we need it ' Start dmach0 --> will set the TRFREQ Bit (DMA Channel Transfer Request). ' Setting this bit requests a DATA TRANSFER on the DMA channel. ' We use here Enable_dmach0 Alias Dma_ch0_ctrla.7 This bit is automatically cleared when the DMA TRANSACTION is completed Enable Interrupts My_string = "Hello Bascom" + Chr(13) + Chr(10) ' Hello Bascom + Carriage Return + Line Feed Set Enable_dmach0 ' Enable the DMA Channel 0 (This bit is automatically cleard when transaction is completed) Bitwait Dma_ready , Set ' Wait until first DMA transaction is ready (DMA TRANSACTION COMPLETE Interrupt) Reset Dma_ready My_string = "Hello XMEGA" + Chr(13) + Chr(10) Set Enable_dmach0 ' Enable the DMA Channel 0 (This bit is automatically cleard when transaction is completed) End '----------[Interrupt Service Routines]----------------------------------------- ' Dma_ch0_int is for DMA Channel ERROR Interrupt A N D for TRANSACTION COMPLETE Interrupt ' Which Interrupt fired must be checked in Interrupt Service Routine Dma_ch0_int: ' DMA Transaction complete If Dma_intflags.0 = 1 Then ' Channel 0 Transaction Interrupt Flag Set Dma_intflags.0 ' Clear the Channel 0 Transaction Complete flag Set Dma_ready End If '( If Dma_intflags.4 = 1 Then ' Channel 0 ERROR Flag Set Dma_intflags.4 ' Clear the flag Set Dma_channel_0_error ' Channel 0 Error End If ') Return CONFIG EDMA NEW 2080 Top Previous Next Action Configures the enhanced direct memory access (DMA) module of the XMEGA. Syntax CONFIG EDMA=enabled|disabled, DOUBLEBUF=db, CPM=cpm , CHM=chm Remarks DMA By default the DMA is disabled. Use ENABLED to enable the module. db DOUBLE BUFFER This options will set the double buffer mode. By default is is DISABLED. To allow for continuous transfer, two channels can be interlinked so that the second takes over the transfer when the first is finished and vice versa. This is called double buffering. When a transmission is completed for the first channel, the second channel is enabled. When a request is detected on the second channel, the transfer starts and when this is completed the first channel is enabled again Modes : - DISABLED : No double buffer enabled - CH01 : Double buffer enabled on channel0/1 - CH23 : Double buffer enabled on channel2/3 - CH01CH23 : Double buffer enabled on channel0/1 and channel2/3 cpm Channel Priority Mode If several channels request data transfer at the same time a priority scheme is available to determine which channel is allowed to transfer data. Application software can decide whether one or more channels should have a fixed priority or if a round robin scheme should be used. A round robin scheme means that the channel that last transferred data will have the lowest priority Modes : RR : Round Robin CH0RR123 : Channel0 > Round Robin (Channel 1, 2 and 3) CH01RR23 : Channel0 > Channel1 > Round Robin (Channel 2 and 3) CH0123 : Channel0 > Channel1 > Channel2 > Channel3 chm Channel Mode The channel mode selects the mode. Possible options for channel mode are : PER0123 : 4 peripheral channels 0,1,2,3 STD0 : 1 standard channel, 2 peripheral channels 2,3 STD2 : 2peripheral channels 0,1, 1 standard channel 2 STD02 : 2 standard channels 0,2 You also need to set the individual EDMA channels using CONFIG EDMACHx. See also CONFIG DMACHx , START DMACHx , CONFIG DMA , CONFIG EDMAx Example See CONFIG DMACHx CONFIG EDMAx NEW 2080 Top Previous Next Action Configures the enhanced direct memory access (DMA) channel of the XMEGA. Syntax CONFIG EDMACHx=enabled|disabled,BURSTLEN=bl, CHANRPT=chrpt, CTR=ctr, SINGLESHOT=ss, TCI=tci, EIL=eil,SAR=sar, SAM=sam,DAR=dar,DAM=dam, TRIGGER,trig, BTC=btc,SADR=sadr, DADR=dadr Remarks In order to understand the various options better, we first have a quick look at DMA. Please consult the help topic CONFIG DMAx and the atmel documentation for the EDMA. Normally, when you want to transfer data, the processor need to execute a number of operations. The BASCOM MEMCOPY for example will use processor instructions like LD (load data) and ST(store data) in a loop. If you want to clear 32KB of memory you need at least 32 K instructions. This will consume time, and all this time the processor can not handle other tasks. In a PC, you do not want to use the processor to be busy when you load a file from disk. The EDMA controller will handle this. It can move blocks of memory between devices while the processor performs other tasks. You can also send for example an array in SRAM to an USART over EDMA so the processor will not be busy handling the transfer from the Array to the USART. There is also an example to receive bytes over USART to SRAM in the Bascom-AVR/Samples folders. Before CONFIG EDMACHx can be use