村网通总站 姬家寨村 455496.nync.com 欢迎您!
《姬家寨村数字功放机》
硬件电路设计:姬学瑞;软件程序编写:姬学瑞;版权所有,侵权必究!姬家寨村电子科技研究所研制!
《姬家寨村数字功放机》
硬件电路设计:姬学瑞;软件程序编写:姬学瑞;版权所有,侵权必究!姬家寨村电子科技研究所研制!
《01ADC》:
#include <reg52.h>
#include "intrins.h"
#include "delay.h"
#include "adc.h"
extern uchar Key_adc_data = 0 ;
/*******************************
Initial ADC sfr
**********************************************************************************************
P1M0[7 : 0] P1M1[7 : 0] I/O口模式(P1.x如果用作A/D使用,先要将其设置为开漏或高阻输入)
0 0 准双向口(传统8051 I/O口) ,灌电流可达20mA,拉电流为230uA。
0 1 推换输出(强上啦输出,可达20mA,要加上拉电阻,尽量少用)
1 0 仅为输入(高阻),如果该I/O口作为A/D使用,可选择此模式。
1 1 开漏(Open Drain),如果该I/O口作为A/D使用,可选择此模式。
**********************************************************************************************
********************************/
void InitADC()
{
P1M0 = 0x40; //Set all P16 高阻
P1M1 = 0x00;
ADC_DATA = 0; //Clear previous result
ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
Delay(2); //ADC power-on and delay
}
/*----------------------------
Get ADC result
----------------------------*/
void GetADCResult()
{
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | chs | ADC_START; //开ADC电源、选择最低速、选择P1.6输入、启动ADC转换。ADC_CONTR = 100x 1110
_nop_(); //Must wait before inquiry
_nop_();
_nop_();
_nop_();
while (!(ADC_CONTR & ADC_FLAG));//Wait complete flag ;
//ADC_FLAG = 0001 0000 ,如果没有转换完毕 ADC_CONTR = 1000 1110, ADC_CONTR & ADC_FLAG = 0000 0000;
// 如果转换完毕 ADC_CONTR = 1001 1110, ADC_CONTR & ADC_FLAG = 0001 0000;
ADC_CONTR &= ~ADC_FLAG; //Close ADC ,
// ~ADC_FLAG = 1110 1111;ADC_CONTR = 1001 1110 , ADC_CONTR & ~ADC_FLAG = 1000 1110; 将ADC_CONTR中的 ADC_FLAG位置零。
Key_adc_data = ADC_DATA; //Return ADC result
}
/*----------------------------
Software delay function
----------------------------*/
void Delay(WORD n)
{
WORD x;
while (n--)
{
x = 5000;
while (x--);
}
}
//void LED(unsigned char LedKey)
//{
// if(POWER_RELAY==1)
// {
// LED0=0;
// }
// else
// {
// LED0=1;
// delayms(2000);
// LED0=0;
// delayms(2000);
// }
//}
《02audio_ctl》:
/*
*********************************************************************************************************
*
* 模块名称 : 音频处理控制模块。
* 文件名称 : audio_ctl.c
* 版 本 :
* 说 明 : 音频处理控制主程序。
* 修改记录 :
* 版本号 日期 作者 说明
*
*********************************************************************************************************
*/
#include "audio_ctl.h"
#include "iic.h"
#include "main.h"
#include "led_display.h"
#include "eepromcz.h"
/* 按键代码 */
uchar tda7449Table[10];
extern uchar IR_key ;
extern uchar KeyCode ;
extern uchar display_factor = 0;
//display_factor = 0: 音量, = 1: 高音, = 2: 低音, = 3: ch1, = 4: ch2,
//display_factor = 5: mute off,= 6: mute on, = 7:立体声, = 8: 左声道,= 9: 右声道
extern uchar balan_R_value1 = 0;
extern uchar balan_L_value1 = 0;
extern uchar address; //芯片地址(这里是88H)
extern uchar sub_addr; //功能码(10H)
extern uchar in_select; //输入通道选择初始化,in_select = 3,选择 in1
extern uchar in_gain; //输入增益初始化,in_gain = 10,输入增益20dB
extern uchar volume_value; //音量初始化,volume_value = 25,音量-25dB
extern uchar not_use; //不用
extern uchar bass_value; //低音控制初始化,bass_value = 15, 低音0dB
extern uchar treble_value; //高音控制初始化,treble_value = 15, 低音0dB
extern uchar balan_R_value; //右声道增益初始化,balan_R_value = 0, 0dB
extern uchar balan_L_value; //左声道增益初始化,balan_L_value = 0, 0dB
extern uchar S_R_L_value; //0为立体声,1为左声道,2为右声道;
extern uchar balan_R_flag; //balan_R_flag = 0, 递减;balan_R_flag = 1递加;
extern uchar balan_L_flag; //balan_L_flag = 0, 递减;balan_L_flag = 1递加;
extern uchar mute_off_on; //mute_off_on = 0, 不静音;mute_off_on = 1静音;
extern uchar mute_buffer; //静音时,音量值暂存;
/*
eeprom_read();
address = tda7449Table[0];
sub_addr = tda7449Table[1];
in_select = tda7449Table[2];
in_gain = tda7449Table[3];
volume_value = tda7449Table[4];
not_use = tda7449Table[5];
bass_value = tda7449Table[6];
treble_value = tda7449Table[7];
balan_R_value = tda7449Table[8];
balan_L_value = tda7449Table[9];
balan_R_value1 = tda7449Table[8];
balan_L_value1 = tda7449Table[9];
tda7449_write();
*/
//**********************************************************************************************
//红外控制
//**********************************************************************************************
void IR_REM_control(void)
{
if (IR_key > 0)
{
switch ( IR_key )
{
case 1: /* 选择通道1 */
tda7449Table[2] = 3;
// eeprom_write();
tda7449_write();
IR_key = 0;
display_factor = 3;
break;
case 2: /*选择通道2 */
tda7449Table[2] = 2;
// eeprom_write();
tda7449_write();
IR_key = 0;
display_factor = 4;
break;
case 9: /* 音量加 */
volume_dec();
IR_key = 0;
display_factor = 0;
break;
case 10: /* 音量减 */
volume_inc();
IR_key = 0;
display_factor = 0;
break;
case 13: /* 低音减 */
bass_dec();
IR_key = 0;
display_factor = 2;
break;
case 14: /* 低音加 */
bass_inc();
IR_key = 0;
display_factor = 2;
break;
case 5: /* 高音减 */
treble_dec();
IR_key = 0;
display_factor = 1;
break;
case 6: /* 高音加 */
treble_inc();
IR_key = 0;
display_factor = 1;
break;
case 17: /* 右声道音量控制 */
balance_R();
IR_key = 0;
break;
case 18: /* 左声道音量控制 */
balance_L();
IR_key = 0;
break;
case 20: /* 立体声 */
tda7449Table[8] = balan_R_value;
tda7449Table[9] = balan_L_value;
// eeprom_write();
tda7449_write();
IR_key = 0;
display_factor = 7;
break;
case 21: /* 右声道 */
tda7449Table[8] = balan_R_value;
tda7449Table[9] = 120;
// eeprom_write();
tda7449_write();
IR_key = 0;
display_factor = 9;
break;
case 22: /* 左声道 */
tda7449Table[8] = 120;
tda7449Table[9] = balan_L_value;
// eeprom_write();
tda7449_write();
IR_key = 0;
display_factor = 8;
break;
case 24: /* 复位 */
reset();
IR_key = 0;
display_factor = 0;
break;
case 25: /* 静音关 */
tda7449Table[4] = volume_value;
// eeprom_write();
tda7449_write();
IR_key = 0;
display_factor = 5;
break;
case 26: /* 静音开 */
tda7449Table[4] = 56;
// eeprom_write();
tda7449_write();
IR_key = 0;
display_factor = 6;
break;
default:
break;
}
}
}
//display_factor = 0: 音量, = 1: 高音, = 2: 低音, = 3: ch1, = 4: ch2,
//display_factor = 5: mute off,= 6: mute on, = 7:立体声, = 8: 左声道,= 9: 右声道
//**********************************************************************************************
//键盘控制
// USER键 : PG8 (低电平表示按下)
// TAMPEER键 : PC13 (低电平表示按下)
// WKUP键 : PA0 (!!!高电平表示按下)
// 摇杆UP键 : PG15 (低电平表示按下)
// 摇杆DOWN键 : PD3 (低电平表示按下)
// 摇杆LEFT键 : PG14 (低电平表示按下)
// 摇杆RIGHT键: PG13 (低电平表示按下)
// 摇杆OK键 : PG7 (低电平表示按下)
//**********************************************************************************************
/*
void button_control(void)
{
if (KeyCode > 0)
{
switch (KeyCode)
{
case 1: // ch1/ch2切换
ch1_ch2_select();
KeyCode = 0;
break;
case 2: //音量/低音/高音等加
switch (display_factor)
{
case 0: // 音量加
volume_inc();
KeyCode = 0;
display_factor = 0;
break;
case 1: // 高音加
treble_inc();
KeyCode = 0;
display_factor = 1;
break;
case 2: // 低音加
bass_inc();
KeyCode = 0;
display_factor = 2;
break;
default:
break;
}
break;
case 3: //音量/低音/高音等减
switch (display_factor)
{
case 0: // 音量减
volume_dec();
KeyCode = 0;
display_factor = 0;
break;
case 1: // 高音减
treble_dec();
KeyCode = 0;
display_factor = 1;
break;
case 2: // 低音减
bass_dec();
KeyCode = 0;
display_factor = 2;
break;
default:
break;
}
break;
case 4: //音量/低音/高音等控制选择
if((display_factor > 2)&&(display_factor < 7)) display_factor = 0;
else if (display_factor > 8) display_factor = 0;
else if((display_factor > 0)&&(display_factor < 2)) display_factor++;
else if(display_factor == 0) display_factor++;
else if(display_factor == 2) display_factor = 7;
else if((display_factor > 6)&&(display_factor < 9)) display_factor++;
KeyCode = 0;
break;
case 5: //静音
mute();
KeyCode = 0;
break;
default:
break;
}
}
eeprom_write();
led_display();
}
*/
//display_factor = 0: 音量, = 1: 高音, = 2: 低音, = 3: ch1, = 4: ch2,
//display_factor = 5: mute off,= 6: mute on, = 7:立体声, = 8: 左声道,= 9: 右声道
void button_control(void)
{
if (KeyCode > 0)
{
switch (KeyCode)
{
case 1: /* 音量加 */
volume_inc();
KeyCode = 0;
display_factor = 0;
break;
case 2: /* 音量减 */
volume_dec();
KeyCode = 0;
display_factor = 0;
break;
case 3: /* 高音加 */
treble_inc();
KeyCode = 0;
display_factor = 1;
break;
case 4: /* 高音减 */
treble_dec();
KeyCode = 0;
display_factor = 1;
break;
case 5: /* 低音加 */
bass_inc();
KeyCode = 0;
display_factor = 2;
break;
case 6: /* 低音减 */
bass_dec();
KeyCode = 0;
display_factor = 2;
break;
case 7: /* 选择通道1 */
tda7449Table[2] = 3;
// eeprom_write();
tda7449_write();
KeyCode = 0;
display_factor = 3;
break;
case 8: /*选择通道2 */
tda7449Table[2] = 2;
// eeprom_write();
tda7449_write();
KeyCode = 0;
display_factor = 4;
break;
case 9: //静音
mute();
KeyCode = 0;
break;
default:
break;
}
eeprom_write();
led_display();
}
}
//**********************************************************************************************
//音量加
//tda7449Table[4] = volume_value
//**********************************************************************************************
void volume_inc(void)
{
if((volume_value > 0)&&(volume_value < 57))volume_value--;
// if(volume_value > 47)volume_value = 47;
// else if((volume_value > 0)&&(volume_value < 48))volume_value--;
else if(volume_value == 0)volume_value = 0;
tda7449Table[4] = volume_value;
// eeprom_write();
tda7449_write();
}
//**********************************************************************************************
// 音量加
//**********************************************************************************************
void volume_dec(void)
{
if(volume_value < 56)volume_value++;
// if(volume_value == 47)volume_value = 56;
// else if(volume_value < 47)volume_value++;
else if(volume_value > 56)volume_value = 56;
tda7449Table[4] = volume_value;
// eeprom_write();
tda7449_write();
}
//**********************************************************************************************
// 低音加
//tda7449Table[6] = bass_value
//**********************************************************************************************
void bass_inc(void)
{
if(bass_value < 7)bass_value++;
else if(bass_value == 7)bass_value = 15;
else if(bass_value > 8)bass_value--;
else if(bass_value == 8)bass_value = 8;
tda7449Table[6] = bass_value;
// eeprom_write();
tda7449_write();
}
//**********************************************************************************************
// 低音减
//tda7449Table[6] = bass_value
//**********************************************************************************************
void bass_dec(void)
{
if((bass_value > 0)&&(bass_value < 8))bass_value--;
else if(bass_value == 0)bass_value = 0;
else if((bass_value > 7)&&(bass_value < 15))bass_value++;
else if(bass_value == 15)bass_value = 7;
tda7449Table[6] = bass_value;
// eeprom_write();
tda7449_write();
}
//**********************************************************************************************
// 高音加
//tda7449Table[7] = treble_value
//**********************************************************************************************
void treble_inc(void)
{
if(treble_value < 7)treble_value++;
else if(treble_value == 7)treble_value = 15;
else if(treble_value > 8)treble_value--;
else if(treble_value == 8)treble_value = 8;
tda7449Table[7] = treble_value;
// eeprom_write();
tda7449_write();
}
//**********************************************************************************************
// 高音减
//tda7449Table[7] = treble_value
//**********************************************************************************************
void treble_dec(void)
{
if((treble_value > 0)&&(treble_value < 8))treble_value--;
else if((treble_value > 7)&&(treble_value < 15))treble_value++;
else if(treble_value == 15)treble_value = 7;
else if(treble_value == 0)treble_value = 0;
tda7449Table[7] = treble_value;
// eeprom_write();
tda7449_write();
}
//**********************************************************************************************
// 平衡加 balan_R_value = 0,
//tda7449Table[8] = balan_R_value
//balan_R_flag = 0, 递减;balan_R_flag = 1递加;
//**********************************************************************************************
void balance_R(void)
{
if(balan_R_flag == 0)
{
if(balan_R_value == 120){balan_R_value = 120; balan_R_flag = 1;}
else if(balan_R_value < 79)balan_R_value++;
else if(balan_R_value == 79){balan_R_value = 120; balan_R_flag = 1;}
}
else
{
if(balan_R_value == 120)balan_R_value = 79;
else if((balan_R_value > 0)&&(balan_L_value < 80))balan_R_value--;
else if(balan_R_value == 0){balan_L_value = 0; balan_R_flag = 0;}
}
tda7449Table[8] = balan_R_value;
// eeprom_write();
tda7449_write();
}
//**********************************************************************************************
// 平衡减
// tda7449Table[9] = balan_L_value;
//balan_L_flag = 0,递加 ;balan_L_flag = 1,递减;
//**********************************************************************************************
void balance_L(void)
{
if(balan_L_flag == 0)
{
if(balan_L_value == 120){balan_L_value = 120; balan_L_flag = 1;}
else if(balan_L_value < 79)balan_L_value++;
else if(balan_L_value == 79){balan_L_value = 120; balan_L_flag = 1;}
}
else
{
if(balan_L_value == 120)balan_L_value = 79;
else if((balan_L_value > 0)&&(balan_L_value < 80))balan_L_value--;
else if(balan_L_value == 0){balan_L_value = 0; balan_L_flag = 0;}
}
tda7449Table[9] = balan_L_value;
// eeprom_write();
tda7449_write();
}
//**********************************************************************************************
// 复位
//**********************************************************************************************
void reset(void)
{
display_factor = 0;
address = 0x88; //芯片地址(这里是88H)
sub_addr = 0x10; //功能码(10H)
in_select = 3; //输入通道选择初始化,in_select = 3,选择 in1
in_gain = 5; //输入增益初始化,in_gain = 10,输入增益20dB
volume_value = 20; //音量初始化,volume_value = 25,音量-25dB
not_use = 0; //不用
bass_value = 15; //低音控制初始化,bass_value = 15, 低音0dB
treble_value = 15; //高音控制初始化,treble_value = 15, 低音0dB
balan_R_value = 0; //右声道增益初始化,balan_R_value = 0, 0dB
balan_L_value = 0; //左声道增益初始化,balan_L_value = 0, 0dB
S_R_L_value = 0; //0为立体声,1为左声道,2为右声道;
tda7449Table[0] = address;
tda7449Table[1] = sub_addr;
tda7449Table[2] = in_select;
tda7449Table[3] = in_gain ;
tda7449Table[4] = volume_value;
tda7449Table[5] = not_use;
tda7449Table[6] = bass_value;
tda7449Table[7] = treble_value;
tda7449Table[8] = balan_R_value;
tda7449Table[9] = balan_L_value;
// eeprom_write();
tda7449_write();
}
//**********************************************************************************************
// 静音
// mute_off_on = 0, 不静音;mute_off_on = 1 静音;
//**********************************************************************************************
void mute(void)
{
if(mute_off_on == 0)
{
mute_buffer = volume_value;
volume_value = 56;
mute_off_on = 1;
display_factor = 6;
}
else
{
volume_value = mute_buffer;
mute_off_on = 0;
display_factor = 5;
}
tda7449Table[4] = volume_value;
volume_value = mute_buffer;
// eeprom_write();
tda7449_write();
}
//**********************************************************************************************
// 立体声/左声道/右声道切换
//**********************************************************************************************
void stereo_R_L(void)
{
if(S_R_L_value == 0)S_R_L_value = 1;
else if(S_R_L_value == 1)S_R_L_value = 2;
else if(S_R_L_value > 1)S_R_L_value = 0;
switch (S_R_L_value)
{
case 0:
balan_R_value1 = balan_R_value;
balan_L_value1 = balan_L_value;
break;
case 1:
balan_R_value1 = balan_R_value;
balan_L_value1 = 120 ;
break;
case 2:
balan_R_value1 = 120 ;
balan_L_value1 = balan_L_value;
break;
}
tda7449Table[8] = balan_R_value1;
tda7449Table[9] = balan_L_value1;
// eeprom_write();
tda7449_write();
}
//**********************************************************************************************
// 输入通道CH1/CH2切换
//**********************************************************************************************
void ch1_ch2_select(void)
{
if(in_select == 2)
{
in_select = 3;
display_factor = 3;
}
else
{
in_select = 2;
display_factor = 4;
}
tda7449Table[2] = in_select;
// eeprom_write();
tda7449_write();
}
//**********************************************************************************************
// DTA7449初始化
//**********************************************************************************************
void Init_DTA7449(void)
{
address = 0x88; //芯片地址(这里是88H)
sub_addr = 0x10; //功能码(10H)
in_select = 3; //输入通道选择初始化,in_select = 3,选择 in1
in_gain = 5; //输入增益初始化,in_gain = 10,输入增益20dB
volume_value = 20; //音量初始化,volume_value = 25,音量-25dB
not_use = 0; //不用
bass_value = 15; //低音控制初始化,bass_value = 15, 低音0dB
treble_value = 15; //高音控制初始化,treble_value = 15, 低音0dB
balan_R_value = 0; //右声道增益初始化,balan_R_value = 0, 0dB
balan_L_value = 0; //左声道增益初始化,balan_L_value = 0, 0dB
S_R_L_value = 0; //0为立体声,1为左声道,2为右声道;
mute_off_on = 0;
eeprom_read();
if(( in_select < 2)||(in_select > 3))in_select = 2;
if( volume_value > 56 ) volume_value = 20;
if( bass_value > 15 ) bass_value = 15;
if( treble_value > 15 )treble_value = 15;
if( mute_off_on > 0 )mute_off_on = 0;
tda7449Table[0] = address;
tda7449Table[1] = sub_addr;
tda7449Table[2] = in_select;
tda7449Table[3] = in_gain ;
tda7449Table[4] = volume_value;
tda7449Table[5] = not_use;
tda7449Table[6] = bass_value;
tda7449Table[7] = treble_value;
tda7449Table[8] = balan_R_value;
tda7449Table[9] = balan_L_value;
tda7449_write();
}
//**********************************************************************************************
// 对tda7449写数据, 将tda7449Table[10]中的10个数据写入tda7449
//**********************************************************************************************
void tda7449_write(void)
{
uchar j;
Start();
for (j = 0; j < 11; j++)
{
write_byte(tda7449Table[j]);
respons(); //应答
}
Stop();
}
//**********************************************************************************************
《03delay》:
#include "delay.h"
#include <INTRINS.H>
/**********************************************************
//us延时程序
***********************************************************/
void delay_nus(uint i)
{
while(i--);
}
/**********************************************************
//ms延时程序
***********************************************************/
void delay_nms(uint i)
{
for(i;i>0;i--)
{
delay_nus(1000);
}
}
/************************************************************
约1ms延时函数 (12MHZ)
*************************************************************/
void delayms(uint ms)
{
unsigned int i,j;
for(i=ms;i>0;i--)
for(j=111;j>0;j--);
}
/************************************************************
约1ms延时函数 (12MHZ)
*************************************************************/
void Delay1ms() //@12MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 12;
j = 168;
do
{
while (--j);
} while (--i);
}
/************************************************************
约10ms延时函数 (12MHZ)
*************************************************************/
void Delay10ms() //@12MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 117;
j = 183;
do
{
while (--j);
} while (--i);
}
/************************************************************
约200ms延时函数 (12MHZ)
*************************************************************/
void Delay200ms() //@12.000MHz
{
unsigned char i, j, k;
i = 10;
j = 31;
k = 147;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
/*************************************************************/
《04eepromcz》:
#include "eepromcz.h"
#include "audio_ctl.h"
extern uchar address; //芯片地址(这里是88H)
extern uchar sub_addr; //功能码(10H)
extern uchar in_select; //输入通道选择初始化,in_select = 3,选择 in1
extern uchar in_gain; //输入增益初始化,in_gain = 10,输入增益20dB
extern uchar volume_value; //音量初始化,volume_value = 25,音量-25dB
extern uchar not_use; //不用
extern uchar bass_value; //低音控制初始化,bass_value = 15, 低音0dB
extern uchar treble_value; //高音控制初始化,treble_value = 15, 低音0dB
extern uchar balan_R_value; //右声道增益初始化,balan_R_value = 0, 0dB
extern uchar balan_L_value; //左声道增益初始化,balan_L_value = 0, 0dB
extern uchar S_R_L_value; //0为立体声,1为左声道,2为右声道;
extern uchar balan_R_flag; //balan_R_flag = 0, 递减;balan_R_flag = 1递加;
extern uchar balan_L_flag; //balan_L_flag = 0, 递减;balan_L_flag = 1递加;
extern uchar mute_off_on; //mute_off_on = 0, 不静音;mute_off_on = 1静音;
extern uchar mute_buffer; //静音时,音量值暂存;
/******************************************************
注意了,要写数据时,一定要对该扇区先擦除后写数据的,所以要写
的数据尽量不要多,也可以对不同功能的数据存在不同的扇区里。
字节编程前,必须是其内容是FF,所以必须要通过扇区檫出
******************************************************/
/******************************************************
address = tda7449Table[0];
sub_addr = tda7449Table[1];
in_select = tda7449Table[2];
in_gain = tda7449Table[3];
volume_value = tda7449Table[4];
not_use = tda7449Table[5];
bass_value = tda7449Table[6];
treble_value = tda7449Table[7];
balan_R_value = tda7449Table[8];
balan_L_value = tda7449Table[9];
balan_R_value1 = tda7449Table[8];
balan_L_value1 = tda7449Table[9];
******************************************************/
/****************************
software delay function
****************************/
void EepromDelay(uchar n)
{
uint x;
uchar y;
for( y=0;y<n;y++)
for(x=0;x<100;x++);
}
/**************************************************
disable isp/iap/eeprom function
make MCU in a safe state
**************************************************/
void IapIdle()
{
IAP_CONTR=0; //CLOSE IAP FUNCTION
IAP_CMD=0; //CLEAR COMMAND TO STANDBY
IAP_TRIG=0; //CLEAR TRIGGER REGISTER
IAP_ADDRH=0X80; //DATA PTR POINT TO NON_EEPROM AREA
IAP_ADDRL=0; //CLEAR IAP ADDRESS TO PREVENT MISUSE
}
/*******************************************************
READ ONE BYTE FROM ISP/IAP/EEPROM EREA
INPUT: ADDR(ISP/ISP/EEPROM ADDRESS)
OUTPUT: FLASH DATA
*******************************************************/
uchar IapReadByte(uint addr)
{
uchar dat; //data buffer
IAP_CONTR=ENABLE_IAP; //OPEN IAP FUNCTION ,AND SET WAIT TIME
IAP_CMD=CMD_READ; //SET ISP/IAP/EEPROM READ COMMAND
IAP_ADDRL=addr; //set ISP/IAP/EEPROM ADDRESS LOW
IAP_ADDRH=addr>>8; //set ISP/IAP/EEPROM ADDRESS HIGH
IAP_TRIG=0X46; //SET TRIGGER COMMAND1 (0X46)
IAP_TRIG=0XB9; //SET TRIGGER COMMAND2(0XB9),送46和b9是触发命令
_nop_(); //MCU will hold here until ISP/IAP/EEPROM operation complete
dat=IAP_DATA; //READ ISP/IAP/EEPROM DATA
IapIdle(); //close ISP/IAP/EEPROM FUNTION
return dat; //return flash data
}
/*******************************************************
Program one byte to ISP/IAP/EEPROM area
INPUT: ADDR(ISP/ISP/EEPROM ADDRESS)
dat (ISP/ISP/EEPROM data)
OUTPUT: -
*******************************************************/
void IapProgramByte(uint addr,uchar dat)
{
IAP_CONTR=ENABLE_IAP; //OPEN IAP FUNCITON,AND SET WAIT TIME
IAP_CMD=CMD_PROGRAM; //SET ISP/IAP/EEPROM PROGRAM COMMAND
IAP_ADDRL=addr; //set ISP/IAP/EEPROM ADDRESS LOW
IAP_ADDRH=addr>>8; //set ISP/IAP/EEPROM ADDRESS HIGH
IAP_DATA=dat; //write ISP/IAP/EEPROM data
IAP_TRIG=0X46; // SEND trigger command1(0x46)
IAP_TRIG=0XB9; //SEND TRIGGER COMMAND2(0XB9)
_nop_();
IapIdle();
}
/*******************************************************
Erase one sector area
INPUT: ADDR(ISP/ISP/EEPROM ADDRESS)
OUTPUT: -
*******************************************************/
void IapEraseSector(uint addr)
{
IAP_CONTR=ENABLE_IAP; //OPEN IAP FUNCITON,AND SET WAIT TIME
IAP_CMD=CMD_ERASE; //SET ISP/IAP/EEPROM ERASE COMMAND
IAP_ADDRL=addr; //set ISP/IAP/EEPROM ADDRESS LOW
IAP_ADDRH=addr>>8; //set ISP/IAP/EEPROM ADDRESS HIGH
IAP_TRIG=0X46; // SEND trigger command1(0x46)
IAP_TRIG=0XB9; //SEND TRIGGER COMMAND2(0XB9)
_nop_();
IapIdle();
}
/****************************
****************************/
void eeprom_read()
{
in_select = IapReadByte(IAP_ADDRESS0);
volume_value = IapReadByte(IAP_ADDRESS1);
bass_value = IapReadByte(IAP_ADDRESS2);
treble_value = IapReadByte(IAP_ADDRESS3);
mute_off_on = IapReadByte(IAP_ADDRESS4);
}
/****************************
****************************/
void eeprom_write()
{
IapEraseSector(IAP_ADDRESS0);
IapProgramByte(IAP_ADDRESS0,in_select);//将数据写回到eeprom中去
IapEraseSector(IAP_ADDRESS1);
IapProgramByte(IAP_ADDRESS1,volume_value);//将数据写回到eeprom中去
IapEraseSector(IAP_ADDRESS2);
IapProgramByte(IAP_ADDRESS2,bass_value);//将数据写回到eeprom中去
IapEraseSector(IAP_ADDRESS3);
IapProgramByte(IAP_ADDRESS3,treble_value);//将数据写回到eeprom中去
IapEraseSector(IAP_ADDRESS4);
IapProgramByte(IAP_ADDRESS4,mute_off_on);//将数据写回到eeprom中去
}
《05i2c_bus》:
/*********************************************************************************
头文件及宏定义 ,tda7449的写数据可以是加总线,也可以是不加
加的总线只要写出首地址,自己会自动循环往下加;
不是加总线必须每次都要写从地址,这里我们用的就不是加总线
*********************************************************************************/
#include<reg51.h>
#include "iic.h"
#include "REG51.h"
//extern uint respons_fg;
sbit sda=P3^5;
sbit scl=P3^4;
/*********************************************************************************
US级延时程序,让IIC总线有反应时间
*********************************************************************************/
void delay2()
{
unsigned char i;
i = 3;
while (--i);
}
/********************************************************************************
开始信号,当scl为高电平的时候,sda出现下降沿
********************************************************************************/
void start() //开始信号
{
sda=1;
delay2();
scl=1;
delay2();
sda=0;
delay2();
scl=0;
delay2();
}
/*********************************************************************************
停止信号,当scl为高电平的时候,sda出现上升沿
*********************************************************************************/
void stop() //停止
{
sda=0;
delay2();
scl=1;
delay2();
sda=1;
delay2();
}
/*
*********************************************************************************************************
* 函 数 名: Ack
* 功能说明: CPU产生一个ACK信号
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void Ack(void)
{
sda=0; /* CPU驱动SDA = 0 */
delay2();
scl=1; /* CPU产生1个时钟 */
delay2();
scl=0;
delay2();
sda=1; /* CPU释放SDA总线 */
}
/*******************************************************************************
应答信号,当主机(单片机)发给从机(tda7449)一个高电平,在
scl为高电平时,如果sda总线被从机TDA7449拉低就是一个应答,说明
从机已经完成操作有空闲了。如果一直为高则等待,如果从机不给反应,
等待一段时间后也退出,并置SCL为低电平
********************************************************************************/
/*
void respons() //应答
{
uchar j,respons_fg;
sda=1;
delay2();
scl=1;
delay2();
while((sda==1)&&(j<200))j++;
if (sda == 1) // CPU读取SDA口线状态
{
respons_fg = 1;
}
else
{
respons_fg = 0;
}
scl=0;
delay2();
}
*/
void respons() //应答
{
uchar j;
sda=1;
delay2();
scl=1;
delay2();
while((sda==1)&&(j<200))j++;
scl=0;
delay2();
}
/*********************************************************************************
初始话总线,让sda和scl为高电平
*********************************************************************************/
void init()
{
sda=1;
delay2();
scl=1;
delay2();
}
/********************************************************* **************************
写字节函数,一个字节是8位,必须一位一位传到sda总线上,
通过左移一位,将最高位移到PSW寄存器的CY位,将Cy位在scl
为低电平时送到sda总线,因为只有scl为低电平时sda数据才可以
改变
*************************************************************************************/
void write_byte(uchar date)
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
scl=0;
delay2();
sda=CY;
delay2();
scl=1;
delay2();
}
scl=0;
delay2();
sda=1;
delay2();
}
/************************************************************************************
主机往从机某个地址写数据
格式是:开始信号,从机地址,应答,从机某个单元的地址,应答,数据,应答,停止
*************************************************************************************/
/*
void write_add(uchar address,uchar date)
{
start();
write_byte(0x88);
respons();
write_byte(address);
respons();
write_byte(date);
respons();
stop();
}
/***********************************************************************
读字节程序,这里tda7449只有写,没有读所以不用
读字节有个返回值
************************************************************************/
/***************************
uchar read_byte()
{
uchar i,k;
scl=0;
delay2();
sda=1;
delay2();
for(i=0;i<8;i++)
{
scl=1;
delay2();
k=(k<<1)|sda;
scl=0;
delay2();
}
return k;
}
*****************************/
/***********************************************************************
延时程序这里没用
************************************************************************/
/***************************
void delay1(uchar x)
{
uchar a,b;
for(a=x;a>0;a--)
for(b=100;b>0;b--);
}
*****************************/
/***********************************************************************
将从机某个地址的数据读出来
tda7449这里没用到
************************************************************************/
/*******************************************
uchar read_add(uchar address)
{
uchar date;
start();
write_byte(0x88);
respons();
write_byte(address);
respons();
start();
write_byte(0x88);
respons();
date=read_byte();
stop();
return date;
}
*******************************************/
《06IR_REM_DECOD》:
/**************************************************************************************************
文件名:IR_REM_DECOD.c
作者:
版本:V1.0
描述:
**************************************************************************************************/
#include "IR_REM_DECOD.h"
#include <reg52.h>
#include "delay.h"
#include "audio_ctl.h"
#include "main.h"
#include "led_display.h"
extern uchar IR_key;
uchar RXDDATA[4]={0x00,0x00,0x00,0x00}; //存放接收到的四组红外编码
sbit IR_GET = P3^2; //红外接收数据输入端
/************************************************************
外部中断0服务函数
原理:红外遥控发射芯片采用PPM编码方式,当发射器按键按下后,将发射一组108ms的编码脉冲。
遥控编码脉冲由前导码、8位用户码、8位用户码的反码、8位操作码以及8位操作码的反码组成。
通过对用户码的检验,每个遥控器只能控制一个设备动作,这样可以有效地防止多个设备之间
的干扰。编码后面还要有编码的反码,用来检验编码接收的正确性,防止误操作,增强系统的
可靠性。前导码是一个遥控码的起始部分,由一个9ms的低电平(起始码)和一个4. 5ms的高电平
(结果码)组成,作为接受数据的准备脉冲。
---- -----------------------
| | |
| | |
| | |
---------------------------------------------- -----
|----------------------------------------------|-----------------------|
9ms 4.5ms
以脉宽为0. 56ms、周期为1. 12ms的组合表示二进制的"0";
---- -----
| | |
| | |
| | |
----- -----
|-----|-----|
0.56ms 0.56ms
以脉宽为1. 68ms、周期为2. 24ms的组合表示二进制的"1"。
---- -----------------
| | |
| | |
| | |
----- -----
|-----|-----------------|
0.56ms 1.68ms
如果按键按下超过108ms仍未松开,接下来发射的代码(连发代码)
将仅由起始码(9ms)和结束码(2. 5ms)组成。
---- ---------- ------//----------
| | | | |
| | | | |
| | | | |
---------------------------------------------- - |
|----------------------------------------------|----------|-| -----
9ms 2.5ms 0.56ms
|------------------------------------------------------------------------------|
108ms
单片机采用外部中断INTI管脚和红外接收头的信号线相连,中断方式为边沿触发方式。并用定时器0计算
中断的间隔时间,来区分前导码、二进制的"1"、"0"码。并将8位操作码提取出来在数码管上显示。
*************************************************************/
void IR_REM_DECOD() //下降沿触发:接收不到红外时OUT高电平,接收到红外时OUT低电平。
{
uchar four,one,num=0;
uchar tempdata=0;
IR_key = 0;
EX0 = 0; //关中断0使能,防止处理过程中再接收红外信号
delayms(2); //稍延时2ms,防干扰
if (IR_GET) //再检测红外接收脚(9ms的前导低电平),为高电平说明是干扰
{
EX0 =1; //使能中断0
return; //退出中断程序
}
while(!IR_GET); //等IR变为高电平,跳过9ms的前导低电平信号。
while (IR_GET); //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
for (four=0;four<4;four++) //四组数据
{
for (one=0;one<8;one++) //每组数据8位
{
//temp = 2000;
// while( (IR_GET==0 ) && (temp!=0) )// temp--需2.2us, temp=460可实现1ms延时
// {temp--;} //0和1低电平时间都一样,所以关键是判断高电平的时间,这里如果为低电平且满足1ms时间,就等待,为高了,就执行下条语句
while(!IR_GET); //等IR变为高电平,跳过低电平信号。
Delay1ms();
if((IR_GET==1 ) ) // 检测到高电平1的话说明该位为1,延时1毫秒等待脉冲高电平结束
{
tempdata |= (1<<one); // dataH= ~data dataL= data
Delay1ms();
}
else tempdata &= ~(1<<one); // 检测到低电平0的话,说明该位为0,继续检测下一位
}//全部四组数据接收结束
RXDDATA[four]=tempdata;
}
if (RXDDATA[2]!=~RXDDATA[3]) //检测接收到的数据是否正确
{ //不正确则
EX0=1; //使能中断0
// IRKey=VOLP_KEY_DOWN;
// KeyMessageProc(IRKey);
return; //退出中断
}
else //如果接收正确
{
IR_key = RXDDATA[2];
IR_REM_control();
eeprom_write();
led_display();
}
EX0 = 1; //处理完红外接收,使能中断0,退出中断0
}
《07KeyScan》:
#include "KeyScan.h"
#include "adc.h"
uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff}; //共阳极LED段码0~9,全灭;
extern uchar KeyCode ;
extern uchar Key_adc_data ;
/*******************************************************************************
函数名: KeyScan
描述: 按键扫描程序
输入:
输出: KeyCode
返回: 无
sbit CH1_CH2_KEY = P1^6;
sbit VOL_INC_KEY = P1^5;
sbit VOL_DEC_KEY = P1^4;
sbit SEL_KEY = P1^3;
sbit MUTE_KEY = P1^2;
*******************************************************************************/
/*
void KeyScan(void)
{
CH1_CH2_KEY = 1;
VOL_INC_KEY = 1;
VOL_DEC_KEY = 1;
SEL_KEY = 1;
MUTE_KEY = 1;
if(CH1_CH2_KEY == 0)
{
Delay10ms();
if(CH1_CH2_KEY == 0)
{
KeyCode = 1;
}
}
else if(VOL_INC_KEY == 0)
{
Delay10ms();
if(VOL_INC_KEY == 0)
{
KeyCode = 2;
}
}
else if(VOL_DEC_KEY == 0)
{
Delay10ms();
if(VOL_DEC_KEY == 0)
{
KeyCode = 3;
}
}
else if(SEL_KEY == 0)
{
Delay10ms();
if(SEL_KEY == 0)
{
KeyCode = 4;
}
}
else if(MUTE_KEY == 0)
{
Delay10ms();
if(MUTE_KEY == 0)
{
KeyCode = 5;
}
}
}
*/
void KeyScan(void)
{
InitADC();
GetADCResult();
if( Key_adc_data <12 )
{
delayms(10);
if( Key_adc_data < 12 ) KeyCode = 1; //音量加
}
else if( 12 < Key_adc_data && Key_adc_data < 35 )
{
delayms(10);
if( 12 < Key_adc_data && Key_adc_data < 35 )KeyCode = 2; //音量减;
}
else if( 36 < Key_adc_data && Key_adc_data < 65 )
{
delayms(10);
if( 36 < Key_adc_data && Key_adc_data < 65 )KeyCode = 3; //高音加;
}
else if( 66 < Key_adc_data && Key_adc_data < 91 )
{
delayms(10);
if( 66 < Key_adc_data && Key_adc_data < 91 )KeyCode = 4; //高音减;
}
else if( 92 < Key_adc_data && Key_adc_data < 117 )
{
delayms(10);
if( 92 < Key_adc_data && Key_adc_data < 117 )KeyCode = 5; //低音加;
}
else if( 118 < Key_adc_data && Key_adc_data < 143 )
{
delayms(10);
if( 118 < Key_adc_data && Key_adc_data < 143 )KeyCode = 6; //低音减;
}
else if( 144 < Key_adc_data && Key_adc_data < 164 )
{
delayms(10);
if( 144 < Key_adc_data && Key_adc_data < 164 )KeyCode = 7; //CH1;
}
else if( 165 < Key_adc_data && Key_adc_data < 194 )
{
delayms(10);
if( 165 < Key_adc_data && Key_adc_data < 194 )KeyCode = 8; ///CH2;
}
else if( 195 < Key_adc_data && Key_adc_data < 220 )
{
delayms(10);
if( 195 < Key_adc_data && Key_adc_data < 220 )KeyCode = 9; //MUTE;
}
else if( Key_adc_data > 221 )
{
delayms(10);
if( Key_adc_data < 221 ) KeyCode = 0; //没有键按下;
}
}
《08led_display》:
/**************************************************************************************************
头文件
**************************************************************************************************/
#include "led_display.h"
/**************************************************************************************************
LED段码,h,g,f,e ,d,c,b,a排列
**************************************************************************************************/
uchar code tab1[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff}; //共阳极LED段码0~9,全灭;
extern uchar display_factor ;
//display_factor = 0: 音量, = 1: 高音, = 2: 低音, = 3: ch1, = 4: ch2,
//display_factor = 5: mute off,= 6: mute on, = 7:立体声, = 8: 左声道,= 9: 右声道
extern uchar address; //芯片地址(这里是88H)
extern uchar sub_addr; //功能码(10H)
extern uchar in_select; //输入通道选择初始化,in_select = 3,选择 in1
extern uchar in_gain; //输入增益初始化,in_gain = 10,输入增益20dB
extern uchar volume_value; //音量初始化,volume_value = 25,音量-25dB
extern uchar not_use; //不用
extern uchar bass_value; //低音控制初始化,bass_value = 15, 低音0dB
extern uchar treble_value; //高音控制初始化,treble_value = 15, 低音0dB
extern uchar balan_R_value; //右声道增益初始化,balan_R_value = 0, 0dB
extern uchar balan_L_value; //左声道增益初始化,balan_L_value = 0, 0dB
extern uchar S_R_L_value; //0为立体声,1为左声道,2为右声道;
extern uchar balan_R_flag; //balan_R_flag = 0, 递减;balan_R_flag = 1递加;
extern uchar balan_L_flag; //balan_L_flag = 0, 递减;balan_L_flag = 1递加;
extern uchar mute_off_on; //mute_off_on = 0, 不静音;mute_off_on = 1静音;
extern uchar mute_buffer; //静音时,音量值暂存;
/**************************************************************************************************
**************************************************************************************************/
void led_display(void)
{
uchar display[5];
uchar Di,Dj;
switch ( display_factor )
{
case 0: /* 选择音量控制 */
display[2]=0xc7; //L的七段码
display[3]=0xc0; //O的七段码
display[4]=0xc1; //U的七段码
negative = 0;
if(volume_value > 0)negative = 1;
Di = volume_value; //
display[0]= Di%10; //
display[1]= Di/10;
display[0]= tab1[display[0]]; //查出七段码
if(display[1] == 0)
{
display[1]= 0xff;
}
else
{
display[1]= tab1[display[1]]; //查出七段码
}
DisplayProc(display[0],display[1],display[2],display[3],display[4] ) ;
break;
case 1: /*选择高音控制 */
display[2]=0x86; //E的七段码
display[3]=0x88; //R的七段码
display[4]=0x87; //t的七段码
Di = treble_value; //
Dj = treble_value; //
negative = 0;
// if((Dj < 8)&&(Dj > 0)){Di = (14 - Di*2);negative = 1;}
// else if(Dj == 0){Di = 14 ;negative = 1;}
// else if((Dj > 7)&&(Dj < 16)) Di =((15 - Di)*2 );
// else if(Dj == 15)Di = 0;
if(Dj == 0){Di = 14 ;negative = 1;}
else if((Dj < 7)&&(Dj > 0)){Di = (14 - Di*2);negative = 1;}
else if(Dj == 7)Di = 0;
else if((Dj > 7)&&(Dj < 15)) Di =((15 - Di)*2 );
else if(Dj == 15)Di = 0;
display[0]= Di%10; //
display[1]= Di/10;
display[0]= tab1[display[0]]; //查出七段码
if(display[1] == 0)
{
display[1]= 0xff;
}
else
{
display[1]= tab1[display[1]]; //查出七段码
}
DisplayProc(display[0],display[1],display[2],display[3],display[4] ) ;
break;
case 2: /*选择低音控制 */
display[2]=0x92; //S的七段码
display[3]=0x88; //A的七段码
display[4]=0x80; //B的七段码
Di = bass_value; //
Dj = bass_value; //
negative = 0;
// if((Dj < 8)&&(Dj > 0)){Di = (14 - Di*2);negative = 1;}
// else if(Dj == 0){Di = 14 ;negative = 1;}
// else if((Dj > 7)&&(Dj < 16)) Di =((15 - Di)*2 );
// else if(Dj == 15)Di = 0;
if(Dj == 0){Di = 14 ;negative = 1;}
else if((Dj < 7)&&(Dj > 0)){Di = (14 - Di*2);negative = 1;}
else if(Dj == 7)Di = 0;
else if((Dj > 7)&&(Dj < 15)) Di =((15 - Di)*2 );
else if(Dj == 15)Di = 0;
display[0]= Di%10; //
display[1]= Di/10;
display[0]= tab1[display[0]]; //查出七段码
if(display[1] == 0)
{
display[1]= 0xff;
}
else
{
display[1]= tab1[display[1]]; //查出七段码
}
DisplayProc(display[0],display[1],display[2],display[3],display[4] ) ;
break;
case 3: /*选择通道1 */
display[2]=0xf9; //1的七段码
display[3]=0x89; //H的七段码
display[4]=0xc6; //C的七段码
Di = volume_value; //
display[0]= Di%10; //
display[1]= Di/10;
display[0]= tab1[display[0]]; //查出七段码
if(display[1] == 0)
{
display[1]= 0xff;
}
else
{
display[1]= tab1[display[1]]; //查出七段码
}
DisplayProc(display[0],display[1],display[2],display[3],display[4] ) ;
break;
case 4: /*选择通道2 */
display[2]=0xa4; //2的七段码
display[3]=0x89; //H的七段码
display[4]=0xc6; //C的七段码
Di = volume_value; //
display[0]= Di%10; //
display[1]= Di/10;
display[0]= tab1[display[0]]; //查出七段码
if(display[1] == 0)
{
display[1]= 0xff;
}
else
{
display[1]= tab1[display[1]]; //查出七段码
}
DisplayProc(display[0],display[1],display[2],display[3],display[4] ) ;
break;
case 5: /*选择静音关 */
display[2]=0xc7; //L的七段码
display[3]=0xc0; //O的七段码
display[4]=0xc1; //U的七段码
negative = 1;
Di = volume_value; //
display[0]= Di%10; //
display[1]= Di/10;
display[0]= tab1[display[0]]; //查出七段码
if(display[1] == 0)
{
display[1]= 0xff;
}
else
{
display[1]= tab1[display[1]]; //查出七段码
}
DisplayProc(display[0],display[1],display[2],display[3],display[4] ) ;
break;
case 6: /*选择静音开 */
display[0]=0xc0; //0的七段码
display[1]=0xc0; //0的七段码
display[2]=0xc0; //0的七段码
display[3]=0xc0; //0的七段码
display[4]=0xc0; //0的七段码
negative = 0;
DisplayProc(display[0],display[1],display[2],display[3],display[4] ) ;
break;
case 7: /*选择立体声 */
display[2]=0x88; //R的七段码
display[3]=0xbf; //—的七段码
display[4]=0xc7; //L的七段码
Di = volume_value; //
display[0]= Di%10; //
display[1]= Di/10;
display[0]= tab1[display[0]]; //查出七段码
if(display[1] == 0)
{
display[1]= 0xff;
}
else
{
display[1]= tab1[display[1]]; //查出七段码
}
DisplayProc(display[0],display[1],display[2],display[3],display[4] ) ;
break;
case 8: /*选择左声道 */
display[2]=0xff; //灭的七段码
display[3]=0xbf; //—的七段码
display[4]=0xc7; //L的七段码
Di = volume_value; //
display[0]= Di%10; //
display[1]= Di/10;
display[0]= tab1[display[0]]; //查出七段码
if(display[1] == 0)
{
display[1]= 0xff;
}
else
{
display[1]= tab1[display[1]]; //查出七段码
}
DisplayProc(display[0],display[1],display[2],display[3],display[4] ) ;
break;
case 9: /*选择右声道 */
display[2]=0x88; //R的七段码
display[3]=0xbf; //—的七段码
display[4]=0xff; //灭的七段码
Di = volume_value; //
display[0]= Di%10; //
display[1]= Di/10;
display[0]= tab1[display[0]]; //查出七段码
if(display[1] == 0)
{
display[1]= 0xff;
}
else
{
display[1]= tab1[display[1]]; //查出七段码
}
DisplayProc(display[0],display[1],display[2],display[3],display[4] ) ;
break;
default:
break;
}
}
/**************************************************************************************************
164移位操作,每次完成一个字节的传送
Reset Clock A1 A2 QA QB ... QH
H 上升沿 H D D QAn ... QGn
**************************************************************************************************/
void sendbyte(uchar seg)
{
uchar num,count;
num=seg;
for(count=0;count<8;count++)
{
dat_164=num&0x80; //将最高位移到164的数据位,第一次移出的位在h,二次在g,以此类推
num=_crol_(num,1); //循环左移,将低位逐位移到最高位上,需加入<intrins.h>相当于 num=num<<1
clk_164=0; //产生上升沿
delay_nus(2); //us级延时
clk_164=1;
}
}
/**************************************************************************************************
**************************************************************************************************/
void DisplayClear(void)
{
uchar DisplayBuffer[5];
uchar i;
for(i=0;i<5;i++)
{
DisplayBuffer[i]=0xff;
}
sendbyte(DisplayBuffer[0]) ; // sent low value
delay_nus(2); //us级延时
sendbyte(DisplayBuffer[1]) ; // sent low value
delay_nus(2); //us级延时
sendbyte(DisplayBuffer[2]) ; // sent low value
delay_nus(2); //us级延时
sendbyte(DisplayBuffer[3]) ; // sent low value
delay_nus(2); //us级延时
sendbyte(DisplayBuffer[4]) ; // sent low value
delay_nus(2); //us级延时
}
/**************************************************************************************************
**************************************************************************************************/
void DisplayZero(void)
{
uchar DisplayBuffer[5];
uchar i;
for(i=0;i<5;i++)
{
DisplayBuffer[i]=0xc0;
}
sendbyte(DisplayBuffer[0]) ; // sent low value
delay_nus(2); //us级延时
sendbyte(DisplayBuffer[1]) ; // sent low value
delay_nus(2); //us级延时
sendbyte(DisplayBuffer[2]) ; // sent low value
delay_nus(2); //us级延时
sendbyte(DisplayBuffer[3]) ; // sent low value
delay_nus(2); //us级延时
sendbyte(DisplayBuffer[4]) ; // sent low value
delay_nus(2); //us级延时
}
/**************************************************************************************************
**************************************************************************************************/
void DisplayProc(uchar diaplay0,uchar diaplay1,uchar diaplay2,uchar diaplay3,uchar diaplay4 )
{
sendbyte(diaplay0) ;
sendbyte(diaplay1) ;
sendbyte(diaplay2) ;
sendbyte(diaplay3) ;
sendbyte(diaplay4) ;
}
/************************************************************************************************
机器读eeprom初始化,初始化数字电位器电位器,power,sel开关,初始化显示
************************************************************************************************/
void DisReadEepromInit(void)
{
uchar VOL_NUM1, SEL_NUM1;
uchar display1[5];
VOL_NUM1=IapReadByte(IAP_ADDRESS1); // 读出eeprom数据
SEL_NUM1=IapReadByte(IAP_ADDRESS2);
if( SEL_NUM1==0x02) //usb数字音源, 显示usb 两位音量数字
{
//数字处理,两位
VOL_NUM1=VOL_NUM1/4; //数字电位器00-255,显示成音量00-64,所以要除以4
display1[0]= VOL_NUM1%10; //最右边数码管 ,显s数字最低位,示数字代码 ,取模 送给低位
display1[1]= VOL_NUM1/10;
display1[0]= tab1[display1[0]]; //查出七段码
display1[1]= tab1[display1[1]]; //查出七段码
//字母显示,有两种,一种是模拟音源,显示cd,一种是数字音源,显示USB
display1[2]=0x83; //b 的七段码
display1[3]=0x92; //s 的七段码
display1[4]=0xc1; //最左边数码管 ,显示字母代码 ,u的七段码
DisplayProc(display1[0],display1[1],display1[2],display1[3],display1[4] ) ;
SEL_NUM1=0x02;
IapEraseSector(IAP_ADDRESS2);
IapProgramByte(IAP_ADDRESS2,SEL_NUM1);//将数据写回到eeprom中去
}
else //模拟音源显示CD
{
VOL_NUM1=VOL_NUM1/4; //数字电位器00-255,显示成音量00-32,所以要除以8
display1[0]= VOL_NUM1%10; //最右边数码管 ,显s数字最低位,示数字代码 ,取模 送给低位
display1[1]= VOL_NUM1/10;
display1[0]= tab1[display1[0]]; //查出七段码
display1[1]= tab1[display1[1]]; //查出七段码
display1[2]=0xff;
display1[3]=0xa1;
display1[4]=0xc6; //最左边数码管 ,显示字母代码c
DisplayProc(display1[0],display1[1],display1[2],display1[3],display1[4] ) ;
SEL_NUM1=0x01;
IapEraseSector(IAP_ADDRESS2);
IapProgramByte(IAP_ADDRESS2,SEL_NUM1);//将数据写回到eeprom中去
}
}
《09main》:
/**************************************************************************************************
文件名:main.c
作者:
版本:V1.0
日期:2
描述:
**************************************************************************************************/
#include <reg52.h>
#include "main.h"
#include "led_display.h"
#include "eepromcz.h"
#include "KeyScan.h"
#include "delay.h"
#include "audio_ctl.h"
#include "IR_REM_DECOD.h"
//#define FOSC 1200000
#define FOSC 1105920
#define TimerCount (65536-FOSC/12/4000) //4s=1us*4000定时,采用 timer calculation in 12T mode
extern uchar IR_key = 0;
extern uchar KeyCode = 0 ;
sbit IR_GET = P3^2; //红外接收数据输入端
extern uchar address = 0x88; //芯片地址(这里是88H)
extern uchar sub_addr = 0x10; //功能码(10H)
extern uchar in_select = 3; //输入通道选择初始化,in_select = 3,选择 in1
extern uchar in_gain = 10; //输入增益初始化,in_gain = 10,输入增益20dB
extern uchar volume_value = 25; //音量初始化,volume_value = 25,音量-25dB
extern uchar not_use = 0; //不用
extern uchar bass_value = 15; //低音控制初始化,bass_value = 15, 低音0dB
extern uchar treble_value = 15; //高音控制初始化,treble_value = 15, 低音0dB
extern uchar balan_R_value = 0; //右声道增益初始化,balan_R_value = 0, 0dB
extern uchar balan_L_value = 0; //左声道增益初始化,balan_L_value = 0, 0dB
extern uchar S_R_L_value = 0; //0为立体声,1为左声道,2为右声道;
extern uchar balan_R_flag = 0; //balan_R_flag = 0, 递减;balan_R_flag = 1递加;
extern uchar balan_L_flag = 0; //balan_L_flag = 0, 递减;balan_L_flag = 1递加;
extern uchar mute_off_on = 0; //mute_off_on = 0, 不静音;mute_off_on = 1静音;
extern uchar mute_buffer = 0; //静音时,音量值暂存;
/************************************************************************************************
主函数,注意主函数只有一个
第一次读eeprom的值,如果连续几个单元的内容相等,则进行初始化设置,否则从eeprom读出来赋值
************************************************************************************************/
void main()
{
init_machine(); //LED显示初始化
init_timer0(); //定时器0初始化
Init_DTA7449(); //DTA7449初始化
led_display();
while(1)
{
KeyCode = 0;
KeyScan();
if(KeyCode > 0)
{
button_control();
Delay200ms(); //@12.000MHz
}
if(IR_GET == 0)IR_REM_DECOD();
}
}
/************************************************************************************************
定时初始化 定时5毫秒
************************************************************************************************/
void init_timer0(void)
{
TMOD=0X01;//SET TIMER0 AS MODE1(16BITS)
TL0=TimerCount; //initial time0 low byte,只取TimerCount的低8位
TH0=TimerCount>>8; //initial time0 hight byte,右移8位把高8位移到低8位送给TH0
ET0=1; //enable timer0 interrupt
EA=1; //enable global interrupt swtich
// count=2; //initial count
TR0=1;
}
/************************************************************************************************
************************************************************************************************/
void init_machine(void)
{
// uchar display[5];
// uchar DI;
// uchar code tab1[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff}; //共阳极LED段码0~9,全灭;
DisplayClear();
Delay10ms(); //@12MHz
/************************************************************************************************
显示,共5位,UOL(音量)/BAS(低音)/TER(高音)/CH1(通道1)/CH2(通道2),音量大小(00-31)dB
显示先送数字,再送字母代码
************************************************************************************************/
// display[0]=0xc0;//0x92; // 5的七段码 ,因为最大音量显示32,现在15刚好一半
// display[1]=0xf9; // 1的七段码
// DI = volume_value; //数字电位器00-255,显示成音量00-64,所以要除以4
// display[0]= DI%10; //最右边数码管 ,显s数字最低位,示数字代码 ,取模 送给低位
// display[1]= DI/10;
// display[0]= tab1[display[0]]; //查出七段码
// display[1]= tab1[display[1]]; //查出七段码
// display[2]=0x86; //E的七段码
// display[3]=0x88; //R的七段码
// display[4]=0xce; //T的七段码
// display[2]=0x92; //S的七段码
// display[3]=0x88; //A的七段码
// display[4]=0x80; //B的七段码
// display[2]=0xc7; //L的七段码
// display[3]=0xc0; //O的七段码
// display[4]=0xc1; //U的七段码
// DisplayProc(display[0],display[1],display[2],display[3],display[4] ) ;
// IapEraseSector(IAP_ADDRESS1);
// IapEraseSector(IAP_ADDRESS1);
// IapEraseSector(IAP_ADDRESS2);
// IapEraseSector(IAP_ADDRESS3);
// IapEraseSector(IAP_ADDRESS4);
// IapProgramByte(IAP_ADDRESS1,VOL_NUM);
// IapProgramByte(IAP_ADDRESS4,VOL_NUM);
// IapProgramByte(IAP_ADDRESS1,MUTE_NUM);//将数据写回到eeprom中去
// IapProgramByte(IAP_ADDRESS2,SEL_NUM);
// IapProgramByte(IAP_ADDRESS3,POWER_NUM);
}
《10max5389》:
#include "max5389.h"
/**********************************************************
//数字电位器初始化,先调到最小,然后再调整到中间位置
***********************************************************/
void init_max5389()
{
dec_max5389(255); // 先调到最小
inc_max5389(127); // 再调整到中间位置
}
/**********************************************************
//数字电位器num表示要调步数,256个抽头,相当于255步
//ud为高,cs为低,inc来个下降沿进行上调步数工作
***********************************************************/
void inc_max5389(uchar num)
{
max5389_cs =0;
max5389_ud=1; // UD拉高,实行上调步数操作
delay_nus(3); //延时3us
for(num;num>0;num--)
{
max5389_inc=1;
delay_nus(200);
max5389_inc=0; //inc产生负跳变
delay_nus(200);
}
}
/**********************************************************
//数字电位器num表示要调步数,256个抽头,相当于255步
//ud为低,cs为低,inc来个下降沿进行下调步数工作
***********************************************************/
void dec_max5389(uchar num)
{
max5389_cs =0;
max5389_ud=0; // UD拉低,实行下调步数操作
delay_nus(3); //延时3us
for(num;num>0;num--)
{
max5389_inc=1;
delay_nus(200);
max5389_inc=0; //inc产生负跳变
delay_nus(200);
}
}
/*
void set_max5389(uchar num,uchar ud,uchar save)
// num移动的步数,ud增加减少选择,save保存选择
{
max5389_cs =0;
if(ud==1)
{
max5389_ud=1;
}
else
{
max5389_ud=0;
}
delay_nus(10) ;
for(num;num>0;num--)
{
max5389_inc=1;
delay_nus(5) ;
max5389_inc=0; //inc产生负跳变
delay_nms(1) ;
}
delay_nus(10) ;
if(save==1)
{
max5389_inc=1;
}
delay_nus(10) ;
max5389_cs =1;
}
*/
《姬家寨村数字功放机》
硬件电路设计:姬学瑞;软件程序编写:姬学瑞;版权所有,侵权必究!姬家寨村电子科技研究所研制!