to drive a few leds, you have gone from pic16f to pic18f and then pic24f?PIC24FJ64GA102-I/SP (SPDIP)
what's so special about your application that a lowly pic16f cannot do?
to drive a few leds, you have gone from pic16f to pic18f and then pic24f?PIC24FJ64GA102-I/SP (SPDIP)
the code presented so far is so poorly written that I don't think you are making headways against that goal.My objective to this was that once the decimal display algorithm was understood
//initialize the led display
void led_init(void) {
//reset the display dig pins
DIG_OFF(DIG0_PORT, DIG0); IO_OUT(DIG0_DDR, DIG0);
DIG_OFF(DIG1_PORT, DIG1); IO_OUT(DIG1_DDR, DIG1);
DIG_OFF(DIG2_PORT, DIG2); IO_OUT(DIG2_DDR, DIG2);
DIG_OFF(DIG3_PORT, DIG3); IO_OUT(DIG3_DDR, DIG3);
//reset the segment pins
SEG_OFF(SEG0_PORT, SEG0); IO_OUT(SEG0_DDR, SEG0);
SEG_OFF(SEG1_PORT, SEG1); IO_OUT(SEG1_DDR, SEG1);
SEG_OFF(SEG2_PORT, SEG2); IO_OUT(SEG2_DDR, SEG2);
SEG_OFF(SEG3_PORT, SEG3); IO_OUT(SEG3_DDR, SEG3);
SEG_OFF(SEG4_PORT, SEG4); IO_OUT(SEG4_DDR, SEG4);
SEG_OFF(SEG5_PORT, SEG5); IO_OUT(SEG5_DDR, SEG5);
SEG_OFF(SEG6_PORT, SEG6); IO_OUT(SEG6_DDR, SEG6);
SEG_OFF(SEG7_PORT, SEG7); IO_OUT(SEG7_DDR, SEG7);
SEG_OFF(SEG8_PORT, SEG8); IO_OUT(SEG8_DDR, SEG8);
SEG_OFF(SEG9_PORT, SEG9); IO_OUT(SEG9_DDR, SEG9);
//SEG_OFF(SEG10_PORT, SEG10); IO_OUT(SEG10_DDR, SEG10);
//SEG_OFF(SEG11_PORT, SEG11); IO_OUT(SEG11_DDR, SEG11);
//SEG_OFF(SEG12_PORT, SEG12); IO_OUT(SEG12_DDR, SEG12);
//SEG_OFF(SEG13_PORT, SEG13); IO_OUT(SEG13_DDR, SEG13);
}
//update the display
void led_display(void) {
uint16_t tmp; //display pattern - for > 8 segments
//uint8_t tmp; //display segment pattern - for 8 segments or less
static uint8_t dig=0; //current dig to be displayed on
//IO_FLP(LED_PORT, LED); //for debug only
//turn off all digits
DIG_OFF(DIG0_PORT, DIG0);
DIG_OFF(DIG1_PORT, DIG1);
DIG_OFF(DIG2_PORT, DIG2);
DIG_OFF(DIG3_PORT, DIG3);
//load the segments (seg0..10]
tmp = LRAM[dig]; //current digit to be displayed
if (tmp & (1<<0)) SEG_ON(SEG0_PORT, SEG0); else SEG_OFF(SEG0_PORT, SEG0);
if (tmp & (1<<1)) SEG_ON(SEG1_PORT, SEG1); else SEG_OFF(SEG1_PORT, SEG1);
if (tmp & (1<<2)) SEG_ON(SEG2_PORT, SEG2); else SEG_OFF(SEG2_PORT, SEG2);
if (tmp & (1<<3)) SEG_ON(SEG3_PORT, SEG3); else SEG_OFF(SEG3_PORT, SEG3);
if (tmp & (1<<4)) SEG_ON(SEG4_PORT, SEG4); else SEG_OFF(SEG4_PORT, SEG4);
if (tmp & (1<<5)) SEG_ON(SEG5_PORT, SEG5); else SEG_OFF(SEG5_PORT, SEG5);
if (tmp & (1<<6)) SEG_ON(SEG6_PORT, SEG6); else SEG_OFF(SEG6_PORT, SEG6);
if (tmp & (1<<7)) SEG_ON(SEG7_PORT, SEG7); else SEG_OFF(SEG7_PORT, SEG7);
if (tmp & (1<<8)) SEG_ON(SEG8_PORT, SEG8); else SEG_OFF(SEG8_PORT, SEG8);
if (tmp & (1<<9)) SEG_ON(SEG9_PORT, SEG9); else SEG_OFF(SEG9_PORT, SEG9);
//if (tmp & (1<<10)) SEG_ON(SEG10_PORT, SEG10); else SEG_OFF(SEG10_PORT, SEG10);
//if (tmp & (1<<11)) SEG_ON(SEG11_PORT, SEG11); else SEG_OFF(SEG11_PORT, SEG11);
//if (tmp & (1<<12)) SEG_ON(SEG12_PORT, SEG12); else SEG_OFF(SEG12_PORT, SEG12);
//if (tmp & (1<<13)) SEG_ON(SEG13_PORT, SEG13); else SEG_OFF(SEG13_PORT, SEG13);
//turn on current digit, and advance to the next digit (max = 4)
switch (dig) {
case 0: DIG_ON(DIG0_PORT, DIG0); dig = 1; break;
case 1: DIG_ON(DIG1_PORT, DIG1); dig = 2; break;
case 2: DIG_ON(DIG2_PORT, DIG2); dig = 3; break;
case 3: DIG_ON(DIG3_PORT, DIG3); dig = 0; break;
}
}
led_init(); //reset the led display module
tmr2_init(LED_PS, LED_PR); //reset tmr2
tmr2_act(led_display); //install user handler
ei(); //enable global interrupts
//prepare adc value
adc = (++adc) & 0x3ff; //adc is a 10-bit value
volt = ADC2VOLT(adc); //convert adc to VOLT -> 0..300/1024
//prepare for display
tmp = volt;
LRAM[0]= led_font[tmp % 10]; tmp /= 10; //lsb conversion
LRAM[1]= led_font[tmp % 10]; tmp /= 10;
LRAM[2]= led_font[tmp % 10]; tmp /= 10;
LRAM[3]= led_font[tmp % 10]; tmp /= 10; //msb conversion
It is done in xc8.Is this written in CCS? If
You want to go from 7-segment to decimal (1 of 10)? I would use a PROM or EPROM and go from 7 segment to BCD then BCD to Decimal. With one EPROM you could handle two digits.Greetings,
There are a few of the PIC DVM found on the web using a PIC16F676. They are designed to drive seven segment LED displays. I have been aiming to attempt to build one to output decimal instead of seven segment in order to drive a set of edge-lit displays. The only example of such a circuit uses the rare and obsolete CA3162e Intersil IC (A/D converter) and a 74HC145 (BCD to Decimal driver) in the image below:
View attachment 91249
The aim was to create a more modern version of this using the PIC micro. The PIC16F676 doesn't have enough I/O pins to handle ten LED's in a row. The Microchip search tool led me to the PIC16F1826 as it has enough I/O's and has a 10bit A/D converter. But looking at the C code for the 676 DVM, it is using 2 byte HEX to build the segment patterns for seven segment displays. I wasn't certain that this would work so easily for ten LED's as I ended up creating 3 byte HEX (or 12 bits) for each single LED pattern and the PIC16F1826 is an 8bit device. I attempted to compile the code with XC8 under MPLAB X IDE 3.05 to learn that the code appeared to be made for another compiler. I had to make changes to the code to fit the new pin arrangements and it compiled. I ran the MCU but at this point, the three multiplexers are working but there is no output. Is there a more correct way to drive the ten LED's/row? I haven't been able to find a different way to drive the LED's in this fashion. I am not a programming expert and am sure I'm missing the point somewhere and I have an inclination that I may be going about this the wrong way. I have the schematic and the code I've been trying to work on if requested. Any help would be greatly appreciated.
by Jake Hertz
by Jake Hertz
by Aaron Carman
by Jake Hertz