# dsPIC30f4011 sinusoidal PWM generation

1. ## dsPIC30f4011 sinusoidal PWM generation

Hi,
i'm trying to do my project by using dsPIC30f4011 to generate 5kHz 3 phase sine wave with PWM module. inputs are 2 variable voltage (0-5V) into ADC module then change float to integer and generate ramp signal to find the angle of input value then use park (Iα,Iβ»Id,Iq) and inverse clarke (Id,Iq»Ia,Ib,Ic) transform to get 3 phase signal and send to PWM module. it will gets 3 pulse signals. Finally, put signals to i2c module to connect with DAC converter.
Is my idea OK?
can anybody give me idea or sample code.

Regard

2. ## Re: dsPIC30f4011 sinusoidal PWM generation

In the past I used a MCP4101 digital pot which has an SPI interface to generate sine waves of approx 2KHz
MCP41010

not sure if it would work at 5KHz but worth considering
the alternative is a DAC - for example I used Integra development boards with Texas DSP processors and high speed DACs to generate frequencies of 1 to 10 MHz

•

3. ## Re: dsPIC30f4011 sinusoidal PWM generation

thanks for reply

Now, I have problem about Qmath (it's use in changing float to integer), i don't know to write code in C.
can you give me some example code.

thank you very much

4. ## Re: dsPIC30f4011 sinusoidal PWM generation

it depends on what you are trying to do, e.g. the range of float values and what size integer you are converting too.
e.g. if you are driving a 12bit DAC (range -2048 to +2047 ) from a sine function (range -1.0 to +1.0) you could do something like
Code:
`   int DACvalue= (int) (2047.0 * sin(angle));`

•

5. ## Re: dsPIC30f4011 sinusoidal PWM generation

My inputs are 2 voltage values (vary 0-5V) into 10 bit ADC , i want to change these inputs from float to integer for taken to use in park transform calculation.
can you give exam code and some advice for me

thank for advance

6. ## Re: dsPIC30f4011 sinusoidal PWM generation

a 10bit ADC would give output 0 to 1023 or -512 to 511 for the full range input depending on how it is set up.
Assuming 0 to 1023 - 0 volts would be represented by 0 and 5 volts by 1023 so conversion from ADC value to a float voltage would be
Code:
`   float voltage = 5.0f* ADCvalue / 1023.0f;`
would give you a value in the range 0 to 5.0

7. ## Re: dsPIC30f4011 sinusoidal PWM generation

your post has useful for me.
I will do follow your advice, thank you very much.

At this moment,i use i2c module to connect ADC converter
can anyone give me some code and idea.

reguard

8. ## Re: dsPIC30f4011 sinusoidal PWM generation

any particular reason why you are not using the ADC of the dsPIC30f4011 ?

here is some sample code to drive the I2C interface of a PIC24 (the dsPIC should be similar)
Code:
```// i2cFunctions.c - to drive I2C2 interface

#define USE_AND_OR
#include "i2c.h"
#include "Hardware.h"
#include "stdio.h"
#include "timer.h"

static int I2C2address=0; 		// address of I2C2 device

//    This routine is used to write a byte to the I2C2 bus. The input parameter data_out is written to the
//    I2C2TRN register. If IWCOL bit is set,write collision has occured and -1 is returned,
//    if acknowledge timeout return -2, else 0 is returned.
char MasterWriteI2C2(const unsigned char data_out)
{
I2C2TRN = data_out;						// write data byte
if(I2C2STATbits.BCL)
{ printf("I2C Master bus collision detect %0x\n", I2C2STAT); return -1; }        /* If write collision occurs,return -1 */
if(I2C2STATbits.IWCOL)
{ printf("I2C write collision detect %0x\n", I2C2STAT); return -1; }        /* If write collision occurs,return -1 */
int timeOutCount=10000;
while(I2C2STATbits.TBF || I2C2CONbits.SEN || I2C2CONbits.PEN || I2C2CONbits.RCEN || I2C2CONbits.ACKEN || I2C2STATbits.TRSTAT || I2C2STATbits.ACKSTAT)
if(!timeOutCount--) { printf("\n\rMasterWriteI2C2 address %#x timeout config %#x status %#x \n\r", I2C2address, I2C2CON, I2C2STAT);	return -2; }
//    printf(" %0x ", I2C2STAT);
return 0;
}

//  This routine is used to write out an array to the
// I2C2 bus.If write collision occurs,-3 is sent.If
//  Nack is received, -2 is sent.If arrayis written 0 is returned.
static unsigned int MasterPutArrayI2C2(const unsigned char * wrptr, int count)
{
int i=0;
while(count--)                           //transmit data
{
if((i=MasterWriteI2C2(*wrptr)) < 0) return i;	    // write a byte - return on error
wrptr++;
}
return 0;
}

// write to I2C2 address array wrptr of length, if sendStop is 1 send a STOP at end
int writeI2C2(const int address, const unsigned char *wrptr, int length, int sendStop)
{
unsigned int i2cbrg=((SYSCLK/100000L)-(SYSCLK/1111111L))-1;	/* Baud rate is set for 100 Khz */
unsigned int config1 = (I2C_ON | I2C_IDLE_CON | I2C_CLK_HLD	/* Configure I2C for 7 bit address mode */
| I2C_IPMI_DIS | I2C_7BIT_ADD   | I2C_SLW_DIS | I2C_SM_DIS |
I2C_GCALL_DIS | I2C_STR_DIS |   I2C_NACK | I2C_ACK_DIS | I2C_RCV_DIS |
I2C_STOP_DIS | I2C_RESTART_DIS  | I2C_START_DIS);
// problem with Master bus colision on PIC24s, see
//   http://forum.microchip.com/tm.aspx?m=271183&mpage=1&key=
TRISAbits.TRISA3=0;
LATAbits.LATA3 = 0;   //where LATBx = the SDAx pin
LATAbits.LATA3 = 1;
OpenI2C2(config1,i2cbrg);									/* open the I2C2 device */
//printf("\nwrite I2C2 %#x %0x %0x I2C stat %0x \n", address,config1,i2cbrg,I2C2STAT);
IdleI2C2();
StartI2C2();												/* send START */
while(I2C2CONbits.SEN );									/* Wait till Start sequence is completed */
if(MasterWriteI2C2(I2C2address=address) < 0) return -1;	/* Write Slave address and set master for transmission */
if(MasterPutArrayI2C2(wrptr, length) < 0) return -1;		/* Transmit string of data */
if(!sendStop) return 0;
StopI2C2();												/* send STOP */
while(I2C2CONbits.PEN);									/* Wait till stop sequence is completed */
CloseI2C2();
return 0;
}

// read from I2C2 device address
// initially send tx_data (length tx_length), restart and read rx_length bytes into rs_data
int readI2C2(int address, unsigned char *tx_data, int tx_length, unsigned char * rx_data, int rx_length)
{
//int i;
unsigned int i2c_data_wait= 11152;
//printf("\n\rread I2C2 %#x ", address);
writeI2C2(address,tx_data, tx_length, 0);		// send address and register number etc
RestartI2C2();     							// send RESTART ready for a read!
while(I2C2CONbits.RSEN );						// wait for restart complete
if(MasterWriteI2C2(address+1)<0)return -1;	/* Write Slave address and set master for read */
if(MastergetsI2C2(rx_length, rx_data, i2c_data_wait)!=0)return -1;	// read data from slave
// uart2_puts("\n\rread  ");
// for(i=0;i<rx_length;i++) { printHex(rx_data[i],uart2_putchar); uart2_putchar(' ');}
StopI2C2();									/* send stop */
while(I2C2CONbits.PEN);						/* Wait till stop sequence is completed */
CloseI2C2();									// close I2C2 device
return 0;
}```
I appeared to use it for reading the EUI-48 node address from a Microchip 24AA02E48 serial EEPROM
Code:
```// read 24AA02E48 serail EEPROM with EUI-48 node identy
int read24AA02E48MACaddress(void)
{
// MAC address is at EPROM address FAhex
unsigned char data[10] ={0xfa}, check[3]={0, 0x4,0xa3};						// read from 0xfa
int i;
printf("read 24AA02E48 serail EEPROM with EUI-48 node identy\n");
readI2C(address, data, 1, data, 6);		// read 6 bytes
// if node ID does not exist return otherwise set it up```

•

9. ## Re: dsPIC30f4011 sinusoidal PWM generation

thank you very much for your reply,
i will taken to apply in my project.

--[[ ]]--