📄 my_2000-0618.c
字号:
#include "c8051f340.h"
sbit SLEEP_2K=P1^1; //出
sbit RST_2K=P1^0; //出
sbit CHAN_RXD=P0^1;//出
sbit CHAN_TXD=P0^2;// 入
sbit EPR_2K=P0^3;//入
sbit CHAN_R_STRB=P0^4;//出
sbit CHAN_S_STRB=P0^5; // 出
sbit CHAN_CLK=P0^0; //出
sbit COMM_RTS = P2^3; // 出
sbit COMM_DSR = P2^6; //入
sbit COMM_CTS = P2^7; //入
sbit COMM_DTR = P2^4; //出
sbit COMM_TXD = P2^2; //出
sbit COMM_RXD = P2^5; //入
sbit KEY_RESET=P2^0; //入
sbit LINK_INTP=P2^1; //入
sbit CODEC_SCLK = P1^7; //入
sbit CODEC_DCSI = P1^6; //出
sbit ceshi=P3^5;
//#define Max_buff_num 10 //定义最大发送数 给CPLD
#define COMMSENDPACKETLEN 9 //包头加64 BIT CPU 给CPLD的数据结构
#define COMMPACKETHEADER 0x9c //包头为 9C
#define CLOCK_LOW 0x7F
#define CLOCK_HIGH 0xFE
#define pBuffer2kHead 0x13EC //定义接收过来的包头
bit CommRecvingFlg;//和CPLD通信的标志位
//bit RX_2000_BIT; //接受2000的通信标志位
bit timer1_expired; //flag for 20s & 100ms delay
bit encoder_recv=0; //CPU从2000接受完数据标志位
bit Cpld2_cpu_DataFlg; //CPLD传给CPU数据结束标志
bit CommRecvFlg = 0; //CPU接收CPLD后的数据位自锁位
bit CmdCmx2000StartFlg = 0; // command for starting cmx618
bit CmdCmx2000LoopFlg = 0; // command for loop test
bit phase =0;
bit TX_2000_BIT=1;
unsigned int timer1_counter;
unsigned char tx2kProcess = 3;/*0:传送16位(一个字);1:发送接下来的23字;2:延时20ms;3:缓冲区状态判别及跳转*/
unsigned char rx2KProcess = 0;/*0:接收16位(一个字);1:接收数据判别及跳转;2:延时20ms;3:缓冲区状态判别及跳转;4:丢弃16位;5丢弃下接下来的23个16位,并回跳*/
unsigned char rx2KCnt;/*接收,计数16个bit为一字*/
unsigned char tx2KCnt;/*发送,计数16个bit为一字*/
unsigned char rx2KCntB;/*接收,计数24个字为一帧*/
unsigned char tx2KCntB;/*发送,计数24个字为一帧*/
unsigned char MaxLength = 0;//CPLD传给CPU的实际字节长度
unsigned char Length = 0;//接收CPLD的字节长度
//unsigned char T_Count=0; //发送给CPLD的字节数
//unsigned int i;
unsigned char CommSendBuffer[COMMSENDPACKETLEN]; //CPU发射给CPLD缓冲区
unsigned char CommRecvBuff[10]; //CPLD发给CPU的接收缓冲区
unsigned int xdata sendBuf[12];
unsigned int xdata PreLoad2k[12] = {0x13EC,0x0000,0x9030,0x0000,0x0000,0x0000,0x4330,0x0000,0x0000,0x0000,0x00FF,0x5024};
unsigned int xdata buffer2k[24];
/*
#define CRYSTAL_FREQUENCY 22118400 // Crystal Frequency in Hz
// XFCN Setting Macro
#if (CRYSTAL_FREQUENCY <= 32000)
#define XFCN 0
#elif(CRYSTAL_FREQUENCY <= 84000)
#define XFCN 1
#elif(CRYSTAL_FREQUENCY <= 225000)
#define XFCN 2
#elif(CRYSTAL_FREQUENCY <= 590000)
#define XFCN 3
#elif(CRYSTAL_FREQUENCY <= 1500000)
#define XFCN 4
#elif(CRYSTAL_FREQUENCY <= 4000000)
#define XFCN 5
#elif(CRYSTAL_FREQUENCY <= 10000000)
#define XFCN 6
#elif(CRYSTAL_FREQUENCY <= 30000000) //外接的是这个范围
#define XFCN 7
#else
#error "Crystal Frequency must be less than 30MHz"
#endif
/*global variable*/
//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// OSCILLATOR_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This function initializes the system clock to use the external oscillator
// in crystal mode.
//
//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void)
{
unsigned int i=0; // Delay counter
OSCXCN = 0x77; // Start external oscillator with 外部晶体振荡方式2分频
// the appropriate XFCN setting
// based on crystal frequency
for (i=0; i < 3000; i++); // Wait for crystal osc. to start
while ((OSCXCN & 0x80)==0); // Wait for crystal osc. to settle
RSTSRC = 0x06; // Enable missing clock detector and 使能时钟丢失检测,VDD为监视器
// VDD Monitor reset
CLKSEL = 0x01; // Select external oscillator as system 外部2分频
// clock source
OSCICN = 0x00; // Disable the internal oscillator.
}
/*-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This function configures the crossbar and ports pins.
//
// The oscillator pins should be configured as analog inputs when using the
// external oscillator in crystal mode.
//
// P0.0 digital out push-pull /CHAN CLK
// P0.1 digital out push-pull CHAN_RXD
// P0.2 digital in CHAN_TXD
// P0.3 digital in 2000_EPR
// P0.4 digital out push-pull CHAN_R_STRB
// P0.5 digital out push-pull CHAN_T_STRB
// P0.6 analog don't care XTAL1
// P0.7 analog don't care XTAL2
// P1.0 digital out push-pull RST_2000
// P1.1 digital out push-pull 2000_SLEEP
// P1.6 digital out push-pull CODEC_DCSI
// P1.7 digital in CODEC_SCLK
// P2.0 digital in RESET
// P2.1 digital in LINK_INTP
// P2.2 digital out push-pull CPLD_A_RXD
// P2.3 digital CPLD_A_DSR
// P2.4 digital out push-pull CPLD_A_CTS
// P2.5 digital in CPLD_A_TXD
// P2.6 digital in CPLD_A_RTS
// P2.7 digital CPLD_A_DTR
//-----------------------------------------------------------------------------*/
void PORT_Init (void)
{
P0MDIN &= ~0xC0; // P0.6, P0.7 are analog
P0MDIN |= 0x0C; // P0.2, P0.2 are digital
P1MDIN |= 0x80; // P1.7 are digital
P2MDIN |= 0x63; // P2.0,P2.1,P2.5, P2.6 are digital
P0MDOUT = 0x33;
P1MDOUT = 0x07;
P2MDOUT = 0x14;
P0SKIP = 0xFF;
P1SKIP = 0x7F;
P2SKIP = 0xDB;
// Crossbar Initialization
XBR0 = 0x00;
XBR1 = 0x50;
XBR2 = 0x01;
LINK_INTP = 1;
KEY_RESET = 1;
CODEC_DCSI = 1;
}
/*
void PORT_Init (void)
{
P0MDIN = 0x3F;
P0MDOUT = 0x33;
P1MDOUT = 0x43;
P2MDOUT = 0x1C;
P0SKIP = 0xFF;
P1SKIP = 0xFF;
P2SKIP = 0xDB;
P3SKIP = 0x07;
XBR1 = 0x40;
XBR2 = 0x01;
}
*/
/*-----------------------------------------------------------------------------
// PCA0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This function disables the watchdog timer.
//
//-----------------------------------------------------------------------------*/
void pca0Init(void)
{
PCA0MD &= ~0x40;
//PCA0MD = 0x00;
}
/*-----------------------------------------------------------------------------
//通用延时函数 delay
//-----------------------------------------------------------------------------*/
void delay(void)
{
unsigned int x;
for(x = 0; x < 650; x)
x++;
}
//-----------------------------------------------------------------------------
// CLKMUL_Init ()
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This routine initializes the Clock Multiplier using the Internal Oscillator
// as the source.
//
//-----------------------------------------------------------------------------
void UART_Init(void)
{
SBRLL1 = 0xc0; // 9600 @ 11059200
SBRLH1 = 0xfd;
SCON1 = 0x10; //串口接受允许
SMOD1 = 0x1C; //奇校验 硬件奇偶使能 8位数据
SBCON1 = 0x43; //波特率发生使能 不分频
}
void Timer_Init(void) //0.005秒
{
TMOD = 0x11;
TL1 = 0xff; // SYSCLK = 11059200 经2分频 0.005秒
TH1 = 0x27; // 16bit mode 20ms 65536 - clk/t
}
void Interrupts_Init()
{
EIE2 = 0x02;
IE = 0xA8;
}
void InitComm() //和CPLD通信端口初始
{
COMM_RTS = 1;
COMM_DSR = 1;
COMM_CTS = 1;
COMM_DTR = 1;
COMM_DTR = 0; // put the DTR low
Length = 0; // buffer length is 0
}
void timer1() interrupt 3 //以后要修正T1的初值
//
//INPUTS: none
//
//OUTPUTS: none
//
//DESCRIPTION: Timer 1 Interrupt Servide Routine.
// This timer is used for:
// - switch debouncing within "main"
// - the 20s delay for Chip Erase lockup prevention
// - the 100ms delay needed in the CMX618 initialization.
// A counter is decremented each time Timer 1 overflows.
// When the count reaches 0, a flag is set.
//********************************
{
timer1_counter--;
if(timer1_counter == 0)
{
timer1_expired = 1;
TR1 = 0;
}
else
TR1 = 1;
TH1 = 0x27; //reload for 5ms overflow
TL1 = 0xff;
}
void timer2Init(void) // 主要和2000通信用中断
{
CKCON |= 0x30; // Timer2 uses SYSCLK11059200经12分频 产生2400读写时钟脉冲
TMR2RLL = CLOCK_LOW; // Reload value to be used in Timer2
TMR2RLH = CLOCK_HIGH; // Reload value to be used in Timer2
TMR2L = CLOCK_LOW; // Init the Timer2 register
TMR2H = CLOCK_HIGH; // Init the Timer2 register
ET2 = 1; // Timer2 interrupt enabled
}
void rxRecFirst() //在主函数调用一次
{
while(EPR_2K);
TR2=1; //打开定时器2
}
void CommRecvData() //接受管脚的电平检测
{
COMM_DTR = 0; // put the DTR low 接受许可 此管脚为输出
if(!COMM_DSR) //此管脚为输入,来检测 CPLD—A-RTS传过来的电位
{
if(~CommRecvingFlg) //如果没有在接受
{
CommRecvingFlg=1; //置接受标志位
Length = 0; // buffer length is 0
}
}
else
{
//CommEnableInterrupt(FALSE);
CommRecvingFlg=0; //没有接受置位
}
}
void CommSend2Cpld2() //CPU给CPLD发送数据
{
unsigned char i = 0;
COMM_RTS = 0; //发出申请
for(i = 0; i < COMMSENDPACKETLEN; i++)
{
CommSendBuffer[i] = 0; //清发射缓冲里面的值
}
CommSendBuffer[0] = COMMPACKETHEADER; //把包头附给第一位
CommSendBuffer[1] =buffer2k[12]>>8;
CommSendBuffer[2] =buffer2k[12];
CommSendBuffer[3] =buffer2k[13]>>8;
CommSendBuffer[4] =buffer2k[13];
CommSendBuffer[5] =buffer2k[14]>>8;
CommSendBuffer[6] =buffer2k[14];
CommSendBuffer[7] =buffer2k[15]>>8;
CommSendBuffer[8] =buffer2k[15];
CommSendBuffer[9] =buffer2k[16]>>8;
EIE2=EIE2&0xfd; //关闭UART1中断
if (COMM_CTS) //CTS为低 准备开始发送
{
timer1_counter = 12; //3个20毫秒的中断
timer1_expired = 0; //标志 记数从3减到0 此位就为1
TR1 = 1;
while(!timer1_expired); //等待 60毫秒 timer1_expired 置1
timer1_expired = 0;
if(COMM_CTS)
goto next;
}
else // 如果CTS为低,就开始往CPLD发送数据
{
for(i = 0; i < COMMSENDPACKETLEN; i++)
{
SBUF1 = CommSendBuffer[i]; //
while(!(SCON1&0x02)); // 等待中断标志为1
SCON1 &= ~0x02; //发送中断清零
timer1_counter = 4; //1
timer1_expired = 0;
TH1=0x27;
TL1=0xff; //
TR1 = 1;
while(!timer1_expired); //等待20毫秒
timer1_expired = 0;
}
encoder_recv=0;
}
next:
COMM_RTS = 1;
EIE2=EIE2|0x02; //打开UART1中断
}
serial1 () interrupt 16 //接收数据函数中断
{
unsigned char temp,temp_state;
EA=0;//从CPLD接到数据就关闭总中断
temp_state = SCON1 ;
// ceshi=0; //测试用
if(temp_state & 0x01) //接收中断
{ //如果收到一个字节 接收标志位置位
temp = SBUF1;//把接到数据传给TEMP
SCON1 &= ~0xc1; //把标志位清零
if ((temp == 0xff) && (!CommRecvFlg)) //接收标志位为0接收自锁位 OXFF 为声码启动指令
{
CommRecvFlg = 1;
MaxLength = 3; //这时只接收3个字节
Length = 0;
CommRecvBuff[Length++] = temp;
}
else if ((temp == 0x80) && (!CommRecvFlg)) //80为语音压缩码 CPLD给 CPU 的包头
{
CommRecvFlg = 1;
MaxLength = 9; //这时接收9个字节
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -