设为首页 - 加入收藏 - 网站地图 我爱嵌入式(www.52embed.com),专注嵌入式开发技术!
当前位置:主页 > 嵌入式软件 > 正文

C8051F020单片机DAC产生正弦信号源码

时间:2015-05-11 21:14 来源:未知 作者:admin 阅读:
/***************************************************************
功能:实现DAC模拟信号输出,由T4定时控制DAC0输出DTMF信号
作者:ZDP
时间:2005-11-30
版本:V1.0
***************************************************************/
 
#include <c8051f020.h>              // SFR declarations
 
//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F02x
//-----------------------------------------------------------------------------
 
sfr16 DP       = 0x82;              // data pointer
sfr16 TMR3RL   = 0x92;              // Timer3 reload value
sfr16 TMR3     = 0x94;              // Timer3 counter
sfr16 ADC0     = 0xbe;              // ADC0 data
sfr16 ADC0GT   = 0xc4;              // ADC0 greater than window
sfr16 ADC0LT   = 0xc6;              // ADC0 less than window
sfr16 RCAP2    = 0xca;              // Timer2 capture/reload
sfr16 T2       = 0xcc;              // Timer2
sfr16 RCAP4    = 0xe4;              // Timer4 capture/reload
sfr16 T4       = 0xf4;              // Timer4
sfr16 DAC0     = 0xd2;              // DAC0 data
sfr16 DAC1     = 0xd5;              // DAC1 data
 
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
#define SYSCLK 22118400             // SYSCLK frequency in Hz
 
#define SAMPLERATED 100000L         // update rate of DAC in Hz
 
#define phase_precision 65536       // range of phase accumulator
 
// DTMF phase adder values based on SAMPLERATED and <phase_precision>
 
#define LOW697 697 * phase_precision / SAMPLERATED
#define LOW770 770 * phase_precision / SAMPLERATED
#define LOW852 852 * phase_precision / SAMPLERATED
#define LOW941 941 * phase_precision / SAMPLERATED
 
#define HI1209 1209 * phase_precision / SAMPLERATED
#define HI1336 1336 * phase_precision / SAMPLERATED
#define HI1477 1477 * phase_precision / SAMPLERATED
#define HI1633 1633 * phase_precision / SAMPLERATED
 
//-----------------------------------------------------------------------------
// 函数定义
//-----------------------------------------------------------------------------
 
void main (void);
void SYSCLK_Init (void);
void PORT_Init (void);
 
void Timer4_Init (int counts);
void Timer4_ISR (void);
 
//-----------------------------------------------------------------------------
// 全局变量
//-----------------------------------------------------------------------------
unsigned phase_add1;
unsigned phase_add2;
 
bit tone1_en;
bit tone2_en;
 
char code SINE_TABLE[256] = {
   0x00, 0x03, 0x06, 0x09, 0x0c, 0x0f, 0x12, 0x15,
   0x18, 0x1c, 0x1f, 0x22, 0x25, 0x28, 0x2b, 0x2e,
   0x30, 0x33, 0x36, 0x39, 0x3c, 0x3f, 0x41, 0x44,
   0x47, 0x49, 0x4c, 0x4e, 0x51, 0x53, 0x55, 0x58,
   0x5a, 0x5c, 0x5e, 0x60, 0x62, 0x64, 0x66, 0x68,
   0x6a, 0x6c, 0x6d, 0x6f, 0x70, 0x72, 0x73, 0x75,
   0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7c,
   0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
   0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7e,
   0x7d, 0x7c, 0x7c, 0x7b, 0x7a, 0x79, 0x78, 0x77,
   0x76, 0x75, 0x73, 0x72, 0x70, 0x6f, 0x6d, 0x6c,
   0x6a, 0x68, 0x66, 0x64, 0x62, 0x60, 0x5e, 0x5c,
   0x5a, 0x58, 0x55, 0x53, 0x51, 0x4e, 0x4c, 0x49,
   0x47, 0x44, 0x41, 0x3f, 0x3c, 0x39, 0x36, 0x33,
   0x30, 0x2e, 0x2b, 0x28, 0x25, 0x22, 0x1f, 0x1c,
   0x18, 0x15, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03,
   0x00, 0xfd, 0xfa, 0xf7, 0xf4, 0xf1, 0xee, 0xeb,
   0xe8, 0xe4, 0xe1, 0xde, 0xdb, 0xd8, 0xd5, 0xd2,
   0xd0, 0xcd, 0xca, 0xc7, 0xc4, 0xc1, 0xbf, 0xbc,
   0xb9, 0xb7, 0xb4, 0xb2, 0xaf, 0xad, 0xab, 0xa8,
   0xa6, 0xa4, 0xa2, 0xa0, 0x9e, 0x9c, 0x9a, 0x98,
   0x96, 0x94, 0x93, 0x91, 0x90, 0x8e, 0x8d, 0x8b,
   0x8a, 0x89, 0x88, 0x87, 0x86, 0x85, 0x84, 0x84,
   0x83, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81,
   0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82,
   0x83, 0x84, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
   0x8a, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x93, 0x94,
   0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa4,
   0xa6, 0xa8, 0xab, 0xad, 0xaf, 0xb2, 0xb4, 0xb7,
   0xb9, 0xbc, 0xbf, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
   0xd0, 0xd2, 0xd5, 0xd8, 0xdb, 0xde, 0xe1, 0xe4,
   0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf7, 0xfa, 0xfd
};
 
 
//-----------------------------------------------------------------------------
// 主函数
//-----------------------------------------------------------------------------
 
void main (void) {
 
   WDTCN = 0xde;                    // 关闭WDT
   WDTCN = 0xad;
 
   SYSCLK_Init ();
 
   PORT_Init ();
 
   REF0CN = 0x03;                   // 启用内部的电压基准源
 
   DAC0CN = 0x97;                   // 启用 DAC0 及T4定时更新
   Timer4_Init(SYSCLK/SAMPLERATED); // 初始化T4为DAC0定时更新
 
   tone1_en = 1;
   tone2_en = 1;
 
   phase_add1 = LOW697;
   phase_add2 = HI1633;
 
   EA = 1;                          // 开中断
 
   while (1);
}
 
//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
 
void SYSCLK_Init (void)
{
   int i;                           // delay counter
 
   OSCXCN = 0x67;                   // start external oscillator with
                                    // 22.1184MHz crystal
 
   for (i=0; i < 256; i++) ;        // Wait for osc. to start up
   
   while (!(OSCXCN & 0x80)) ;       // Wait for crystal osc. to settle
 
   OSCICN = 0x88;                   // select external oscillator as SYSCLK
                                    // source and enable missing clock
                                    // detector
 
}
 
//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
void PORT_Init (void)
{
   XBR0     = 0x00;
   XBR1     = 0x00;
   XBR2     = 0x40;                 // Enable crossbar and weak pull-ups
}
 
//-----------------------------------------------------------------------------
// Timer4_Init
//-----------------------------------------------------------------------------
//
void Timer4_Init (int counts)
{
   T4CON = 0;                       // STOP timer; set to auto-reload mode
   CKCON |= 0x40;                   // T4M = '1'; Timer4 counts SYSCLKs
   RCAP4 = -counts;                 // set reload value
   T4 = RCAP4;
   EIE2 |= 0x04;                    // enable Timer4 interrupts
   T4CON |= 0x04;                   // start Timer4
}
 
//-----------------------------------------------------------------------------
// Timer4_ISR
//-----------------------------------------------------------------------------
//
void Timer4_ISR (void) interrupt 16 using 3
{
   static unsigned phase_acc1 = 0;
   static unsigned phase_acc2 = 0;
 
   char temp1;                      
   char temp2;
   char code *table_ptr;
 
   T4CON &= ~0x80;                  // 清T4计数溢出标致位
 
   table_ptr = SINE_TABLE;
 
   if ((tone1_en) && (tone2_en)) {
      phase_acc1 += phase_add1;
      temp1 = *(table_ptr + (phase_acc1 >> 8));
      phase_acc2 += phase_add2;
      temp2 = *(table_ptr + (phase_acc2 >> 8));
      DAC0H = 0x80 ^ ((temp1 >> 1) + (temp2 >> 1));
   } else if (tone1_en) {
      phase_acc1 += phase_add1;
      temp1 = *(table_ptr + (phase_acc1 >> 8));
      DAC0H = 0x80 ^ temp1;
   } else if (tone2_en) {
      phase_acc2 += phase_add2;
      temp2 = *(table_ptr + (phase_acc2 >> 8));
      DAC0H = 0x80 ^ temp2;
   }
}
 

(责任编辑:admin)

顶一下
(0)
0%
踩一下
(0)
0%
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。