CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Scrolling an LED display
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Tue Apr 06, 2021 1:48 pm     Reply with quote

I never knew that and I have been using the 16F722 for many years!
It took a while to find out what VCAP meant because a search of the CCS manual turned up nothing. I found it on the data sheet but then how do I set it? I searched the manual again for FUSES and then realized I needed to look in the 16F722A.h file to see how to set fuses. Stuff long forgotten.
Anyway I added it to the fuses, connected a ceramic 0.1uF between pin 2 and pin 8 and compiled and ran. It made no difference.
For anyone else as dumb as I the PIC has an internal 3.2v regulator for internal logic. The I/O runs off the 5v. A capacitor is supposed to be added to one of the VCAP pins and the pin has to be enabled by fuses. VCAP_A0 in the code below sets pin 2 (A0) as the VCAP pin. You cannot use it for anything else but there are other pins that can be used if A0 is needed specifically.
The following does not work but the commented out statements do work. Fast_io does not help. Pins A3 thru A5 are grounded thru 1k resistors. I think it's the compiler that can't handle PORT_A=i<<6;
TRIS 0x0f will still make it work!
Code:
/* Pre-processor directives */
#include <16F722A.H>
#include <stdio.h>
#fuses INTRC_IO, NOWDT, PUT, NOPROTECT, VCAP_A0
#use delay (clock=8MHZ)                       // osc defaults to 8 MHz
#byte PORT_A = getenv("SFR:PORTA")
// #use fast_io(A)

/* The main function */
void main()
 {
    int i,j;                  // counter

// initialize ports
//    set_tris_a(0x0f);       // this works with PORT_A=(i<<6);
    set_tris_a(0x3f);       // this does NOT work with PORT_A=(i<<6);

// main loop
  while (1)                 // endless loop
  {
    for(i=0;i<=3;i++)       // cycle through digits
     {
 //     j=i<<6;
//      output_a(i<<6);       // works with set_tris_a(0x3f);
//      PORT_A=j;        // does not work with set_tris_a(0x3f);
      PORT_A=i<<6;             
      delay_ms(1000);       // display for 1 second
    }                  // end for(i) loop



  }                   // end of endless while loop
}                    // end of main function

// end
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Tue Apr 06, 2021 2:00 pm     Reply with quote

For what it is worth here is the .lst that is relevant for someone who still remembers assembly. I used to use it on an Intel 8008 chip.
OOPS, wrong file. I will edit again in a second
Here it is:
.................... // initialize ports
.................... // set_tris_a(0x0f); // this works with PORT_A=(i<<6);
.................... set_tris_a(0x3f); // this does NOT work with PORT_A=(i<<6);
*
0026: MOVLW 3F
0027: BSF 03.5
0028: MOVWF 05
.................... // main loop
.................... while (1) // endless loop
.................... {
.................... for(i=0;i<=3;i++) // cycle through digits
0029: BCF 03.5
002A: CLRF 22
002B: MOVF 22,W
002C: SUBLW 03
002D: BTFSS 03.0
002E: GOTO 03E
.................... {
.................... // j=i<<6;
.................... // output_a(i<<6); // works with set_tris_a(0x3f);
.................... // PORT_A=j; // does not work with set_tris_a(0x3f);
.................... PORT_A=i<<6;
002F: SWAPF 22,W
0030: MOVWF 05
0031: RLF 05,F
0032: RLF 05,F
0033: MOVLW C0
0034: ANDWF 05,F
.................... delay_ms(1000); // display for 1 second
0035: MOVLW 04
0036: MOVWF 24
0037: MOVLW FA
0038: MOVWF 25
0039: GOTO 004
003A: DECFSZ 24,F
003B: GOTO 037
003C: INCF 22,F
003D: GOTO 02B
.................... } // end for(i) loop
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Apr 06, 2021 2:21 pm     Reply with quote

hay I've GOT 8008s here on PCBs !!
1st 8bit micro......
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Tue Apr 06, 2021 4:52 pm     Reply with quote

8008 in good shape are $20 ea and more like $100 if the gold ones. I have not checked for years. I had a big stash of Mitel 8008 that I got from Ford surplus when he shut down and I was selling them for $20 ea.
Your Nixies are valuable too and Numitrons worth over $20. Some big Nixies sell for $400 ea or more.
Do you have any fiber optic incandescent displays or mechanical ones you would sell? Also a ROM for the 4004 ROM, I forget the number, maybe 4003. We should take this private.
Peter
Jerson



Joined: 31 Jul 2009
Posts: 125
Location: Bombay, India

View user's profile Send private message Visit poster's website

PostPosted: Tue Apr 06, 2021 8:13 pm     Reply with quote

rovtech wrote:
For what it is worth here is the .lst that is relevant for someone who still remembers assembly. I used to use it on an Intel 8008 chip.

.................... PORT_A=i<<6;
002F: SWAPF 22,W
0030: MOVWF 05
***** 0031: RLF 05,F
***** 0032: RLF 05,F
0033: MOVLW C0
0034: ANDWF 05,F

.................... } // end for(i) loop

Now that you are looking at the LST file, see the 2 indented instructions. These are the ones that are causing trouble due to the R-M-W issue. (Read Modify Write).

What the compiler is trying to do is perform the rotation on the port (reg 5) itself. Therefore, when it tries to rotate, it hits upon the RMW problem where a bit which is set to 1 could read 0 if not pulled up externally.

This is definitely a compiler writer interpretation and is not wrong, but could be considered a quirk.

Compare the LST file with the one in which the intermediate variable is used and which works correctly. You will understand the problem.

TIP : Always look under the hood (LST) when in trouble.

Cheers
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Wed Apr 07, 2021 10:24 am     Reply with quote

Thanks Jerson;
I investigated and printed the Mid-range MCU family instruction set.
Several things bother me:
Why are the operations carried out on the PORT_A?
Why are only two RLF 05,f shown? I asked for six.
At the end of the Instruction set the 16F7X devices are specifically mentioned that an RMW on an analog pin results in reading a 0. It mentions configuring the port incorrectly. Other interested parties using 16F7x should read the whole thing. I assume it refers to 7xx as well.
The TRIS is mentioned as not recommended but they don't say what to use. Maybe I should be using #USE FIXED_IO(a_outputs=PIN_A7, PIN_A6)
Back to one of my original questions; what are the rules for operations on the right side of an = sign? My understanding is that i in my program does not change except in the for statement. That appears to be the case but why is the rotate left being carried out on the PORT_A. That seems totally wrong. I assumed that i would be read into a register, shifted left 6 times and moved into PORT_A.
Jerson



Joined: 31 Jul 2009
Posts: 125
Location: Bombay, India

View user's profile Send private message Visit poster's website

PostPosted: Wed Apr 07, 2021 10:31 am     Reply with quote

Hi rovtech

I guess you missed the swapf 22,w instruction just preceeding the ones I marked. That shifts the 4 bits. Then the 2 rotates to make a total of 6

This R-M-W problem is a well known issue if you do not use pull-up resistors or configure a port as analog.

Another thing - the compiler writer is a human and could make a choice while implementing. This could be apt for most situations, but in this case, it is definitely something that should not be done on a Port Register. I guess the compiler treats the PORT_A Byte declaration as a normal memory register. Therefore the quirky behaviour

Again I re-iterate - when in doubt, look under the hood - at the listings irrespective of the CPU maker since you're dependent on the mind of the compiler writer to interpret your instructions.

Cheers
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Wed Apr 07, 2021 11:53 am     Reply with quote

Thanks again Jerson;
I did not understand the SWAPF,22,w instruction. I did not know how many bits in a nibble. Now I see it swaps the four upper bit with the four lower bits so 0b00000010 becomes 0b00100000 which the same as rotate left 4 times. I would never do it that way - too much confusion for me to remember.
I thought the 16F722 errata problems were solved with the 16F722A but did not realize it was booby trapped with the VCAP issue and now this.
Is this R-M-W problem applicable to the other PICs like the 16F1509 and 16F1938 which are what I have been using to replace the 16F722 (because it has no hardware I2C Master)?
This really sucks and is the reason I avoid shortcuts like the SWAPF above. I find doing everything in one statement can get me into trouble.
Doing the shift on another variable then outputting it may not be cute programming but it is safer.
Jerson



Joined: 31 Jul 2009
Posts: 125
Location: Bombay, India

View user's profile Send private message Visit poster's website

PostPosted: Wed Apr 07, 2021 7:52 pm     Reply with quote

You will find the R-M-W issue with many of the old vintage PICs. The newer ones, I think, allow you to do these operations differently (I could be wrong here).

The PIC architecture writes outputs to a latch. The read happens to digitally read back the pins. So, if the pin is loaded or is not pulled up, the logic 1 output may be read back as a 0. Therefore, what you may have intended to happen and what really happens could be different. So, if in doubt, it helps to check the datasheet to see if the conflicting pin has a dual function which is enabled by default or you have the R-M-W issue by analyzing your code.

The VCAP may not be an issue in your case as the CapSense module is off by default on this chip.

Oh one thing. C language shortcuts seem cute and can make a newbie think the author is highly skilled. However, as with everything cute in this world, it has its own caveats ;)
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
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