/* 007_DDS.c * This code implements a Direct Digital Synthesis (DDR) Audio Signal Generator * DDR Specifications * Phase Accumulator = 24-Bit DDR * Fclock = 372kHz (DDS While loop repeat rate) * Resolution = 0.02 Hz * Phase Steps = 128 Byte * Max Frequency = 25 kHz (~14 samples per cycle) * Commands = 4 Byte Command to change the frequency * Created: 05-Feb-16 9:17:08 AM * Author: Ajoy Raman */ //-------------Remarks------------------ /* ------------Commands Hex values --------------------- Break Command 42 42 42 42 B in ASCII Identify 49 49 49 49 I in ASSCII 5kHz Sin 53 03 70 DC S in ASCII Followed by Frequency Setting in Hex corresponds to a phase step of 225,500 25kHz Triangle 54 11 34 4D T in ASCII Followed by Frequency Setting in Hex corresponds to a phase step of 1,127,501 5kHz RampUp 55 03 70 DC U in ASCII Followed by Frequency Setting in Hex 5kHz RampDn 44 03 70 DC D in ASCII Followed by Frequency Setting in Hex Load Arbitrary Data 4C 4C 4C 4C L in ASCII This is to be followed by 128 Hex Data 6-Bit maximum 1F Hex / 63 Dec 5kHz Arbitrary 41 03 70 DC A in ASCII Followed by Frequency Setting in Hex */ /* 18 Feb 16 Code modified for reading arbitrary waveform data Switches between a 4-bit / 256 Buffer based on command 0x4C = Load Arbitrary This should be followed by 128 Bytes of waveform 6-Bit data in Hex 0x41 Runs the Arbitrary waveform */ /* Program computes the value of phase_step required based on input commands mode,phase_step_b2, phase_step_b1 and phase_step_b0=0x40. The DDS loop uses a while loop with minimum instructions so as achieve the fastest FClock. The USART Rx is implemented in interrupt mode so that the while loop can be broken using a break statement based on command inputs. 8Feb16 Shifted 8-bit >> 6-bit mode PORTB */ // MD5 Checksum // 08148d98f2fb35746dfcd3112f664307 //-------------Includes----------------- #include #include #include //-------------Defines------------------- #define F_CPU 16000000UL //CPU Clock Speed #define USART_BAUDRATE 38400 // Define baud rate #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1) //Function prototypes ------------------------------------------------------------- void USART_Init(void); void USART_SendByte(uint8_t u8Data); uint8_t USART_ReceiveByte(); void DDS_OUT(); void Calculate(); uint8_t create_out_map( uint8_t MAP[128]); //Waveform tables------------------------------------------------------------------- uint8_t SIN_MAP[128]={//8Bit>>2 0x1F,0x21,0x22,0x24,0x25,0x27,0x28,0x2A,0x2B,0x2D,0x2E,0x30,0x31,0x32,0x33,0x35, 0x36,0x37,0x38,0x39,0x3A,0x3A,0x3B,0x3C,0x3D,0x3D,0x3E,0x3E,0x3E,0x3F,0x3F,0x3F, 0x3F,0x3F,0x3F,0x3F,0x3E,0x3E,0x3E,0x3D,0x3D,0x3C,0x3B,0x3A,0x3A,0x39,0x38,0x37, 0x36,0x35,0x33,0x32,0x31,0x30,0x2E,0x2D,0x2B,0x2A,0x28,0x27,0x25,0x24,0x22,0x21, 0x1F,0x1E,0x1C,0x1B,0x19,0x18,0x16,0x15,0x13,0x12,0x10,0x0F,0x0E,0x0C,0x0B,0x0A, 0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08, 0x09,0x0A,0x0B,0x0C,0x0E,0x0F,0x10,0x12,0x13,0x15,0x16,0x18,0x19,0x1B,0x1C,0x1E }; uint8_t TRI_MAP[128]={ 0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E, 0x2F,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E, 0x3F,0x3E,0x3D,0x3C,0x3B,0x3A,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30, 0x2F,0x2E,0x2D,0x2C,0x2B,0x2A,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20, 0x1F,0x1E,0x1D,0x1C,0x1B,0x1A,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10, 0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00, 0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E, 0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E }; uint8_t RAMPUP_MAP[128]={ 0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07, 0x07,0x08,0x08,0x09,0x09,0x0A,0x0A,0x0B,0x0B,0x0C,0x0C,0x0D,0x0D,0x0E,0x0E,0x0F, 0x0F,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17, 0x17,0x18,0x18,0x19,0x19,0x1A,0x1A,0x1B,0x1B,0x1C,0x1C,0x1D,0x1D,0x1E,0x1E,0x1F, 0x1F,0x20,0x20,0x21,0x21,0x22,0x22,0x23,0x23,0x24,0x24,0x25,0x25,0x26,0x26,0x27, 0x27,0x28,0x28,0x29,0x29,0x2A,0x2A,0x2B,0x2B,0x2C,0x2C,0x2D,0x2D,0x2E,0x2E,0x2F, 0x2F,0x30,0x30,0x31,0x31,0x32,0x32,0x33,0x33,0x34,0x34,0x35,0x35,0x36,0x36,0x37, 0x37,0x38,0x38,0x39,0x39,0x3A,0x3A,0x3B,0x3B,0x3C,0x3C,0x3D,0x3D,0x3E,0x3E,0x3F }; uint8_t RAMPDN_MAP[128]={ 0x3F,0x3E,0x3E,0x3D,0x3D,0x3C,0x3C,0x3B,0x3B,0x3A,0x3A,0x39,0x39,0x38,0x38,0x37, 0x37,0x36,0x36,0x35,0x35,0x34,0x34,0x33,0x33,0x32,0x32,0x31,0x31,0x30,0x30,0x2F, 0x2F,0x2E,0x2E,0x2D,0x2D,0x2C,0x2C,0x2B,0x2B,0x2A,0x2A,0x29,0x29,0x28,0x28,0x27, 0x27,0x26,0x26,0x25,0x25,0x24,0x24,0x23,0x23,0x22,0x22,0x21,0x21,0x20,0x20,0x1F, 0x1F,0x1E,0x1E,0x1D,0x1D,0x1C,0x1C,0x1B,0x1B,0x1A,0x1A,0x19,0x19,0x18,0x18,0x17, 0x17,0x16,0x16,0x15,0x15,0x14,0x14,0x13,0x13,0x12,0x12,0x11,0x11,0x10,0x10,0x0F, 0x0F,0x0E,0x0E,0x0D,0x0D,0x0C,0x0C,0x0B,0x0B,0x0A,0x0A,0x09,0x09,0x08,0x08,0x07, 0x07,0x06,0x06,0x05,0x05,0x04,0x04,0x03,0x03,0x02,0x02,0x01,0x01,0x00,0x00,0x00 }; //------------------Globals------------------------------------- uint8_t table_index; //128 step tables volatile uint8_t DataMode; uint32_t phase_accumulator, phase_step; volatile static uint8_t next_write=0; // the pointers to the receive buffer volatile uint8_t buffer[4]; // circular buffer for receiver volatile uint8_t mode,phase_step_b2, phase_step_b1,phase_step_b0; volatile uint8_t cmd_recd; uint8_t DDS_OUT_MAP[128]; volatile uint8_t DDS_ARB_BUF[128]; //-----------------USART RX ISR---------------------------------- ISR(USART_RX_vect){ // the interrupt signal when a byte is received by the USART // store the data into the buffer if (DataMode==1){//4 Byte Data Mode buffer[next_write++] = UDR0; if (next_write == 4){ next_write = 0; mode=buffer[0]; phase_step_b2=buffer[1]; phase_step_b1=buffer[2]; phase_step_b0=buffer[3];//lsb if (mode==0x4C){ DataMode=0; } } } else if (DataMode==0){//256 Data Mode DDS_ARB_BUF[next_write++] = UDR0; if (next_write == 128){ next_write = 0; DataMode=1; } } } //-------------------------------Main ------------------------------- int main(void){ DDRB =0xFF; //PORTB all outputs USART_Init(); // Initialize USART sei(); // enable all interrupts mode=0x42; DataMode=1; while(1){ // Repeat indefinitely _delay_ms(100); if (mode== 0x53){//Set Sin phase_accumulator=0; Calculate(); USART_SendByte(0x44); USART_SendByte(0x44); USART_SendByte(0x53); USART_SendByte(0x5F); USART_SendByte(0x53); USART_SendByte(0x69); USART_SendByte(0x6E); USART_SendByte(0x5F); USART_SendByte(0x53); USART_SendByte(0x65); USART_SendByte(0x74); USART_SendByte(0x0D); USART_SendByte(0x0A); create_out_map( SIN_MAP); DDS_OUT(); } else if (mode==0x54){//Set Triangle phase_accumulator=0; Calculate(); USART_SendByte(0x44); USART_SendByte(0x44); USART_SendByte(0x53); USART_SendByte(0x5F); USART_SendByte(0x54); USART_SendByte(0x72); USART_SendByte(0x69); USART_SendByte(0x5F); USART_SendByte(0x53); USART_SendByte(0x65); USART_SendByte(0x74); USART_SendByte(0x0D); USART_SendByte(0x0A); create_out_map( TRI_MAP); DDS_OUT(); } else if (mode== 0x55){//Set Ramp UP phase_accumulator=0; Calculate(); USART_SendByte(0x44); USART_SendByte(0x44); USART_SendByte(0x53); USART_SendByte(0x5F); USART_SendByte(0x52); USART_SendByte(0x61); USART_SendByte(0x6D); USART_SendByte(0x70); USART_SendByte(0x55); USART_SendByte(0x70);USART_SendByte(0x5F); USART_SendByte(0x53); USART_SendByte(0x65); USART_SendByte(0x74); USART_SendByte(0x0D); USART_SendByte(0x0A); create_out_map( RAMPUP_MAP); DDS_OUT(); } else if (mode==0x44){//Set Ramp DN phase_accumulator=0; Calculate(); USART_SendByte(0x44); USART_SendByte(0x44); USART_SendByte(0x53); USART_SendByte(0x5F); USART_SendByte(0x52); USART_SendByte(0x61); USART_SendByte(0x6D); USART_SendByte(0x70); USART_SendByte(0x44); USART_SendByte(0x6E);USART_SendByte(0x5F); USART_SendByte(0x53); USART_SendByte(0x65); USART_SendByte(0x74); USART_SendByte(0x0D); USART_SendByte(0x0A); create_out_map( RAMPDN_MAP); DDS_OUT(); } else if (mode==0x41) {//Run Arbitrary Data phase_accumulator=0; Calculate(); USART_SendByte(0x44); USART_SendByte(0x44); USART_SendByte(0x53); USART_SendByte(0x5F); USART_SendByte(0x41); USART_SendByte(0x72);USART_SendByte(0x62);USART_SendByte(0x5F); USART_SendByte(0x53); USART_SendByte(0x65); USART_SendByte(0x74); USART_SendByte(0x0D); USART_SendByte(0x0A); /*uint8_t j; for (j=0;j<128;j++){ USART_SendByte(DDS_ARB_BUF[j]); } */ create_out_map( DDS_ARB_BUF); DDS_OUT(); } else if (mode==0x49){//Identify USART_SendByte(0x41); USART_SendByte(0x6A); USART_SendByte(0x5F); USART_SendByte(0x53); USART_SendByte(0x69); USART_SendByte(0x67); USART_SendByte(0x47); USART_SendByte(0x65); USART_SendByte(0x6E);USART_SendByte(0x0D);USART_SendByte(0x0A);//Aj_SigGen mode=42; //break } } //} } //Functions ------------------------------------------------------------------------ void Calculate(){ phase_step = phase_step_b0; phase_step = phase_step + ((phase_step_b1*0x100) & 0x0000ffff); phase_step = phase_step+ ((phase_step_b2*0x10000)& 0x00ffffff); } //DDS_OUT void DDS_OUT(){ while(1){ // While loop 43 Cycles runs at 372kHz phase_accumulator=phase_accumulator + phase_step; table_index=(phase_accumulator)>>16; //shifting by 8,16 require less cycles table_index=table_index>>1; PORTB=DDS_OUT_MAP[table_index]; if(mode==0x42) break; } } //Initialize USART void USART_Init(void){ // Set baud rate UBRR0L = BAUD_PRESCALE;// Load lower 8-bits into the low byte of the UBRR register UBRR0H = (BAUD_PRESCALE >> 8); /* Load upper 8-bits into the high byte of the UBRR register Default frame format is 8 data bits, no parity, 1 stop bit to change use UCSRC, see AVR data-sheet*/ // Enable receiver and transmitter and receive complete interrupt UCSR0B = ((1<