Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .include "m328Pdef.inc"
- .equ fclk = 16000000 ; frequencia do clock do processador
- ; register usage
- .def temp = R16 ; variável temporária
- ; Configuração da interface do arduíno com o display 1602
- .equ lcd_D7_port = PORTD ; lcd D7 connection
- .equ lcd_D7_bit = PORTD7
- .equ lcd_D7_ddr = DDRD
- .equ lcd_D6_port = PORTD ; lcd D6 connection
- .equ lcd_D6_bit = PORTD6
- .equ lcd_D6_ddr = DDRD
- .equ lcd_D5_port = PORTD ; lcd D5 connection
- .equ lcd_D5_bit = PORTD5
- .equ lcd_D5_ddr = DDRD
- .equ lcd_D4_port = PORTD ; lcd D4 connection
- .equ lcd_D4_bit = PORTD4
- .equ lcd_D4_ddr = DDRD
- .equ lcd_E_port = PORTB ; lcd Enable pin
- .equ lcd_E_bit = PORTB1
- .equ lcd_E_ddr = DDRB
- .equ lcd_RS_port = PORTB ; lcd Register Select pin
- .equ lcd_RS_bit = PORTB0
- .equ lcd_RS_ddr = DDRB
- ; LCD module information
- .equ lcd_LineOne = 0x00 ; posição de início da linha 1 no display
- .equ lcd_LineTwo = 0x40 ; posição de início da linha 2 no display
- ; LCD instructions
- .equ lcd_Clear = 0b00000001 ; substitui todos os caracteres do display pelo ASCII "espaço"
- .equ lcd_Home = 0b00000010 ; retorna o curso para a primeira posição da primeira linha
- .equ lcd_EntryMode = 0b00000110 ; muda o cursor da esquerda para a direita em operações de read/write
- .equ lcd_DisplayOff = 0b00001000 ; desliga o display
- .equ lcd_DisplayOn = 0b00001100 ; liga o dislay
- .equ lcd_FunctionReset = 0b00110000 ; reincializa o display LCD
- .equ lcd_FunctionSet4bit = 0b00101000 ; 4-bit de dados, display de duas linhas, fonte 5 x 7
- .equ lcd_SetCursor = 0b10000000 ; define a posição do cursor
- ;REgistradores utilizados pelo código do Keypad
- .def lb = R25
- .def hb = R24
- .def contagem=r23
- .def debounce=r22
- .def temp2=r21
- .def temp3=r18
- .def dbl=r20
- .def dbh=r19
- ;PARA MULTIPLICAR
- .DEF rm1 = R0 ; Número binário a ser multiplicado (8 Bit)
- .DEF rmh = R1 ; Armazém intermediário
- .DEF rm2 = R2 ; Número binário com que o primeiro será multiplicado (8 Bit)
- .DEF rel = R3 ; Resultado, LSB (16 Bit)
- .DEF reh = R4 ; Resultado, MSB
- .DEF rmp = R17 ; Registrador multi propósitos para carregamento
- ; ****************************** Interrupção de Reset *******************************
- .org 0x0000
- jmp start ; pula para start quando a interrupção de reset é disparada.
- .org INT_VECTORS_SIZE;Início do programa
- ; ****************************** Código do programa principal **************************
- start:
- ; inicializando os apontadores de pilha para trabalharem com as faixas de memória do processador
- ldi temp,low(RAMEND)
- out SPL,temp
- ldi temp,high(RAMEND)
- out SPH,temp
- ; Configurando os pinos do processador a serem utilizados com o display
- sbi lcd_D7_ddr, lcd_D7_bit ; 4 data lines - output
- sbi lcd_D6_ddr, lcd_D6_bit
- sbi lcd_D5_ddr, lcd_D5_bit
- sbi lcd_D4_ddr, lcd_D4_bit
- ; Configurando os pinos do processador a serem utilizados como barramento de controle do display
- sbi lcd_E_ddr, lcd_E_bit ; E line - output
- sbi lcd_RS_ddr, lcd_RS_bit ; RS line - output
- ; Inicializando o display
- call lcd_init_4d ; initialize the LCD display for a 4-bit interface
- ;Inicializando o número a ser modificado pelo keypad
- ldi contagem, 0
- ldi debounce, 0
- ;
- ;
- ;
- ;============================================Área que deverá ser alterada no trabalho==============================================================
- ; Exibindo a primeira linha de informação no display
- ;Primeira string, início na posição de memória 0x040B
- ldi XH, 0x04
- ldi XL, 0x0B
- ldi temp, 'A'
- st X+, temp;o incremento de X está sendo feito automatiamente com X+
- ldi temp, 'R'
- st X+, temp
- ldi temp, 'E'
- st X+, temp
- ldi temp, 'A'
- st X+, temp
- ldi temp, ' '
- st X+, temp
- ldi temp, 'C'
- st X+, temp
- ldi temp, 'I'
- st X+, temp
- ldi temp, 'R'
- st X+, temp
- ldi temp, 'C'
- st X+, temp
- ldi temp, 0;o zero indica o fim da string
- st X+, temp
- ldi XH, 0x04
- ldi XL, 0x0B
- ldi temp, lcd_LineOne ; estabece em qual linha a informação será exibida
- call lcd_write_string_4d ; chama a subrotina que imprime na tela do display
- ; display the second line of information
- ;String two, start in 0x0418
- ldi temp, 'D' ;DIGITE RAIO PARA O CALCULO, DE 1 A 5
- st X+, temp
- ldi temp, 'I'
- st X+, temp
- ldi temp, 'G'
- st X+, temp
- ldi temp, 'T'
- st X+, temp
- ldi temp, ' '
- st X+, temp
- ldi temp, 'R'
- st X+, temp
- ldi temp, ':'
- st X+, temp
- ldi temp, ' '
- st X+, temp
- ;************Keypad code
- LDI temp, 0b0100_0000 ;selecionar entrada A0
- STS ADMUX, temp
- inicio:
- ;Ajustando endereço de memória para armazenar a tecla pressionada. Só tem valor real para a segunda tecla pressionada
- ldi XH, 0x04
- ldi XL, 0x20
- LDI temp, 0b1100_0010 ;Ativar conversão AD e o prescaler
- sts ADCSRA, TEMP
- AGUARDAR_CONVERSAO:
- LDS temp, ADCSRA ;lendo status do processo de conversão
- ANDI temp,0b00010000 ;checando se a conversão já terminou
- BREQ AGUARDAR_CONVERSAO ;senão, volta para aguardar_conversao(esperar)
- LDS ZL,ADCL ;ler o byte inferior da conversão (16bits)
- LDS ZH,ADCH ;ler o byte superior da conversão (16bits)
- ldi temp, 200 ; delay para diminuir o debounce
- call delay1mS
- comparacoes:
- ;Comparações para os diversos botões
- ;Direita
- ldi lb, 0b01100100
- ldi hb, 0b00000000
- cp ZL, lb
- cpc ZH, hb
- brcs direita
- ;Cima
- ldi lb, 0b11001000
- ldi hb, 0b00000000
- cp ZL, lb
- cpc ZH, hb
- brcs cima
- ;baixo
- ldi lb, 0b10010000
- ldi hb, 0b00000001
- cp ZL, lb
- cpc ZH, hb
- brcs baixo
- ;Esquerda
- ldi lb, 0b01011000
- ldi hb, 0b00000010
- cp ZL, lb
- cpc ZH, hb
- brcs esquerda
- ;select
- ldi lb, 0b00100000
- ldi hb, 0b00000011
- cp ZL, lb
- cpc ZH, hb
- brcs select
- ldi debounce, 0
- retorna_inicio:
- RJMP inicio
- ;Alterar apenas a partir daqui
- ;O trecho abaixo exibe qual dos botões Esquerda, Direita, Cima e Baixo foi apertado
- direita:;NAO PRECISOU UTILIZAR PQ SÓ PRECISA DE UMA VARIAVEL QUE É O RAIO
- cpi debounce, 'd'
- breq retorna_inicio
- ldi debounce, 'd'
- ldi temp, '*'
- st X+, temp
- rjmp escreve_linha_2
- esquerda:;NAO PRECISOU UTILIZAR PQ SÓ PRECISA DE UMA VARIAVEL QUE É O RAIO
- cpi debounce, 'e'
- breq retorna_inicio
- ldi debounce, 'e'
- ldi temp, '*'
- st X+, temp
- rjmp escreve_linha_2
- cima:
- cpi debounce, 'c'
- breq retorna_inicio
- ldi debounce, 'c'
- ;bloqueio de incremento > 5
- cpi contagem, 9
- breq retorna_inicio
- ;fim de bloqueio de decremento >5
- inc contagem
- st X+, contagem
- rcall converte_ascii_2d
- rjmp escreve_linha_2
- baixo:
- cpi debounce, 'b'
- breq retorna_inicio
- ldi debounce, 'b'
- ;bloqueio de incremento < 0
- cpi contagem, 0
- breq retorna_inicio
- ;fim de bloqueio de incremento < 0
- dec contagem
- ;Fim de Convertendo número para ASCII
- st X+, contagem
- rcall converte_ascii_2d
- rjmp escreve_linha_2
- select: ;ONDE É FEITO O CALCULO
- ;call lcd_Clear
- cpi debounce, 's'
- breq retorna_inicio
- ldi debounce, 's'
- ldi temp, '*'
- mov rm2, contagem;CALCULO DO R AO QUADRADO
- mov rm1, contagem
- MULT8:
- ; Zera valores de início
- clr rmh ; zera armazém intermediário
- clr rel ; zera registradores de resultado
- clr reh
- ; Aqui iniciamos o ciclo de multiplicação
- ; Aqui iniciamos o ciclo de multiplicação
- MULT8a:
- ;
- ; Passo 1: Rotaciona o bit mais baixo do número 2 para a flag de carry (divide por 2, rotaciona um zero no bit 7)
- ;
- clc ; zera carry
- ror rm2 ; bit 0 vai para o carry, bit 1 a 7 vão uma posição para direita, carry vai para o bit 7
- ;
- ; Passo 2: Decisão dependendo se foi 0 ou 1 que foi rotacionado para o carry
- ;
- brcc MULT8b ; pula por cima da adição, se o carry for 0
- ;
- ; Passo 3: Soma 16 bits em rmh:rml ao resultado, com estouro do LSB para o MSB
- ;
- add rel,rm1 ; soma o LSB de rm1 ao resultado
- adc reh,rmh ; soma carry e MSB de rm1
- ;
- MULT8b:
- ;
- ; Passo 4: Multiplicar rmh:rm 1 por 2 (16 bits, desvio à esquerda)
- ;
- clc ; zera carry (clear carry bit)
- rol rm1 ; rotaciona o LSB à esquerda (multiplica por 2)
- rol rmh ; rotaciona o carry para o MSB e o MSB uma casa à esquerda
- ;
- ; Passo 5: Checa se há ainda números 1 no binário 2, se sim, continua multiplicando
- ;
- tst rm2 ; todos os bits zero?
- brne MULT8a ; se não, vá para o loop
- ;
- ; Fim da multiplicação r ao quadrado, resultado em reh:rel
- mov contagem, rel
- ; multiplicar por 3 (PI)...
- mov rm1, rel
- ldi rmp,0b00000011
- mov rm2,rmp ; para o segundo registrador
- MULT9:
- ;
- ; Zera valores de início
- clr rmh ; zera armazém intermediário
- clr rel ; zera registradores de resultado
- clr reh
- ;
- ; Aqui iniciamos o ciclo de multiplicação
- ; Aqui iniciamos o ciclo de multiplicação
- ;
- MULT9a:
- ;
- ; Passo 1: Rotaciona o bit mais baixo do número 2 para a flag de carry (divide por 2, rotaciona um zero no bit 7)
- ;
- clc ; zera carry
- ror rm2 ; bit 0 vai para o carry, bit 1 a 7 vão uma posição para direita, carry vai para o bit 7
- ;
- ; Passo 2: Decisão dependendo se foi 0 ou 1 que foi rotacionado para o carry
- ;
- brcc MULT9b ; pula por cima da adição, se o carry for 0
- ;
- ; Passo 3: Soma 16 bits em rmh:rml ao resultado, com estouro do LSB para o MSB
- ;
- add rel,rm1 ; soma o LSB de rm1 ao resultado
- adc reh,rmh ; soma carry e MSB de rm1
- ;
- MULT9b:
- ;
- ; Passo 4: Multiplicar rmh:rm 1 por 2 (16 bits, desvio à esquerda)
- ;
- clc ; zera carry (clear carry bit)
- rol rm1 ; rotaciona o LSB à esquerda (multiplica por 2)
- rol rmh ; rotaciona o carry para o MSB e o MSB uma casa à esquerda
- ;
- ; Passo 5: Checa se há ainda números 1 no binário 2, se sim, continua multiplicando
- ;
- tst rm2 ; todos os bits zero?
- brne MULT9a ; se não, vá para o loop
- ;
- ; Fim da multiplicação r ao quadrado, resultado em reh:rel
- st X+, rel;resultado aproximado
- rcall converte_ascii_2d
- rjmp escreve_linha_2
- ; Rotina que converte um valor na memória na posição X-1 em ASCII (para dois dígitos)
- converte_ascii_2d: ld temp, -X
- mov temp2, temp
- clr temp3
- testa_maior: cpi temp2, 10
- brmi menorq10
- subi temp2, 10
- inc temp3
- jmp testa_maior
- menorq10: cpi temp3, 0
- breq so_unidades
- ldi temp, 48
- add temp, temp3
- st X+, temp
- so_unidades: ldi temp, 48
- add temp, temp2
- st X+, temp
- ret
- escreve_linha_2:
- ldi temp, ' ' ;espaço em branco
- st X+, temp
- ldi temp, 0 ;o zero indica o fim da string
- st X, temp
- ldi XH, 0x04 ;posição de memória onde começa a segunda string
- ldi XL, 0x19
- ldi temp, lcd_LineTwo ; estabece em qual linha a informação será exibida
- call lcd_write_string_4d ; chama a subrotina que imprime na tela do display
- rjmp retorna_inicio
- ; ===============================Fim da Área que deverá ser alterada no trabalho =======================================================
- here:
- rjmp here
- ; ****************************** Fim do programa principal *******************
- ; ============================== 4-bit LCD Subroutines ======================
- ; Purpose: initialize the LCD module for a 4-bit data interface
- lcd_init_4d:
- ; Power-up delay
- ldi temp, 100 ; initial 40 mSec delay
- call delayTx1mS
- ; Set up the RS and E lines for the 'lcd_write_4' subroutine.
- cbi lcd_RS_port, lcd_RS_bit ; select the Instruction Register (RS low)
- cbi lcd_E_port, lcd_E_bit ; make sure E is initially low
- ; Reset the LCD controller.
- ldi temp, lcd_FunctionReset ; first part of reset sequence
- call lcd_write_4
- ldi temp, 10 ; 4.1 mS delay (min)
- call delayTx1mS
- ldi temp, lcd_FunctionReset ; second part of reset sequence
- call lcd_write_4
- ldi temp, 200 ; 100 uS delay (min)
- call delayTx1uS
- ldi temp, lcd_FunctionReset ; third part of reset sequence
- call lcd_write_4
- ldi temp, 200 ; this delay is omitted in the data sheet
- call delayTx1uS
- ; Preliminary Function Set instruction - used only to set the 4-bit mode.
- ; The number of lines or the font cannot be set at this time since the controller is still in the
- ; 8-bit mode, but the data transfer mode can be changed since this parameter is determined by one
- ; of the upper four bits of the instruction.
- ldi temp, lcd_FunctionSet4bit ; set 4-bit mode
- call lcd_write_4
- ldi temp, 80 ; 40 uS delay (min)
- call delayTx1uS
- ; Function Set instruction
- ldi temp, lcd_FunctionSet4bit ; set mode, lines, and font
- call lcd_write_instruction_4d
- ldi temp, 80 ; 40 uS delay (min)
- call delayTx1uS
- ; The next three instructions are specified in the data sheet as part of the initialization routine,
- ; so it is a good idea (but probably not necessary) to do them just as specified and then redo them
- ; later if the application requires a different configuration.
- ; Display On/Off Control instruction
- ldi temp, lcd_DisplayOff ; turn display OFF
- call lcd_write_instruction_4d
- ldi temp, 80 ; 40 uS delay (min)
- call delayTx1uS
- ; Clear Display instruction
- ldi temp, lcd_Clear ; clear display RAM
- call lcd_write_instruction_4d
- ldi temp, 4 ; 1.64 mS delay (min)
- call delayTx1mS
- ; Entry Mode Set instruction
- ldi temp, lcd_EntryMode ; set desired shift characteristics
- call lcd_write_instruction_4d
- ldi temp, 80 ; 40 uS delay (min)
- call delayTx1uS
- ; This is the end of the LCD controller initialization as specified in the data sheet, but the display
- ; has been left in the OFF condition. This is a good time to turn the display back ON.
- ; Display On/Off Control instruction
- ldi temp, lcd_DisplayOn ; turn the display ON
- call lcd_write_instruction_4d
- ldi temp, 80 ; 40 uS delay (min)
- call delayTx1uS
- ret
- ; ---------------------------------------------------------------------------
- ; Purpose: display a string of characters on the LCD
- lcd_write_string_4d:
- ; preserve registers
- push ZH ; preserve pointer registers
- push ZL
- ; fix up the pointers for use with the 'lpm' instruction
- lsl ZL ; shift the pointer one bit left for the lpm instruction
- rol ZH
- ; set up the initial DDRAM address
- ori temp, lcd_SetCursor ; convert the plain address to a set cursor instruction
- call lcd_write_instruction_4d ; set up the first DDRAM address
- ldi temp, 80 ; 40 uS delay (min)
- call delayTx1uS
- ; write the string of characters
- lcd_write_string_4d_01:
- ld temp, X+
- cpi temp, 0 ; check for end of string
- breq lcd_write_string_4d_02 ; done
- ; arrive here if this is a valid character
- call lcd_write_character_4d ; display the character
- ldi temp, 80 ; 40 uS delay (min)
- call delayTx1uS
- rjmp lcd_write_string_4d_01 ; not done, send another character
- ; arrive here when all characters in the message have been sent to the LCD module
- lcd_write_string_4d_02:
- pop ZL ; restore pointer registers
- pop ZH
- ret
- ; ---------------------------------------------------------------------------
- ; Purpose: send a byte of information to the LCD data register
- lcd_write_character_4d:
- sbi lcd_RS_port, lcd_RS_bit ; select the Data Register (RS high)
- cbi lcd_E_port, lcd_E_bit ; make sure E is initially low
- call lcd_write_4 ; write the upper 4-bits of the data
- swap temp ; swap high and low nibbles
- call lcd_write_4 ; write the lower 4-bits of the data
- ret
- ; ---------------------------------------------------------------------------
- ; Purpose: send a byte of information to the LCD instruction register
- lcd_write_instruction_4d:
- cbi lcd_RS_port, lcd_RS_bit ; select the Instruction Register (RS low)
- cbi lcd_E_port, lcd_E_bit ; make sure E is initially low
- call lcd_write_4 ; write the upper 4-bits of the instruction
- swap temp ; swap high and low nibbles
- call lcd_write_4 ; write the lower 4-bits of the instruction
- ret
- ; ---------------------------------------------------------------------------
- ; Purpose: send a nibble (4-bits) of information to the LCD module
- lcd_write_4:
- ; set up D7
- sbi lcd_D7_port, lcd_D7_bit ; assume that the D7 data is '1'
- sbrs temp, 7 ; check the actual data value
- cbi lcd_D7_port, lcd_D7_bit ; arrive here only if the data was actually '0'
- ; set up D6
- sbi lcd_D6_port, lcd_D6_bit ; repeat for each data bit
- sbrs temp, 6
- cbi lcd_D6_port, lcd_D6_bit
- ; set up D5
- sbi lcd_D5_port, lcd_D5_bit
- sbrs temp, 5
- cbi lcd_D5_port, lcd_D5_bit
- ; set up D4
- sbi lcd_D4_port, lcd_D4_bit
- sbrs temp, 4
- cbi lcd_D4_port, lcd_D4_bit
- ; write the data
- ; 'Address set-up time' (40 nS)
- sbi lcd_E_port, lcd_E_bit ; Enable pin high
- call delay1uS ; implement 'Data set-up time' (80 nS) and 'Enable pulse width' (230 nS)
- cbi lcd_E_port, lcd_E_bit ; Enable pin low
- call delay1uS ; implement 'Data hold time' (10 nS) and 'Enable cycle time' (500 nS)
- ret
- ; ============================== End of 4-bit LCD Subroutines ===============
- ; ============================== Time Delay Subroutines =====================
- ; Purpose: provide a delay of (YH:YL) x 1 mS
- delayYx1mS:
- call delay1mS ; delay for 1 mS
- sbiw YH:YL, 1 ; update the the delay counter
- brne delayYx1mS ; counter is not zero
- ; arrive here when delay counter is zero (total delay period is finished)
- ret
- ; ---------------------------------------------------------------------------
- ; Purpose: provide a delay of (temp) x 1 mS
- delayTx1mS:
- call delay1mS ; delay for 1 mS
- dec temp ; update the delay counter
- brne delayTx1mS ; counter is not zero
- ; arrive here when delay counter is zero (total delay period is finished)
- ret
- ; ---------------------------------------------------------------------------
- ; Purpose: provide a delay of 1 mS
- delay1mS:
- push YL ; [2] preserve registers
- push YH ; [2]
- ldi YL, low (((fclk/1000)-18)/4) ; [1] delay counter
- ldi YH, high(((fclk/1000)-18)/4) ; [1]
- delay1mS_01:
- sbiw YH:YL, 1 ; [2] update the the delay counter
- brne delay1mS_01 ; [2] delay counter is not zero
- ; arrive here when delay counter is zero
- pop YH ; [2] restore registers
- pop YL ; [2]
- ret ; [4]
- ; ---------------------------------------------------------------------------
- ; Purpose: provide a delay of (temp) x 1 uS with a 16 MHz clock frequency
- delayTx1uS:
- call delay1uS ; delay for 1 uS
- dec temp ; decrement the delay counter
- brne delayTx1uS ; counter is not zero
- ; arrive here when delay counter is zero (total delay period is finished)
- ret
- ; ---------------------------------------------------------------------------
- ; Purpose: provide a delay of 1 uS with a 16 MHz clock frequency
- delay1uS:
- push temp ; [2] these instructions do nothing except consume clock cycles
- pop temp ; [2]
- push temp ; [2]
- pop temp ; [2]
- ret ; [4]
- ; ============================== End of Time Delay Subroutines ==============
- ;
- ; projeto area circulo final.asm
- ;
- ;
Advertisement
Add Comment
Please, Sign In to add comment