📄 dac0_dtmf1.c
字号:
/***************************************************************
功能:实现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;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -