ok heres a correction
Code:
if(timet[minbug]==68)if(secs==16)
{timet[minbug]=0;secs++;}
if(timet[minbug]==68)if(secs==16)
{timet[minbug]=0;secs++;}
That's so off the mark that I would suggest, as I did earlier, that you go back and read the data sheet more thoroughly.the deviation is 1 second every 4096
So you expect a yes ,yes sir, Im all wrong? I just cant verify what you say. You refuse to show your source, but compare some program "X" to mine.I was simply trying to help you learn programming. No need to get so hyped up.
I did. This is the result.That's so off the mark that I would suggest, as I did earlier, that you go back and read the data sheet more thoroughly.
I dont understand the grammar, frankly. "The bugs" now youre giving out, instead process one problem after the other. How do you know my programming abilities?The bugs that u pointed out is quite common amongst people who are beginning to code those devices.
[/quote]Unfortunately for you, you picked a very difficult device to code.
There are lots of long tenured beginners.Started with embedded C 5 years ago or so.
Ok but I only wish to process problems one by one, improve c skills. Your replies in this regard are most welcome.There are lots of long tenured beginners.
I think you will learn far more by doing it yourself.Solutions please.
#define DIG1_PORT PORTB
#define DIG1_DDR TRISB
#define DIG1 (1<<0)
//Pin11/SegA on RA3
#define SEGA_PORT PORTA
#define SEGA_DDR TRISA
#define SEGA (1<<3)
//Pin10/SegF on RA2
#define SEGF_PORT PORTA
#define SEGF_DDR TRISA
#define SEGF (1<<2)
//Pin9/Dig2 on RA1
#define DIG2_PORT PORTA
#define DIG2_DDR TRISA
#define DIG2 (1<<1)
//Pin8/Dig3 on RB7
#define DIG3_PORT PORTB
#define DIG3_DDR TRISB
#define DIG3 (1<<7)
//Pin7/SegB on RA0
#define SEGB_PORT PORTA
#define SEGB_DDR TRISA
#define SEGB (1<<0)
//Pin6/Dig4 on RB6
#define DIG4_PORT PORTB
#define DIG4_DDR TRISB
#define DIG4 (1<<6)
//Pin5/SegG on RB5
#define SEGG_PORT PORTB
#define SEGG_DDR TRISB
#define SEGG (1<<5)
//Pin4/SegC on RB4
#define SEGC_PORT PORTB
#define SEGC_DDR TRISB
#define SEGC (1<<4)
//Pin3/SegDP on RB3
#define SEGDP_PORT PORTB
#define SEGDP_DDR TRISB
#define SEGDP (1<<3)
//Pin2/SegD on RA2
#define SEGD_PORT PORTB
#define SEGD_DDR TRISB
#define SEGD (1<<2)
//Pin1/SegE on RA1
#define SEGE_PORT PORTB
#define SEGE_DDR TRISB
#define SEGE (1<<1)
#include <xc.h> // 32 KHZ LEd 7 segment clock
#pragma config OSC = LP WDT = OFF CP = OFF // configuration 16F54
const unsigned char dig_PORTA[] @0x01a ={0b1111,0b0011,0b1011,0b1011,\
0b0111,0b1110,0b1110,0b1011,\
0b1111,0b1111,0b1111,0b0110,\
0b1110,0b0011,0b1010,0b1010,\
0b1101,0b0001,0b1001,0b1001,\
0b0101,0b1100,0b1100,0b1001,\
0b1101,0b1101,0b1101,0b0100,\
0b1100,0b0001,0b1000,0b1000,\
0b1111,0b0011,0b1011,0b1011,\
0b0111,0b1110,0b1110,0b1011,\
0b1111,0b1111,0b1111,0b0110,\
0b1110,0b0011,0b1010,0b1010,\
0b1111,0b0011,0b1011,0b1011,\
0b0111,0b1110,0b1110,0b1011,\
0b1111,0b1111,0b1111,0b0110,\
0b1110,0b0011,0b1010,0b1010}; // segment and sink driving table for PORTA
const unsigned char dig_PORTB[] @0x60 ={0b11010110,0b11010000,0b11100110,0b11110100,\
0b11110000,0b11110100,0b11110110,0b11110000,\
0b11110110,0b11110100,0b11110010,0b11100110,\
0b11000110,0b11010110,0b11110110,0b11100110,\
0b11010111,0b11010001,0b11100111,0b11110101,\
0b11110001,0b11110101,0b11110111,0b11110001,\
0b11110111,0b11110101,0b11110011,0b11100111,\
0b11000111,0b11010111,0b11110111,0b11100111,\
0b01010111,0b01010001,0b01100111,0b01110101,\
0b01110001,0b01110101,0b01110111,0b01110001,\
0b01110111,0b01110101,0b01110011,0b01100111,\
0b01000111,0b01010111,0b01110111,0b01100111,\
0b10010111,0b10010001,0b10100111,0b10110101,\
0b10110001,0b10110101,0b10110111,0b10110001,\
0b10110111,0b10110101,0b10110011,0b10100111,\
0b10000111,0b10010111,0b10110111,0b10100111}; // segment and sink driving table for PORTB
unsigned char* tptr;
unsigned char v_phase,v_digphase,secs;
unsigned char ddata[8];
unsigned char timet[5];
#define hrh 0
#define hrl 1
#define minh 2
#define minl 3
#define minbug 4
void update() // precompute the display data, load from ROM table
{unsigned char i,i2;
for(i=0;i<4;i++)
{
i2=timet[i]+(i<<4);
*(tptr+i+i)=dig_PORTA[i2];
*(tptr+1+i+i)=dig_PORTB[i2];
}
}
void display() // update the multiplex display
{
TRISA=0xff;TRISB=0xff;
PORTA=*(tptr+v_digphase);
PORTB=*(tptr+1+v_digphase);
TRISA=0;TRISB=0;
v_phase+=0x10;v_phase&=0x30;
v_digphase+=2;v_digphase&=0x07;
}
void minplus()
{
secs=0;
timet[minl]++;
timet[minbug]++;
if(timet[minl]==10)
{
timet[minl]=0;if(++timet[minh]==6)
{
timet[minh]=0;
if(++timet[hrl]==10){timet[hrh]+=1;timet[hrl]=0;}
if(timet[hrl]==4)if(timet[hrh]==2){timet[hrh]=0;timet[hrl]=0;}
}
}
}
void secplus()
{
TMR0&=0x1f;
*(tptr+3)^=0x8; // blink rhe LED
secs++;
if(timet[minbug]==68)if(secs==16)
{timet[minbug]=0;secs++;}
}
void main(void)
{
v_phase=0;v_digphase=0; //initialization
secs=0;timet[minbug]=0;
timet[minl]=0;timet[minh]=0;timet[hrl]=0;timet[hrh]=0;
TRISB=0;TRISA=0;OPTION=0x07;
tptr=&ddata[0];
update(); // display 00.00
sett_reloop:;
TRISB=0x02;
if((PORTB&0x02)==0)
{
TMR0=0;TRISB=0;
while(TMR0<0x2)display();
minplus();update();TMR0=0;
goto sett_reloop;
}else TRISB=0;
while(1)
{
if(TMR0&0x20) secplus(); else if(secs==60)
{minplus();update();}
display();
}}
Unfortunately, when I went to program the chip, MPLAB bricked my PM3 so I was not able to test it on actual hardware. I wanted to do that before adding the Time Set functions but have to wait to get the PM3 up again. If you are still interested, I'll proceed (since I wired a breadboard). Otherwise you can have the code as is if you want. It's a decent example of baseline PIC coding and a reminder of why you wouldn't do it if you had a choice. The only reason I took a shot at it was because I just ported some client code from the C54 to the F54 for cost/availability reasons and had some chips laying around.Memory Summary:
Program space used C1h ( 193) of 200h words ( 37.7%)
Data space used Eh ( 14) of 19h bytes ( 56.0%)
EEPROM space None available
Data stack space used 0h ( 0) of Bh bytes ( 0.0%)
Configuration bits used 1h ( 1) of 1h word (100.0%)
ID Location space used 0h ( 0) of 4h bytes ( 0.0%)
You have compiled in FREE mode.
Using Omnicient Code Generation that is available in PRO mode,
you could have produced up to 60% smaller and 400% faster code.
See http://www.microchip.com/MPLABXCcompilers for more information.
make[2]: Leaving directory 'M:/UP/PIC/Clock54/Clock54.X'
make[1]: Leaving directory 'M:/UP/PIC/Clock54/Clock54.X'
BUILD SUCCESSFUL (total time: 1s)
Loading code from M:/UP/PIC/Clock54/Clock54.X/dist/ReleasePM3/production/Clock54.X.production.hex...
Loading completed
TMR0&=0x1f;
if((TMR0&0b11100000)!=tmrx)secplus();
tmrx=TMR0&0b11100000;
#include <xc.h> // 32 KHZ LED 7 segment clock, V1.00 - 72% F:ASH used
#pragma config OSC = LP WDT = OFF CP = OFF // configuration 16F54
const unsigned char dig_PORTA[] @0x01a ={0b1111,0b0011,0b1011,0b1011,\
0b0111,0b1110,0b1110,0b1011,\
0b1111,0b1111,0b1111,0b0110,\
0b1110,0b0011,0b1010,0b1010,\
0b1101,0b0001,0b1001,0b1001,\
0b0101,0b1100,0b1100,0b1001,\
0b1101,0b1101,0b1101,0b0100,\
0b1100,0b0001,0b1000,0b1000,\
0b1111,0b0011,0b1011,0b1011,\
0b0111,0b1110,0b1110,0b1011,\
0b1111,0b1111,0b1111,0b0110,\
0b1110,0b0011,0b1010,0b1010,\
0b1111,0b0011,0b1011,0b1011,\
0b0111,0b1110,0b1110,0b1011,\
0b1111,0b1111,0b1111,0b0110,\ // 16 values for each multiplex phase
0b1110,0b0011,0b1010,0b1010}; // segment and sink driving table for PORTA
const unsigned char dig_PORTB[] @0x60 ={0b11010110,0b11010000,0b11100110,0b11110100,\
0b11110000,0b11110100,0b11110110,0b11110000,\
0b11110110,0b11110100,0b11110010,0b11100110,\
0b11000110,0b11010110,0b11110110,0b11100110,\
0b11010111,0b11010001,0b11100111,0b11110101,\
0b11110001,0b11110101,0b11110111,0b11110001,\
0b11110111,0b11110101,0b11110011,0b11100111,\
0b11000111,0b11010111,0b11110111,0b11100111,\
0b01010111,0b01010001,0b01100111,0b01110101,\
0b01110001,0b01110101,0b01110111,0b01110001,\
0b01110111,0b01110101,0b01110011,0b01100111,\
0b01000111,0b01010111,0b01110111,0b01100111,\
0b10010111,0b10010001,0b10100111,0b10110101,\
0b10110001,0b10110101,0b10110111,0b10110001,\
0b10110111,0b10110101,0b10110011,0b10100111,\
0b10000111,0b10010111,0b10110111,0b10100111}; // segment and sink driving table for PORTB
unsigned char* tptr; // pointer to display buffer
unsigned char v_phase,v_digphase,secs,tmrx;
unsigned char ddata[8]; // array for display buffer
unsigned char timet[4]; // array for time
#define hrh 0
#define hrl 1
#define minh 2
#define minl 3
void update() // precompute the display data, load from ROM table
{unsigned char i,i2;
for(i=0;i<4;i++)
{// RAM buffer holds values for PORTA and PORTB for each multiplex phase
i2=timet[i]+(i<<4);
*(tptr+i+i)=dig_PORTA[i2];
*(tptr+1+i+i)=dig_PORTB[i2];
}
}
void display() // update the multiplex display
{
TRISA=0xff;TRISB=0xff;// required to turn off PORTs because ghosting
PORTA=*(tptr+v_digphase);
PORTB=*(tptr+1+v_digphase);
TRISA=0;TRISB=0;// turn on again
v_digphase+=2;v_digphase&=0x07;// increment and mask out upper 5 bits same as rollover at 0x08
}
void minplus()
{// 24 hours clock logic
secs=0;
timet[minl]++;
if(timet[minl]==10)
{
timet[minl]=0;if(++timet[minh]==6)
{
timet[minh]=0;
if(++timet[hrl]==10){timet[hrh]+=1;timet[hrl]=0;}
if(timet[hrl]==4)if(timet[hrh]==2){timet[hrh]=0;timet[hrl]=0;}
}
}
}
void secplus()
{
tmrx=TMR0&0b11100000; //mask out lower 5 bits
*(tptr+3)^=0x8; // blink rhe LED
secs++;
}
void main(void)
{
tmrx=0;v_digphase=0;secs=0;
timet[minl]=0;timet[minh]=0;timet[hrl]=0;timet[hrh]=0;
TRISA=0;OPTION=0x07;TMR0=0;
tptr=&ddata[0]; // clear variables
update(); // display 00.00
sett_reloop:;// pushbutton logic to set time at startup
TRISB=0x02;
if((PORTB&0x02)==0)
{// pushbutton was hold down, enter
TMR0=0;TRISB=0;
while(TMR0<0x2)display();// small delay and increment minutes
minplus();update();TMR0=0;
goto sett_reloop;// reloop until button is released
}else TRISB=0;
while(1)
{// check if any of the 3 upper bits have changed = 1 sec elapsed
if((TMR0&0b11100000)!=tmrx)secplus();if(secs==60){minplus();update();}
display();// multiplex display from RAM buffer
}}
So you say with your much smaller program code, the display isnt flickering?One thing you have to be careful of when substituting an '84 for a '54 is the smaller stack on the latter. Just for grins, I coded a clock to @takao21203 's specs using a 16F54 mainly to see how XC8 did with the low-end processors. I had to be careful in the table lookups due to to the miserable 2 level stack but basic timekeeping/muxed display with 32KHz XTAL sims OK. Display IO is re-mappable at compile time as are output levels for CC/CA displays, 12/24hour time etc. It compiles like this in XC8 Free mode:
Unfortunately, when I went to program the chip, MPLAB bricked my PM3 so I was not able to test it on actual hardware. I wanted to do that before adding the Time Set functions but have to wait to get the PM3 up again. If you are still interested, I'll proceed (since I wired a breadboard). Otherwise you can have the code as is if you want. It's a decent example of baseline PIC coding and a reminder of why you wouldn't do it if you had a choice. The only reason I took a shot at it was because I just ported some client code from the C54 to the F54 for cost/availability reasons and had some chips laying around.
I'm happy for you that you finally got it, after ~40 back-and-forth.Dont need to write to TMR0 then.