Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

LCD Library For C18

Status
Not open for further replies.

AtomSoft

Well-Known Member
I was thinking about how i manage code and decided to split or make libraries of sort for C18. Yes i know it has its own but i like learning from and adding to the library. Here is my own package for 4 Bit LCD control. Including a Generic Schematic and information in a nice small PDF which is included.

I hope you enjoy!

Thanks go out to all who helped me.

Comming Soon:
AGM1264F: 128x64 Graphic LCD
DS1337: I2C Serial Real-Time Clock
DS1804: NV Trimmer Potentiometer
MAX1112: +5V, Low-Power, Multi-Channel, Serial 8-Bit ADCs


Its just for generic use and can be modified to fit anyone needs.

EDIT: I forgot to attach the file lol
10/02/08 - With Fixed delay
 

Attachments

  • LCD Library.zip
    104.7 KB · Views: 1,191
Last edited:
Great job, much easier to incorporate your code than the bloated code library example found in C18.
 
while i was working on my GLCD library i stumbled across a bad mistake on my part in the DELAY.C code for most my projects. And that is:

Delay10KTCYx(unit):
The value of unit can be any 8-bit value. A value in the range [1,255] will delay (unit * 10000) cycles. A value of 0 causes a delay of 2,560,000 cycles.

The issue was if you have a 20Mhz clock this value would then be 500 which is way over. So here is the fix.

Code:
void delay_s(char sec)
{
    char x, i; 
    i = 1;

    d_tmp = (d_mhz / 4) / 10000;

    if(d_tmp > 255){
        i = 2;
        d_tmp2 = d_tmp - 255;
        d_tmp = 255;
    }

    for(x=0;x<i;x++){
        for(lt=0;lt<sec;lt++){
            Delay10KTCYx(d_tmp);
        }
        d_tmp = d_tmp2;
    }
}
 
Last edited:
Can it be used with 40 MHz

Hi,

I believe changing the d_Mhz value in the delay routines would make this work for 40 MHz also. Thanks for the code and sharing it.

Regards
 
since you are maintaining your library. I suggest you put a version on it and roll the number with each release/update. that way people can tell if they have the latest.
 
Nice to here that andig. It should work for most pics at most speeds. Mainly because it does the math for you. It will divide the Mhz and all that. May be some cycles off but works well. I recommend it not be used for the uS stuff but for mS and S its great.

philb I wouldnt say im maintaining it but ill be sure to rename the zip with a version or something so everyone can see which is the latest. Good idea.
 
The version number also needs to go into the source code. It is what any programmer will see long after the zip is lost. Comments regarding changes in each rev are nice too.

3v0

philb I wouldnt say im maintaining it but ill be sure to rename the zip with a version or something so everyone can see which is the latest. Good idea.
 
Last edited:
Ok im new to this lol i mean like how would i go about this? Just make a comment on the top or something like author , date, rev, build?

Whats the diff from rev and build?
 
If you are distributing binary, then you should number each time you build it with different source. I think you are just releasing source code so it doesn't matter.
 
Ok im new to this lol i mean like how would i go about this? Just make a comment on the top or something like author , date, rev, build?

Whats the diff from rev and build?

If you were working for a company they might have a standard format but it can be as simple as this sort of thing.

Code:
//  File Name: Feldspar_6
//  Author: Alphonso J. Sludgepump
//  Date: 00/00/00
//
//  Rock identification routines for the XRAY system.
//
//  Rev 0:
//    Initial Revision.
//  Rev 1: 
//    Added missing function fixMyFlat(char x)
//

Have you looked at the _H_USER stream that allows the use of fprintf in C18. It is very easy to use.
 
Last edited:
Thanks 3v0 i know its been a while but i made a new delay routine ... works way better and closest possible to the exact delay needed.

Using a 20Mhz Crystal:
ASKED = ACTUAL
1 ms = 932.600000 uSecs (ACTUAL)
1 sec = 996.342000 mSec (ACTUAL)

Used MPLAB Stop watch for time test.

ASDELAY.C
Code:
//  File Name: ASDELAY.C, ASDELAY.H
//  Author: Jason Lopez
//  Date: 10/22/08
//
//  Seconds and Milliseconds Delay Routine for C18
//
//  Rev 0:
//    Initial Revision.
//

#include "asdelay.h"

unsigned int tempa,tempb,tempc;

void delay_ms(char Time2Delay) // 1ms = 932.600000 uSecs
{
    tempa = tempb = tempc = 0;

    tempa = (((Time2Delay * SpeedMhz) / 4) / 1000000) - 2;

    if (tempa > 255){
       tempb = tempa - 255;
       Delay1KTCYx(255);
       if (tempb > 255){
          tempc = tempb - 255;
          Delay1KTCYx(255);
          Delay1KTCYx(tempc);
       } else {
          Delay1KTCYx(tempb);
       }

    } else {
        Delay1KTCYx(tempa);
    }
    return;
}
void delay_s(char Time2Delay)   // 1 second = 996.342000 mSec
{
    tempa = tempb = tempc = 0;

    tempa = (((Time2Delay * SpeedMhz) / 4) / 10000) - 2;

    if (tempa > 255){
       tempb = tempa - 255;
       Delay10KTCYx(255);
       if (tempb > 255){
          tempc = tempb - 255;
          Delay10KTCYx(255);
          Delay10KTCYx(tempc);
       } else {
          Delay10KTCYx(tempb);
       }

    } else {
        Delay10KTCYx(tempa);
    }
    return;
}

ASDELAY.H
Code:
//  File Name: ASDELAY.C, ASDELAY.H
//  Author: Jason Lopez
//  Date: 10/22/08
//
//  Seconds and Milliseconds Delay Routine for C18
//
//  Rev 0:
//    Initial Revision.
//

#ifndef __ASDELAY_H
#define __ASDELAY_H

#include <delays.h>
#define SpeedMhz 20000000

void delay_ms(char Time2Delay);
void delay_s(char Time2Delay);

#endif
 
Nothing new yet since for some reason my DS1337 isnt keep time. I even have a DS1337C with internal OSC and the time is way to fast... Im starting to think i have some type of electrical interference of some sort amongst the wiring in my room. But not sure. Ill write something this week. Also for some other maxim toys!
 
if you look at most of my post i usually put code.. like:

https://www.electro-tech-online.com/threads/ds1337-wierd-problem.84839/

I stripped my code and put the basics below with a example on how to use it.
Code:
#define SDA_PORT PORTBbits.RB0
#define SDA LATBbits.LATB0
#define SDA_TRIS TRISBbits.TRISB0
#define SCL LATBbits.LATB1

char slave_r = 0b11010001;    //Change this to your device add + r/w bit (my ds1337 was 1101000 and to read the lsb is 1)
char slave_w = 0b11010000;    //Change this to your device add + r/w bit (my ds1337 was 1101000 and to write the lsb is 0)

void i2c_byte(char addr);
void i2c_start(void);
void i2c_ack(void);
char i2c_input(void);
void i2c_clock(void);
void i2c_stop(void);

////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////            I2C FUNCTIONS
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
void i2c_clock(void)
{
    SCL = 1;
    delay_us(5);
    SCL = 0;
}

void i2c_start(void){
    SDA_TRIS=0;   //SDA Output
    SCL=0;        //Clock Low
    SDA=1;        //SDA High
    SCL=1;        //Clock high

    delay_us(4);                
    SDA=0;        //SDA Low

    delay_us(1);
    SCL=0;        //Clock Low
}

void i2c_byte(char addr){
    char bl;
    for(bl=0;bl<8;bl++){

        if((addr & 0x80) != 0)
            SDA = 1;
        else
            SDA = 0;

    i2c_clock();
    addr=addr<<1;
    }
}

void i2c_ack(void){
    SDA_TRIS = 1;   //SDA Input
    i2c_clock();
    delay_us(5);
    //while(SDA);
    SDA_TRIS = 0;
}

char i2c_input(void){
    char temp;
    char i;

    SDA_TRIS = 1;

    temp=0;  
    i = 0;           
    for(i=0;i<8;i++){  
        temp=temp<<1;   

        if(SDA_PORT) 
            temp|=1;

        i2c_clock();
    }

    SDA_TRIS = 0;
    return temp;
}

void i2c_stop(void){
    SDA = 0;
    SCL = 1;
    delay_us(3);
    SDA = 1;
    SCL = 0;
}
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
////            RTC FUNCTIONS :Example on how to use above I2C Code.          ////
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
char rtc_write(char offset, char data){

    char temp;
    i2c_start();                //Start
    i2c_byte(slave_w);          //Slave Byte
    i2c_ack();                  //ACK
    i2c_byte(offset);           //Address Offset
    i2c_ack();                  //ACK
    i2c_byte(data);          //Slave Byte
    i2c_ack();                  //ACK
    i2c_stop;                    //Stop
    return temp;
}
char rtc_read(char offset){

    char temp;
    i2c_start();                //Start
    i2c_byte(slave_w);          //Slave Byte
    i2c_ack();                  //ACK
    i2c_byte(offset);           //Address Offset
    i2c_ack();                  //ACK
    i2c_start();                //Start
    i2c_byte(slave_r);          //Slave Byte    
    i2c_ack();                  //ACK
    temp = i2c_input();         //Get Data
    i2c_ack();                  //ACK
    i2c_stop;                    //Stop
    return temp;
}
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top