1 2 3 Previous Next 39 Replies Latest reply on Dec 19, 2014 9:05 PM by quan.trieu

    DAC output with timer

    quan.trieu

      Hi everyone, I am using CY8C27443

         

      My task is to output the DAC value in a period of time (seconds), to be more precise, I attach a picture below

         

      I offset the voltage to 2.5V so in first 100s, the DAC value is 2.05V, after that it's changed to 2.2V and so on (with rate of change equal 1V/s). 

         

      I implemented it using the DAC with a 8 bit timer. An interrupt is generated each 2ms, so I can get the 1s period (I attached my prj below). I update my DAC value for each phase. However the output didn't go like the picture but it was only true in the first phase (2.05V in 100s) then it went wrong. To be specific, it went up directly to 3.7V then went down to 2V, then it repeated (sorry the result was on the oscilloscope so I was unable to post it here). 

         

      Could you please take a look at my project and tell me what went wrong, thank you very much!

        • 1. Re: DAC output with timer
          user_1377889

          Generally: Global variables which get changed in an interrupt-handler MUST be declared as "volatile" or accesses to them might get optimized-out depending on the compiler and the settings you use.

             

          I cannot deduct from your (uncommented) program how you are setting the requred dac under which circumstances. To be honest: flag and flag1 are not rather meaningful variable names...

             

           

             

          You wrote     while (10<flag1<=11)
           

             

          when you mean if(flag1 == 11) it is better to write that down.

             

           

             

          the fmod function with integer arguments will consume many MIPS better use the %-operator

             

           

             

          I would suggest you to (at least for the test-phase) set the CPU speed to 12 or 24 MHz, 3 MHz can sometimes be too slow.

             

           

             

          Bob

          • 2. Re: DAC output with timer
            user_14586677

            If you are creating a complex waveform, or a periodic waveform,

               

            or even a one shot waveform, consider using an interrupt driven

               

            table approach. That would eliminate the jitter in sampling time you

               

            incur in your approach, if that is of concern.

               

             

               

            An ap note that may be of use - www.cypress.com/     AN2025

               

             

               

            www.cypress.com/     AN2096

               

            www.cypress.com/     AN74170

               

             

               

            Also set Op-Amp Bias and A-Buff_Power in global properties to high

               

            power to get full CM range at output pin.

               

             

               

            Regards, Dana.

            • 3. Re: DAC output with timer
              quan.trieu

               Bob and danaa, thank you for your replies!

                 

              I changed my prj as your suggestions, however,the results are not true as expected. It only went well in the first ten seconds (2.05V), but after that it jumped directly to 3.6V (picture below) and went on at this value. 

                 

                 

              To danaa: I also thinked of look up table but in the sine wave prj, it updated with each counter tick, however for my prj, it must update with both milisec and secs so I didn't get the idea to manage it. 

                 

              I also attached my prj with comments, please take a look again and give me some advice. Thanks alot!

              • 4. Re: DAC output with timer
                user_1377889

                I am missing the infinite loop that usually is used in embedded programming. Your code exits in main() and you do not know what will happen then.

                   

                The variavle named "value" (better name would be "DAC_Value") is declared as a global variable and only initialized once. I would at least initialize it in the routine where I use it or declare it as a local var to get the chance to call the routine twice or more often.

                   

                I would suggest you not to count up your value all the time, there are points within your program where you may assign a constant to it to generate the wanted voltage, so in case of mis-counting you get a defined voltage.

                   

                Why do you stop the DAC at the end? What voltage do you want at the end of the cycle? and what do you want to happen after one cycle is through?

                   

                 

                   

                Bob

                • 5. Re: DAC output with timer
                  user_27941315

                  Here is the modification I made to your program:

                     

                   

                     

                  while (tick1s<=10)  //DAC output 2.05V if the time is below 10s, the analog output value is later offset by -2.5V

                     

                  {

                     

                  DAC9_1_WriteStall(value);

                     

                  }

                     

                  while  (tick1s==11)      //DAC output increase with rate of change 0.15V/s

                     

                  {

                     

                  if(tick2ms%16==0)

                     

                  {

                     

                  value +=1;

                     

                  DAC9_1_WriteStall(value);

                     

                  }

                     

                  }

                     

                  while(tick1s < 22)   //DAC output at 2.2V

                     

                  {

                     

                  DAC9_1_WriteStall(value);

                     

                  }

                     

                      while(tick1s==22)   // DAC output increase to 3.1V with rate of change 1V/s

                     

                  {

                     

                  if(tick2ms%3==0)

                     

                  {

                     

                  value+=1;

                     

                  DAC9_1_WriteStall(value);

                     

                  }

                     

                  }

                     

                  while(tick1s<50)    //Keep the voltage at 3.1V

                     

                  {

                     

                  DAC9_1_WriteStall(value);

                     

                  }

                     

                        //DAC9_1_Stop();

                     

                   

                     

                  The program as stated should be functionnal, but in your case your problem is related to the interrupt. 

                     

                   

                     

                  In the following line : if(tick2ms%16==0), your program have the time to do several pass before tick2ms get changed. Consequently this line: value+=1; will be executed more than once, so the variable "value" will be higher than expected.

                     

                   

                     

                  Regards

                  • 6. Re: DAC output with timer
                    quan.trieu

                    Thank you guys for your replies!

                       

                    To Bob: You're right, I have added the infinite loop and changed the DAC_value to local variables. I also assigned some constant DAC value to get the defined voltage and after that I found the errors in my project. As I said above, the initial value for my DAC is 2.05V, then it comes up to 2.2V and after some time it goes to 3.1V. Then it will be offset to -2.5V to get the value in the picture in my first post

                       

                    To Eric: You got the point. The problem lies where I update the DAC value. Here is the modified code I get from Bob's and your suggestions

                       
                        void Timer_DAC(void)   
                       
                        {   
                       
                         int DAC_value_2_05V = 167;   
                       
                         int DAC_value_2_2V = 198;   
                       
                         int DAC_value_3_1V = 373;   
                       
                         while (tick1s<=10)  //DAC output 2.05V if the time is below 10s, the analog output value is later offset by -2.5V   
                       
                         {   
                       
                         DAC9_1_WriteStall(DAC_value_2_05V);   
                       
                         }   
                       
                         while (tick1s==11)      //DAC output increase with rate of change 0.15V/s   
                       
                         {        
                       
                         if(tick2ms%16==0)   
                       
                         {   
                       
                         DAC_value_2_05V +=1;   
                       
                         DAC9_1_WriteStall(DAC_value_2_05V);   
                       
                         }   
                       
                         }   
                       
                         while (tick1s<22)   //DAC output at 2.2V   
                       
                         {   
                       
                         DAC9_1_WriteStall(DAC_value_2_2V);   
                       
                         }   
                       
                         while (tick1s==22)   // DAC output increase to 3.1V with rate of change 1V/s   
                       
                         {        
                       
                         if(tick2ms%3==0)        
                       
                         {   
                       
                         DAC_value_2_2V+=1;   
                       
                         DAC9_1_WriteStall(DAC_value_2_2V);   
                       
                         }   
                       
                         }   
                       
                         while (tick1s<50)   
                       
                         {   
                       
                         DAC9_1_WriteStall(DAC_value_3_1V);   
                       
                         }   
                       
                         //DAC9_1_Stop();   
                       
                        }   
                       
                            
                       
                        the signal is from the middle of the screen to the right.    
                       
                        My idea is when tick1s equals 11 (at the second of 11), I will have tick2ms tick 500 times so for each time tick2ms equal 16, 32, 48,... to 500 (tick2ms%16==0) then the DAC_value will be updated. However it comes up so high (about 3.6V - DAC value around 450). After that I used constant DAC value and it went down as in the picture. The change occured at the time expected so I think the interrupt works well.    
                       
                        Do you guys have any idea why was it like this?    
                    • 7. Re: DAC output with timer
                      user_27941315

                      To avoid this behaviour you could set a flag in your interrupt, execute the code once the flag is set then reset the flag. it will get set at the next interrupt and so on.

                         

                       

                         

                      It could look somthing like this:

                         

                      if(tick2ms%16==0 && flag2ms){

                         

                          flag2ms = 0;

                         

                          ...

                         

                      }

                         

                       

                         

                      Regards

                      • 8. Re: DAC output with timer
                        quan.trieu

                         Thanks EricS, your idea is valuable to me!

                           

                        I followed your suggestions and it seems to work out, however it still got some problems that I can't tell why it was like this. I have been trying all the morning but the results are the same. It seems that the counter in "if" function got double so the DAC value update got double too. I know this is going to work but I couldn't go to my expected results :(

                           

                           

                        #pragma interrupt_handler Timer8_1_ISR

                           

                        void Timer8_1_ISR(void)

                           

                        {

                           

                        flag2ms=1;

                           

                        tick2ms++;

                           

                        if (tick2ms == 500) //output period of timer is 2ms, so I set the interrupt to get 1s

                           

                        { tick2ms = 1;

                           

                        tick1s++;

                           

                        }

                           

                        }

                           

                        void Timer_DAC(void)

                           

                        {

                           

                        int DAC_value_2_05V = 167;

                           

                        int DAC_value_2_2V = 198;

                           

                        int DAC_value_3_1V = 373;

                           

                        while (tick1s<=10)  //DAC output 2.05V if the time is below 10s, the analog output value is later offset by -2.5V

                           

                        {

                           

                        DAC9_1_WriteStall(DAC_value_2_05V);

                           

                        }

                           

                        while (tick1s==11)      //DAC output increase with rate of change 0.15V/s

                           

                        {

                           

                        if(tick2ms%16==0 && flag2ms)

                           

                        {

                           

                        flag2ms=0;

                           

                        DAC_value_2_05V +=1;

                           

                        }

                           

                        DAC9_1_WriteStall(DAC_value_2_05V);

                           

                        }

                           

                        while (tick1s<22)   //DAC output at 2.2V

                           

                        {

                           

                        DAC9_1_WriteStall(DAC_value_2_2V);

                           

                        }

                           

                        while (tick1s==22)   // DAC output increase to 3.1V with rate of change 1V/s

                           

                        {

                           

                        if(tick2ms%3==0 && flag2ms)

                           

                        {

                           

                        flag2ms=0;

                           

                        DAC_value_2_2V+=1;

                           

                        }

                           

                        DAC9_1_WriteStall(DAC_value_2_2V);

                           

                        }

                           

                        while (tick1s<50)

                           

                        {

                           

                        DAC9_1_WriteStall(DAC_value_3_1V);

                           

                        }

                           

                        //DAC9_1_Stop();

                           

                        }

                           

                        Please take a look and give me some advices. Thank you so much!

                        • 9. Re: DAC output with timer
                          ki.leung

                          It may be easier if you upload the project here.

                          • 10. Re: DAC output with timer
                            user_14586677

                            Why not consider a table driven approach. Say tsktable[ 5 ][ 3 ], first element in

                               

                            table length of time for a specific part of waveform, second the begining V, third

                               

                            end V, and based on timer value ramp or stay put the DAC outut. You could even

                               

                            add a 4 elemnet to table, that is timer values to initiate next part of waveform. So you

                               

                            just test in code timer value and current element of table. when equal you then implement

                               

                            the table instructions, either ramp or stay put.

                               

                             

                               

                            Then if start and end V same, do nothing for all but the first time sample. If end V >

                               

                            start V ramp each timer sample the count increment to get to final V.

                               

                             

                               

                            Just a thought, Dana,

                               

                             

                               

                             

                               

                             

                               

                            • 11. Re: DAC output with timer
                              quan.trieu

                               Here is my current project, please have a look!

                                 

                              Danaa: Thank you, I will think of your approach. In fact, I didn't know there is a table approach to this DAC, I only know of the array approach as in sine wave example. 

                                 

                              Regards, 

                              • 12. Re: DAC output with timer
                                ki.leung

                                1. How do you get the 3 DAC values?

                                   

                                 

                                   

                                int DAC_value_2_05V = 167;

                                   

                                int DAC_value_2_2V = 198;

                                   

                                int DAC_value_3_1V = 373;

                                   

                                2. With 5V full swing and 512 steps, each step should be 9.77mV and you have 32 increments within 1 second, so it would be 0.3125 V. the change would then be 0.3125V/S which is what you are getting now

                                • 13. Re: DAC output with timer
                                  quan.trieu

                                  To my understanding, the DAC range and ADC range is determined by Ref Mux parameter in Global Resources. 

                                     

                                  I chose Ref Mux equals to (Vdd/2)+/-Bandgap so the DAC range would be 1.2V to 3.8V with values from 0 to 511. That's how I get the DAC values for each voltage. 

                                     

                                  If the full range swing is 5V then it will go as you say but the DAC range is 2.6V so it should be halved. 

                                     

                                  Please correct me if I'm wrong. 

                                     

                                  Regards, 

                                  • 14. Re: DAC output with timer
                                    ki.leung

                                     In that case, your value should be correct.

                                       

                                    How about toggle a output pin in the 2ms interrupt, and use a CRO to check if 

                                       

                                    1. the timing is same every time and is 2ms

                                       

                                    2. there should be 32 counts during the 11th seconds.

                                    1 2 3 Previous Next