//**************************************************************** // SLAVE_PIC_UART_and_LCD(CPU: dsPIC30F4013) // // UART : 8 bit, non parity, 1 stop bit // Used U1ATX, U1ARX // // LCD unlook busy : not switch direction (write fixed) // // CPU dsPIC30F4013 // 7.37MHz Internal RC oscillator, 16x PLL enabled // Fcy=7.37MHzx16/4=29.48MHz, Tcy=33.92ns // // 2011/12/31: N.Ishii //**************************************************************** #include #include "uart.h" //-------------------------------------------------------------- // Divice configuration _FWDT(WDT_OFF); _FGS(CODE_PROT_OFF); _FOSC(CSW_FSCM_OFF & FRC_PLL16); //OSC, PLL Setting _FBORPOR(PBOR_OFF & PWRT_64 & MCLR_EN); // UART control register unsigned int _U1BRG; unsigned int _U1MODE; unsigned int _U1STA; //------------------------- // message table char msg1[] = {"First Line\0"}; char msg2[] = {"Second Line\0"}; //------------------------------------------------------------------ //#define Fcy 7370000*4 //#define BaudRate 19200 #define CR 0x0d #define LF 0x0a #define STX 0x02 //------------------------------------------------------------------ // LCD Define: R/W_pin= GND (Fixed Write) #define LCD_DATA_WR_MODE LATFbits.LATF1 = 1 // RS_pin = 1 #define LCD_INST_WR_MODE LATFbits.LATF1 = 0 // RS_pin = 0 #define LCD_ENABLE_ON LATFbits.LATF0 = 1 #define LCD_ENABLE_OFF LATFbits.LATF0 = 0 #define LCD_DATA_BIT4 LATBbits.LATB9 #define LCD_DATA_BIT5 LATBbits.LATB10 #define LCD_DATA_BIT6 LATBbits.LATB11 #define LCD_DATA_BIT7 LATBbits.LATB12 //--------------------------------------------------------------------------------------------- // LCD Instraction Code #define FOUR_BIT_FONT5x7dot 0x28 // + TWO_LINE(1/16Duty), SEG1_50_SEG51_100, COM1_COM16 #define DISP_ON_CURSOR_ON_BLINK_OFF 0x0e #define DISP_CLEAR_CURSOR_HOME 0x01 #define RAM_WR_AFTER_PLUS_1 0x06 // Entory mode set #define DDRAM_START_ADDRESS_SET 0x80 #define DISP_ON_CURSOR_OFF_BLINK_OFF 0x0c //------------------------------------------------------------------------- int n = 0,i=0; char RX1[17],RX2[17]; char RX1_LCD[17],RX2_LCD[17]; int cmd; int LineMode = 1; //------------------------------------------------------------------------- // Delay Subrutin void Waitx1ms(int x) // Td = 1mS * x { int i,j; for(i = 0 ; i < x ; ++i) { for(j = 0 ; j < 5000 ; ++j) asm("clrwdt"); //Td=1mS } } void Waitx1us(int x) // Td = 1uS * x { int i,j; for(i = 0 ; i < x ; ++i) { for(j = 0 ; j < 5 ; ++j) asm("clrwdt"); //Td=1uS } } //-------------------------------------------------------------------- void one_chr_wr(char chr_code) { LCD_DATA_WR_MODE; //RS_pin = 1: select data Reg // A Higher 4bit data out LCD_DATA_BIT7 = (unsigned int)((chr_code & 0x80)>>7); LCD_DATA_BIT6 = (unsigned int)((chr_code & 0x40)>>6); LCD_DATA_BIT5 = (unsigned int)((chr_code & 0x20)>>5); LCD_DATA_BIT4 = (unsigned int)((chr_code & 0x10)>>4); Waitx1us(1); LCD_ENABLE_ON; Waitx1us(1); LCD_ENABLE_OFF; // A Lower 4bit data out LCD_DATA_BIT7 = (unsigned int)((chr_code & 0x08)>>3); LCD_DATA_BIT6 = (unsigned int)((chr_code & 0x04)>>2); LCD_DATA_BIT5 = (unsigned int)((chr_code & 0x02)>>1); LCD_DATA_BIT4 = (unsigned int)(chr_code & 0x01); Waitx1us(1); LCD_ENABLE_ON; Waitx1us(1); LCD_ENABLE_OFF; Waitx1us(50); } void lcd_chr_wr(char *buffer) { while(*buffer != '\0') { one_chr_wr(*buffer); /* calling another function */ /* to write each char to the lcd module */ buffer++; } } void lcd_inst_wr(char inst_code) { LCD_INST_WR_MODE; //RS_pin = 0: select Instruction Reg // A Higher 4bit data out LCD_DATA_BIT7 = (unsigned int)((inst_code & 0x80)>>7); LCD_DATA_BIT6 = (unsigned int)((inst_code & 0x40)>>6); LCD_DATA_BIT5 = (unsigned int)((inst_code & 0x20)>>5); LCD_DATA_BIT4 = (unsigned int)((inst_code & 0x10)>>4); Waitx1us(1); LCD_ENABLE_ON; Waitx1us(1); LCD_ENABLE_OFF; // A Lower 4bit data out LCD_DATA_BIT7 = (unsigned int)((inst_code & 0x08)>>3); LCD_DATA_BIT6 = (unsigned int)((inst_code & 0x04)>>2); LCD_DATA_BIT5 = (unsigned int)((inst_code & 0x02)>>1); LCD_DATA_BIT4 = (unsigned int)(inst_code & 0x01); Waitx1us(1); LCD_ENABLE_ON; Waitx1us(1); LCD_ENABLE_OFF; if ((inst_code & 0x03) != 0) Waitx1ms(20); // inst_code is Clear(0x01) or Cursor Home(0x02) Then Wait 20mS else Waitx1us(50); // other code Then Wait 50uS } void lcd_init(void) { // Allow a delay(minimum of 15ms) Waitx1ms(20); //------ 1st step: port_output regster set -------------- // Initialize the data port/control pins to zero LCD_DATA_BIT7 = 0; LCD_DATA_BIT6 = 0; LCD_DATA_BIT5 = 0; LCD_DATA_BIT4 = 0; LCD_INST_WR_MODE; //RS_pin = 0 LCD_ENABLE_OFF; //E_pin = 0 //-------------------------------------------------------- // dsPIC30F4013 //------- 2nd step: port_mode regster set --------------- // Configure the data pins as output TRISBbits.TRISB9 =0; // RB9 is LCD DB4 OUTPUT TRISBbits.TRISB10 =0; // RB10 is LCD DB5 OUTPUT TRISBbits.TRISB11 =0; // RB11 is LCD DB6 OUTPUT TRISBbits.TRISB12 =0; // RB12 is LCD DB7 OUTPUT // Make all control pins as outputs TRISFbits.TRISF0 =0; // RF0 is LCD Enable OUTPUT TRISFbits.TRISF1 =0; // RF1 is LCD RS OUTPUT //------------------------------------------------------- // Initialize stage 1: Set stage 1 only 8-bit Interface // Set Upper 4 Bit Data on RB9 - RB12 LCD_DATA_BIT7 = 0; LCD_DATA_BIT6 = 0; LCD_DATA_BIT5 = 1; LCD_DATA_BIT4 = 1; Waitx1us(1); LCD_ENABLE_ON; Waitx1us(1); LCD_ENABLE_OFF; Waitx1ms(5); // Initialize stage 2: Set stage 2 only 8-bit Interface LCD_DATA_BIT7 = 0; LCD_DATA_BIT6 = 0; LCD_DATA_BIT5 = 1; LCD_DATA_BIT4 = 1; Waitx1us(1); LCD_ENABLE_ON; Waitx1us(1); LCD_ENABLE_OFF; Waitx1ms(1); // Initialize stage 3: Set stage 3 only 8-bit Interface LCD_DATA_BIT7 = 0; LCD_DATA_BIT6 = 0; LCD_DATA_BIT5 = 1; LCD_DATA_BIT4 = 1; Waitx1us(1); LCD_ENABLE_ON; Waitx1us(1); LCD_ENABLE_OFF; Waitx1ms(1); // Initialize stage 4: 4-bit Interface LCD_DATA_BIT7 = 0; LCD_DATA_BIT6 = 0; LCD_DATA_BIT5 = 1; LCD_DATA_BIT4 = 0; Waitx1us(1); LCD_ENABLE_ON; Waitx1us(1); LCD_ENABLE_OFF; Waitx1ms(1); //----- Fixed LCD Setting------------ lcd_inst_wr(FOUR_BIT_FONT5x7dot); // Function Set lcd_inst_wr(DISP_ON_CURSOR_ON_BLINK_OFF); lcd_inst_wr(DISP_CLEAR_CURSOR_HOME); // Set DDRAM Address = 0 lcd_inst_wr(RAM_WR_AFTER_PLUS_1); // Entry mode Set } //------------------------------------------------------------------------ void LCD() { cmd = ReadUART1(); switch(cmd) { case CR: LineMode = 1; n = 0; // Reset Char Send Counter break; case LF: LineMode = 2; n = 0; break; case STX: // Transmit Buffer for(i = 0; i <= 15; i++) { RX1_LCD[i] = RX1[i]; RX2_LCD[i] = RX2[i]; } RX1_LCD[16] = '\0'; RX2_LCD[16] = '\0'; // LCD Disp. lcd_inst_wr(DISP_CLEAR_CURSOR_HOME); lcd_chr_wr(RX1_LCD); lcd_inst_wr(0xc0); lcd_chr_wr(RX2_LCD); break; default: switch(LineMode) { case 1: RX1[n] = cmd; break; case 2: RX2[n] = cmd; break; default: break; } n++; break; } } //----------------------------------------------------------------------------------------------------- /// Main routine int main(void) { // Set ADPCFG: RB1 Port is All Digital Pin ADPCFG = 0xFFFF; TRISDbits.TRISD0=0; // RD0 is LED output used debug LATDbits.LATD0 = 1; // Debug LED OFF // Initialize LCD lcd_init(); lcd_inst_wr(DISP_ON_CURSOR_OFF_BLINK_OFF); // Confirmation UART1 Module OFF CloseUART1(); // Set INT UART1 (Desable Interrupt) ConfigIntUART1( UART_RX_INT_DIS & UART_TX_INT_DIS); // Initialize UART1 _U1BRG= 95; // BaudRate=Fcy/(16(U1BRG+1))= 19193bps(19200bps) // alternate I/O (U1ATX/U1ARX), N81 _U1MODE= UART_EN & UART_IDLE_CON & UART_ALTRX_ALTTX & UART_DIS_WAKE & UART_DIS_LOOPBACK & UART_EN_ABAUD & UART_NO_PAR_8BIT & UART_1STOPBIT; _U1STA= UART_INT_TX_BUF_EMPTY & UART_TX_PIN_NORMAL & UART_TX_ENABLE & UART_INT_RX_CHAR & UART_ADR_DETECT_DIS & UART_RX_OVERRUN_CLEAR; // Open UART1 OpenUART1(_U1MODE, _U1STA, _U1BRG); // Initiale LCD Disp. lcd_chr_wr(msg1); // "First Line" lcd_inst_wr(0xc0); lcd_chr_wr(msg2); // "Second Line" while(1) { while(!DataRdyUART1()); // Wait Not Rx Ready LCD(); } return 0; }