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.