?? pproject._c
字號:
//****************************系統程序頭文件****************************//
#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
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -