#include <xc.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "configbits.h"
#include "i2c.h" // This header file includes I2C.c file which is used to interface the I2C
#include "uart.h" // This header file includes uart.c file which is used to interface the UART for serial communication
#include "segment.h"
#include "lcd.h"
#define _XTAL_FREQ 20000000
#define I2C_SPEED 100000 // kbps
//Function Declarations
// Define RTC device address
#define DS1307_Add_write 0xD0
#define DS1307_Add_read 0xD1
#define switch1 PORTCbits.RC0
#define switch2 PORTCbits.RC1
#define switch3 PORTCbits.RC2
int sec,min,hour;
int Day,Date,Month,Year;
int i;
char secs[10],mins[10],hours[10];
char Clock_type = 0x06;
char AM_PM = 0x05;
int H_value,M_value,S_value;
int upd_hour,upd_min,upd_sec;
int status,status1,status2;
char BCDtoDecimal (char val)
{
char res;
res = (val & 0x0F) + ((val & 0xF0)>>4)*10;
return res;
}
char Dec2BCD(char val)
{
char res;
res = (val/10) << 4;
res = res | (val % 10);
return res;
}
void RTC_Clock_Write(char sec1, char min1, char hour1, char AM_PM) // function for clock
{
I2C_Start();
I2C_Write(0xD0);
I2C_Write(0x00);
// I2C_Write(0x80); //CH = 1 Stop oscillator
I2C_Write(Dec2BCD(sec1));
I2C_Write(Dec2BCD(min1)); //Minute
I2C_Write(Dec2BCD(hour1)); //Hour
I2C_Stop(); //Stop the I2C Protocol
__delay_ms(20);
}
void RTC_Read_Clock(char read_clock_address)
{
I2C_Start();
I2C_Write(DS1307_Add_write);
I2C_Write(Dec2BCD(read_clock_address));
I2C_ReStart();
I2C_Write(DS1307_Add_read);
sec = I2C_Read_Byte(); //read data and send ack for continuous reading
I2C_Send_ACK();
min = I2C_Read_Byte(); //read data and send ack for continuous reading
I2C_Send_ACK();
hour= I2C_Read_Byte(); //read data and send nack for indicating stop reading
I2C_Send_NACK();
}
void Read_RTCclock(void)
{
RTC_Read_Clock(0); //gives second,minute and hour
I2C_Stop();
__delay_ms(10);
if(hour & (1<<Clock_type)){ // check clock is 12hr or 24hr
hour = hour & (0x1f);
hour = BCDtoDecimal(hour);
min = BCDtoDecimal(min);
sec = BCDtoDecimal(sec);
Segment_Disp(hour,min,sec);
}
else{
hour = hour & (0x3f);
hour = BCDtoDecimal(hour);
min = BCDtoDecimal(min);
sec = BCDtoDecimal(sec);//__delay_ms(250);
Segment_Disp(hour,min,sec);
}
}
void main()
{
ADCON1 = 0X0F;
segment_Init();
int count = 0;
InitI2C();
TRISB0 = 1;
TRISB1= 1;
TRISC0 = 1;
TRISC1 = 1;
TRISC2 = 1;
PORTC = 0X00; //set frequency to 8 MHz
while(1)
{
Read_RTCclock();
}
}
I can´t find any display multiplexing in your code.using multiplexing concept
#include <xc.h>
#include "configbits.h"
#include "segment.h"
#define _XTAL_FREQ 20000000 //define crystal frequency to 20MHz
#define control1 PORTBbits.RB2
#define control2 PORTBbits.RB3
#define control3 PORTBbits.RB4
#define control4 PORTBbits.RB5
#define control5 PORTBbits.RB6
#define control6 PORTBbits.RB7
char binary_pattern[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void segment_Init(void)
{
TRISD = 0X00; // initialize PORTD pins to active low
TRISB2 = 0;
TRISB3 = 0;
TRISB4 = 0;
TRISB5 = 0;
// // TRISC = 0X00;
TRISB6 = 0;
TRISB7 = 0;
ADCON1 = 0X0F; // To Make PORTB pins as Digital I/O
control1 = 1; // TurnOff all 6 Segments
control2 = 1;
control3 = 1;
control4 = 1;
control5 = 1;
control6 = 1;
}
void Segment_Disp(int value1, int value2, int value3)
{
// PORTD = 0X80;
unsigned int a,b,c,d,e,f;
a = value1 / 10;
b = value1%10;
c = value2/10;
d = value2%10;
e = value3 / 10;
f = value3 % 10;
PORTD=binary_pattern[a];
control1=0;
__delay_ms(3);
control1=1;
PORTD=binary_pattern[b] | 0x80;
control2=0;
__delay_ms(3);
control2=1;
PORTD=binary_pattern[c];
control3 = 0;
__delay_ms(3);
control3=1;
PORTD=binary_pattern[d] | 0x80;
control4 = 0;
__delay_ms(3);
control4=1;
PORTD=binary_pattern[e];
control5 = 0;
__delay_ms(3);
control5 = 1;
PORTD=binary_pattern[f];
control6 = 0;
__delay_ms(3);
control6 = 1;
}
Thanks for your response, can explain a bit more in detail about thisYou could wire the SQR/OUT to the microcontroller´s port.
Every time there is a rising edge at this port read the RTC (could be done in main loop context)
after reading the RTC calculate all values .. and store the display data (port D) in an array.
(Once per second)
Klaus
You could wire the SQR/OUT to the microcontroller´s port.
/*
* File: main.c
* Author: dan1138
* Compiler: XC8 V2.32
* IDE: MPLABX v5.50
*
* Created on July 26, 2021, 3:26 PM
*
* PIC18F4550
* +----------:_:----------+
* VPP -> 1 : RE3/MCLR/VPP PGD/RB7 : 40 <> DIGIT0/PGD
* <> 2 : RA0/AN0 PGC/RB6 : 39 <> DIGIT1/PGC
* <> 3 : RA1/AN1 PGM/RB5 : 38 <> DIGIT2
* <> 4 : RA2/AN2 AN11/RB4 : 37 <> DIGIT3
* <> 5 : RA3/AN3 AN9/RB3 : 36 <> DIGIT4
* <> 6 : RA4 INT2/AN8/RB2 : 35 <> DIGIT5
* <> 7 : RA5/AN4 INT1/AN10/RB1 : 34 <>
* <> 8 : RE0/AN5 INT0/AN12/RB0 : 33 <>
* <> 9 : RE1/AN6 VDD : 32 <- 5v0
* <> 10 : RE2/AN7 VSS : 31 <- GND
* 5v0 -> 11 : VDD RD7 : 30 <> SEGdp
* GND -> 12 : VSS RD6 : 29 <> SEGg
* <> 13 : OSC1 RD5 : 28 <> SEGf
* <> 14 : OSC2 RD4 : 27 <> SEGe
* <> 15 : RC0 RX/RC7 : 26 <>
* <> 16 : RC1/CCP2 TX/RC6 : 25 <>
* <> 17 : RC2/CCP1 D+/RC5 : 24 <- (can only be used as GPIO input)
* <> 18 : RC3 D-/RC4 : 23 <- (can only be used as GPIO input)
* SEGa <> 19 : RD0 RD3 : 22 <> SEGd
* SEGb <> 20 : RD1 RD2 : 21 <> SEGc
* +-----------------------:
* DIP-40
*
* Description:
*
* Homework assignment see EDA board:
* https://www.edaboard.com/threads/ds1307-slows-with-7-segment-display.398985/
*
* This is an application to show how to use the TIMER0 interrupt to
* refresh a multiplexed six digit 7-segment LED display matrix.
*/
#pragma config PLLDIV = 1, CPUDIV = OSC1_PLL2, USBDIV = 1
#pragma config FOSC = INTOSC_XT, FCMEN = OFF, IESO = OFF
#pragma config PWRT = OFF, BOR = OFF, BORV = 3, VREGEN = OFF
#pragma config WDT = OFF, WDTPS = 32768, CCP2MX = ON
#pragma config PBADEN = ON, LPT1OSC = OFF, MCLRE = ON
#pragma config STVREN = ON, LVP = OFF, ICPRT = OFF, XINST = OFF
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF
#pragma config CPB = OFF, CPD = OFF
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF
#pragma config WRTC = OFF, WRTB = OFF, WRTD = OFF
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF
#pragma config EBTRB = OFF
#include <xc.h>
#define _XTAL_FREQ (8000000ul)
/*
* Common cathode LED segment drivers for hexadecimal digits
*/
const char LEDDigit[] =
{
/* gfedcba _ */
0b00111111, /* | | */
/* |_| */
/* */
0b00000110, /* | */
/* | */
/* _ */
0b01011011, /* _| */
/* |_ */
/* _ */
0b01001111, /* _| */
/* _| */
/* */
0b01100110, /* |_| */
/* | */
/* _ */
0b01101101, /* |_ */
/* _| */
/* _ */
0b01111101, /* |_ */
/* |_| */
/* _ */
0b00000111, /* | */
/* | */
/* _ */
0b01111111, /* |_| */
/* |_| */
/* _ */
0b01100111, /* |_| */
/* | */
/* _ */
0b01110111, /* |_| */
/* | | */
/* */
0b01111100, /* |_ */
/* |_| */
/* _ */
0b00111001, /* | */
/* |_ */
/* */
0b01011110, /* _| */
/* |_| */
/* _ */
0b01111001, /* |_ */
/* |_ */
/* _ */
0b01110001, /* |_ */
/* | */
/* */
0b00000000, /* blank */
/* */
};
volatile unsigned char DigitSegments[6];
volatile unsigned char DigitSelected;
/*
* Interrupt Service Routines
*/
void __interrupt(high_priority) ISR_hi(void)
{
if((INTCONbits.T0IE) && (INTCONbits.T0IF)) /* TIMER0 asserts and interrupt every 1.024 milliseconds */
{
/*
* Turn on one of six digits in the LED display matrix
*/
INTCONbits.T0IF = 0;
LATB |= 0b11111100; /* Turn off all digit drivers */
if(DigitSelected >= sizeof(DigitSegments)) DigitSelected = 0;
LATD = DigitSegments[DigitSelected];
LATB &= ~(0x80>>DigitSelected);
DigitSelected++;
}
}
/*
* Convert unsigned long to 6 decimal digits for the LED display
*/
void LED_ulToSegments(unsigned long data)
{
unsigned char Digit;
Digit = sizeof(DigitSegments);
do
{
Digit--;
DigitSegments[Digit] = LEDDigit[data % 10];
data /= 10;
} while(Digit);
}
/*
* Make LED display blank
*/
void LED_blank(void)
{
unsigned char Digit;
Digit = sizeof(DigitSegments);
do
{
DigitSegments[--Digit] = 0;
} while(Digit);
}
/*
* Main application
*/
void main(void)
{
unsigned long Count;
INTCONbits.GIEH = 0; /* disable all interrupt sources */
INTCONbits.GIEL = 0;
INTCONbits.INT0IE = 0;
INTCONbits.RBIE = 0;
INTCONbits.TMR0IE = 0;
INTCON3bits.INT1IE = 0;
INTCON3bits.INT2IE = 0;
PIE1 = 0;
PIE2 = 0;
RCONbits.IPEN = 0; /* Use legacy interrupt mode */
/*
* Select 8 MHz internal oscillator
*/
OSCCON = 0x72;
/*
* Make all GPIOs digital
*/
ADCON1 = 0x0F; /* Disable all ADC analog inputs */
CMCON = 0x07; /* Disable all Comparator analog inputs */
/*
* Setup LED multiplexer
*/
INTCONbits.TMR0IE = 0;
TRISD = 0; /* Make segment drivers outputs */
TRISB &= 0b00000011; /* Make digit drivers outputs */
DigitSelected = 0;
LED_blank();
T0CON = 0b01000010; /* TIMER0 off, FOSC/4 clock, prescale 1:8 */
INTCON2bits.T0IP = 1; /* Select high priority interrupt handler */
TMR0 = 0;
INTCONbits.TMR0IF = 0;
INTCONbits.TMR0IE = 1;
T0CONbits.TMR0ON = 1; /* Turn on TIMER0 */
/*
* Enable system interrupts
*/
INTCONbits.GIEL = 1;
INTCONbits.GIEH = 1;
/*
* Process loop
*/
Count = 0;
for(;;)
{
__delay_ms(1000);
LED_ulToSegments(Count++);
}
}
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?