/**************************************************************************************
工程名稱(chēng):雙機(jī)通信
說(shuō)明:此程序可以實(shí)現(xiàn)兩個(gè)單片機(jī)之間的相互通信;串口采用方式1
工作,10位異步接受和發(fā)送,波特率可變,由定時(shí)器1控制;且含有校驗(yàn)
程序說(shuō)明:SCON:串口通信控制寄存器
SBUF:串行口的收發(fā)緩沖寄存器
PCON:電源管理寄存器。當(dāng)SMOD=1時(shí)串行口的波特率加倍。
IE:中斷允許寄存器。ES=1表示允許串行口中斷
TI:發(fā)送中斷標(biāo)志位,TI由硬件置位,置位表示一幀信息發(fā)送結(jié)束,TI在發(fā)送數(shù)據(jù)前必須由軟件清0
RI:接收中斷標(biāo)志位,RI由硬件置位,置位表示一幀信息接收結(jié)束,RI在接收數(shù)據(jù)前必須由軟件清0
完成日期:2009年8月18日
修改日期:2009年8月23日
*******************************************************************************************/
#include
#include "lcd12864.h"
unsigned long vo_num1=0;//接收到的頻率值
unsigned long vo_num3=0;// 接收到的失真度
unsigned int vo_num4=0;//緩存校驗(yàn)值
unsigned char vo_num2[8];//緩存我們串口接收到的數(shù)據(jù)
unsigned char m=0;
unsigned int buf;
unsigned int pf=0;//校驗(yàn)和
#define seg_c P2 //將數(shù)碼管的段顯示定義到P2口
#define bit_c P0 //將數(shù)碼管的位選擇定義到P0口
#define fosc 22118400 //定義晶體振蕩頻率
#define bps 9600 //定義我們要通訊的波特率
#define th1 256-(fosc/12/16/bps) //利用宏計(jì)算出我們要給定時(shí)器中賦什么樣的值才能滿(mǎn)足我們需要的波特率
//將0-F 查表 成我們鍵盤(pán)對(duì)應(yīng)的字符
unsigned char code seg[11]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09,0xff};//定義從0-9 所對(duì)應(yīng)的段碼
unsigned char num[8]={9,8,7,6,5,4,3,2}; //聲明8個(gè)顯示緩存 對(duì)應(yīng)我們數(shù)碼管的8個(gè)位
/**********************************************************************************
函數(shù)名稱(chēng):串口初始化函數(shù)
**********************************************************************************/
void serial_init (void) //在使用串口模式1 前要初始 化串口寄存器等...
{
SCON=0x50; //串口工作于方式1,10位異步接收/發(fā)送,波特率可變
TMOD=0X20; //因?yàn)槟J?用到了定時(shí)器1的自動(dòng)重裝模式,所以要這樣設(shè)置定時(shí)器
PCON=0X00; //為了讓通訊速率更快,設(shè)置SMOD=1 那么它所在的寄存器PC0N=0X80 ,串行口的波特率加倍。
TH1=th1; //將宏計(jì)算的定時(shí)器初值放到TH1中
TL1=th1;
TR1=1;//啟動(dòng)定時(shí)器來(lái)產(chǎn)生串口工作所需要的波特率
ES =1;//允許出串口中斷
EA=1; //打開(kāi)總中斷允許位
}
/**********************************************************************************
函數(shù)名稱(chēng):串口發(fā)送數(shù)據(jù)函數(shù)
**********************************************************************************/
void putbyte(unsigned char byte)// 利用硬件串口方式1 發(fā)送一個(gè)字節(jié)數(shù)據(jù)
{
SBUF=byte;//將要發(fā)送的數(shù)據(jù)送到發(fā)送緩沖區(qū)域,系統(tǒng)自動(dòng)發(fā)送
while(!TI);//查詢(xún)是否發(fā)送結(jié)束 當(dāng)TI=1 代表發(fā)送結(jié)束
TI=0;//清發(fā)送結(jié)束位方便下一次發(fā)送
}
/**********************************************************************************
函數(shù)名稱(chēng):串口接收數(shù)據(jù)函數(shù)
說(shuō)明:采用中斷方式接收數(shù)據(jù),串口中斷的服務(wù)號(hào)是4
**********************************************************************************/
//串口中斷服務(wù)函數(shù) 無(wú)論接收中斷或者發(fā)送中斷都能進(jìn)來(lái)
serial () interrupt 4
{
if(RI) //RI=1,表示一楨數(shù)據(jù)接收完
{
vo_num2[m]=SBUF;
m++;
// if(m>8)
// m=0;
}
RI=0; //RI清0之后才能接收到下一幀數(shù)據(jù)。
}
/**********************************************************************************
函數(shù)名稱(chēng):軟件延時(shí)函數(shù)
**********************************************************************************/
void delay(unsigned char ms) //軟件延遲函數(shù)
{
unsigned int a=0;
while(ms--)
{
for(a=0;a<10;a++);
}
}
/**********************************************************************************
函數(shù)名稱(chēng):顯示函數(shù)
說(shuō)明:數(shù)碼管段選是P2口,位選是P0口。
**********************************************************************************/
void display(unsigned int dis)
{
unsigned char loop=0;
num[0]=10;
num[1]=10;
num[2]=10;
num[3]=dis/10000; //得到要顯示數(shù)據(jù)的萬(wàn)位
num[4]=(dis%10000)/1000; //得到要顯示數(shù)據(jù)的千位
num[5]=(dis%1000)/100; //得到要顯示數(shù)據(jù)的百位
num[6]=(dis%100)/10; //得到要顯示數(shù)據(jù)的十位
num[7]=(dis%10); //得到要顯示數(shù)據(jù)的個(gè)位
for(loop=0;loop<8;loop++)
{
bit_c=~(0x01<
delay(6);
seg_c=0xff; //在這里加了這句話(huà),消除鬼影
}
}
/**********************************************************************************
函數(shù)名稱(chēng)發(fā)送校驗(yàn)函數(shù)
說(shuō)明:
**********************************************************************************/
void check_transport( unsigned int buf)
{
do
{ pf=0x00; //校驗(yàn)和清零
putbyte(buf); //發(fā)送數(shù)據(jù)并求解校驗(yàn)和
pf=(pf+buf&0x01+buf&0x02+buf&0x04+buf&0x08+buf&0x10+buf&0x20+buf&0x40+buf&0x80);
//求解校驗(yàn)和
putbyte(pf); //發(fā)送校驗(yàn)和
} while(SBUF!=0);
}
/**********************************************************************************
函數(shù)名稱(chēng):接收校驗(yàn)函數(shù)
說(shuō)明:
**********************************************************************************/
void check_receive()
{
while(1)
{
pf=0x00; //校驗(yàn)和清零
// vo_num4=SBUF;
// pf=pf+(vo_num4&0x01+vo_num4&0x02+vo_num4&0x04+vo_num4&0x08+vo_num4&0x10+vo_num4&0x20+vo_num4&0x40+vo_num4&0x80);
vo_num2[m]=SBUF;
pf=pf+( vo_num2[m]&0x01+vo_num2[m]&0x02+ vo_num2[m]&0x04+ vo_num2[m]&0x08+ vo_num2[m]&0x10+ vo_num2[m]&0x20+ vo_num2[m]&0x40+vo_num2[m]&0x80);
//求解校驗(yàn)和
if((SBUF^pf)==0x00) //判斷求出的校驗(yàn)和與接收到的校驗(yàn)和是否相等
{
putbyte(0x00);
m++;
break;
}
else
{
putbyte(0xff); //如果不相等。則發(fā)送ff
}
}//while(1)
}
/**********************************************************************************
函數(shù)名稱(chēng):主函數(shù)
說(shuō)明:
**********************************************************************************/
void disp(void)
{
lcd_init(0);
refrash_charactor();
lcd_clear();
str_1="頻率: Hz";
str_2="失真度:0. ";
lcd_display(1,1,str_1);
lcd_display(1,2,str_2);
}
main()
{
unsigned char temp;
serial_init (); //在使用串口模式1 前要初始
disp();
while(1)
{
// putbyte(0xeb) ;
// putbyte(0x90) ;
// putbyte(0xaa) ;
// m=0;
// check_receive();
if(vo_num2[0]==0xeb&&vo_num2[1]==0x90&&vo_num2[2]==0xaa)
{ vo_num1=vo_num2[3]*256+vo_num2[4];//頻率
vo_num3=(vo_num2[5]*256+vo_num2[6])*10; //失真度
refrash_charactor(vo_num1,vo_num3);
lcd_display(4,1,freq);
lcd_display(6,2,dist);
m=0;
}
}//while(1)
}