Tengo la placa explorer 16 dev equipada con el PIC24FJ128GA010. Escribí un código C para escribir algo en el LCD y un LED parpadeando después. Escribí el mismo código en ensamblador y ambos códigos funcionan. Me di cuenta de algo después de programar la placa con el código en ensamblador es que cuando se desconecta la alimentación y se vuelve a conectar el LCD no muestra nada, debo reprogramar el dispositivo de nuevo desde MPLAB X, pero con el código en C la placa funciona correctamente.
¡Y otra cosa rara, en ensamblador escribí una función de retardo simple que depende de la disminución de un valor y una instrucción de bifurcación si no es cero, parece que el código entra en un bucle infinito porque el valor nunca se incrementa de alguna manera! Esto lo descubrí mientras depuraba.
#define FOSC (8000000ULL)
#define FCY (FOSC/2)
#pragma config JTAGEN=OFF, GCP=OFF,GWRP=OFF , COE=OFF , FWDTEN=OFF, ICS=PGx2
#pragma config FCKSM=CSDCMD, OSCIOFNC=OFF,POSCMOD=XT, FNOSC=PRI
#include <libpic30.h>
#include <p24FJ128GA010.h>
#include <xc.h>
#define LCD_RS PORTBbits.RB15
#define LCD_RW PORTDbits.RD5
#define LCD_E PORTDbits.RD4
void LCD_SendChar(char value)
{
PORTE = value;
LCD_RS = 1;
LCD_E = 1;
Nop();
LCD_E = 0;
__delay_ms(5);
}
void LCD_SendCmd(int cmd)
{
PORTE = cmd;
LCD_RS = 0;
LCD_E = 1;
Nop();
LCD_E = 0;
__delay_ms(5);
}
void LCD_SendString(char* value)
{
while(*value != 0)
LCD_SendChar(*value++);
}
void LCD_Init()
{
TRISE = 0x00;
TRISDbits.TRISD4 = 0;
TRISDbits.TRISD5 = 0;
TRISBbits.TRISB15 = 0;
__delay_ms(50);
// Function Set
// 0 0 1 8/4 2/1 10/7 x x | 0x20 - 0x3F
LCD_SendCmd(0x38);
// Display ON/OFF and Cursor
// 0 0 0 0 1 D U B | 0x08 - 0x0F
LCD_SendCmd(0x0E);
// Character Entry Mode
// 0 0 0 0 0 1 1/D S | 0x04 - 0x07
LCD_SendCmd(0x06);
// Clear Display
// 0 0 0 0 0 0 0 1
LCD_SendCmd(0x01);
// Display and Cursor Home
// 0 0 0 0 0 0 1 x
LCD_SendCmd(0x02);
}
int main()
{
LCD_Init();
LCD_SendCmd(0x82);
LCD_SendString("Hello World!");
TRISA = 0x00;
LATA = 0xAA;
while(1) {
LATA ^= 0xFF;
__delay_ms(500);
}
return (0);
}
;.include "p24fj128ga010.inc"
.include "xc.inc"
config __CONFIG2, POSCMOD_XT & OSCIOFNC_OFF & FCKSM_CSDCMD & FNOSC_PRI
config __CONFIG1, JTAGEN_OFF & GCP_OFF & GWRP_OFF & COE_OFF & FWDTEN_OFF & ICS_PGx2
.global _main
.text
_main:
CALL LCD_INIT
MOV #0x82, W0
CALL LCD_SendCmd
MOV #'H', W0
CALL LCD_SendChar
MOV #'E', W0
CALL LCD_SendChar
MOV #'L', W0
CALL LCD_SendChar
MOV #'L', W0
CALL LCD_SendChar
MOV #'O', W0
CALL LCD_SendChar
MOV #' ', W0
CALL LCD_SendChar
MOV #'W', W0
CALL LCD_SendChar
MOV #'O', W0
CALL LCD_SendChar
MOV #'R', W0
CALL LCD_SendChar
MOV #'L', W0
CALL LCD_SendChar
MOV #'D', W0
CALL LCD_SendChar
MOV #'!', W0
CALL LCD_SendChar
CLR TRISA
CLR LATA
COM LATA
L: GOTO L
LCD_INIT:
CLR TRISE
BCLR TRISD, #4
BCLR TRISD, #5
BCLR TRISB, #15
CALL Delay_1
;Function Set
;0 0 1 8/4 2/1 10/7 x x | 0x20 - 0x3F
MOV #0x38, W0
CALL LCD_SendCmd
;Display ON/OFF and Cursor
;0 0 0 0 1 D U B | 0x08 - 0x0F
MOV #0x0E, W0
CALL LCD_SendCmd
;Character Entry Mode
;0 0 0 0 0 1 1/D S | 0x04 - 0x07
MOV #0x06, W0
CALL LCD_SendCmd
;Clear Display
;0 0 0 0 0 0 0 1
MOV #0x01, W0
CALL LCD_SendCmd
;Display and Cursor Home
;0 0 0 0 0 0 1 x
MOV #0x02, W0
CALL LCD_SendCmd
RETURN
LCD_SendCmd:
MOV W0, PORTE
BCLR PORTB, #15
BSET PORTD, #4
NOP
BCLR PORTD, #4
CALL Delay_1
RETURN
LCD_SendChar:
MOV W0, PORTE
BSET PORTB, #15
BSET PORTD, #4
NOP
BCLR PORTD, #4
CALL Delay_1
RETURN
Delay_1:
REPEAT #0xD00
NOP
RETURN
Delay:
REPEAT #16383
NOP
RETURN
Delay_1s:
MOV #0xFFFF, W0
MOV W0, G
R1: DEC G
REPEAT #0x3D
NOP
BRA NZ, R1
RETURN
.end
ACTUALIZACIÓN - El dispositivo no lee ningún controlador de LCD programado (C o ensamblado) al reiniciar la alimentación, por lo que no muestra nada en la pantalla LCD, pero todo lo demás funciona :\N-.