![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
jake1272
Joined: 15 Mar 2021 Posts: 37
|
Problem with DS3231 and PIC16F1847 |
Posted: Sun Apr 11, 2021 5:15 am |
|
|
Hi everyone,
I am building a real-time clock/calendar with 2 alarm functions using the PIC16F1847 microcontroller and DS3231 RTC chip. Time, date, and alarms are displayed on a 20×4 LCD screen. But so far I cannot display anything on the LCD. Any suggestions?
The compiler is CCS v5.065
The IDE is MPLAB X IDE v5.40
Here is the driver and my code:
Code: | // LCD module connections
#define LCD_RS_PIN PIN_A2
#define LCD_RW_PIN PIN_A3
#define LCD_ENABLE_PIN PIN_A4
#define LCD_DATA4 PIN_A7
#define LCD_DATA5 PIN_A6
#define LCD_DATA6 PIN_B5
#define LCD_DATA7 PIN_B4
// end LCD module connections
// pin definitions
#define button1 PIN_B1
#define button2 PIN_B2
#define button3 PIN_B3
#define LED_PIN PIN_B6
#include <16F1847.h>
#fuses INTRC_IO ,NOMCLR,NOLVP,NOBROWNOUT,PUT,NOWDT
#use delay(internal = 8MHz)
#use I2C(MASTER, I2C1, SLOW = 100000, STREAM = DS3231_STREAM)
#use fast_io(b)
#use fast_io(a)
#include <lcd.c> // include LCD driver source file
#include <DS3231.c> // include DS3231 driver source file
int8 i;
// DS3231 library variable declaration
RTC_Time *mytime, *alarm1, *alarm2;
// external interrupt routine
#INT_EXT
void ext_isr(void)
{
output_high(LED_PIN);
clear_interrupt(INT_EXT);
}
// function for displaying day of the week
void dow_print()
{
lcd_gotoxy(1, 2);
switch(mytime->dow)
{
case SUNDAY : printf(lcd_putc, "Sun"); break;
case MONDAY : printf(lcd_putc, "Mon"); break;
case TUESDAY : printf(lcd_putc, "Tue"); break;
case WEDNESDAY: printf(lcd_putc, "Wed"); break;
case THURSDAY : printf(lcd_putc, "Thu"); break;
case FRIDAY : printf(lcd_putc, "Fri"); break;
default : printf(lcd_putc, "Sat");
}
}
// a small function for buttons debounce
int1 debounce(int16 button)
{
int8 count = 0;
for(int8 i = 0; i < 5; i++)
{
if ( !input(button) )
count++;
delay_ms(10);
}
if(count > 2) return 1;
else return 0;
}
void wait()
{
set_timer0(0);
while( (get_timer0() < 62500L) && (input(button1) || i >= 5) && input(button2) && (input(button3) || i < 5) ) ;
}
int8 edit(int8 x_pos, int8 y_pos, int8 parameter)
{
if(i < 5)
while( debounce(button1) ); // call debounce function (wait for B1 to be released)
else
while( debounce(button3) ); // call debounce function (wait for B3 to be released)
lcd_gotoxy(x_pos, y_pos); // move cursor to row y_pos, column x_pos
while(TRUE)
{
while(!input(button2))
{
parameter++;
if( (i == 0 || i == 5) && parameter > 23) // if hours > 23 ==> hours = 0
parameter = 0;
if( (i == 1 || i == 6) && parameter > 59) // if minutes > 59 ==> minutes = 0
parameter = 0;
if(i == 2 && parameter > 31) // if day > 31 ==> day = 1
parameter = 1;
if(i == 3 && parameter > 12) // if month > 12 ==> month = 1
parameter = 1;
if(i == 4 && parameter > 99) // if year > 99 ==> year = 0
parameter = 0;
printf(lcd_putc, "%02u\b\b", parameter);
delay_ms(200);
}
lcd_putc(" \b\b");
wait();
printf(lcd_putc, "%02u\b\b", parameter);
wait();
if( (!input(button1) && i < 5) || (!input(button3) && i >= 5) )
{
i++; // increment 'i' for the next parameter
return parameter; // return parameter value and exit
}
}
}
void alarms_edit(int8 _alarm)
{
int1 alarm_c;
if(_alarm == 1) {
lcd_gotoxy(38, 1);
alarm_c = Alarm1_Status();
}
else {
lcd_gotoxy(38, 2);
alarm_c = Alarm2_Status();
}
while( debounce(button3) ); // call debounce function (wait for B3 to be released)
while(TRUE)
{
while( !input(button2) )
{
alarm_c = !alarm_c;
if(alarm_c)
lcd_putc("ON \b\b\b");
else
lcd_putc("OFF\b\b\b");
delay_ms(500);
}
lcd_putc(" \b\b\b");
wait();
if(alarm_c) lcd_putc("ON \b\b\b");
else lcd_putc("OFF\b\b\b");
wait();
if( !input(button3) )
{
if(_alarm == 1)
{
if(alarm_c) Alarm1_Enable(); // enable alarm1
else Alarm1_Disable(); // disable alarm1
}
else
{
if(alarm_c) Alarm2_Enable(); // enable alarm2
else Alarm2_Disable(); // disable alarm2
}
return;
}
}
}
// main function
void main()
{
setup_oscillator(OSC_8MHZ); // set internal oscillator to 8MHz
set_tris_b(0x0F); // configure RB0~4 ins as inputs
port_b_pullups(0x0E); // enable RB1, RB2 & RB3 internal pull-ups
enable_interrupts(GLOBAL); // enable global interrupts
enable_interrupts(INT_EXT_H2L); // enable external interrupt (INT0) with edge from high to low
delay_ms(1000); // wait a second
lcd_init(); // initialize LCD module
IntSqw_Set(OUT_INT); // DS3231 INT/SQW pin configuration (interrupt when alarm)
Disable_32kHZ(); // disable DS3231 32kHz output
while(TRUE)
{
// read current time and date
mytime = RTC_Get();
// print time
lcd_gotoxy(1, 1);
printf(lcd_putc, "%02u:%02u:%02u", mytime->hours, mytime->minutes, mytime->seconds);
// print date
dow_print(); // print week day
lcd_gotoxy(5, 2);
printf(lcd_putc, "%02u/%02u/20%02u", mytime->day, mytime->month, mytime->year);
// read alarm1
alarm1 = Alarm1_Get();
// print alarm1
lcd_gotoxy(21, 1);
printf(lcd_putc, "A1: %02u:%02u:00", alarm1->hours, alarm1->minutes);
lcd_gotoxy(38, 1);
if( Alarm1_Status() )
lcd_putc("ON ");
else
lcd_putc("OFF");
// read alarm2
alarm2 = Alarm2_Get();
// print alarm2
lcd_gotoxy(21, 2);
printf(lcd_putc, "A2: %02u:%02u:00", alarm2->hours, alarm2->minutes);
lcd_gotoxy(38, 2);
if( Alarm2_Status() )
lcd_putc("ON ");
else
lcd_putc("OFF");
// read chip temperature
signed int16 chip_temp = Get_Temperature();
// print chip temperature
lcd_gotoxy(11, 1);
if (chip_temp < 0) // if temperature is negative
printf(lcd_putc, "T:-%02Lu.%02Lu%cC", abs(chip_temp) / 100, abs(chip_temp) % 100, 223);
else
printf(lcd_putc, "T: %02Lu.%02Lu%cC", chip_temp / 100, chip_temp % 100, 223);
// if button B1 is pressed
if( !input(button1) )
if( debounce(button1) ) // call debounce function (make sure if B1 is pressed)
{
i = 0;
setup_timer_0(T0_INTERNAL | T0_DIV_16); // start Timer0 with internal clock & prescaler=16
mytime->hours = edit(1, 1, mytime->hours); // edit hours
mytime->minutes = edit(4, 1, mytime->minutes); // edit minutes
mytime->seconds = 0; // reset seconds
while( debounce(button1) ); // call debounce function (wait for button B1 to be released)
while(TRUE)
{
while( !input(button2) ) // if button B2 button is pressed
{
mytime->dow++;
if(mytime->dow > 7) mytime->dow = 1;
dow_print(); // print week day
delay_ms(500);
}
lcd_gotoxy(1, 2);
lcd_putc(" "); // print 3 spaces
wait(); // call wait() function
dow_print(); // print week day
wait(); // call wait() function
if( !input(button1) ) // if button B1 is pressed
break;
}
mytime->day = edit(5, 2, mytime->day); // edit day
mytime->month = edit(8, 2, mytime->month); // edit month
mytime->year = edit(13, 2, mytime->year); // edit year
while( debounce(button1) ); // call debounce function (wait for button B1 to be released)
// disable Timer0
// write data to the RTC chip
RTC_Set(mytime);
}
// if button B3 is pressed
if( !input(button3) )
if( debounce(button3) ) // call debounce function (make sure if B3 is pressed)
{
i = 5;
setup_timer_0(T0_INTERNAL | T0_DIV_16); // start Timer0 with internal clock & prescaler=16
alarm1->hours = edit(25, 1, alarm1->hours); // edit alarm1 hours
alarm1->minutes = edit(28, 1, alarm1->minutes); // edit alarm1 minutes
alarm1->seconds = 0; // reset alarm1 seconds
Alarm1_Set(alarm1, HOURS_MINUTES_SECONDS_MATCH); // alarm when hours, minutes and seconds match
Alarm1_IF_Reset(); // reset alarm1 interrupt flag
alarms_edit(1); // edit alarm1 ON & OFF
i = 5;
alarm2->hours = edit(25, 2, alarm2->hours); // edit alarm2 hours
alarm2->minutes = edit(28, 2, alarm2->minutes); // edit alarm2 minutes
Alarm2_Set(alarm2, HOURS_MINUTES_MATCH); // alarm when hours and minutes match
Alarm2_IF_Reset(); // reset alarm2 interrupt flag
alarms_edit(2); // edit alarm2 ON & OFF
while( debounce(button3) ); // call debounce function (wait for button B3 to be released)
}
if( input(LED_PIN) && !input(button2) )
{
output_low(LED_PIN);
if( Alarm1_IF_Check() )
{
Alarm1_IF_Reset(); // reset alarm1 interrupt flag
Alarm1_Disable(); // disable alarm1
}
if( Alarm2_IF_Check() )
{
Alarm2_IF_Reset(); // reset alarm2 interrupt flag
Alarm2_Disable(); // disable alarm2
}
}
delay_ms(100);
}
}
// end of code. |
Last edited by jake1272 on Sun Apr 11, 2021 5:53 am; edited 2 times in total |
|
![](templates/subSilver/images/spacer.gif) |
dyeatman
Joined: 06 Sep 2003 Posts: 1924 Location: Norman, OK
|
|
Posted: Sun Apr 11, 2021 5:28 am |
|
|
You need to remove the CCS DS3231 driver code from your posting.
Posting driver code is against CCS rules and copyright. _________________ Google and Forum Search are some of your best tools!!!! |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9168 Location: Greensville,Ontario
|
|
Posted: Sun Apr 11, 2021 5:44 am |
|
|
re: But so far I cannot display anything on the LCD
'anything' ? hmm...
Can you simply display 'Hello World' on the LCD ?
You need to break down the program into parts.
1st, can you get the PIC to run a 1Hz blinking LED program ?
if no, stay here until it works....
2nd confirm you can display 'hello world' on the display. This will confirm the LCD code is good, I/O pins, etc.
if no, stay here until it works...
3rd NOW try the DS3231 portion of the program... |
|
![](templates/subSilver/images/spacer.gif) |
jake1272
Joined: 15 Mar 2021 Posts: 37
|
|
Posted: Sun Apr 11, 2021 5:55 am |
|
|
dyeatman wrote: | You need to remove the CCS DS3231 driver code from your posting.
Posting driver code is against CCS rules and copyright. |
I am really sorry I have not fully read the terms and conditions. My bad |
|
![](templates/subSilver/images/spacer.gif) |
jake1272
Joined: 15 Mar 2021 Posts: 37
|
|
Posted: Sun Apr 11, 2021 5:58 am |
|
|
temtronic wrote: | re: But so far I cannot display anything on the LCD
'anything' ? hmm...
Can you simply display 'Hello World' on the LCD ?
You need to break down the program into parts.
1st, can you get the PIC to run a 1Hz blinking LED program ?
if no, stay here until it works....
2nd confirm you can display 'hello world' on the display. This will confirm the LCD code is good, I/O pins, etc.
if no, stay here until it works...
3rd NOW try the DS3231 portion of the program... |
I am just trying to say the time and date cannot be displayed on the lcd
Yes I can print on the LCD with this test code
Code: | // LCD module connections
#define LCD_RS_PIN PIN_A2
#define LCD_RW_PIN PIN_A3
#define LCD_ENABLE_PIN PIN_A4
#define LCD_DATA4 PIN_A7
#define LCD_DATA5 PIN_A6
#define LCD_DATA6 PIN_B5
#define LCD_DATA7 PIN_B4
// end LCD module connections
#include <16F1847.h>
#fuses NOMCLR NOBROWNOUT NOLVP INTRC_IO
#use delay(clock = 4MHz)
#include <lcd.c>
unsigned int8 i;
void lcd_shift_left(){
lcd_send_byte(0,0x18); // Shift left command
}
void lcd_shift_right(){
lcd_send_byte(0,0x1E); // Shift right command
}
void main(){
setup_oscillator(OSC_4MHZ); // Set the internal oscillator to 4MHz
lcd_init(); // Initialize LCD module
lcd_putc('\f'); // Clear LCD
lcd_gotoxy(2, 1); // Go to column 2 row 1
lcd_putc("PIC16F1847"); // Display "PIC16F1847"
delay_ms(1000); // Wait 1 second
lcd_gotoxy(1, 2); // Go to column 1 row 2
lcd_putc("LCD example");
delay_ms(1000);
lcd_gotoxy(21, 1); // Go to column 1 row 3
lcd_putc("Hello world!");
delay_ms(1000);
for(i = 0; i < 8; i++){
lcd_shift_right(); // Shift right
delay_ms(100);}
for(i = 0; i < 4; i++){
lcd_shift_left(); // Shift left
delay_ms(100);}
for(i = 0; i < 200; i++){
lcd_gotoxy(25, 2); // Go to column 5 row 4
printf(lcd_putc,"%3u",i); // Write i with 3 numbers max
delay_ms(200);
}
while(TRUE); // Endless loop
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9168 Location: Greensville,Ontario
|
|
Posted: Sun Apr 11, 2021 6:20 am |
|
|
great... least PICs running and LCD is OK...
next step....
goto the code library, and downlode PCMPs 'I2C SCANNER' program, compile and burn and run.....
It should find the DS3231 chip. If not, recheck wiring and be sure I2C pullups are there. If the DS3231 is a module, they _may_ be on the PCB.....
stay in this loop until scanner finds the DS3231.
Jay |
|
![](templates/subSilver/images/spacer.gif) |
jake1272
Joined: 15 Mar 2021 Posts: 37
|
|
Posted: Sun Apr 11, 2021 7:13 am |
|
|
Thank You, Jay. I have run the "I2C SCANNER" program and I got this print out in the terminal:
ACK addr: AE
ACK addr: D0
Number of i2c chips found: 2 |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9168 Location: Greensville,Ontario
|
|
Posted: Sun Apr 11, 2021 7:54 am |
|
|
D0 is the DS3231 RTC chip.
no idea what the AE address is for.
I cut my own RTC code as I have an ancient compiler....
Jay |
|
![](templates/subSilver/images/spacer.gif) |
jake1272
Joined: 15 Mar 2021 Posts: 37
|
|
Posted: Sun Apr 11, 2021 8:01 am |
|
|
I still have my pickit3 connected do you think that might be a problem? Which part of the code were you using when you are saying "you cut your own RTC code" ?
Thanks again |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9168 Location: Greensville,Ontario
|
|
Posted: Sun Apr 11, 2021 8:13 am |
|
|
I made my own DS3231 'driver'.
Having PK3 on shouldn't matter, I do that all the time..no pun intended.
Jay |
|
![](templates/subSilver/images/spacer.gif) |
jake1272
Joined: 15 Mar 2021 Posts: 37
|
|
Posted: Sun Apr 11, 2021 9:43 am |
|
|
Thanks, Jay, I will keep trying in the meantime what library will you recommend to fulfill my goal. This what I am trying to do "In the circuit, there will be 3 push buttons for setting time, date, and alarms, and one LED for indicating the alarms when occurred". |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19358
|
|
Posted: Sun Apr 11, 2021 10:22 am |
|
|
Big key difference between the working test and the problem code is
selecting fast_io. Don't. 99% of CCS code does not use fast_io.... |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9168 Location: Greensville,Ontario
|
|
Posted: Sun Apr 11, 2021 10:36 am |
|
|
As Mr. T points out, get rid of the fast_io().....let the compiler automatically handle the I/O as required !
In 2 1/2 decades of 'playing with PICs' and CCS C, I've only needed fast_io() 2 or 3 times. In each case, i needed to have very specific timing for proprietory interfaces.
One problem with using fast_io() is that if you change a pin YOU must re-code tris settings and what WILL happen, is you'll forget to do that, then 'it doesn't work' problems show up.
In your case, LCD module and RTC are 'slow' devices.
While I don't have the CCS DS3231 driver, I'm fairly confident that it does work. |
|
![](templates/subSilver/images/spacer.gif) |
jake1272
Joined: 15 Mar 2021 Posts: 37
|
|
Posted: Sun Apr 11, 2021 10:39 am |
|
|
Ttelmah wrote: | Big key difference between the working test and the problem code is
selecting fast_io. Don't. 99% of CCS code does not use fast_io... |
Thanks for the suggestion I have removed that, still it doesn't solve the problem |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9168 Location: Greensville,Ontario
|
|
Posted: Sun Apr 11, 2021 11:42 am |
|
|
did you also delete all set_tris...() statements ? |
|
![](templates/subSilver/images/spacer.gif) |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|