这是基于STC系列的PWM方式输出pcm音频的驱动,PC通过uart将pcm数据发送下来之后再通过pwm方式将PCM数据输出,采样率为8k,调制频率为58593.75,代码如下:
//以下是DV_Timer.H头文件部分
/*******************************************************************************************
文档说明:板载spaker驱动文件头文件
*******************************************************************************************/
//硬件资源占用:
//GPIO tim0
//设备模式描述:
//接口函数:
void DV_Spaker_Init(void);
void DV_Spaker_Service(void);
//以下是DV_Timer.c正文文件部分
#include "stc15w.h"
#include "Drive_Spaker.h"
#define CCP_S1 0x10 //P_SW1.4
#define CCP_S0 0x20 //P_SW1.5
#define LED_Port P25
extern unsigned short uartidex;//cmd字符计数器、cmd有效与否检测
extern unsigned short uartmax;
unsigned short timeridex = 0;
unsigned short timermax = 256;
xdata unsigned char buf[64] = { 0 };//每次1个字符作为控制命令
//注意系统时钟应该设置为33.000MHz
/*******************************************************************************************
函数说明:初始化io口并配置状态
参数:
输出:
*******************************************************************************************/
void DV_Spaker_Init()
{
ACC = P_SW1;
ACC &= ~(CCP_S0 | CCP_S1); //CCP_S0=0 CCP_S1=0
P_SW1 = ACC; //(P1.2/ECI, P1.1/CCP0, P1.0/CCP1, P3.7/CCP2)
// ACC = P_SW1;
// ACC &= ~(CCP_S0 | CCP_S1); //CCP_S0=1 CCP_S1=0
// ACC |= CCP_S0; //(P3.4/ECI_2, P3.5/CCP0_2, P3.6/CCP1_2, P3.7/CCP2_2)
// P_SW1 = ACC;
//45.35147微秒@33.000MHz
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x27; //设置定时初值
TH0 = 0xFA; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1;
CCON = 0; //初始化PCA控制寄存器
//PCA定时器停止
//清除CF标志
//清除模块中断标志
CL = 0; //复位PCA寄存器
CH = 0;
CMOD = 0x04; //设置PCA时钟源2分频//最终被调制频率为58,593.75
//允许PCA定时器溢出中断
PCA_PWM0 = 0x0A; //PCA模块0工作于8位PWM
CCAP0H = CCAP0L = 0x06; //PWM0的占空比为25% ((40H-30H)/40H)
CCAPM0 = 0x24; //PCA模块0为8位PWM模式
// PCA_PWM1 = 0x06; //PCA模块1工作于8位PWM
// CCAP1H = CCAP1L = 0x06; //PWM1的占空比为25% ((40H-30H)/40H)
// CCAPM1 = 0x24; //PCA模块1为8位PWM模式
CR = 1; //PCA定时器开始工作
EA = 1;
LED_Port = 0;
}
/*******************************************************************************************
函数说明:
参数:
输出:
*******************************************************************************************/
void Timer0() interrupt 1 using 1
{
if(timeridex < timermax)
CCAP0H = CCAP0L = buf[timeridex++];
//SBUF = buf[timeridex++];
else
CCAP0H = CCAP0L = 0;
}
/*******************************************************************************************
函数说明:
参数:
输出:
*******************************************************************************************/
void DV_Spaker_Service()
{
if((timeridex >= timermax) && (uartidex >= uartmax))
{
//交换缓冲区
if(timermax == 128){
timeridex = 128;
timermax = 0;
uartidex = 0;
uartmax = 128;
}
else{
timeridex = 0;
timermax = 128;
uartidex = 128;
uartmax = 0;
}
SBUF = 0X30;//通知上位机数据准备好了
}
}