#include<iom8v.h>
#include<macros.h>
#pragma interrupt_handler Time0_ov:iv_TIMER0_OVF
#pragma interrupt_handler Time1_capture:iv_TIMER1_CAPT
unsigned char flash declare[]={"This the PCM codec programa"};
unsigned char PCM_word,BCLK_cycle,Frame_flag;
#define TLED 0x80;
#define SPC_BCLK (1<<PB1)
#define SPC_FS (1<<PB3)
#define SPC_DT (1<<PC4)
#define SPC_RX (1<<PC3)
#define SPC_TX (1<<PC2)
#define SPC_CLK (1<<PC1)
#define SPC_EN (1<<PC0)
#define SPC_DR (1<<PD2)
unsigned char time,click;
void PORT_INIT(void)
{
DDRB|=1<<PB1|1<<PB2|1<<PB3; //置PB1,PB2,PB3为输出口
DDRC|=1<<PC0|1<<PC1|1<<PC3; //置 PC0,PC1,PC3为输出口
DDRD|=1<<PD1|1<<PD2|1<<PD7; //置PD1,PD2,PD7,为输出口
PORTB|=SPC_BCLK; //PC_BCLK置一
PORTC|=SPC_DT|SPC_RX|SPC_TX|SPC_CLK|SPC_EN; //MC145540SPC控制端置高电平
}
void Time_init(void)
{
TCCR0|=1<<CS02; //设置定时器0的时钟源,对系统时钟256分频
TCCR1A|=1<<COM1A0; //比较匹配时OC1A电平取反
TCCR1B|=1<<WGM12|1<<CS10|1<<ICES1; //设置定时器1波形产生模式(产生128KHZ),时钟源无分频,CTC模式
TCCR2|=1<<WGM21|1<<COM20|1<<CS21;//设置定时器0波形产生模式(产生8KHZ),时钟源32分频,CTC模式
OCR1A=57; //128KHz
OCR2=124; //8KHz
}
void Interrupt_init()
{
_SEI(); //打开全局中断
TIMSK|=1<<TOIE0|1<<TICIE1; //开定时器0溢出中断,定时器一捕获中断
}
void Time0_ov()
{
TCNT0=130; // 定时2MS
if(++time>250) //500MS
{
time=0;
click^=0xff;
PORTD^=TLED;
}
}
void USART_INIT(void)
{
UCSRB|=1<<TXEN; //全能串口发送
UBRRL=12; //波特率设置(76k)
UCSRC|=1<<URSEL|3<<UCSZ0; //8位数据,一位停止位
}
void Send_Char(unsigned char data)
{
unsigned char B_TXC;
while(!UCSRA&(1<<UDRE));//等侍发送器为空
UDR=data; //发送数据
/*do
B_TXC=UCSRA&(1<<TXC); //等侍数据发送完毕
while(!B_TXC);
UCSRA|=1<<TXC;*/
}
void Send_Byte_Codec(unsigned char data)
{
unsigned char i;
PORTC&=~SPC_CLK; //SPC_CLD拉低
PORTC&=~SPC_EN; //SPC_EN使能
for(i=0;i<8;i++) //发送一个字节
{
PORTC&=~SPC_CLK; //SPC_CLD拉低
if(data&0x80)
PORTC|=SPC_RX;
else
PORTC&=~SPC_RX;
data<<=1;
_NOP();
PORTC|=SPC_CLK;
_NOP();
_NOP();
}
PORTC|=SPC_EN;
}
unsigned char Read_Byte_Codec(void)
{
unsigned char data,i;
PORTC|=SPC_CLK; //SPC_CLD拉低
PORTC&=~SPC_EN; //SPC_EN使能
for(i=0;i<8;i++)//读取一个字节
{
PORTC|=SPC_CLK;
data<<=1;
_NOP();
PORTC&=~SPC_CLK;
_NOP();
_NOP();
if(PINC&SPC_TX)
data|=0x01;
else
data&=0xfe;
}
PORTC|=SPC_EN;
return(data);
}
void Codec_init(void)
{
Send_Byte_Codec(0x70);
Send_Byte_Codec(0xec); //BR0
Send_Byte_Codec(0x71);
Send_Byte_Codec(0x37); //BR1
Send_Byte_Codec(0x72);
Send_Byte_Codec(0xc3); //BR2
Send_Byte_Codec(0x73);
Send_Byte_Codec(0x20); //BR3
}
void Time1_capture(void)
{
unsigned char temp;
if(PINB&SPC_FS)
{
temp=PINC&SPC_DT;
PCM_word>>=1;
if(temp) //如果SPC_FST和SPC_BCLK同时为高电平,则读取一位数据
PCM_word|=0x80;
if(++BCLK_cycle>7) //连续读取八位数据
{
BCLK_cycle=0;
Frame_flag=1;
TIMSK&=~(1<<TICIE1);//输入捕获中断暂时关闭
//PORTB&=~SPC_FS;
}
}
}
void main(void)
{
unsigned char i;
PORT_INIT(); //端口初始化
Time_init(); //定时器初始化
Interrupt_init(); //中断初始化
USART_INIT(); //串口初始化
Codec_init(); //MC145540初始化
for(i=0;i<27;i++)
{
Send_Char(declare[i]);
}
PORTB|=SPC_FS;
while(1)
{
//if(click) PORTD|=0X80;
//else PORTD&=0X7F;
if(Frame_flag)
{
Frame_flag=0;
Send_Char(PCM_word);//将读回来的PCM语言编码数据发送给上位机
PCM_word=0;
//PORTB|=SPC_FS;
TIMSK|=1<<TICIE1; //发送发数据打开捕获中断
}
}
}