• 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.

Generating PWM using PIC10F206(6 pin controller)

DrG

Active Member
It's clearly stated in the page 1 Summary of the post #14 link that the NCO has two functions, the first of which is (and I quote) "a PWM with a fixed 50% duty cycle".
Yeah, you are correct and it does say that here...

"These new integrated peripherals include a new Configurable Logic Cell (CLC) which allows the user to do simple Boolean functions – such as AND/OR/XOR logic functions and D/JK/SR state functions, a Numerically Controlled Oscillator (NCO) module which provides two functions; a PWM with a fixed 50% duty cycle and an increased frequency resolution function that lends itself well to applications such as ballast control, a Complementary Waveform Generator (CWG) which provides a complementary waveform to various inputs sources including the PWM, the CLC, or NCO, and finally an integrated temperature indicator for low cost temperature measurements. "

In the context of the data sheet's discussion of the NCO and its two modes, it is not deceptive in my view, especially since there is the discussion of PWM in the section on that peripheral. Misleading, well yeah, but not slimy.
 

DrG

Active Member
i need a PWM signal having a frquecny of 1 khz with a duty of 10% ..Does this guy can do this job?
As has been pointed out, yes, you can do that very easily...in fact, I just did it and it took about 15 minutes. I used a 202, but the only difference I see is that the 206 has a comparator...also, I only had a 202 on hand.

Code:
#include <xc.h>

#define _XTAL_FREQ 4000000
#pragma config MCLRE = OFF, CP = OFF, WDTE = OFF

int main() {
    GPIO = 0b000000;
    TRIS=0b111101; // GPIO1 as output
    
here:
    GPIO = 0b000010; // pulse on
    __delay_us(100);
    GPIO = 0b000000; // pulse off
    __delay_us(900);
    goto here;
    
    return (1);
}
202PWM.jpg

There are some caveats.

First is accuracy. I have used simple c code and am ignoring the time to jump and am depending upon the __delay_us function(). Of course, you can do this in asm and calculate instruction times and get better accuracy. Even so, assuming you are using the onboard osc, you will have some addition variability to address.

In addition to the accuracy, there is the issue of what else it is supposed to do. In the example above, it does not do anything else. You could fill those delays with stuff if you were very careful with timing (something simple like adding the capability to turn it on/off by another I/O).

As also mentioned, if you just wanted it to run and nothing else, you might use a 555. Yes, true, but for me, I would probably go ahead and just uses the 202 if it fit the bill as illustrated, because I have one on hand, have familiarity with the programming hardware and software, and there are fewer components needed - it is bloody easy. That is just my preference and I would not argue strongly one way or the other.

Finally, as is often the case, a poster asks the question without fully explaining what they want t do....then you never hear from them again. With that in mind, I would also suggest that you look into the 10f32X There you have a PWM peripheral and some other peripherals and you can have those peripherals do the grunt work (after you configure them) freeing up your program to do much more.
 

DrG

Active Member
This chip has CLC... LOL.... To do what with.... Two inputs one output.... I thought it useless on an 8 pin....
When that chip first came out, or more accurately, when I first heard about them, I was intrigued. I ended up buying a little demo board that they offer. Now, to be sure, there is nothing on that board that I do not already have...except the chip, but I could have bought that for much less. As I recall, I did get some kind of deal and the board was about US$10.

Although it was little more than an impulse buy, what sold me was that they have demo software for the board. So, I figured, this was a relatively cheap educational opportunity - and it was and I don't regret it at all.

There is no clc examples in that demo code (again as I recal) just adc and pwm and initialization stuff. after gaining some easy introductory lessons, I did a little bit of exploring using the clc.

See here and the software configuration tool here. Also, a specific use AN here. It is actually pretty impressive in some ways (there are software inputs as you can see).

Truth is, I never used it for anything put exploration and playing and education. This, because I didn't have a specific need. I would like to think that at least some of the knowledge sunk in such that if a need arises, I will be able to revisit the clc with a solution in mind. I like to think a lot of things :)
 

Nigel Goodwin

Super Moderator
Most Helpful Member
If you go to the XPress website there are some CLC examples:


Your example above is basically what Pommie proposed, but you got it right! :D

One criticism - why on earth are you using a goto? :nailbiting:

How do you even know how to use a goto?.

C:
while(1)
{   
    GPIO = 0b000010; // pulse on
    __delay_us(100);
    GPIO = 0b000000; // pulse off
    __delay_us(900);
}
 

DrG

Active Member
One criticism - why on earth are you using a goto? :nailbiting:

How do you even know how to use a goto?.
I use them whenever I want regardless of what anybody else thinks says or does. I will continue to do so. My guess is that although you may not want to admit it, you have also and probably used a branch or jmp many many times in many many asm programs on many different chips, as have I.

But look, I understand the pressures that you must endure correcting errors (use while(1) not goto, what is wrong with you man, have you gone mad?!!!) when they don't exist, so if it gives you agita, just remember that on the Pic 10F202, GOTO is also an ASM instruction. In the c code that I posted, the resulting asm code for that instruction "goto here" is.... yep, you guessed it.. Anyways, remember, while(there is no error in the code example I wrote), I will make make more errors than you will ever be able to correct, so, you know, you have that going for ya .... :)
 

Nigel Goodwin

Super Moderator
Most Helpful Member
I use them whenever I want regardless of what anybody else thinks says or does. I will continue to do so. My guess is that although you may not want to admit it, you have also and probably used a branch or jmp many many times in many many asm programs on many different chips, as have I.
Assembler is entirely different, and goto is rarely used in high level languages, as there's pretty well never any need for it.

But look, I understand the pressures that you must endure correcting errors (use while(1) not goto, what is wrong with you man, have you gone mad?!!!) when they don't exist, so if it gives you agita, just remember that on the Pic 10F202, GOTO is also an ASM instruction. In the c code that I posted, the resulting asm code for that instruction "goto here" is.... yep, you guessed it.. Anyways, remember, while(there is no error in the code example I wrote), I will make make more errors than you will ever be able to correct, so, you know, you have that going for ya .... :)
It's not an 'error' it's just very bad practice - even more so in Pascal than C (which is a very 'messy' language anyway), but still no reason to use it, particularly in the example in question.
 

DrG

Active Member
It's not an 'error' it's just very bad practice - even more so in Pascal than C (which is a very 'messy' language anyway), but still no reason to use it, particularly in the example in question.
Ahhh, the Best Practices Defense and its red-headed step child, very bad practice. Of course, there is the added "particularly in the example in question"

The Unholy GOTO.jpg
This can be little more than conventional nonsense....spreading what one heard and accepted years ago without understanding it in the first place.

How about this: You can never use a GOTO and are destined to condemn all GOTOs that come to your attention and I will use a GOTO whenever I want, and we will co-exist in a civil manner on the same planet....I mean, it's not like you voted for _____.
 
Last edited:

be80be

Well-Known Member
Heres with goto
Code:
Disassembly Listing for testS
Generated From:
C:/Users/be80b/Desktop/testS/testS.X/dist/default/production/testS.X.production.elf
Nov 16, 2019 9:41:57 AM

---  C:/Users/be80b/Desktop/testS/testS.X/newmain.c  ----------------------------------------------------
1:             #include <xc.h>
2:             
3:             #define _XTAL_FREQ 4000000
4:             #pragma config MCLRE = OFF, CP = OFF, WDTE = OFF
5:             
6:             int main() {
7:                 GPIO = 0b000000;
01ED  0066     CLRF GPIO
8:                 TRIS=0b111101; // GPIO1 as output
01EE  0C3D     MOVLW 0x3D
01EF  0006     TRIS GPIO
9:                 
10:            here:
11:                GPIO = 0b000010; // pulse on
01F0  0C02     MOVLW 0x2
01F1  0026     MOVWF GPIO
12:                __delay_us(100);
01F2  0C21     MOVLW 0x21
01F3  0028     MOVWF __pcstackBANK0
01F4  02E8     DECFSZ __pcstackBANK0, F
01F5  0BF4     GOTO 0x1F4
13:                GPIO = 0b000000; // pulse off
01F6  0066     CLRF GPIO
14:                __delay_us(900);
01F7  0CB3     MOVLW 0xB3
01F8  0028     MOVWF __pcstackBANK0
01F9  0BFA     GOTO 0x1FA
01FA  02E8     DECFSZ __pcstackBANK0, F
01FB  0BF9     GOTO 0x1F9
01FC  0BFD     GOTO 0x1FD
01FD  0BFE     GOTO 0x1FE
15:                goto here;
01FE  0BF0     GOTO 0x1F0
16:               
17:                return (1);
18:            }
 

rjenkinsgb

Well-Known Member
Most Helpful Member
Ahhh, the Best Practices Defense and its red-headed step child, very bad practice.
An objective view:
I'd say that if you understand the compiler and the code it will produce, and it's for your own projects - there is no technical difference, use whichever you like.

However, if people who do not understand the workings of compilers see "goto" in examples of C code, assume it must be OK and start using it to eg. jump in or out of a function, it's setting an extremely bad precedent.


If the stack state is different than it should be at the target of the goto (like a return was missed, that would have changed the stack), it will result in a memory leak or crash.

Sticking with conventional C "good practice " program flow and just saying "Don't do it" (in public at least) avoids that possible confusion.


I've used goto in C, but in (literally) exceptional circumstances - a system we produced some years ago that used plug-in I/O cards, where the software did a scan of all the I/O slot addresses during initialisation to verify the configuration.
A slot with no card caused a CPU memory access exception and the only easy way to continue cleanly was to adjust the stack within the exception routine and use a goto aimed at the appropriate part of the code after the section that caused the exception. It worked fine, for that purpose.
 

be80be

Well-Known Member
Heres while 1
Code:
Disassembly Listing for testS
Generated From:
C:/Users/be80b/Desktop/testS/testS.X/dist/default/production/testS.X.production.elf
Nov 16, 2019 11:48:57 AM

---  C:/Users/be80b/Desktop/testS/testS.X/newmain.c  ----------------------------------------------------
1:             #include <xc.h>
2:             
3:             #define _XTAL_FREQ 4000000
4:             #pragma config MCLRE = OFF, CP = OFF, WDTE = OFF
5:             
6:             int main() {
7:                 GPIO = 0b000000;
01ED  0066     CLRF GPIO
8:                 TRIS=0b111101; // GPIO1 as output
01EE  0C3D     MOVLW 0x3D
01EF  0006     TRIS GPIO
9:                 
10:            while(1)
11:            {   
12:                GPIO = 0b000010; // pulse on
01F0  0C02     MOVLW 0x2
01F1  0026     MOVWF GPIO
13:                __delay_us(100);
01F2  0C21     MOVLW 0x21
01F3  0028     MOVWF __pcstackBANK0
01F4  02E8     DECFSZ __pcstackBANK0, F
01F5  0BF4     GOTO 0x1F4
14:                GPIO = 0b000000; // pulse off
01F6  0066     CLRF GPIO
15:                __delay_us(900);
01F7  0CB3     MOVLW 0xB3
01F8  0028     MOVWF __pcstackBANK0
01F9  0BFA     GOTO 0x1FA
01FA  02E8     DECFSZ __pcstackBANK0, F
01FB  0BF9     GOTO 0x1F9
01FC  0BFD     GOTO 0x1FD
01FD  0BFE     GOTO 0x1FE
01FE  0BF0     GOTO 0x1F0
16:            }
17:            }
 

DrG

Active Member
An objective view:
I don't think your presented view is any more objective than mine. But, I agree with, pretty much, everything you said.

In my own practice, and there are plenty of examples of code that I have written on line and that are publicly viewable, I do not use goto in C.

During development of a program, I will use goto in C programs. This is largely a debugging technique and, typically, its usage is something like a breakpoint, e.g., "here: goto here"; Beyond that, I might use it to simulate or rather 'bookmark' something akin to what I would call a terminal error - knowing that eventually this will become a function.

In this case, I chose to use goto to easily and succinctly illustrate a process for the OP, whom as I predicted, has not as yet returned and gave little information about his level of experience and understanding.

If you do a simple search for "why is goto bad" or something similar like "is goto still bad" you will get a large number of hits and plenty of misunderstandings and a few pros and more cons. If you take the time to go through more formal discussions (e.g., http://david.tribble.com/text/goto.html) you can gain a much better understanding of the history and true relevance of the issue. For example, breaking out of nested loops and you can consider programming languages that do not have a goto and why C has not removed goto from the standard and so on and so forth.

To believe that the use of a single GOTO in that example merits condemnation "still no reason to use it, particularly in the example in question." is nonsense. What now, it is spaghetti code? It was a simple and straightforward example that illustrated well the issue.

In the instant case, I took the time and effort to write a simple program that directly addressed what the OP asked. I did not just write and include the code, I took a picture of the resulting output and went through some length to explain it and the caveats involved. I even suggested an additional, and likely, "better" solution for a few cents more.

For that, I was met with a clearly condescending criticism, and in response, I made fun it I mocked it, pointedly and efficiently. Guilty as charged. But the criticism was largely BS and little more than, well you got the program right but what is the matter with you?! You used a GOTO!! All of this from someone who posted nothing else of substance in the thread other than pointing to an example of clc usage - after I had already posted links to clc usage/examples and addressed that issue, which another user brought up.

Your point about the frailty of a beginner who might see a GOTO and think that it is ok to use them, is a bit contrived, but is not without some merit. That is not, however, always a practical matter for a public forum and this place is certainly not an Introduction to C class. If all messages need to strictly adhere to a beginner as the lowest common denominator, the subject matter would necessarily be so limited that it can only be considered for beginners.

This is a matter of style and a matter of how a user responded to a legitimate post that I maintain, made a legitimate and appropriate contribution. Contrast that response with my response to your suggested solution to the op amp input in this thread. Your proposed solution was, in fact, listed in a linked reference that I provided in the first post, of what NOT to do. Your post received a like from a very well respected (and deservedly so) member.

Did you see me condescend to you and say something like..Hah!! I knew it! You so-called hardware experts don't know what you are talking about. I did not. I responded respectfully and, if anything, in a self-deprecating manner, because in that case (but not this case) I am the beginner. Moreover, I have no reason to not respect you as I have read many of your posts and I don't have to think that every single thing that you have written is correct for me to show you respect.

When I read those condescending post(s), I wanted to metaphorically, "slap the boy". Do you think I don't know what while(1) is son? Do you think that while(1) is easier to understand (see here for example)? Now, the small point being made could have been made in a respectful tone, but it was not - that was not an accident. I can see three such examples in the last few weeks and only one of those involved me.

That is, in my opinion, what has gone on here and I will continue to stick up for myself and, on occasion, when I feel like it, call out BS. Is it worth the bickering and retaliation? - I don't know, maybe not, but maybe it is, because how users who contribute (a lot or a little bit) are treated has a good deal to do with the success or failure of a public board...and there are many to choose from.

I am also fine with letting you or Nigel get the last word on this (so long as it is not completely ridiculous).
 

Latest threads

EE World Online Articles

Loading
Top