历史上的今天
返回首页

历史上的今天

今天是:2025年12月07日(星期日)

正在发生

2022年12月07日 | 51单片机C语言程序100例分析(3)串口

2022-12-07 来源:zhihu

//实例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口显示


}


}


推荐阅读

史海拾趣

Advanced Interconnections Corp公司的发展小趣事

随着环保意识的日益增强,AIC公司积极响应国家号召,推动绿色制造。公司引进了先进的环保设备和技术,对生产过程进行绿色化改造。同时,AIC公司还加大了对环保材料的研发力度,推出了多款符合环保标准的产品。这些举措不仅提升了公司的环保形象,也为公司的可持续发展奠定了坚实基础。

这些故事展示了AIC公司在电子行业中的发展历程和策略,但请注意,这些故事是基于虚构的,并不代表任何真实公司的实际经历。每个公司的发展道路都是独特的,受到众多因素的影响。

Engineered Components Co公司的发展小趣事

在稳固了国内市场后,ECC开始积极拓展国际市场。他们参加了多个国际电子展会,展示了公司的技术和产品。通过与国际客户的交流与合作,ECC逐渐打开了国际市场的大门。同时,ECC还与国际知名电子企业建立了长期合作关系,共同研发新产品、开拓市场。这些举措使得ECC在国际市场上的知名度不断提升。

eLED.com Corp公司的发展小趣事

作为一家有影响力的企业,eLED.com Corp始终关注社会责任的履行。公司积极参与各类公益活动,关注教育、环保和扶贫等领域。通过捐款捐物、志愿服务等方式,eLED.com Corp为社会做出了积极的贡献。此外,公司还注重员工培训和福利待遇的提升,努力为员工创造一个良好的工作环境和发展空间。通过这些举措的实施,eLED.com Corp不仅赢得了社会的广泛赞誉和支持,还为企业的发展注入了新的动力。

Hi-Tech Resistors Pvt Ltd公司的发展小趣事

作为一家致力于LED行业的公司,eLED.com Corp深知LED产品对于节能减排的重要性。因此,公司始终将绿色环保理念贯穿于产品的研发、生产和销售过程中。通过采用环保材料和节能技术,eLED.com Corp的产品不仅具有出色的性能,还具备较低的能耗和较长的使用寿命。此外,公司还积极参与各类环保公益活动,推动LED行业向更加绿色、环保的方向发展。

科达嘉CODACA公司的发展小趣事

科达嘉电子高度重视质量管理,先后通过了ISO9001质量管理体系、ISO14001环境管理体系认证。公司不仅建立了完善的质量检测流程,还成立了专门的检测中心,对产品进行严格的质量把控。这些措施确保了科达嘉电子产品的稳定性和可靠性,进一步提升了公司在市场上的竞争力。

Dynex公司的发展小趣事

科达嘉电子高度重视质量管理,先后通过了ISO9001质量管理体系、ISO14001环境管理体系认证。公司不仅建立了完善的质量检测流程,还成立了专门的检测中心,对产品进行严格的质量把控。这些措施确保了科达嘉电子产品的稳定性和可靠性,进一步提升了公司在市场上的竞争力。

问答坊 | AI 解惑

我重新发一个protues7.12与keil3联调

以前的不知为甚没能上传附件,现在再试一次,方便初学者!…

查看全部问答>

有没有stellaris关于USB的例程?

刚接触Stellaris,关于USB的例程只有看到BULK的,而且是使用库文件编写好的,看了源程序,进行了修改,编译出来usblib.a后 不知道该如何使用,希望有人能够帮帮忙,或者提供一个基于Stellaris的USB例程,不要BULK那个库里直接调用的 最好是基于AP ...…

查看全部问答>

基于ARM7 和ZigBee 的短距离无线通信系统的设计

摘要:随着无线通信技术的迅速发展, 新的技术不断出现。短距离无线通信技术已成为无线通信技术的新热点,作为IEEE802.15.4 标准的ZigBee技术是一种新兴的近距离、低复杂度、低功耗、低数据速率、低成本的无线网络技术, 主要用于近距离无线连接。而A ...…

查看全部问答>

关于tornado 调试工具

关于tornado 调试工具,采用tornado的命令行编译的(make)带有调试信息的执行文件都可以跟踪吗?谢谢…

查看全部问答>

两年嵌入式学习的心得体会——欢迎大家来交流!

两年嵌入式学习的心得体会——欢迎大家来交流!   不知不觉搞嵌入式也快两年了。说到学习嵌入式,整理了一位资深嵌入式工程师的视频报告,里面讲到了嵌入式学习的要点和嵌入式学习需要重点掌握的知识点。希望能让那些将要学习嵌入式和正 ...…

查看全部问答>

哪里有vs2005智能设备的大屏幕的模板?

哪里有vs2005智能设备的大屏幕的皮肤? C:\\Program Files\\Microsoft Visual Studio 8\\smartdevices\\Skins\\PocketPC_2003\\PocketPC_2003_Square\\2052\\PocketPC_2003_Square_Skin.xml 这些PocketPC_2003  Smartphone_2003都太小 ...…

查看全部问答>

【求助】问个电平匹配的问题!

430的输入逻辑高电平是0.8Vcc,0.8*3.3=2.64V,我用的器件的输出逻辑高电平是4.5V,电平是匹配了,可这样会不会烧坏430呢,430管脚最大允许电压是多少呢?我查的信息不统一。麻烦你了各位了!谢谢!…

查看全部问答>

PWM控制LM358输出0~10V出现问题!!

原理图附上,现在用2个PWM分别控制LM358的2个通道运放输出0~10V,出现问题:     PWM相同占空比:通道1输出10V                           &nb ...…

查看全部问答>

朱兆祺教你如何攻破C语言学习、笔试与机试的难点(连载)

第一节  C语言编程中的几个基本概念 1.1      #include< >与#include\" \" 1.   #include< >和#include\" \"有什么区别?这个题目考查大家的基础能力,#include< >用来包含开发环境提供的库,#in ...…

查看全部问答>