Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
for some reason i get errors... Some questions:
1. Do i have to include header in each c file?
2. How do i extern a #define?
Can someone show me some examples of this. I hate the c18 manual it sux. No good info in it.
3. Anyone got a better resource than the c18 manual?
#include <p18f4525.h>
#include <stdio.h>
#include <delays.h>
#pragma config WDT = OFF, OSC = HS, LVP = OFF
void main(void);
//////////////////////////////////////////////////////
//// Delay Stuff
//////////////////////////////////////////////////////
void delay_s(unsigned char);
void delay_ms(unsigned char);
void delay_us(unsigned char);
//////////////////////////////////////////////////////
//// I2C Stuff
//////////////////////////////////////////////////////
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);
//////////////////////////////////////////////////////
//// RTC Stuff
//////////////////////////////////////////////////////
char rtc_read(char offset);
char rtc_write(char offset, char data);
//////////////////////////////////////////////////////
//// LCD Stuff
//////////////////////////////////////////////////////
void lcd_clr_line(char line);
void lcd_init(void);
void lcd_cmd(unsigned char cmd);
void lcd_char(unsigned char tchar);
void lcd_string(char *);
void lcd_nybble(unsigned char data,char rs);
void e_togg(void);
//////////////////////////////////////////////////////
//// General Stuff
//////////////////////////////////////////////////////
void set_time(void);
void get_buttons(char hm);
//////////////////////////////////////////////////////
//// Variables and Defines
//////////////////////////////////////////////////////
#define SDA_PORT PORTCbits.RC4
#define SDA LATCbits.LATC4
#define SDA_TRIS TRISCbits.TRISC4
#define SCL LATCbits.LATC3
//////////////////////////////////////////////////////
//// RTC Variables
//////////////////////////////////////////////////////
char slave_r = 0b11010001;
char slave_w = 0b11010000;
//////////////////////////////////////////////////////
//// LCD Variables and Define
//////////////////////////////////////////////////////
char Line1 = 0x80; // 0x80 is the command hex to move cursor to 0 (Line 1 first character)
char Line2 = 0xC0; // 0xC0 is the command hex to move cursor to 64 (Line 2 first character)
#define lcd_rs LATBbits.LATB4 // define LCD RS - PIN
#define lcd_e LATBbits.LATB5 // define LCD E - PIN
#define lcd_DB7 LATBbits.LATB0 // define LCD Data Bit 7
#define lcd_DB6 LATBbits.LATB1 // define LCD Data Bit 6
#define lcd_DB5 LATBbits.LATB2 // define LCD Data Bit 5
#define lcd_DB4 LATBbits.LATB3 // define LCD Data Bit 4
//////////////////////////////////////////////////////
//// General Variables and Defines
//////////////////////////////////////////////////////
#define up_btn PORTAbits.RA0
#define set_btn PORTAbits.RA1
//////////////////////////////////////////////////////
//// RTC Variables
//////////////////////////////////////////////////////
char time[9] = " ";
char s_time[9] = " ";
char seconds;
char minutes;
char hours;
char g_hr_high, g_hr_low;
char g_min_high, g_min_low;
char stringA[9] = {'S','e','t',' ','H','o','u','r',0};
char stringB[12] = {'S','e','t',' ','M','i','n','u','t','e','s',0};
char stringC[13] = {'T','h','e',' ','T','i','m','e',' ','I','s',':',0};
void main(void)
{
char sec_low, sec_high;
char min_low, min_high;
char hr_low, hr_high;
char tmp,tmp2;
ADCON1 = 0b00001111;
TRISC = 0x00;
TRISB = 0x00;
TRISA = 0x00;
TRISAbits.TRISA0 = 1;
TRISAbits.TRISA1 = 1;
lcd_init(); //Launch Initialize function
lcd_clr_line(0);
delay_ms(50);
lcd_cmd(Line1); //Set to Line 2
delay_ms(50);
lcd_string(stringC); //Send our string.
delay_ms(60);
while(1){
for(tmp=0;tmp<9;tmp++){
time[tmp] = 0x30;
s_time[tmp] = 0x30;
}
time[2] = 0x3A;
time[5] = 0x3A;
time[8] = 0;
s_time[1] = 0x31;
s_time[2] = 0x3A;
s_time[5] = 0x3A;
s_time[8] = 0;
seconds = rtc_read(0x00);
minutes = rtc_read(0x01);
hours = rtc_read(0x02);
time[7] = sec_low = (seconds & 0x0F) + '0';
time[6] = sec_high = ((seconds>>4) & 0x0F) + '0';
time[4] = min_low = (minutes & 0x0F) + '0';
time[3] = min_high = ((minutes>>4) & 0x0F) + '0';
time[1] = hr_low = (hours & 0x0F) + '0';
time[0] = hr_high = ((hours>>4) & 0x0F) + '0';
lcd_cmd(Line2); //Set to Line 1
delay_ms(1);
lcd_string(time); //Send our string.
delay_ms(50);
if(set_btn){
set_time();
delay_ms(50);
rtc_write(0x00,0x00);
s_time[0]-= 0x30;
s_time[1]-= 0x30;
s_time[3]-= 0x30;
s_time[4]-= 0x30;
tmp2 = (s_time[3]<<4) + s_time[4];
rtc_write(0x01,tmp2);
tmp2 = (s_time[0]<<4) + s_time[1];
rtc_write(0x02,tmp2);
lcd_clr_line(0);
delay_ms(50);
lcd_cmd(Line1); //Set to Line 2
delay_ms(50);
lcd_string(stringC); //Send our string.
delay_ms(60);
}
}
}
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
//// DELAY FUNCTIONS
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
void delay_s(unsigned char x)
{
char var1;
for(var1=0;var1<x;var1++)
{
Delay10KTCYx(500); //5,000,000 cycles = 1 second
}
}
void delay_ms(unsigned char x)
{
char var1;
for(var1=0;var1<x;var1++)
{
Delay1KTCYx(5); //5,000 cycles = 1 us
}
}
void delay_us(unsigned char x)
{
char var1;
for(var1=0;var1<x;var1++)
{
Delay1TCY(); //5 cycle = 1 us
Delay1TCY();
Delay1TCY();
Delay1TCY();
Delay1TCY();
}
}
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
//// 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
//Start - 5us
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
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
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;
}
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
//// TIME FUNCTIONS
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
void set_time(void){
lcd_clr_line(0);
delay_ms(100);
lcd_clr_line(1);
delay_ms(100);
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
lcd_cmd(Line1); //Set to Line 1
delay_ms(100);
lcd_string(stringA); //Send our string.
delay_ms(100);
lcd_clr_line(1);
delay_ms(50);
lcd_cmd(Line2); //Set to Line 2
delay_ms(50);
lcd_string(s_time); //Send our string.
delay_ms(60);
while(!set_btn){
delay_ms(50);
if(up_btn)
get_buttons(1);
}
///////////////////////////////////////////////////////////
lcd_clr_line(0);
delay_ms(100);
lcd_clr_line(1);
delay_ms(100);
///////////////////////////////////////////////////////////
lcd_cmd(Line1); //Set to Line 1
delay_ms(100);
lcd_string(stringB); //Send our string.
delay_ms(100);
lcd_clr_line(1);
delay_ms(50);
lcd_cmd(Line2); //Set to Line 2
delay_ms(50);
lcd_string(s_time); //Send our string.
delay_ms(60);
while(!set_btn){
delay_ms(50);
if(up_btn){
get_buttons(0);
}
}
}
void get_buttons(char hm){
if (hm == 1){
if(s_time[0] == 0x31){
if(s_time[1] < 0x32){
s_time[1]++;
} else {
s_time[1] = 0x31;
s_time[0] = 0x30;
}
} else {
s_time[1]++;
if(s_time[1] > 0x39){
s_time[1] = 0x30;
s_time[0]++;
}
}
} else {
s_time[4]++;
if(s_time[4] > 0x39){
s_time[4] = 0x30;
if(s_time[3] == 0x35)
s_time[3] = 0x30;
else
s_time[3]++;
}
}
lcd_clr_line(1);
delay_ms(50);
lcd_cmd(Line2); //Set to Line 1
delay_ms(50);
lcd_string(s_time); //Send our string.
delay_ms(60);
}
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
//// LCD FUNCTIONS
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
void lcd_clr_line(char line)
{
//This is our clear line command.
char tline; //The line to clear variable
char x; //loop variable
if(line==0) //set the variable value based on line
tline=0x80; // 0 = Line 1
else
tline=0xA8; // 1 = Line 2
lcd_cmd(tline); // Send command to jump to beggining of line (1/2)
delay_ms(1);
for(x=0;x<40;x++){ // Loop through all 40 chars of line (even tho 16 are viewable)
lcd_char(0x20); // Send Blank Character
delay_us(500);
}
lcd_cmd(tline); // Go back to beggining of line
delay_ms(1);
}
void lcd_init(void)
{ //This is our lcd initialization function
delay_ms(20); // Wait at least 16 mS after powerup
lcd_nybble(0x03,0); // send 0x03 cmd 3 times to initialize
delay_us(160);
e_togg(); // Since 0x03 nybble is on the port already
delay_us(160); // we just toggle 2 more times
e_togg();
delay_us(160);
lcd_nybble(0x02,0); //Enable 4 bit mode
delay_us(160);
lcd_cmd(0x28); //set 4-bit mode and 2 lines @ 5x7
delay_us(160);
lcd_cmd(0x10); //cursor move & shift left
delay_us(160);
lcd_cmd(0x06); //entry mode = increment
delay_us(160);
lcd_cmd(0x0d); //display on - cursor blink on
delay_us(160);
lcd_cmd(0x01); //clear display
delay_us(160);
delay_ms(5);
}
void e_togg(void){
lcd_e = 1;
lcd_e = 0;
}
void lcd_cmd(unsigned char letter)
{
//This is our Command Function
//The RS is set to 0 to signify this is a command
unsigned char temp; //Our temp Variable
temp=letter; //move letter to temp
temp=temp>>4; //shift temp to right by 4
lcd_nybble(temp,0); //send the 4 out
temp=letter; //move letter to temp
temp=temp&0x0f; //and out first 4
lcd_nybble(temp,0); //send out last 4
}
void lcd_char(unsigned char letter)
{
//This is the same as the lcd_cmd function except
//that is sets RS to 1 telling the lcd this is characters
unsigned char temp;
temp=letter;
temp=temp>>4;
lcd_nybble(temp,1);
temp=letter;
temp=temp&0x0f;
lcd_nybble(temp,1);
}
void lcd_string(char *senpoint)
{
while(*senpoint != '\0') //While we havent seen a \0 (esc) go on
{
lcd_char(*senpoint); //send 1st char to our char function
senpoint++; //send next
}
}
void lcd_nybble(unsigned char nyb,char rs)
{
char i;
char x;
lcd_rs = rs; //Set RS Pin (defined in header file)
for(i=0;i<4;i++){ //Loop through nybble
if((nyb & 0x08) != 0) //AND the nybble to 8
x=1; //if the AND == 1 set x
else
x=0; //if the AND == 0 clear x
if(i==0) //select RA3:RA0 and set/clear pins
lcd_DB7=x;
if(i==1)
lcd_DB6=x;
if(i==2)
lcd_DB5=x;
if(i==3)
lcd_DB4=x;
nyb=nyb<<1; //shift nybble to the left by 1 (4 times total)
}
e_togg(); //toggle E pin (defined in header file)
}
ok found a mojor problem (well for me it is)
My Line:
tmp2 = ((s_time[0]<<4) | s_time[1]); // For setting Hour
How can i add to this line to set the 7:5 bits without changing the others?
The problem is it sets the clock for 24 Hour. I tried :
& 0b00011111;
(and)
| 0b01000000;
This produces a weird result. Lets say i set time to 12:01 it will change it to 62:01 or something like that.
Any thoughts?
Here is the address map.
![]()
At some point you need to step back and spend some time learning C. The time you spend doing so will be well worth it.