⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 baozhan_one.c

📁 用单片机做的公交车报站器
💻 C
字号:
#include"intrins.h"
#include"STC89C58RD.h"
#include"baozhan_one.h"


unsigned char idata cur_state=0;       //全局变量,指示当前站点状态信息
unsigned int xdata isd_addr[30];               //全局变量,指示当前录放音地址信息(行数)
unsigned char idata init_R_addr=1;        //标志位,指示是否需要初始化录音地址,1是0否


void main()
{
	
	init();
	EA=0;
	enable_in_ram();     //允许内部1024byteRAM,允许ALE.默认是允许的
    	dis_ale();     //禁止ale,允许内部扩展1024byteRAM
	init_isd();
	dis_low=1;        //关数码管显示
	dis_high=1;
	EA=1;
	


	while(1)
	{
		if(rec_ctrl==0)             //录音键按下
		{
			delay_kb(10);           //延时,消抖
			if(rec_ctrl==0)
			{
				isd_rec();
				init_R_addr=0;
			}
			else
				break;
		}
	        else
	        {
	         	kbscan();
	         	switch(kbscan())
		        {
		        	case 0: cur_state=0;
						isd_play(isd_addr);
		        	    	break;
			        case 1: cur_state=1;
			        	isd_play(isd_addr);
		             	        break;
			        case 2: cur_state=2;
			        	isd_play(isd_addr);
		              	        break;
			        case 3: cur_state=3;
			        	isd_play(isd_addr);
		              	        break;
				case 4: cur_state=4;
					isd_play(isd_addr);
		              	        break;
				case 5: cur_state=5;
					isd_play(isd_addr);
		               	        break;
				case 6: cur_state=6;
					isd_play(isd_addr);
		              	        break;;
				case 7: cur_state=7;
					isd_play(isd_addr);
		               	        break;
				case 8: cur_state=8;
					isd_play(isd_addr);
		             	        break;
				case 9: cur_state--;
					isd_play(isd_addr);
				        break;
				case 10:isd_play(isd_addr);
					break;
				case 11:cur_state++;
					isd_play(isd_addr);
					break;
				default:break;
			}
		}
	}
}
			
		













void init(void)          //初始化系统参数
{
	PCON=0x00;           //smod=0;
	SCON=0x40;           //串口工作方式1,8位UART,ren=0禁止接收
	TMOD=0x21;           //定时器1工作方式2,8位自动重载T/C
	                         //定时器0工作方式1,16位定时器,用于定时产生中断进行显示扫描
	TH1=253;             //TH1=256-(28800/baudrate),9600bps
	TL1=253;
	TH0=0xf8;           //定时器0定时2MS
	TL0=0x30;
	
	TR1=1;            //启动T1
	TR0=1;            //启动T0
	ET0=1;            //开定时器0中断
	ES=1;             //开串口中断
	EA=1;             //开总中断
	REN=1;            //使能串口接收
}
	
	
void init_isd(void)
{
	ss=1;
	sclk=1;
	rac=1;
	int0=1;
}		
	




void timer0(void) interrupt 1 using 2
{
	unsigned char bitselect=0;        //显示位切换标志位
	unsigned char disply[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
	                          0x88,0x83,0xc6,0xal,0x86,0x8e};   //字形数0-9,A-F;
	static unsigned char cur_dpy;
	cur_dpy=cur_state;

	TH0=0xf8;           //重装计数初值
	TL0=0x30;
	
	if(cur_dpy>=10&&cur_dpy<20)
	{
		dis_low=1;           //关显示
		dis_high=1;
		cur_dpy-=10;
		disdata=disply[cur_dpy];        //从p0口输出字形数
		dis_low=0;
	}
	else 
	{
		switch(bitselect)
		{
			case 0:
			{
				if(cur_dpy>=20&&cur_dpy<30)
				{
					dis_low=1;
					cur_dpy-=20;
					disdata=disply[cur_dpy];
					dis_low=0;
				}
				else if(cur_dpy>=30&&cur_dpy<40)
				{
					dis_low=1;
					cur_dpy-=30;
					disdata=disply[cur_dpy];
					dis_low=0;
				}
				else
				{
					dis_low=1;
					disdata=disply[14];
					dis_low=0;
				}
			}
			break;
			
			case 1:
			{
				if(cur_dpy>=20&&cur_dpy<30)
				{
					dis_high=1;
					disdata=disply[1];
					dis_high=0;
				}
				else if(cur_dpy>=30&&cur_dpy<40)
				{
					dis_high=1;
					disdata=disply[2];
					dis_high=0;
				}
				else
				{
					dis_high=1;
					disdata=disply[14];
					dis_high=0;
				}
			}
			break;
			
			default:break;
		}
		bitselect=~bitselect;
	}
	
		
}





void dis_ale()        //禁止ale,允许内部扩展1024byteRAM
{
	AUXR = 0x01;
}

void enable_in_ram()         //允许内部1024RAM,允许ALE.默认是允许的
{
	AUXR = 0x00;
}









//键盘扫描
void delay_kb(unsigned char time)
{
	unsigned char i,j;
	for(i=0;i<time;i++)
	    for(j=0;j<200;j++);
}

unsigned char kbscan(void)
{
	unsigned char i,j,temp;
	unsigned char vertical=0x01;
	unsigned char row=0x10;
	do{
	   P2=0xf0;
	  }while(P2&0xf0==0xf0);
	delay_kb(10);
	P2=0xf0;
	if(P2&0xf0!=0xf0)
	{
		for(i=0;i<4;i++)
		{
			P2=~vertical;
			temp=P2&0xf0;
			for(j=0;j<4;j++)
			{
				if(temp&row==0x00)
				    return(j*8+i);
				temp=temp>>1;
			}
		}
		vertical<<=1;
		

	}
	else return 20;
}
				
			
			
			
			
			
			
			

//ISD4004录放音

void isd_spi(unsigned char cmd)   //ISD4004写控制字
{
	unsigned char m,i,j;
   	ss=1;
   	sclk=0;
   	ss=0;

   	m=cmd;
   	for(i=0;i<8;i++)
   	{
      		m=_cror_(m,1);     //unsigned char _cror_(unsigned char x,unsigned char y);
                           //将X值向右旋Y次,即X值的bit0右旋至bit7.返回X值右旋Y次后的数值
     	 	j=m<<1;
      		mosi=CY;
      		sclk=0;
      		sclk=1;
   	}
   	ss=1;
}






unsigned char chk_ovf(void)    //检测OVF,溢出返回1,否则返回0
{
	isd_spi(rint);      
 	ss=0;
 	sclk=0;
 	sclk=1;
 	if(miso==1)
 	{
 		return 1;
 	}
 	else
 	{
 		return 0;
 	}
 }









void isd_rec(void)  //录音  address--录音地址 0---2400
{
		unsigned char i,m,j;
     	unsigned int datasoute=0,address=0;
     	static unsigned char addr=0;            //初始化isd_addr[]下标
		static unsigned int PR_addr=0;        //初始化行数(指示录放地址)
		
	
      	isd_spi(powerup);
      	delay_isd(5118);        //上电延时
      	isd_spi(powerup);
      	delay_isd(5118);        //上电延时
      	delay_isd(5118);        //上电延时
      	if(init_R_addr==1)        //需要初始化录音地址
      	{
      		ss=1;
      		sclk=0;
     		m=setrec;
      		ss=0;
       		for(i=0;i<16;i++)
     		{
     			address=_iror_(address,1);     //unsigned int _iror_(unsigned int x,unsigned char y);
                                          //将整数类型的X值右旋Y次,即X值的bit0右旋至bit15.返回X值右旋Y次后的16bit数值
        	 	datasoute=address<<1;
       		  	mosi=CY;
         		sclk=0;
         		sclk=1;
     		}
      		for(i=0;i<8;i++)
     		{
         		m=_cror_(m,1);
         		j=m<<1;
         		mosi=CY;
         		sclk=0;
        	 	sclk=1;
     		}
     		ss=1;      //初始化录放起始地址address=0,PR--PLAY or REC
     	 }
      	rec_led=0;          //开录音指示灯
     	isd_spi(rec);       //从当前地址开始录音
     	P0=(P0|0xfc);
     	while(int0==1)       //等待OEM或OVF产生中断
  	{
   		if(rac)          //记录本次录音所占的行数(也就是本次录音有多大)
   		{
   			delay_isd(20000);
   			PR_addr++;     
   		}  
   		if(rec_ctrl==1)   //录音键断开,停止录音
  		{
  			delay_kb(10);        //延时,消抖
  			if(rec_ctrl==1)
  			{
  		  	rec_led=1;      //关录音指示灯
  		  	isd_spi(stop);
  			}  
  		}    
 	}             //while end
 	
 	isd_addr[addr]=PR_addr;         //将语音地址依次存入数组
 	addr++;
 	
 	if(chk_ovf());        //判断是否溢出,若溢出,停止当前ISD工作
 	{
 		rec_led=1;          //关录音指示灯
 		isd_spi(stoppwrdn);
 	}
 	
}           




	
	




void isd_play(unsigned int playaddr[])  //放音程序
{
		unsigned char i,m,j,n;
     	unsigned int datasoute=0,address=0;
     	
     	n=cur_state;
     	address=playaddr[n];

   	isd_spi(powerup);

     	
	ss=1;
      	sclk=0;
      	m=setplay;
      	ss=0;
       	for(i=0;i<16;i++)
     	{
     		address=_iror_(address,1);     //unsigned int _iror_(unsigned int x,unsigned char y);
                                          //将整数类型的X值右旋Y次,即X值的bit0右旋至bit15.返回X值右旋Y次后的16bit数值
         	datasoute=address<<1;
         	mosi=CY;
         	sclk=0;
         	sclk=1;
     	}
      	for(i=0;i<8;i++)
     	{
         	m=_cror_(m,1);
         	j=m<<1;
         	mosi=CY;
         	sclk=0;
         	sclk=1;
     	}
     	ss=1;

    isd_spi(play);
    P0=(P0|0xfc);
    while(int0==1)
    {
    		
   	}                //while end;
}




void delay_isd(unsigned int i)  //延时程序
{
	while(i--);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -