基于C8051F410的波形发生器设计

这段程序大部分是新华龙公司的官方资料,鄙人稍加修改,简化了不少代码,并增加了几种波形,只要按下P1.4键就可以切换。



//-----------------------------------------------------------------------------
// F41x_DACs_SineCosine.c
//-----------------------------------------------------------------------------
// Copyright 2006 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
//
// This program outputs sine and cosine waveforms using the hardware DACs
// on the C8051F410 microcontroller.  The waveforms are output on pins 
// P0.0/IDA0 and P0.1/IDA1.
//
// The output of the DACs is updated upon a Timer3 interrupt.  The Timer3 ISR
// then calculates the output of the DACs for the next interrupt. 
//
// The frequency of the output waveforms is set by the #define <FREQUENCY>.
//
//
// How To Test: 
//
// 1) Download the code to an C8051F410 Development Board
// 2) Check that the J6 and J16 shorting blocks are not installed.  This 
//    ensures that the IDAC outputs are not connected to any other pins
// 3) Check that the J13 and J14 short blocks are installed. This connects
//    the DAC outputs to resistors so that the output current is converted
//    to a voltage
// 4) Connect two oscillscope probes to pins P0.0/IDA0 and P0.1/IDA1.  
//    These pins are available on both the J2 and J11 headers.
// 5) Confirm that there are two waveforms with the output of DAC1 leading 
//    the output DAC0 by 90 degrees.  The frequency of both waveforms should
//    be close to frequency defined by <FREQUENCY>
//
// FID:            41X000036
// Target:         C8051F41x
// Tool chain:     Keil C51 7.50 / Keil EVAL C51
//                 Silicon Laboratories IDE version 2.71
// Command Line:   Default
//
// Release 1.0
//    -Initial Revision (GP)
//    -09 AUG 2006
//

//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------

#include <c8051f410.h>                 // SFR declarations

//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F41x
//-----------------------------------------------------------------------------

sfr16 TMR3RL   = 0x92;                 // Timer3 reload value
sfr16 TMR3     = 0x94;                 // Timer3 counter
sfr16 IDA0     = 0x96;                 // IDA0 high and low bytes
sfr16 IDA1     = 0xF4;                 // IDA1 high and low bytes

//-----------------------------------------------------------------------------
// Global Constants
//-----------------------------------------------------------------------------

#define SYSCLK          24500000       // Internal oscillator frequency in Hz

#define SAMPLE_RATE_DAC 100000L         // DAC sampling rate in Hz
#define PHASE_PRECISION 65536          // range of phase accumulator

#define FREQUENCY       1000           // Frequency of output waveform in Hz
                                       
// <PHASE_ADD> is the change in phase between DAC samples; It is used in 
// the set_DACs routine.
unsigned int PHASE_ADD = 1000 * PHASE_PRECISION / SAMPLE_RATE_DAC;

//EDIT by lineter
unsigned char m;
sbit huan=P1^4;

//EDIT OVER

unsigned int code SINE_TABLE[128] = 
{
   0x0000, 0x0324, 0x0647, 0x096a, 0x0c8b, 0x0fab, 0x12c8, 0x15e2, 
   0x18f8, 0x1c0b, 0x1f19, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11,
   0x30fb, 0x33de, 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, 
   0x471c, 0x49b4, 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842,
   0x5a82, 0x5cb4, 0x5ed7, 0x60ec, 0x62f2, 0x64e8, 0x66cf, 0x68a6, 
   0x6a6d, 0x6c24, 0x6dca, 0x6f5f, 0x70e2, 0x7255, 0x73b5, 0x7504,
   0x7641, 0x776c, 0x7884, 0x798a, 0x7a7d, 0x7b5d, 0x7c29, 0x7ce3, 
   0x7d8a, 0x7e1d, 0x7e9d, 0x7f09, 0x7f62, 0x7fa7, 0x7fd8, 0x7ff6,

};

//-----------------------------------------------------------------------------
// Function Prototypes
//-----------------------------------------------------------------------------

void main(void);
void OSCILLATOR_Init (void);
void PORT_Init (void);
void DAC0_Init (void);
void DAC1_Init (void);
void TIMER3_Init (int counts);
void Set_DACs (void);

void main (void) 
{
   PCA0MD &= ~0x40;                    // Disable Watchdog timer

   OSCILLATOR_Init ();                 // Initialize oscillator
   PORT_Init ();                       // Initialize crossbar and ports
   DAC0_Init ();                       // Initialize DAC0
   DAC1_Init ();                       // Initialize DAC1   
   
   TIMER3_Init(SYSCLK/SAMPLE_RATE_DAC);// Initialize Timer3 to overflow at 
                                       // <SAMPLE_RATE_DAC> times per second

   EA = 1;                             // Enable global interrupts
   m=0;
   while(1) 
   {
		while(huan!=1)
		{
			m++;
			m%=4;
			while(huan!=1);
		}

   }                         // Wait for interrupt
} 

void TIMER3_ISR (void) interrupt 14
{
   TMR3CN &= ~0x80;                   // Clear Timer3 overflow flag 
   Set_DACs();
}

void OSCILLATOR_Init (void)
{
   OSCICN  = 0x87;                     // Set clock to 24.5 MHz
   RSTSRC  = 0x04;                     // Enable missing clock detector
}

void PORT_Init (void)
{
   P0MDIN    &= ~0x03;                   // Configure P0.0 and P0.1 to analog
   P0SKIP    |= 0x03;                   // Skip P0.0 and P0.1 on the crossbar
   P1MDOUT	 &= ~0x10;
   XBR1      = 0x40;                   // Enable Crossbar
}

void DAC0_Init(void)
{
   REF0CN = 0x0A;                      // Enable VDD as VREF

   IDA0CN = 0xB3;                      // Enable IDA0 for 2.0 mA output
                                       // left-justified 
                                       // updated on Timer3 overflows
}

void DAC1_Init(void)
{
   REF0CN = 0x0A;                      // Enable VDD as VREF

   IDA1CN = 0xB3;                      // Enable IDA0 for 2.0 mA output
                                       // left-justified 
                                       // updated on Timer3 overflows
}

void TIMER3_Init (int counts)
{   
   TMR3CN  = 0x00;                     // Resets Timer3, 
                                       // Sets to 16 bit mode
   CKCON  |= 0x40;                     // Use system clock
   TMR3RL  = -counts;                  // Initial reload value

   TMR3    = 0xffff;                   // Sets timer to reload automatically
   EIE1   |= 0x80;                     // Enable Timer3 interrupts
   TMR3CN  = 0x04;                     // Start Timer3
}

void Set_DACs(void)
{
   if (0==m)
   {
	   static unsigned phase_acc = 0;      // Holds phase accumulator
		
	   int SIN_temp, COS_temp;             // Temporary 16-bit variables 
	   unsigned char index;                // Index into SINE table

	   phase_acc += PHASE_ADD;             // Increment phase accumulator
	   index = phase_acc >> 8;
	   
	   	if(index&0x80)
			if(index&0x40)
				SIN_temp = 0xffff-SINE_TABLE[63-index&0x3f];       // Read the table value
			else
				SIN_temp = 0xffff-SINE_TABLE[index&0x3f];       // Read the table value
		else	
			if(index&0x40)
	   			SIN_temp = SINE_TABLE[127-index];       // Read the table value
			else
				SIN_temp = SINE_TABLE[index];       // Read the table value
	   
	   index += 64;                        // 90 degree phase shift 
	   COS_temp = SINE_TABLE[index];

	   // Add a DC bias to change the the rails from a bipolar (-32768 to 32767)
	   // to unipolar (0 to 65535)
	   // Note: the XOR with 0x8000 translates the bipolar quantity into 
	   // a unipolar quantity.

	   IDA0 = SIN_temp ^ 0x8000;             // Update DAC values
	   IDA1 = COS_temp ^ 0x8000;           
	}
	else if (1==m)
	{
		static unsigned char fang=0;
		fang++;
		fang%=100;
		if (fang<50)
		{
			IDA0=0;
		}
		else
		{
			IDA0=0x0ffff;
		}
	}
	else if (2==m)
	{
		static unsigned char fang=0;
		unsigned int san1;
		fang++;
		fang%=100;
		if (fang<50)
		{
			san1=fang<<10;
			IDA0=san1;
		}
		else
		{
			san1=(100-fang)<<10;
			IDA0=san1;
		}	
	}
	else if (3==m)
	{
		static unsigned char fang=0;
		unsigned int san1;
		fang++;
		fang%=100;
		san1=fang<<9;
		IDA0=san1;
	}
}

//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------











注意端口输出模式配置,弄错了会烧单片机的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值