
#include #include #define R_Buf_Len 10 //设置接收缓冲器长度10个字节 unsigned char data R_Buf[R_Buf_Len]=""; //环形接收数据缓冲区 unsigned char data R_I_Ptr; //环形接收缓冲区输入、输出指针 unsigned char bdata Flag; //可进行位操作的变量定义 /************************************** 串行口初始化 ***************************************/ void Init_Service_Port(void) { PCON=0x80; //SMOD=1,通信波特率*2 RCAP2L=0xec; //波特率为38400 RCAP2H=0xff; // T2CON=0x34; //定时器2的工作方式 SCON=0x42; //串行口工作方式 TR2=1; //启动定时器2 REN=1; //串行口允许接收 TI=0; //清除发送中断标志TI RI=0; //清除接收中断标志RI EA=1; //总中断允许控制位打开 ES=1; //串行口中断允许控制位打开 EX0=1;//外部中断0允许打开 IT0=1;//以下降沿作为外部中断0的触发方式 R_I_Ptr=0; //接收缓冲区输入、输出指针 IP=0x10; } void T1_init(void)//定时器T1的初始化函数 { TMOD=0x20;//设定T1的工作模式为2 TH1=0x98;//每104us溢出一次。晶振频率为12Mhz,经12分频后为1Mhz,所以计一次数为1us。 //(2的8次方-104)再转换为16进制即为0x98. TL1=0x98;//模式2为自动重新装入初值的8位计数器,溢出后自动将TH1的值赋给TL1. EA=1;//开中断 ET1=1;//定时器0允许中断 TR1=1;//启动定时器0 } /******************************** 串口单个字符发送函数*******************************/ // 串口发送 ,只有调用了此函数后才能进如中断函数的if(_testbit_(TI))中,当T_Buf[]中只有一个数据时, //运行此函数就能完成发送,当有2个及其以上的字符时,第2,及其之后的字符的发送则是通过if(_testbit_(TI))中的 //SBUF=T_Buf[T_O_Ptr];来完成发送的。 void send_str(unsigned char T_Data) { SBUF=T_Data; //这里数据的发送要一定的时间 delay(1);//这里需要有一定延时,以便数据发送完全 } /*************************************串口字符串发送函数*************************************/ void send_strs(unsigned char *strings_point) { while (1) { if (*strings_point!=0x00)//表示所指的地址有数据 { send_str(*strings_point);//发送单个的字符,在这里进行连续的发送 strings_point++;//指向下一个地址 } else { break; } } //send_str(0x0d);//换行 //send_str(0x0a);//这里不用换行输出,因为它和VB中的程序代码不相兼容,VB中用的是文本输入和输出 } /**************************************** 串行口接收发送测试主程序 *************************************************/ // 串行口接收发送测试主程序 void main(void) { Init_Service_Port(); //串口初始 化 data1=1;//先置高,启动之前要保证有足够的置高时间 data_temp&=0x00; flag_i=0;// flag_j=0; flag_k=0; while(1) { if(lomot_start==1) { if(forward==1) //"前向,加减速运行" { forw_spe_cont(); } if(backward==1) //"后向,加减速运行" { back_spe_cont(); } //char_trans('F');//用‘ ’括起来的为字符;用" "括起来的为字符串 } record_function(); play_function(); } } /************************************** 串行口中断 **************************************/ /********************串行中断标志RI和TI没有置0时,不会再次触发串行口中断*****************/ void com_ser_int(void) interrupt 4 using 3 { if(RI) //接收中断 { R_Buf[R_I_Ptr]=SBUF; //将接收数据存入环形接收缓冲区 if(R_Buf[R_I_Ptr]==video_open[R_I_Ptr])//成立,表示接收区没有数据了 { video_con[0]++; //"视频开" } if(R_Buf[R_I_Ptr]==video_clos[R_I_Ptr])//成立,表示接收区没有数据了 { video_con[1]++; //"视频关" } if(R_Buf[R_I_Ptr]==volume_inc[R_I_Ptr]) { volum_con[0]++; //"音量+" } if(R_Buf[R_I_Ptr]==volume_dec[R_I_Ptr]) { volum_con[1]++; //"音量-" } if(R_Buf[R_I_Ptr]==locomot_on[R_I_Ptr]) { locom_con[0]++; //"机车启动" } if(R_Buf[R_I_Ptr]==locomo_off[R_I_Ptr]) { locom_con[1]++; //"机车停止" } if(R_Buf[R_I_Ptr]==forwar_run[R_I_Ptr]) { direc_con[0]++; //"正方向运行" } if(R_Buf[R_I_Ptr]==backwa_run[R_I_Ptr]) { direc_con[1]++; //"反方向运行" } if(R_Buf[R_I_Ptr]==incr_speed[R_I_Ptr]) { speed_con[0]++; //"加速运行" } if(R_Buf[R_I_Ptr]==decr_speed[R_I_Ptr]) { speed_con[1]++; //"减速运行" } if(R_Buf[R_I_Ptr]==receiv_add[R_I_Ptr]) { Flag_addr[0]++;//前6位相同,后4位不同 } else { if(Flag_addr[0]==6) //确保前面收到了6个*字符 { if((R_Buf[R_I_Ptr]>=0x30) && (R_Buf[R_I_Ptr]<=0x39))//取字符0~9的ASCII值 //里面加括号,逻辑性强些,有助于理解代码 { receiv_add[R_I_Ptr]=R_Buf[R_I_Ptr]-0x30; } if((R_Buf[R_I_Ptr]>=0x41) && (R_Buf[R_I_Ptr]<=0x46)) //取字符A~F的ASCII值 { receiv_add[R_I_Ptr]=R_Buf[R_I_Ptr]-0x37; } if((R_Buf[R_I_Ptr]>=0x61) && (R_Buf[R_I_Ptr]<=0x66)) //取字符a~f的ASCII值 { receiv_add[R_I_Ptr]=R_Buf[R_I_Ptr]-0x57; } Flag_addr[1]++; if(Flag_addr[1]==1) //将第一个字符转换为高位 { receiv_add[R_I_Ptr]=receiv_add[R_I_Ptr]<<4; } if(Flag_addr[1]==2) //将前两个字符组合成一个字节 { receiv_add[R_I_Ptr]=receiv_add[R_I_Ptr]; Flag_addr[2]=receiv_add[6]+receiv_add[7]; } if(Flag_addr[1]==3) //将第三个字符转换为高位 { receiv_add[R_I_Ptr]=rec eiv_add[R_I_Ptr]<<4; } if(Flag_addr[1]==4) //将后两个字符组合成一个字节 { Flag_addr[3]=receiv_add[8]+receiv_add[9]; } } } if(R_Buf[R_I_Ptr]==recor_mode[R_I_Ptr]) { vmode_con[0]++; //"录音模式" } if(R_Buf[R_I_Ptr]==vplay_mode[R_I_Ptr]) { vmode_con[1]++; //"放音模式" } if(R_Buf[R_I_Ptr]==pla_rec_st[R_I_Ptr]) { pl_re_stop++; //"放音模式" } R_I_Ptr=(R_I_Ptr+1)%10; //接收区指针加1 if(video_con[0]==10)//"视频开"标识满足 { all_clear(); send_strs("video_open"); video=1;//"置 1 时打开视频电源" } if(video_con[1]==10)//"视频关"标识满足 { all_clear(); send_strs("video_clos"); video=0; //"置 0 时关闭视频电源" } if(volum_con[0]==10)//"音量+"标识满足 { all_clear(); vol_increment();//"调用音量+函数" send_strs("volume_inc"); } if(volum_con[1]==10)//"音量-"标识满足 { all_clear();//"调用音量-函数" vol_decrement(); send_strs("volume_dec"); } if(locom_con[0]==10)//"机车启动" { all_clear(); lomot_start=1; //将启动标志置1 lomot_stop=0; send_strs("locomot_on"); } if(locom_con[1]==10)//"机车停止" { all_clear(); lomot_start=0; lomot_stop=1; //将停止标志置1 spe_rank=0; send_strs("locomo_off"); } if(direc_con[0]==10)//"正方向运行" { all_clear(); forward=1; //"用来标识前向运行" backward=0; spe_rank=0; //换向后从0速度开始 send_strs("forwar_run"); } if(direc_con[1]==10)//"反方向运行" { all_clear(); forward=0; //"用来标识后向运行" backward=1; spe_rank=0; //换向后从0速度开始 send_strs("backwa_run"); } if(speed_con[0]==10)//"加速运行" { all_clear(); speed_increment(); //"调用加速等级函数" send_strs("incr_speed"); if (spe_rank<10) { send_str(spe_rank+0x30); } else { send_strs("A"); } } if(speed_con[1]==10)//"减速运行" { all_clear(); speed_decrement(); //"调用减速等级函数" send_strs("decr_speed"); if (spe_rank<10) { send_str(spe_rank+0x30); } else { send_strs("A"); } } if((Flag_addr[0]==6) && (Flag_addr[1]==4)) //接收录音和播放地址 { all_clear(); receive_flag=1; send_strs("****** "); send_str(Flag_addr[2]); //将收到的字符返回,用于观察,高8位 send_str(Flag_addr[3]); //返回低8位 } if(vmode_con[0]==10)//"录音模式" { all_clear(); _record=1; send_strs("recor_mode"); } if(vmode_con[1]==10)//"放音模式" { all_clear(); _play=1; send_strs("vplay_mode"); } if(pl_re_stop==10)//录音和放音停止 { all_clear(); _play=0; _record=0; receive_flag=0; send_strs("pla_rec_st"); } RI=0; } if(_testbit_(TI)) ; //发送中断 }
