Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Reset a 16F628A at power up

Status
Not open for further replies.

SteveyD

New Member
I'm running a code that seems to leave shift register values or something behind which is causing some jittery action when I re-write the PIC with the updated code.

I'm still working on making all digits of the 4 digit-7segment led's default to 0000 (zeros) on power up as well.

I'm still learning C code.

Can someone post an example on how to reset all registers at power up.


Thanks
Steve
 
i dont have any links but how about you post your code and i will try to help you from there. Im working on some 7 segment displays now but with no shift registers. I doubt it will help as i use a MAX7221 and it does all the LED control on its own; all i have to do is tell it what i want shown.
 
Here is the code, some of it has ben removed to save space

Code:
//===============================================
//===============================================
#include <16F628A.h> 
#FUSES NOWDT, XT, NOPUT, NOPROTECT, NOBROWNOUT, NOMCLR, NOLVP, NOCPD //628A 

#use delay(clock=4000000)
#include <ds1820.c>

#define RTC_SDA         PIN_A2                
#define RTC_SCL         PIN_A3                
#use i2c(master, sda=RTC_SDA, scl=RTC_SCL)    

BYTE CONST MAP1[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; 
BYTE CONST MAP2[10]={0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF};

BYTE buff[DS1820_SCRATCH_BUFFER_SIZE];
BYTE sensor;
BYTE n;
BYTE temp;
BYTE temp_dec;
BYTE sec,min,hour; 
BYTE fs_flag; 
BYTE RES; 
BYTE D_SHIFT;
BYTE Map_Choice;
BYTE ZERO;
     
#define DEC             PIN_B1 
#define INC             PIN_B2 
#define EXP_OUT_CLOCK   PIN_B3 
#define COLON           PIN_B4 
#define EXP_OUT_DO      PIN_B5 
#define EXP_OUT_CLEAR   PIN_B6 
#define EXP_OUT_LATCH   PIN_B7 

//======================================== 
// initial DS1307 
//======================================== 
void init_DS1307() 
{ 
output_float(RTC_SCL); 
output_float(RTC_SDA); 
} 

//======================================== 
// write data one byte to DS1307 
//======================================== 
void write_DS1307(byte address, BYTE data) 
{ 
   short int status; 
   i2c_start(); 
   i2c_write(0xd0); 
   i2c_write(address); 
   i2c_write(data); 
   i2c_stop(); 
   i2c_start(); 
   status=i2c_write(0xd0); 
   while(status==1) 
   { 
   i2c_start(); 
   status=i2c_write(0xd0); 
   } 
} 

//======================================== 
// read data one byte from DS1307 
//======================================== 
BYTE read_DS1307(byte address) 
{ 
   BYTE data; 
   i2c_start(); 
   i2c_write(0xd0); 
   i2c_write(address); 
   i2c_start(); 
   i2c_write(0xd1); 
   data=i2c_read(0); 
   i2c_stop(); 
   return(data); 
} 

//================================= 
// WRITE DATA TO 6B595 
//================================= 
void write_expanded_outputs(BYTE D) 
{ 
   BYTE i; 
   for(i=1;i<=8;++i) 
   {  // Clock out bits from the eo array 
   if ((D & 0x80)==0) 
      output_low(EXP_OUT_DO); 
   else 
      output_high(EXP_OUT_DO); 
   D=D<<1; 
   output_high(EXP_OUT_CLOCK); 
   output_low(EXP_OUT_CLOCK); 
   } 
} 

//=================================
// show temperature
//=================================
void show_temp() 
{ 
  signed int16 Temp16;
  int1 TempIsPos; 
  int8 sensor; 
  int8 n; 
  int8 count;
  
  output_low(COLON); // low
       
  for (count=0;count<8;count++)  // blink temperature 8 times
  {
  output_low(EXP_OUT_LATCH); 
  sensor=0;   // DS1820 CONNECT TO PIN A0 
  init_ds1820(sensor); 
  write_ds1820_one_byte(0xcc, sensor);  // skip ROM 
  write_ds1820_one_byte(0x44, sensor);  // perform temperature conversion 
  while (read_ds1820_one_byte(sensor)==0xff); // wait for conversion complete 
  init_ds1820(sensor); 
  write_ds1820_one_byte(0xcc, sensor);  // skip ROM 
  write_ds1820_one_byte(0xbe, sensor);  // read the result 
  
  for (n=0; n<DS1820_SCRATCH_BUFFER_SIZE; n++)     // read 9 bytes but, use only one byte 
  { 
     buff[n]=read_ds1820_one_byte(sensor);  // read DS1820 
  } 
 
 Temp16 = make16(buff[1], buff[0]);
 
 if (Temp16 > 0)
  { 
    TempIsPos = TRUE;
    Map_Choice = MAP1[RES]; //  use normal
    ZERO=0x00;
  } 
  else 
  { 
    TempIsPos = FALSE; 
    Temp16 = -Temp16;     // Make absolute value 
    Map_Choice = MAP2[RES]; // show the neg sign
    ZERO=0xBF;
  } 
 
  temp = Temp16 >> 4; 
  temp_dec = ((Temp16 & 0x0F) * 10) / 16;
  
// Display data
      D_SHIFT=0x00;
      write_expanded_outputs(D_SHIFT);
  
      D_SHIFT=(0xD8);      // Show 0xD8=°C, 0xF1=°F
      write_expanded_outputs(D_SHIFT); 

      D_SHIFT = MAP2[ temp_dec ];  // Show fraction 
      write_expanded_outputs(D_SHIFT); 

      RES = temp%10;              // Show 1's 
      D_SHIFT = MAP1[RES]; 
      write_expanded_outputs(D_SHIFT); 

      RES=temp/10;                // Show 10's 
      if (RES==0) 
         D_SHIFT=ZERO; 
      else 
         D_SHIFT=Map_Choice;
         
      write_expanded_outputs(D_SHIFT); 
      output_high(EXP_OUT_LATCH);
      delay_ms(500);

      output_low(EXP_OUT_LATCH);
      for (n=1;n<=4;n++)
      { 
         D_SHIFT=0x00; 
         write_expanded_outputs(D_SHIFT); 
      } 
    output_high(EXP_OUT_LATCH);
    delay_ms(500);
    }
}

//================================= 
// show time 1 
//================================= 
void show_time1() 
{ 
byte m; 
      output_low(EXP_OUT_LATCH); 
      output_low(COLON); // low
      min=read_ds1307(1);
      hour=read_ds1307(2); 
      m=min & 0x0F; 
      D_SHIFT=MAP1[m];
      write_expanded_outputs(D_SHIFT); 
      swap(min); 
      m=min & 0x07; 
      D_SHIFT=MAP1[m];
      write_expanded_outputs(D_SHIFT); 
      m=hour & 0x0F; 
      D_SHIFT=MAP1[m]; 
      write_expanded_outputs(D_SHIFT); 
      swap(hour); 
      m=hour & 0x03; 
      D_SHIFT=MAP1[m]; 
      write_expanded_outputs(D_SHIFT); 
      output_high(EXP_OUT_LATCH); 
      swap(min); 
      swap(hour); 
} 

//================================= 
// check switch 
//================================= 
void check_sw() 
{ 
byte j; 
if (fs_flag!=0) 
{ 
   if (!input(INC)) 
   { 
      if (fs_flag==1) 
      { 
         min=read_ds1307(1); 
         min++; 
         j=min & 0x0F; 
         if (j>=0x0A) min=min+0x06; 
         if (min>=0x60) min=0; 
         write_ds1307(1,min); 
      } 
      else 
      { 
         hour=read_ds1307(2); 
         hour++; 
         j=hour & 0x0F; 
         if (j>=0x0A) hour=hour+0x06; 
         if (hour>=0x24) hour=0; 
         write_ds1307(2,hour); 
      } 
    show_time1(); 
   } 
   if (!input(DEC)) 
   { 
      if (fs_flag==1) 
      { 
         min=read_ds1307(1); 
         if (min!=0) 
         { 
            min--; 
            j=min & 0x0F; 
            if (j>=0x0A) min=min-0x06; 
         } 
         else min=0x59; 
         write_ds1307(1,min); 
      } 
      else 
      { 
         hour=read_ds1307(2); 
         if (hour!=0) 
         { 
            hour--; 
            j=hour & 0x0F; 
            if (j>=0x0A) hour=hour-0x06; 
         } 
         else hour=0x23; 
         write_ds1307(2,hour); 
      } 
    show_time1(); 
   } 
} 
} 

//================================= 
// show time 
//================================= 
void show_time(byte fs) 
{ 
byte m; 
      output_low(EXP_OUT_LATCH); 
      output_high(COLON); // high    
      min=read_ds1307(1);
      hour=read_ds1307(2); 
      m=min & 0x0F; 
      D_SHIFT=MAP1[m];
      write_expanded_outputs(D_SHIFT); 
      swap(min); 
      m=min & 0x07; 
      D_SHIFT=MAP1[m];
      write_expanded_outputs(D_SHIFT); 
      m=hour & 0x0F; 
      D_SHIFT=MAP1[m]; 
      write_expanded_outputs(D_SHIFT); 
      swap(hour); 
      m=hour & 0x03; 
      D_SHIFT=MAP1[m]; 
      write_expanded_outputs(D_SHIFT); 
      output_high(EXP_OUT_LATCH); 
      swap(min); 
      swap(hour); 
      delay_ms(100); 
      check_sw(); 
      delay_ms(100); 
      check_sw(); 
      delay_ms(100); 
      check_sw(); 
      delay_ms(100); 
      check_sw(); 
      delay_ms(100); 
      check_sw(); 
  if (fs==0) 
      { 
         output_low(COLON);  
      } 
      else 
      { 
         if (fs==1) 
         { 
            output_high(COLON); // high
            output_low(EXP_OUT_LATCH); 
            D_SHIFT=0x00; 
            write_expanded_outputs(D_SHIFT); 
            D_SHIFT=0x00; 
            write_expanded_outputs(D_SHIFT); 
            m=hour & 0x0F; 
            D_SHIFT=MAP1[m]; 
            write_expanded_outputs(D_SHIFT); 
            swap(hour); 
            m=hour & 0x03; 
            D_SHIFT=MAP1[m]; 
            write_expanded_outputs(D_SHIFT); 
            output_high(EXP_OUT_LATCH); 
         } 
         else 
         { 
            output_high(COLON);// high 
            output_low(EXP_OUT_LATCH); 
            m=min & 0x0F; 
            D_SHIFT=MAP1[m]; 
            write_expanded_outputs(D_SHIFT); 
            swap(min); 
            m=min & 0x07; 
            D_SHIFT=MAP1[m]; 
            write_expanded_outputs(D_SHIFT); 
            D_SHIFT=0x00; 
            write_expanded_outputs(D_SHIFT); 
            D_SHIFT=0x00; 
            write_expanded_outputs(D_SHIFT); 
            output_high(EXP_OUT_LATCH); 
          } 
      } 
      delay_ms(100); 
      check_sw(); 
      delay_ms(100); 
      check_sw(); 
      delay_ms(100); 
      check_sw(); 
      delay_ms(100); 
      check_sw(); 
      delay_ms(100); 
      check_sw(); 
} 
#int_EXT 
void EXT_isr() 
{ 
fs_flag++; 
if (fs_flag>=3) fs_flag=0;
} 

//===================================== 
// main program start here 
//===================================== 
void main(void) 
{ 
   byte u; 
      delay_ms(100); 
      port_b_pullups(true);
      output_low(EXP_OUT_CLEAR);
      delay_us(10); //was 10
      output_high(EXP_OUT_CLEAR);
    
      init_ds1307(); 
      u=read_ds1307(0); 
      sec=u & 0x7F;// enable RTC 
      write_ds1307(0,sec);   // set second to 00 and enable clock(bit7=0) 
      output_low(EXP_OUT_CLOCK);
      
      fs_flag=0; 
      ext_int_edge(H_TO_L);      // init interrupt triggering for button press 
      enable_interrupts(INT_EXT); 
      enable_interrupts(GLOBAL); 
      
  while(true)
   { 
      disable_interrupts(INT_EXT); 
      if (fs_flag==0) 
      { 
          show_temp();
      } 
      enable_interrupts(INT_EXT); 
      for (u=0;u<20;u++) 
      { 
         show_time(fs_flag); 
      } 
   } 
} //end of main program
 
Last edited:
you took out show_time (seems important) .
The "WRITE DATA TO 6B595" part i assume is the shift registers. Try shifting in all 0's until all shift registers are 0 then initiate the normal code to display info on digits.
 
I'm using TPIC6B595n's for my led drivers/shift registers.

I've edited the previous code post to include the entire code.

For the Max7221, I was looking at these to see if I could create a 16x48 led scrolling matrix as my next project. Also thinkig of the Max6969 or Allegro 6279's
 
Ok cool Now what exactly do you mean by "jittery action when I re-write the PIC with the updated code" ?

EDIT: The MAX6969 looks promising for the scrolling matrix. The only thing is its has 16 Constant-Current LED Outputs meaning you are going to need quiet a few to get a large display like that. the A6279 is really similar to the MAX6969.

Im not sure but i might consider getting " MAX6955 " for the matrix project.
Specs:
# 400kbps 2-Wire I²C-Compatible Interface
# 2.7V to 5.5V Operation
# Drives Up to 16 Digits 7-Segment, 8 Digits 14-Segment, 8 Digits 16-Segment, 128 Discrete LEDs, or a Combination of Digit Types
# Drives Common-Cathode Monocolor and Bicolor LED Displays
# Built-In ASCII 104-Character Font for 14-Segment and 16-Segment Digits and Hexadecimal Font for 7-Segment Digits

That looks like a keeper!
 
Last edited:
When I erase and re-write the chip with a code update, sometimes the led's will not display like the code or the shift registers are locked up. Sometimes its just segment 'a' of the first digit that lights, sometimes its none, and sometimes it runs just fine.

I'm thinking that if I force a shifting of all registers at startup that any previous register settings will clear.

I'm using CSS's PIC C as my editor/compiler software. I dont monkey withthe settings on the software.

Once compiled to hex, I use PICKit2 v2.11 to erase/write-verify the chip same settings each time as well.

I've sent compiled hex files to a friend and he experiences the exact problems when he writes it to his chips as well.

Like I said, I'm still learning C and any suggestions that help me identify the problem an work around is appreciated.

Does this look correct for shifting all zeros at startup?

Code:
//===================================== 
// main program start here 
//===================================== 
void main(void) 
{ 
   byte u; 
      delay_ms(100); 
      port_b_pullups(true);
      output_low(EXP_OUT_CLEAR);
      delay_us(10); //was 10
      output_high(EXP_OUT_CLEAR);

 //try shifting to all Zero's here
    {
      D_SHIFT=0x00;
      write_expanded_outputs(D_SHIFT);
      D_SHIFT=(0x3F);      
      write_expanded_outputs(D_SHIFT); 
      D_SHIFT=(0x3F); 
      write_expanded_outputs(D_SHIFT); 
      D_SHIFT=(0x3F);
      write_expanded_outputs(D_SHIFT); 
      D_SHIFT=(0x3F);
      write_expanded_outputs(D_SHIFT); 
      output_high(EXP_OUT_LATCH);
      delay_ms(500);
      output_low(EXP_OUT_LATCH);
      for (n=1;n<=4;n++)
      { 
         D_SHIFT=0x00; 
         write_expanded_outputs(D_SHIFT); 
      } 
    output_high(EXP_OUT_LATCH);
    delay_ms(500);
    }
 //ends shifting routine at startup

      init_ds1307(); 
      u=read_ds1307(0); 
      sec=u & 0x7F;// enable RTC 
      write_ds1307(0,sec);   // set second to 00 and enable clock(bit7=0) 
      output_low(EXP_OUT_CLOCK);
      
      fs_flag=0; 
      ext_int_edge(H_TO_L);      // init interrupt triggering for button press 
      enable_interrupts(INT_EXT); 
      enable_interrupts(GLOBAL); 
      
  while(true)
   { 
      disable_interrupts(INT_EXT); 
      if (fs_flag==0) 
      { 
          show_temp();
      } 
      enable_interrupts(INT_EXT); 
      for (u=0;u<20;u++) 
      { 
         show_time(fs_flag); 
      } 
   } 
} //end of main program
 
The MAX6969 looks promising for the scrolling matrix. The only thing is its has 16 Constant-Current LED Outputs meaning you are going to need quiet a few to get a large display like that. the A6279 is really similar to the MAX6969.

Was thinking of 1 to drive the 16 rows, and 4 more to drive the 48 columns

MMC/SD to hold the files and still unsure of which uC to drive it all.

Im not sure but i might consider getting " MAX6955 " for the matrix project.
Specs:
# 400kbps 2-Wire I²C-Compatible Interface
# 2.7V to 5.5V Operation
# Drives Up to 16 Digits 7-Segment, 8 Digits 14-Segment, 8 Digits 16-Segment, 128 Discrete LEDs, or a Combination of Digit Types
# Drives Common-Cathode Monocolor and Bicolor LED Displays
# Built-In ASCII 104-Character Font for 14-Segment and 16-Segment Digits and Hexadecimal Font for 7-Segment Digits

That looks like a keeper!

This looks interesting.. 128 discrete led's.. would need 6 for drive the 768 led's in a 16x48 display.

16x48 happens to be what I have handy for a matrix.

I'll dig up the sheets for the 6955 and see what I can come up with.
 
Im not sure but i might consider getting " MAX6955 " for the matrix project.
Specs:
# 400kbps 2-Wire I²C-Compatible Interface
# 2.7V to 5.5V Operation
# Drives Up to 16 Digits 7-Segment, 8 Digits 14-Segment, 8 Digits 16-Segment, 128 Discrete LEDs, or a Combination of Digit Types
# Drives Common-Cathode Monocolor and Bicolor LED Displays
# Built-In ASCII 104-Character Font for 14-Segment and 16-Segment Digits and Hexadecimal Font for 7-Segment Digits

That looks like a keeper!
Here's the only problem(s) I see with the 6955:
bleh2.jpg
I didn't check prices anywhere else, but $27.50 each (in hobbyist quantity)?!?! Ouch!
EDIT: $22.86 at Newark.

And no DIPs available. SSOP and TQFN only. That's not such a big problem though. Doesn't really bother me at all. The high price might be.
 
Last edited:
FUTZ: wow i didnt notice that. But remember its MAXIM meaning free samples. Im sure they will gladly send out 2-4 . I order samples from maxim like crazy mainly because if i build something that uses it and make money from it ill be sure to buy in mass quantity.


SteveyD:
Im starting to think its a oscillator issue now. Or maybe a power supply issue. I have the same issue with my LED Segments when i use some supplies i made. Make sure your power supply is good and in working order. (power supply being a LM7805 or w/e) and also make sure that you have the right Caps for the Crystal and if so or if its a resonator make sure its as close to the PIC as possible.

EDIT: SteveyD:
"Was thinking of 1 to drive the 16 rows, and 4 more to drive the 48 columns"

Thats what i call good thinking. I didnt even think of that. What size ASCII will you use? 8x8 or full 16x16?
8x8 will give you 2 lines at 6 character lines.
16x16 will give you 1 like with 3 characters.
 
Last edited:
8x8 to allow for 2 lines of text.

Running the chips 1x4 will also allow to you use the full 16x48 as a blank pallet to create nifty animation style scrolling images.

With the right uC, add a MMC/SD to it to hold the animation files. no need to write to the MMC/SD just read the file.

Create the file on your computer and save to the card.

For the main issue...

Power supply is a 12vdc wallwart at 170ma. The Multimeter has it functioning correctly.

This feeds an 7805 with smoothing caps on both sides of the rails, as well as a .01uf cap at the uC

As to the oscillator, running a 4Mhz crystal with 22pf caps off each of its pins to ground. The original circuit only shows a 4Mhz crystal from uC pins 15 and 16 tied directly to ground. Perhaps I'm using the wrong type of crystal but its working with the 22pf caps added.
 
170ma.... 4 x 7 segments. Hmmmm. That leaves only apx 6ma per segment before the power supply is overloaded. What is the current draw, and what is the wallwart voltage, when ALL the segments are lit simultaneously?
 
The 628A has a internal 4Mhz Oscillator. Check "4.2.2.6 PCON Register" in the data sheet. Also you may need more power depending how many digits you have on and their resistors etc...

EDIT: Just got my samples from maxim. They happily sent me 8 yeah 8! MAX6953. Which seems great for
32 - 5x7 displays!
thats
160 columns @ 7 rows each. Thats a whopping 1120! LEDS. You think thats enough? LOL
 
Last edited:
The 12vdc 170mA wallwart may be a culprit now that you break it down. I'll change it for a 12vdc 1A and see what happens.

Each segment draws 100mA (20mA draw x 5 led's per segment) so a full on #8 digit would draw ~800mA and all 4 digits displaying 8 would draw 3.2amps.

Odd that while the clock has been running for weeks now when it reaches midnight or 00:00 that it doesnt shut down. That would be the closest it would ever reach to a full on display of 88:88.

Perhaps changing the startup routine from 00:00 to 11:11 may help reduce the initial power drain.
 
do you have resistors on the segments? if so factor that in if not add some resistors to keep down current usage. Also remember it better to do fast switching of digits then to have them all on at 1 time. So it uses a 4th of the current because only 1 digit is on at a single time but to the user it looks steady.

You understand? (im not a good explain-er)
 
Each segment has a 220Ohm resistor on them.

Makes sense to strobe or pulse the segments. I'll see what I can do for that.
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top