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

📄 pproject.c

📁 AVRkaifashili.rar
💻 C
📖 第 1 页 / 共 3 页
字号:
//****************************系统程序头文件****************************//
#include <io8535v.h>	//AT90S8535寄存器定义头文件;
#include <macros.h>	// AT90S8535宏定义,系统程序需要用到此宏定义过的函数;

//****************************定义全局变量****************************//
#define uchar unsigned char
#define uint unsigned int
#include "project.h"

uchar Key_Value;		  //按键键值;
uchar State_Flag;		  //站点标志;
uchar Ack_Flag;		  //确认标志;
uchar Pre_Flag;		  //预报标志;
uchar Move_Flag;		  //滚动标志;
uchar Spec_Flag;		  //特殊信息标志;
uchar EOM_Flag=1;	  //信息结束标志;
uchar Pst_Flag;		  //上、下行标志;
uchar State=1;			  //站数;
uchar Spec;			  //特殊信息数;
uchar Speed=20;		  //文字滚动速度;
uchar Word_Number;	  //显示字数;

//****************************说明****************************//
//语音芯片第1~16段分别保存16站的站名信息
//第17段保存报站信息“到了,请要下车的乘客依次从后门下车”
//第18、19段分别保存预报信息“前方到站”、“请要下车的乘客做好下车准备”
//第20段保存欢迎信息及公交车线路说明
//第21、22段保存特殊提示信息
uchar Snd_Info[]={0,17};			//报站声音信息
uchar Snd_Pre_Info[]={18,0,19};		//预报声音信息
uchar Snd_Spec[]={21,22};			//特殊声音信息
uchar Snd_Welc=20;				//欢迎声音信息
//****************************说明****************************//
//本例公交车语音报站系统包含16站
//为方便起见,所有的站名都以“第n站”代替,其中n为当前站数,n<16
//报站时显示屏滚动显示“第n站到了”
//预报站时显示屏显示“前方到站第n站”
//其中“第n站”字模存放在二维数组State n[3][32]中
//“到了”字模存放在二维数组DL[2][32]中
//“前方到站”字模存放在二维数组QFDZ[4][32]中
uchar text[32];				//当前显示文字
uchar next[32];			//下一个显示文字

//****************************定义中断服务程序****************************//
#pragma interrupt_handler Key_Scan:2			//定义按键中断INT0的中断服务程序
#pragma interrupt_handler Receive_EOM:3		//定义语音中断INT1的中断服务程序

void delay(uchar i)
{for(;i!=0;i--) NOP();}

//****************************I2C驱动程序****************************//
//定义MAX6959时钟线为PA^7
void Set_SCL(uchar i)
{
 if(i)
  PORTA |=0x80;
 else
  PORTA &=0x7f;
}
 
//定义MAX6959数据线为PA^6
void Set_SDA(uchar i)
{
 if(i)
  PORTA |=0x40;
 else
  PORTA &=0xbf;
}

//I2C总线的开始条件:SCL高电平时SDA的下降沿
void Start()
{
 Set_SDA(1);		//SDA=1;
 Set_SCL(1);		//SCL=1;
 delay(100);		//等待时钟信号变成高电平以确保总线开始
 Set_SDA(0);		//SDA=0;
 delay(100);
 Set_SCL(0);		// SCL=0;
}

//I2C总线结束条件:SCL为高电平时SDA的上升沿
void Stop()
{
 Set_SDA(0);		//SDA=0;
 delay(100);
 Set_SCL(1);		//SCL=1;
 delay(100);	    //等待时钟信号变成低电平以确保总线结束
 Set_SDA(1);		//SDA=1;
 delay(100);
 Set_SCL(0);		//SCL=0;
}

//I2C总线应答:读完一个字节后将SDA线拉低,即应答0
void Ack()
{
 Set_SDA(0);		//SDA=0;
 delay(50);
 Set_SCL(1);		//SCL=1;
 delay(100);
 Set_SCL(0);		//SCL=0;
 delay(50);
 Set_SDA(1);		//SDA=1;
}

//I2C总线应答:读完所要求的字节数据后将SDA线拉高,为结束IIC总线操作做准备
void Nack()
{
 Set_SDA(1);		//SDA=1;
 delay(50);
 Set_SCL(1);		//SCL=1;
 delay(100);
 Set_SCL(0);		//SCL=0;
 delay(50);
 Set_SDA(0);		//SDA=0;
}

//检查I2C器件应答情况
void Check_Ack()
{
 Set_SDA(1);		//SDA=1;
 Set_SCL(1);		//SCL=1;
 Ack_Flag=0;		//清除应答标志;
 DDRA &=0xbf; 	//设置SDA为输入
 if(!((PINA & 0x40)>>6))
 {     
  delay(50);
  Set_SCL(0);	//SCL=0;
  delay(100);
 }
 else
 {
  Ack_Flag=1;	//收到应答;
  delay(50);
  Set_SCL(0);	//SCL=0;
  delay(100);
 }
 DDRA |=0xff; 	//重新设置SDA为输出	 
}

//写1bit数据:0
void Write_Bit0()     
{
 Set_SDA(0);		//SDA=0;
 Set_SCL(1);		//SCL=1;
 delay(100);
 Set_SCL(0);		//SCL=0;
}

//写1bit数据:1
void Write_Bit1()       
{
 Set_SDA(1);		//SDA=1;
 Set_SCL(1);		//SCL=1;
 delay(100);
 Set_SCL(0);		//SCL=0;
 Set_SDA(0);		//SDA=0;
}

//写一字节数据Data
void Write_Byte(uchar Data)  
{
 uchar i;
 for(i=0;i<8;i++)
 {
  if(Data & 0x80)        //传输位从高位到低位,先传最高位 
   Write_Bit1();
  else
   Write_Bit0();
  Data <<=1;            //数据左移             
 }
}

//读一字节数据:返回值即读的数据
uchar Read_Byte()            
{
 uchar Read_Data=0xff;		// Read_Data为读入的数据,初始值为0xff
 uchar j;
 for (j=0;j<8;j++)
 {
  Set_SDA(1);		//SDA=1;
  Set_SCL(1);		//SCL=1;
  DDRA &=0xbf;		//设置SDA为输入线
//数据读出,若是0则移位;若是1则与0x01或
  if((PINA & 0x40)==0)
  {
   Read_Data <<=1;
   Read_Data=(Read_Data & 0xfe);                 
   Set_SCL(0);		//SCL=0;
  }
  else 
  {
   Read_Data <<=1;
   Read_Data =( Read_Data  | 0x01);
   Set_SCL(0);		//SCL=0
  }
 }
 DDRA |=0x40;		//设置SDA为输出线
 return(Read_Data);   //返回读出的字节
}

//写一字节数据
void Write_1byte(uchar Slave,uchar Address,uchar Data)
{
 Start();		//开始
 Write_Byte(Slave);		//写I2C器件地址
 do
 {
  Check_Ack();		//检查应答位
 }
 while(Ack_Flag==1);
 Write_Byte(Address);   //送寄存器地址
 do
 { 
  Check_Ack();		//检查应答位
 }
 while(Ack_Flag==1);
 Write_Byte(Data);		//写入一字节数据
 do
 {
  Check_Ack();           //检查应答位
 }
 while(Ack_Flag==1);
 Stop();                  //停止
}

//写两字节数据
void Write_2byte(uchar Slave,uchar Address,uchar Data0,uchar Data1)
{
 Start();		//开始
 Write_Byte(Slave);		//写I2C器件地址
 do
 {
  Check_Ack();		//检查应答位
 }
 while(Ack_Flag==1);//while(F0==1);
 Write_Byte(Address);   //送寄存器地址
 do
 { 
  Check_Ack();		//检查应答位
 }
 while(Ack_Flag==1);
 Write_Byte(Data0);
 do
 {
  Check_Ack();		//检查应答位
 }
 while(Ack_Flag==1);
 Write_Byte(Data1);
 do
 {
  Check_Ack();		//检查应答位
 }
 while(Ack_Flag==1);
 Stop();		//停止信号
}

//读一字节数据
uchar Read_1byte(uchar Slave,uchar Address)
{
 uchar data0,x;
 do
 {
  Start();		//开始信号
  Write_Byte(Slave);		//写I2C器件地址
  Check_Ack();		//检查应答位
 }
 while(Ack_Flag);//while(F0==1);
 do
 {
  Write_Byte(Address);		//写寄存器地址
  Check_Ack();		//检查应答位
 }
 while(Ack_Flag);// while(F0==1);
 do
 {
  Start();		//开始
  Write_Byte(Slave+1);		//写I2C器件地址(+1表示为读操作)
  Check_Ack();		//检查应答位
 }
 while(Ack_Flag);
 data0=Read_Byte();		//读1字节
 Nack();		//读完发送一个Not Ack应答
 Stop();		//停止
 return data0;	//返回读取数据
}

//****************************数字显示程序****************************//
void Led_Display(uchar Number)
{
  uchar d0,d1;
  d0=Number/10;		//取站数的个位
  d1=Number%10;		//取站数的十位
  Write_2byte(0x70,0x20,d1,d0);		//从显示位0开始连续显示两位
}

//****************************键盘处理程序****************************//
void Key_Act(void)
{
 GIMSK &=0x7f;			//关闭中断 
 switch(Key_Value)		//判断键值
 {
  case 1:		  			//若键值为1,则报站 
   Inform(State);			//报第State站
   Lattice_Display();		//显示到站信息
   Key_Value=0;			//重新赋键值为0
   break;
  case 2:		  			//若键值为2,则前进一站
   if(State<16)			//若站数<16,则
    State++;				//站数+1
   else					//否则
	State=0;				//重新赋站数为0
   Led_Display(State);		//显示当前站数
   Key_Value=0; 			//重新赋键值为0
   break;
  case 4:					//若键值为4,则播放特殊信息
   Spec++;				//特殊键按下一次,特殊段+1
   Special(Spec);			//报第Spec段特殊段		  	   
   Key_Value=0; 			//重新赋键值为0
   break;
  case 8:					//若键值为8,则进行上、下行切换
   Pst_Flag=!Pst_Flag;		//上、下行切换
   Key_Value=0; 			//重新赋键值为0
   break;
  case 16:				//若键值为16,则后退一站
   if(State)				//若站数不为0,则
State--;				//站数-1
   else					//否则
	State=16;				//重新赋站数为16
   Led_Display(State);		//显示当前站数
   Key_Value=0; 			//重新赋键值为0
   break;
  case 32:				//若键值为32,则进行预报站
  Pre_Inform(State+1);	//预报第State+1站
   Lattice_Display();		//显示预报站信息
   Key_Value=0; 			//重新赋键值为0
   break;
  default:
   NOP();
 }
 GIMSK |=0x80;	   //8535应为GIMSK
}


//****************************语音芯片驱动程序****************************//
//定义ISD2560使能线为PA^4
void Set_CE(uchar level)
{
 if(level==1)
  PORTA |=0x10;
 else
  PORTA &=0xef;
}

//定义ISD2560的PD线为PA^3
void Set_PD(uchar level)
{
 if(level)
  PORTA |=0x08;
 else
  PORTA &=0xf7;
}

//定义ISD2560的PR线为PA^2
void Set_PR(uchar level)
{
 if(level)
  PORTA |=0x04;
 else
  PORTA &=0xfb;
}

//定义ISD2560的A6/8/9线为PA^1
void Set_A6(uchar level)
{
 if(level)
  PORTA |=0x02;
 else
  PORTA &=0xfd;

⌨️ 快捷键说明

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