51单片机C语言程序100例分析(3)串口

2023-02-23 20:00   367   0  

//实例49:用定时器T0的中断实现"渴望"主题曲的播放




#include    //包含51单片机寄存器定义的头文件


sbit sound=P3^7;     //将sound位定义为P3.7


unsigned int C;      //储存定时器的定时常数


//以下是C调低音的音频宏定义


#define l_dao 262    //将“l_dao”宏定义为低音“1”的频率262Hz


#define l_re 286     //将“l_re”宏定义为低音“2”的频率286Hz


#define l_mi 311     //将“l_mi”宏定义为低音“3”的频率311Hz


#define l_fa 349     //将“l_fa”宏定义为低音“4”的频率349Hz


#define l_sao 392    //将“l_sao”宏定义为低音“5”的频率392Hz


#define l_la 440     //将“l_a”宏定义为低音“6”的频率440Hz


#define l_xi 494     //将“l_xi”宏定义为低音“7”的频率494Hz


//以下是C调中音的音频宏定义


#define dao 523      //将“dao”宏定义为中音“1”的频率523Hz


#define re 587       //将“re”宏定义为中音“2”的频率587Hz


#define mi 659       //将“mi”宏定义为中音“3”的频率659Hz


#define fa 698       //将“fa”宏定义为中音“4”的频率698Hz


#define sao 784      //将“sao”宏定义为中音“5”的频率784Hz


#define la 880       //将“la”宏定义为中音“6”的频率880Hz


#define xi 987       //将“xi”宏定义为中音“7”的频率523H


//以下是C调高音的音频宏定义


#define h_dao 1046      //将“h_dao”宏定义为高音“1”的频率1046Hz


#define h_re 1174       //将“h_re”宏定义为高音“2”的频率1174Hz


#define h_mi 1318       //将“h_mi”宏定义为高音“3”的频率1318Hz


#define h_fa 1396      //将“h_fa”宏定义为高音“4”的频率1396Hz


#define h_sao 1567     //将“h_sao”宏定义为高音“5”的频率1567Hz


#define h_la 1760      //将“h_la”宏定义为高音“6”的频率1760Hz


#define h_xi 1975      //将“h_xi”宏定义为高音“7”的频率1975Hz


/*******************************************


函数功能:1个延时单位,延时200ms


******************************************/


void delay()


{


unsigned char i,j;


for(i=0;i<250;i++)


for(j=0;j<250;j++)


;


}


/*******************************************


函数功能:主函数


******************************************/


void main(void)


{


unsigned char i,j;


//以下是《渴望》片头曲的一段简谱


unsigned  int code f[]={re,mi,re,dao,l_la,dao,l_la,    //每行对应一小节音符


l_sao,l_mi,l_sao,l_la,dao,


l_la,dao,sao,la,mi,sao,


re,


mi,re,mi,sao,mi,


l_sao,l_mi,l_sao,l_la,dao,


l_la,l_la,dao,l_la,l_sao,l_re,l_mi,


l_sao,


re,re,sao,la,sao,


fa,mi,sao,mi,


la,sao,mi,re,mi,l_la,dao,



//以下是简谱中每个音符的节拍



re,


mi,re,mi,sao,mi,


l_sao,l_mi,l_sao,l_la,dao,


l_la,dao,re,l_la,dao,re,mi,


re,


l_la,dao,re,l_la,dao,re,mi,


re,


0xff};//以0xff作为音符的结束标志



//"4"对应4个延时单位,"2"对应2个延时单位,"1"对应1个延时单位


unsignedcharcodeJP[]={4,1,1,4,1,1,2,


2,2,2,2,8,


4,2,3,1,2,2,


10,


4,2,2,4,4,


2,2,2,2,4,


2,2,2,2,2,2,2,


10,


4,4,4,2,2,


4,2,4,4,


4,2,2,2,2,2,2,


10,


4,2,2,4,4,


2,2,2,2,6,


4,2,2,4,1,1,4,


10,


4,2,2,4,1,1,4,


10


};


EA=1;           //开总中断


ET0=1;          //定时器T0中断允许


TMOD=0x00;     //  使用定时器T0的模式1(13位计数器)


while(1)         //无限循环


{


i=0;   //从第1个音符f[0]开始播放


while(f[i]!=0xff)               //只要没有读到结束标志就继续播放


{


C=460830/f[i];


TH0=(8192-C)/32;    //可证明这是13位计数器TH0高8位的赋初值方法


TL0=(8192-C)%32;    //可证明这是13位计数器TL0低5位的赋初值方法


TR0=1;              //启动定时器T0



}



}



}



for(j=0;j

delay();


TR0=0;


i++;



//控制节拍数


//延时1个节拍单位


//关闭定时器T0


//播放下一个音符



/***********************************************************


函数功能:定时器T0的中断服务子程序,使P3.7引脚输出音频的方波


************************************************************/


void Time0(void) interrupt 1 using 1


{


sound=!sound;       //将P3.7引脚输出电平取反,形成方波


TH0 =(8192-C)/32;    //可证明这是13位计数器TH0高8位的赋初值方法


TL0 =(8192-C)%32;    //可证明这是13位计数器TL0低5位的赋初值方法


}

分析:对于音符我就不了解了。


//实例56-1:数据发送程序


#include//包含单片机寄存器的头文件


unsigned char code Tab[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};


//流水灯控制码,该数组被定义为全局变量


/*****************************************************


函数功能:向PC发送一个字节数据


***************************************************/


void Send(unsigned char dat)


{


SBUF=dat;


while(TI==0);


TI=0;


}


/**************************************************************


函数功能:延时约150ms


**************************************************************/


void delay(void)


{


unsigned char m,n;


for(m=0;m<200;m++)


for(n=0;n<250;n++)


;


}


/*****************************************************


函数功能:主函数


***************************************************/


void main(void)


{


unsigned char i;


TMOD=0x20;  //TMOD=00100000B,定时器T1工作于方式2


SCON=0x40;  //SCON=01000000B,串口工作方式1


PCON=0x00;  //PCON=00000000B,波特率9600


TH1=0xfd;   //根据规定给定时器T1赋初值


TL1=0xfd;   //根据规定给定时器T1赋初值


TR1=1;       //启动定时器T1


while(1)


{


for(i=0;i<8;i++)    //模拟检测数据


{


Send(Tab[i]);          //发送数据i


delay();   //50ms发送一次检测数据


}


}


}

分割线


//实例56-2:数据接收程序


#include//包含单片机寄存器的头文件


/*****************************************************


函数功能:接收一个字节数据


***************************************************/


unsigned char Receive(void)


{


unsigned char dat;


while(RI==0)   //只要接收中断标志位RI没有被置“1”


;      //等待,直至接收完毕(RI=1)


RI=0;      //为了接收下一帧数据,需将RI清0


dat=SBUF;  //将接收缓冲器中的数据存于dat


return dat;


}


/*****************************************************


函数功能:主函数


***************************************************/


void main(void)


{


TMOD=0x20;  //定时器T1工作于方式2


SCON=0x50;  //SCON=01010000B,串口工作方式1,允许接收(REN=1)


PCON=0x00;  //PCON=00000000B,波特率9600


TH1=0xfd;  //根据规定给定时器T1赋初值


TL1=0xfd;  //根据规定给定时器T1赋初值


TR1=1;    //启动定时器T1


REN=1;    //允许接收


while(1)


{


P1=Receive();//将接收到的数据送P1口显示


}


}


//实例57-1:数据发送程序


#include//包含单片机寄存器的头文件


sbit p=PSW^0;


unsigned char code Tab[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};


//流水灯控制码,该数组被定义为全局变量


/*****************************************************


函数功能:向PC发送一个字节数据


***************************************************/


void Send(unsigned char dat)


{


ACC=dat;


TB8=p;


SBUF=dat;


while(TI==0)


;


TI=0;


}


/**************************************************************


函数功能:延时约150ms


**************************************************************/


void delay(void)


{


unsigned char m,n;


for(m=0;m<200;m++)


for(n=0;n<250;n++)


;


}


/*****************************************************


函数功能:主函数


***************************************************/


void main(void)


{


unsigned chari;


TMOD=0x20;  //TMOD=00100000B,定时器T1工作于方式2


SCON=0xc0;  //SCON=11000000B,串口工作方式3,


//SM2置0,不使用多机通信,TB8置0


PCON=0x00;  //PCON=00000000B,波特率9600


TH1=0xfd;     //根据规定给定时器T1赋初值


TL1=0xfd;     //根据规定给定时器T1赋初值


TR1=1;       //启动定时器T1


while(1)


{


for(i=0;i<8;i++)    //模拟检测数据


{


Send(Tab[i]);          //发送数据i


delay();   //50ms发送一次检测数据


}


}


}

//实例57-2:数据接收程序


#include//包含单片机寄存器的头文件


sbitp=PSW^0;


/*****************************************************


函数功能:接收一个字节数据


***************************************************/


unsigned char Receive(void)


{


unsigned char dat;


while(RI==0)     //只要接收中断标志位RI没有被置"1"


;        //等待,直至接收完毕(RI=1)


RI=0;      //为了接收下一帧数据,需将RI清0


ACC=SBUF;  //将接收缓冲器中的数据存于dat


if(RB8==p)


{


dat=ACC;


return dat;


}


}


/*****************************************************


函数功能:主函数


***************************************************/


void main(void)


{


TMOD=0x20;  //定时器T1工作于方式2


SCON=0xd0;  //SCON=11010000B,串口工作方式1,允许接收(REN=1)


PCON=0x00;  //PCON=00000000B,波特率9600


TH1=0xfd;     //根据规定给定时器T1赋初值


TL1=0xfd;     //根据规定给定时器T1赋初值


TR1=1;       //启动定时器T1


REN=1;       //允许接收


while(1)


{


P1=Receive();//将接收到的数据送P1口显示


}


}

//实例58:单片机向PC发送数据


#include//包含单片机寄存器的头文件


unsigned char code Tab[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};


//流水灯控制码,该数组被定义为全局变量


/*****************************************************


函数功能:向PC发送一个字节数据


***************************************************/


void Send(unsigned char dat)


{


SBUF=dat;


while(TI==0)


;


TI=0;


}


/**************************************************************


函数功能:延时约150ms


**************************************************************/


void delay(void)


{


unsigned char m,n;


for(m=0;m<200;m++)


for(n=0;n<250;n++)


;


}


/*****************************************************


函数功能:主函数


***************************************************/


void main(void)


{


unsigned char i;


TMOD=0x20;  //TMOD=00100000B,定时器T1工作于方式2


SCON=0x40;  //SCON=01000000B,串口工作方式1


PCON=0x00;  //PCON=00000000B,波特率9600


TH1=0xfd;     //根据规定给定时器T1赋初值


TL1=0xfd;     //根据规定给定时器T1赋初值


TR1=1;       //启动定时器T1


while(1)


{


for(i=0;i<8;i++)    //模拟检测数据


{


Send(Tab[i]);          //发送数据i


delay();   //150ms发送一次数据


}


}


}

//实例59:单片机接收PC发出的数据


#include         //包含单片机寄存器的头文件


/*****************************************************


函数功能:接收一个字节数据


***************************************************/


unsigned char Receive(void)


{


unsigned char dat;


while(RI==0)   //只要接收中断标志位RI没有被置“1”


;      //等待,直至接收完毕(RI=1)


RI=0;      //为了接收下一帧数据,需将RI清0


dat=SBUF;  //将接收缓冲器中的数据存于dat


return dat;


}


/*****************************************************


函数功能:主函数


***************************************************/


void main(void)


{


TMOD=0x20;  //定时器T1工作于方式2


SCON=0x50;  //SCON=01010000B,串口工作方式1,允许接收(REN=1)


PCON=0x00;  //PCON=00000000B,波特率9600


TH1=0xfd;  //根据规定给定时器T1赋初值


TL1=0xfd;  //根据规定给定时器T1赋初值


TR1=1;    //启动定时器T1


REN=1;    //允许接收


while(1)


{


P1=Receive();//将接收到的数据送P1口显示


}


}



登录icspec成功后,会自动跳转查看全文
博客评论
还没有人评论,赶紧抢个沙发~
发表评论
说明:请文明发言,共建和谐网络,您的个人信息不会被公开显示。