Tengo el explorador 16 dev board equipado con el PIC24FJ128GA010. Escribí un código C para escribir algo en la pantalla LCD y un LED parpadea después de eso. Escribí el mismo código en ensamblador y ambos códigos funcionan. Noté que algo después de programar la placa con el código de ensamblaje es que cuando se desconecta la alimentación y se vuelve a conectar la pantalla LCD no muestra nada, debo reprogramar el dispositivo nuevamente desde MPLAB X, pero en el código C la placa funciona correctamente.
Y alguna otra cosa extraña, en el ensamblaje escribí una función de retardo simple que depende de disminuir 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! Descubrí esto mientras estaba depurando.
#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 LCD programado (C o ensamblaje) en el reinicio de energía, por lo tanto, no muestra nada en la pantalla LCD, pero todo lo demás funciona: \