RaspberryPi 4 - ADS1256 - The reading in registers don't work well - raspberry-pi4

I have a project that includes a RaspberryPi 4 and an ADS1256 ADC converter.
It managed to implement as read and write functions of the registers, which are working almost in their entirety, on reading and writing, but reading only once, not repeating for the same register.
The problem is:
When it is tried to read in the second time, the data returned is zero (0x00), including the bits that have no writing enabled.
Do you have any idea what could be some?
Conections:
| Pi 4|Module ADS1256|
+-----+----------------------+
| 4 | 1 | 5v
| 6 | 2 | gnd
| 11 | 6 | DRDY
| 12 | 7 | CS - Chip Select
| 13 | 8 | PDWN - Power Down
| 19 | 4 | DIN - Data In (Slave)
| 21 | 5 | DOUT - Data Out (Slave)
| 23 | 3 | SCLK
Attachment:
Schematic of Module ADS1256.
Main Code:
import ClassADS1256_Question, time
ads = ClassADS1256_Question.ADS1256()
# ----- Configuração Inicial ----
read = 1
while True:
time.sleep(2)
print('----- Read {} ------'.format(read))
# Registers Adress - Name - default value - Result
print('00h STATUS 3xh ', ads.ReadReg(ads.REG_STATUS))
print('01h MUX 01h ', ads.ReadReg(ads.REG_MUX))
print('02h ADCON 20h ', ads.ReadReg(ads.REG_ADCON))
print('03h DRATE F0h ', ads.ReadReg(ads.REG_DRATE))
print('04h IO E0h ', ads.ReadReg(ads.REG_IO))
print('05h OFC0 xxh ', ads.ReadReg(ads.REG_OFC0))
print('06h OFC1 xxh ', ads.ReadReg(ads.REG_OFC1))
print('07h OFC2 xxh ', ads.ReadReg(ads.REG_OFC2))
print('08h FSC0 xxh ', ads.ReadReg(ads.REG_FSC0))
print('09h FSC1 xxh ', ads.ReadReg(ads.REG_FSC1))
print('0Ah FSC2 xxh ', ads.ReadReg(ads.REG_FSC2))
read += 1
Result:
[----- Read 1 ------
#Register Address- Register's Name- Default Value - Result
00h STATUS 3xh 0x30
01h MUX 01h 0x1
02h ADCON 20h 0x20
03h DRATE F0h 0xf0
04h IO E0h 0xff
05h OFC0 xxh 0x67
06h OFC1 xxh 0x1
07h OFC2 xxh 0x0
08h FSC0 xxh 0x9f
09h FSC1 xxh 0x0
0Ah FSC2 xxh 0x45
----- Read 2 ------
00h STATUS 3xh 0x0
01h MUX 01h 0x0
02h ADCON 20h 0x0
03h DRATE F0h 0x0
04h IO E0h 0x0
05h OFC0 xxh 0x0
06h OFC1 xxh 0x0
07h OFC2 xxh 0x0
08h FSC0 xxh 0x0
09h FSC1 xxh 0x0
0Ah FSC2 xxh 0x0
----- Read 3 ------
00h STATUS 3xh 0x0
01h MUX 01h 0x0
02h ADCON 20h 0x0
03h DRATE F0h 0x0
04h IO E0h 0x0
05h OFC0 xxh 0x0
06h OFC1 xxh 0x0
07h OFC2 xxh 0x0
08h FSC0 xxh 0x0
09h FSC1 xxh 0x0
0Ah FSC2 xxh 0x0
----- Read 4 ------
00h STATUS 3xh 0x0
01h MUX 01h 0x0
02h ADCON 20h 0x0
03h DRATE F0h 0x0
04h IO E0h 0x0
05h OFC0 xxh 0x0
06h OFC1 xxh 0x0
07h OFC2 xxh 0x0
08h FSC0 xxh 0x0
09h FSC1 xxh 0x0
0Ah FSC2 xxh 0x0
----- Read 5 ------
00h STATUS 3xh 0x0
01h MUX 01h 0x0
02h ADCON 20h 0x0
03h DRATE F0h 0x0
04h IO E0h 0x0
05h OFC0 xxh 0x0
06h OFC1 xxh 0x0
07h OFC2 xxh 0x0
08h FSC0 xxh 0x0
09h FSC1 xxh 0x0
0Ah FSC2 xxh 0x0
Class (arquivo ClassADS1256_Question)
#Imports -----------------------------------------------------
import wiringpi as wp
#Class -------------------------------------------------------
class ADS1256:
#Constantes da Classe -----------------------------------------
#Constantes de Configuração
SPI_MODE = 1 #There are nothing about this on datasheet but is 1 # nas internet diz que ele é modo 1, mas no datasheet não fala
SPI_CHANNEL = 1 # I don't know why #não sei o que significa
SPI_FREQUENCY = 1000000 # The ADS1256 supports 768kHz to 1.92MHz
DRDY_TIMEOUT = 0.5 # Seconds to wait for DRDY when communicating
DATA_TIMEOUT = 0.00001 # 10uS delay for sending data
SCLK_FREQUENCY = 7680000 # default clock rate is 7.68MHz
#PINOUT #Constantes de Conexão Elétrica
CS_PIN = 12 #29 # mudei pra 29 e testei que é esse mesmo!!!
DRDY_PIN = 11
RESET_PIN = 29 # There are not acess to this port on module # Esse pino não tem no módulo
PDWN_PIN = 13
#Register Adress #Endereço dos Registradores
REG_STATUS = 0x00
REG_MUX = 0x01
REG_ADCON = 0x02
REG_DRATE = 0x03
REG_IO = 0x04
REG_OFC0 = 0x05
REG_OFC1 = 0x06
REG_OFC2 = 0x07
REG_FSC0 = 0x08
REG_FSC1 = 0x09
REG_FSC2 = 0x0A
# Data Rate #Taxa de Amostragem
DRATE_30000 = 0b11110000 # 30,000SPS (default)
DRATE_15000 = 0b11100000 # 15,000SPS
DRATE_7500 = 0b11010000 # 7,500SPS
DRATE_3750 = 0b11000000 # 3,750SPS
DRATE_2000 = 0b10110000 # 2,000SPS
DRATE_1000 = 0b10100001 # 1,000SPS
DRATE_500 = 0b10010010 # 500SPS
DRATE_100 = 0b10000010 # 100SPS
DRATE_60 = 0b01110010 # 60SPS
DRATE_50 = 0b01100011 # 50SPS
DRATE_30 = 0b01010011 # 30SPS
DRATE_25 = 0b01000011 # 25SPS
DRATE_15 = 0b00110011 # 15SPS
DRATE_10 = 0b00100011 # 10SPS
DRATE_5 = 0b00010011 # 5SPS
DRATE_2_5 = 0b00000011 # 2.5SPS
# Comandos
CMD_WAKEUP = 0x00 # Completes SYNC and exits standby mode
CMD_RDATA = 0x01 # Read data
CMD_RDATAC = 0x03 # Start read data continuously
CMD_SDATAC = 0x0F # Stop read data continuously
CMD_RREG = 0x10 # Read from register
CMD_WREG = 0x50 # Write to register
CMD_SELFCAL = 0xF0 # Offset and gain self-calibration
CMD_SELFOCAL= 0xF1 # Offset self-calibration
CMD_SELFGCAL= 0xF2 # Gain self-calibration
CMD_SYSOCAL = 0xF3 # System offset calibration
CMD_SYSGCAL = 0xF4 # System gain calibration
CMD_SYNC = 0xFC # Synchronize the A/D conversion
CMD_STANDBY = 0xFD # Begin standby mode
CMD_RESET = 0xFE # Reset to power-on values
#Status
STATUS_BUFFER_ENABLE = 0x02
STATUS_AUTOCAL_ENABLE = 0x04
STATUS_ORDER_LSB = 0x08
#Gain
AD_GAIN_1 = 0x00
AD_GAIN_2 = 0x01
AD_GAIN_4 = 0x02
AD_GAIN_8 = 0x03
AD_GAIN_16 = 0x04
AD_GAIN_32 = 0x05
AD_GAIN_64 = 0x06
# Clock divider
AD_CLK_EQUAL = 0x20
AD_CLK_HALF = 0x40
AD_CLK_FOURTH = 0x60
#Funções da Classe ------------------------------------------------------
# Função Iniciar
def __init__(self): # Note: A função __init__() é chamada automaticamente toda vez que a Classe está sendo usada para criar um novo objeto.
wp.wiringPiSetupPhys() # Set up the wiringpi object to use physical pin numbers
wp.pinMode(self.DRDY_PIN, wp.INPUT)# Initialize the DRDY pin
wp.pinMode(self.RESET_PIN, wp.OUTPUT)# Initialize the reset pin
wp.digitalWrite(self.RESET_PIN, wp.HIGH)
wp.pinMode(self.PDWN_PIN, wp.OUTPUT)# Initialize PDWN pin
wp.digitalWrite(self.PDWN_PIN, wp.HIGH)
wp.pinMode(self.CS_PIN, wp.OUTPUT)# Initialize CS pin
wp.digitalWrite(self.CS_PIN, wp.HIGH)
wp.wiringPiSPISetupMode(self.SPI_CHANNEL, self.SPI_FREQUENCY,self.SPI_MODE) # Initialize the wiringpi SPI setup
def WaitDRDY(self):
drdy_level = wp.digitalRead(self.DRDY_PIN)
while (drdy_level == wp.HIGH):
drdy_level = wp.digitalRead(self.DRDY_PIN)
def ReadReg(self, registrador): #Figure 34, Page 33 of ADS1256 Datasheet Version SBAS288K − JUNE 2003 − REVISED SEPTEMBER 2013
wp.digitalWrite(self.CS_PIN, wp.LOW) #Select Slave to SPI comunication #liga o chip select
wp.wiringPiSPIDataRW(self.SPI_CHANNEL, bytes([self.CMD_RREG | registrador]))#1st Command Byte: Comand Read plus Register to read
wp.wiringPiSPIDataRW(self.SPI_CHANNEL, bytes([0x00]))#2nd Command Byte #Total register to read more that one
wp.delayMicroseconds(60) #t6
lido = wp.wiringPiSPIDataRW(self.SPI_CHANNEL, bytes(0x01))
wp.digitalWrite(self.CS_PIN, wp.HIGH)
lido = hex(lido[1][0])
return lido
#return hex(ord(lido[1]))
def ReadAllReg(self):
#self.WaitDRDY()
wp.digitalWrite(self.CS_PIN, wp.LOW) #liga o chip select
wp.wiringPiSPIDataRW(self.SPI_CHANNEL, bytes([self.CMD_RREG]))#manda o comando ler e o registrador a ser lido
wp.wiringPiSPIDataRW(self.SPI_CHANNEL, bytes([0x0A]))#quantos resgistradores a mais quer ser lido. Vai seguir a sequencia da tabela de registradores
#self.DataDelay()
wp.delayMicroseconds(60)
lido = wp.wiringPiSPIDataRW(self.SPI_CHANNEL, bytes(0x0B))
wp.digitalWrite(self.CS_PIN, wp.HIGH)
print(lido)
def WriteReg(self, registrador, dado):
wp.digitalWrite(self.CS_PIN, wp.LOW)
wp.wiringPiSPIDataRW(self.SPI_CHANNEL, bytes([self.CMD_WREG | registrador]))
wp.wiringPiSPIDataRW(self.SPI_CHANNEL, bytes([0x00]))
wp.wiringPiSPIDataRW(self.SPI_CHANNEL, bytes([dado]))
wp.digitalWrite(self.CS_PIN, wp.HIGH)
wp.delayMicroseconds(10)# t11 minimo 4*Tclkin, 4*1/7680000 = 0.5 uS
def Reset(self):
wp.digitalWrite(self.CS_PIN, wp.LOW)
wp.wiringPiSPIDataRW(self.SPI_CHANNEL, bytes([self.CMD_RESET]))
wp.digitalWrite(self.CS_PIN, wp.HIGH)
wp.delayMicroseconds(8)
def ReadCanal(self):
result = []
self.WaitDRDY()
#self.WaitDRDY() # Espera o aviso de que pode ler
wp.digitalWrite(self.CS_PIN, wp.LOW) #chip select iniciando a comunicação
wp.wiringPiSPIDataRW(self.SPI_CHANNEL, bytes([self.CMD_RDATA])) # Enviando o comando Ler Dado
wp.delayMicroseconds(50) # delay t6
result.append(wp.wiringPiSPIDataRW(self.SPI_CHANNEL, bytes(0x01))[1][0]) #Lendo o primeiro Bit do dado
result.append(wp.wiringPiSPIDataRW(self.SPI_CHANNEL, bytes(0x01))[1][0]) #Lendo o segundo Bit do dado
result.append(wp.wiringPiSPIDataRW(self.SPI_CHANNEL, bytes(0x01))[1][0]) #Lendo o terceiro Bit do dado
wp.digitalWrite(self.CS_PIN, wp.HIGH) # Chip Select Desativando a comunicação
total = result[0] * 65536 # 2 ^ 16, equivalente a deslocar 16 casas decimais
total += result[1] * 256 # 2 ^ 8, equivalente a deslocar 8 casas decimais
total += result[2]
'''
print(hex(result[0]))
print(hex(result[1]))
print(hex(result[2]))
print(hex(total))
'''
return total
def SetInputMux(self,possel,negsel): #corrigir
print("Mux P {} N {}".format(possel,negsel))
wp.digitalWrite(self.CS_PIN, wp.LOW) #chip select ativado
wp.wiringPiSPIDataRW(self.SPI_CHANNEL, bytes([self.CMD_WREG | self.REG_MUX]))
wp.wiringPiSPIDataRW(self.SPI_CHANNEL, [0x00])
wp.wiringPiSPIDataRW(self.SPI_CHANNEL, [(possel<<4) | (negsel<<0)] )#corrigir aqui
wp.digitalWrite(self.CS_PIN, wp.HIGH) #chip select desativado

Related

Can I get 2 L9637 iso9141 single-wire transceivers talking to each other with an ESP32?

Eventually, I want to tap into the K-line of my Kawasaki Ninja with an (ISO 9141) OBD reader, using an ESP32 WROVER and a L9637 single-wire transceiver. To get there, I'm at the stage of confirming my L9637 chip is wired properly to my ESP32.
Here's where I am:
HardwareSerial Sender(1); // Serial port1 is the 'Sender'
HardwareSerial Receiver(2); // Serial port2 is the 'Receiver'
/*
* LilyGo TTGO T7 v1.5 pins
* ___________
* GND RST | | TXD GND
* N-C VP | ESP32 | RXD 27
* VN 26 | WROVER | 22 25 (22 <- SEND-Rx)
* 35 18 | TTGO | 21 32 (21 -> RCVR-Tx)
* 33 19 | T7 | 27 TDI (27 -> SEND-Tx)
* 34 23 | v1.5 | 25 4 (25 <- RCVR-Rx)
* TMS 5 | | GND 0
* N-C 3v3 | WiFi+BLE | 5v 2
* SD2 TCK | | TDO SD1
* CMD SD3 |______usb__| SD0 CLK
* (back) (+) (-) LiPo Batt Conn
*
* ____________
* 22 <- RX 1 | SENDER | 8 LI
* LO 2 | L9637 | 7 Vs(12v)
* (5v)Vcc 3 | tranceiver | 6 K ->-> K on #2
* 27 -> TX 4 |_____#1_____| 5 Gnd |
* |
* ____________ V
* 25 <- RX 1 | RECEIVER | 8 LI |
* LO 2 | L9637 | 7 Vs(12v) |
* (5v)Vcc 3 | tranceiver | 6 K <-<- K on #1
* 21 -> TX 4 |_____#2_____| 5 Gnd
*
* (need a 510ohm between K and Vs, and a cap to Gnd on each V)
*/
// define Rx and TX on the 2 L9637 chips with K's connected:
// TX is Input for K as output. RX is Output for K as input.
#define Sender_Txd_pin 27 // to Tx on Sender
#define Sender_Rxd_pin 22 // from Rx on Sender L9637
#define Receiver_Txd_pin 21 // to Tx on Receiver L9637
#define Receiver_Rxd_pin 25 // from Rx on Receiver
void setup() {
Serial.begin(115200);
// init both L9637 RX's with a short HIGH-LOW
Serial.println( "init both with Rx HIGH" );
pinMode( Sender_Rxd_pin, OUTPUT );
pinMode( Receiver_Rxd_pin, OUTPUT );
digitalWrite( Sender_Rxd_pin, HIGH );
digitalWrite( Receiver_Rxd_pin, HIGH );
delay(300);
Serial.println( "sending both Rx LOW" );
digitalWrite( Sender_Rxd_pin, LOW );
digitalWrite( Receiver_Rxd_pin, LOW );
delay(25);
Sender.begin(10400, SERIAL_8N1, Sender_Txd_pin, Sender_Rxd_pin); // iso9141 baud rate
Receiver.begin(10400, SERIAL_8N1, Receiver_Txd_pin, Receiver_Rxd_pin);
}
void loop() {
Sender.println( 3 ); // just an integer
delay( 200 );
while (Receiver.available()) {
char RxdChar = Receiver.read();
Serial.print(RxdChar);
}
delay(2000);
}
Note: I've tested the code and the ESP32 serial ports extensively. It works well. I've check the wiring on the (2) L9637 chips, properly powered, 510 ohm resistors, proper capacitors, with their K-lines connected to each other. When I Digital.Write to the Sender L9637 TX, I can see the K respond as well as the Receiver L9637 RX. But when I do the serial write, the Responder.available() never goes true. What gives?
I appreciate any assistance.

uart sending in 8051

In uart, I tried to sent in some numbers that Itried to convert to bcd and then to send.
The code works only from 00 to 99, if I want to send something bigger then 99 it will convert it to an ASCI table to some char or different number.
Could you help me to improve it so that I can to send numbers up to 255?
print_arr:
mov a,#r0
anl a ,#0f0h
swap a
add a , #30h
mov sbuf , a
jnb ti , $
clr ti
mov a , #r0
anl a ,#0fh
add a , #30h
mov sbuf , a
jnb ti , $
clr ti
mov sbuf ,#' ';
jnb ti,$
clr ti
inc r0
djnz r7,print_arr
mov a , #0DH
mov sbuf , a
jnb TI , $
clr TI
mov a , #0AH
mov sbuf , a
jnb TI , $
clr TI
clr TR1
ret
end

R with OpenBLAS

I have the code in R that works
well using the OpenBLAS, on a more modest computer with the following configurations:
[pedro#pedro-avell ~]$ lscpu
Arquitetura: x86_64
Modo(s) operacional da CPU: 32-bit, 64-bit
Ordem dos bytes: Little Endian
Tamanhos de endereço: 39 bits physical, 48 bits virtual
CPU(s): 8
Lista de CPU(s) on-line: 0-7
Thread(s) per núcleo: 2
Núcleo(s) por soquete: 4
Soquete(s): 1
Nó(s) de NUMA: 1
ID de fornecedor: GenuineIntel
Família da CPU: 6
Modelo: 60
Nome do modelo: Intel(R) Core(TM) i7-4710MQ CPU # 2.50GHz
Step: 3
CPU MHz: 3435.870
CPU MHz máx.: 3500,0000
CPU MHz mín.: 800,0000
BogoMIPS: 4989.80
Virtualização: VT-x
cache de L1d: 32K
cache de L1i: 32K
cache de L2: 256K
cache de L3: 6144K
CPU(s) de nó0 NUMA: 0-7
Opções: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt dtherm ida arat pln pts flush_l1d
In the test with a computer with configurations above, I observed by benchmark a 60% improvement in code performance time when considering parallelization. For that, I had to consider export OPENBLAS_NUM_THREADS=1. Therefore,
parallel::mclapply(1:8, FUN = function(x) func_metodos(), mc.cores = 4)), wherein func_metodos() is a function that I implemented in R and want to repeat 8 times.
However, when considering the same simulation on the computer with configurations below, I do not know how to tell the operating system to take into account the existence of 2 sockets, each with 10 cores and 2 threads per core. Should I consider export OPENBLAS_NUM_THREADS = 1 or export OPENBLAS_NUM_THREADS = 2? I considered both and ran the code in R:
parallel::mclapply(1:8, FUN = function(x) func_metodos(), mc.cores = 40))
[marcelo#ursal ~]$ lscpu
Arquitetura: x86_64
Modo(s) operacional da CPU: 32-bit, 64-bit
Ordem dos bytes: Little Endian
Tamanhos de endereço: 46 bits physical, 48 bits virtual
CPU(s): 40
Lista de CPU(s) on-line: 0-39
Thread(s) per núcleo: 2
Núcleo(s) por soquete: 10
Soquete(s): 2
Nó(s) de NUMA: 2
ID de fornecedor: GenuineIntel
Família da CPU: 6
Modelo: 85
Nome do modelo: Intel(R) Xeon(R) Silver 4114 CPU # 2.20GHz
Step: 4
CPU MHz: 800.021
CPU MHz máx.: 3000,0000
CPU MHz mín.: 800,0000
BogoMIPS: 4401.33
Virtualização: VT-x
cache de L1d: 32K
cache de L1i: 32K
cache de L2: 1024K
cache de L3: 14080K
CPU(s) de nó0 NUMA: 0-9,20-29
CPU(s) de nó1 NUMA: 10-19,30-39
Note: When I consider export OPENBLAS_NUM_THREADS = 1 or export OPENBLAS_NUM_THREADS = 2, it appears that the threads are distributed to only 20 of the 40 available cores.
Thanks for any suggestions to solve this issue so that I can use the 40 available cores.

I want to covert a vector to an integer before the begin

Here is my code for a up_down_counter the comments are in dutch but don't matter so much.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity up_down_teller is
port ( maxc_vector : in std_logic_vector(6 downto 0); -- "maximum count" : maximale telwaarde (decimaal) = aantal posities - 1
minc_vector : in std_logic_vector(6 downto 0);
enable : in std_logic;
up_down : in std_logic; -- telrichting
clk_500ms : in std_logic; -- systeemklok
bcd : out std_logic_vector(7 downto 0); -- tellerstand
tc : out std_logic -- tc geeft aan wanneer de maximum telwaarde bereikt is (voor cascade)
);
end up_down_teller;
architecture Behavioral of up_down_teller is
signal maxc_int : integer range 0 to 99;
signal minc_int : integer range 0 to 99;
maxc_int <= to_integer(signed(maxc_vector));
minc_int <= to_integer(signed(minc_vector));
-- berekening maximumwaarden voor eenheden (Emax) en tientallen (Tmaxà
constant Emax : integer := maxc_int mod 10; -- rest na deling mc door 10 levert maximumwaarde voor eenheden
constant Tmax : integer := (maxc_int - Emax)/10; -- mc verminderd met Emax levert veelvoud van 10. Delen door 10 levert het maximumcijfer voor de tientallen.
-- berekening minimumwaarden voor eenheden (Emin) en tientallen (Tmin)
constant Emin : integer := minc_int mod 10; -- rest na deling mc door 10 levert minimumwaarde voor eenheden
constant Tmin : integer := (minc_int - Emin)/10; -- minc_int verminderd met Emin levert veelvoud van 10. Delen door 10 levert het minimumcijfer voor de tientallen.
-- declaratie interne signalen
signal sEcnt_i : integer range 0 to 9; -- declaratie een terugleesbaar signaal voor het tellen van de eenheden
signal sTcnt_i : integer range 0 to 9; -- declaratie een terugleesbaar signaal voor het tellen van de tientallen
BEGIN
tellerproces : process (clk_500ms)
.
.
.
What follows is less important.
When i run this code it generates an error because I can't convert the types before "BEGIN" but I have to so I can do the calculations for the min and max valuees, are there any workarounds for this?
You have to define maxc_int and minc_int as either generics or constants to do this. If you have them as signals they could change during runtime, and you can't change the size of the signals during runtime.
An entity with generics could look like this:
entity up_down_teller is
generic(
maxc_vector : integer range 0 to 99 := 10;
minc_vector : integer range 0 to 99 := 10
);
port ( enable : in std_logic;
up_down : in std_logic; -- telrichting
clk_500ms : in std_logic; -- systeemklok
bcd : out std_logic_vector(7 downto 0); -- tellerstand
tc : out std_logic -- tc geeft aan wanneer de maximum telwaarde bereikt is (voor cascade)
);
end up_down_teller;

Edsim51 Always Invalid Label Error

I'm using EDSIM51 on MacOS. But I'm always getting Invalid Label - **** is keyword errors. Read documentation (User's Guide and Examples pages) but still no idea where I'm making mistake. I've downloaded example codes from Edsim's website, but it's giving same error for their official examples.
For example,
This is an LCD example which taken from their website:
; put data in RAM
MOV 30H, #'A'
MOV 31H, #'B'
MOV 32H, #'C'
MOV 33H, #0 ; end of data marker
; initialise the display
; see instruction set for details
CLR P1.3 ; clear RS - indicates that instructions are being sent to the module
; function set
CLR P1.7 ; |
CLR P1.6 ; |
SETB P1.5 ; |
CLR P1.4 ; | high nibble set
SETB P1.2 ; |
CLR P1.2 ; | negative edge on E
CALL delay ; wait for BF to clear
; function set sent for first time - tells module to go into 4-bit mode
; Why is function set high nibble sent twice? See 4-bit operation on pages 39 and 42 of HD44780.pdf.
SETB P1.2 ; |
CLR P1.2 ; | negative edge on E
; same function set high nibble sent a second time
SETB P1.7 ; low nibble set (only P1.7 needed to be changed)
SETB P1.2 ; |
CLR P1.2 ; | negative edge on E
; function set low nibble sent
CALL delay ; wait for BF to clear
; entry mode set
; set to increment with no shift
CLR P1.7 ; |
CLR P1.6 ; |
CLR P1.5 ; |
CLR P1.4 ; | high nibble set
SETB P1.2 ; |
CLR P1.2 ; | negative edge on E
SETB P1.6 ; |
SETB P1.5 ; |low nibble set
SETB P1.2 ; |
CLR P1.2 ; | negative edge on E
CALL delay ; wait for BF to clear
; display on/off control
; the display is turned on, the cursor is turned on and blinking is turned on
CLR P1.7 ; |
CLR P1.6 ; |
CLR P1.5 ; |
CLR P1.4 ; | high nibble set
SETB P1.2 ; |
CLR P1.2 ; | negative edge on E
SETB P1.7 ; |
SETB P1.6 ; |
SETB P1.5 ; |
SETB P1.4 ; | low nibble set
SETB P1.2 ; |
CLR P1.2 ; | negative edge on E
CALL delay ; wait for BF to clear
; send data
SETB P1.3 ; clear RS - indicates that data is being sent to module
MOV R1, #30H ; data to be sent to LCD is stored in 8051 RAM, starting at location 30H
loop:
MOV A, #R1 ; move data pointed to by R1 to A
JZ finish ; if A is 0, then end of data has been reached - jump out of loop
CALL sendCharacter ; send data in A to LCD module
INC R1 ; point to next piece of data
JMP loop ; repeat
finish:
JMP $
sendCharacter:
MOV C, ACC.7 ; |
MOV P1.7, C ; |
MOV C, ACC.6 ; |
MOV P1.6, C ; |
MOV C, ACC.5 ; |
MOV P1.5, C ; |
MOV C, ACC.4 ; |
MOV P1.4, C ; | high nibble set
SETB P1.2 ; |
CLR P1.2 ; | negative edge on E
MOV C, ACC.3 ; |
MOV P1.7, C ; |
MOV C, ACC.2 ; |
MOV P1.6, C ; |
MOV C, ACC.1 ; |
MOV P1.5, C ; |
MOV C, ACC.0 ; |
MOV P1.4, C ; | low nibble set
SETB P1.2 ; |
CLR P1.2 ; | negative edge on E
CALL delay ; wait for BF to clear
delay:
MOV R0, #50
DJNZ R0, $
RET
**AND ERROR : ** Invalid Label - FİNİSH is keyword
Can you please tell me what is I'm missing?

Resources