11.0592M晶振 ms延时程序
单片机实验指导书

目录实验一系统认识实验 (2)实验二端口I/O输入输出实验 (14)实验三外部中断实验 (17)实验四定时器实验 (21)实验五串行口通信实验 (25)实验六串行通信的调试实验 (29)实验七数码管静态显示实验 (34)实验八数码管动态显示实验 (39)实验一系统认识实验一、实验目的1.学习Keil C51编译环境的使用;2.学习STC单片机的下载软件STC-ISP的使用;3.掌握51单片机输出端口的使用方法。
二、实验内容任选单片机的一组I/O端口,连接LED发光二极管,编写程序实现8个LED按二进制加1点亮。
三、接线方案单片机P10~P17/C51单片机接L0~L7/LED显示,如下图:图1-1实验线路四、实验原理51单片机有4个8位的并行I/O端口:P0、P1、P2、P3,在不扩展存储器、I/O端口,在不使用定时器、中断、串行口时,4个并行端口,32根口线均可用作输入或输出。
作为输出时,除P0口要加上拉电阻外,其余端口与一般的并行输出接口用法相同,但作为输入端口时,必须先向该端口写“1”。
例如P0接有一个输入设备,从P0口输入数据至累加器A中,程序为:MOV P0, #0FFHMOV A, P0若将P0.0位的数据传送至C中,程序为:SETB P0.0MOV C, P0.0五、实验步骤1、连接串行通信电缆和电源线;2、根据图1-1实验线路进行电路连接;3、将C51单片机核心板上的三个开关分别拨到“独立”、“运行”“单片机”;4、打开实验箱上的电源开关。
5、利用Keil C51创建实验程序,并进行编译生成后缀为.HEX的文件;6、利用STC-ISP软件将后缀为.HEX的文件下载到单片机ROM中;7、观察实验现象,并记录。
若实验现象有误请重复第5、6步。
六、参考程序ORG 0000H ;程序的开始LJMP MAIN ;转入主程序ORG 0200H ;主程序的开始MAIN: MOV P1,#00H ;P1口做准备M1: INC P1 ;P1口连接输出计数,LCALL DELAY ;转入延时子程序LJMP M1 ;循环DELAY: MOV R5,#255 ;延时子程序D1: MOV R6,#255DJNZ R6,$DJNZ R5,D1RETEND ;程序体结束七、思考题1、利用其他I/O口实现LED加1点亮功能;2、利用P1端口实现流水灯(左移或右移)功能;3、实现LED其他点亮功能。
为什么单片机的晶振会有 11.0592mhz 这个数字

为什么单片机的晶振会有11.0592MHz 这个数字?71郭昊可以被准确分频成各种通信常用的波特率11.0592MHz = 192*57600 = 384*28800 = 576*19200 = 1152*9600update: @肖孝云: 很好的思路,但是这是什么因果关系?那为什么不能先是有个12M的频率,然后分频成其他的波特率呢?答: 因为美国工业电子联盟(Electronic Industries Alliance,EIA) RS-232-C标准中规定了数据传输速率为: 50、75、100、150、300、600、1200、2400、4800、9600、19200、38400如果继续问为什么它要这么制定, 这个我就不确定了, 据Google是因为由电信线路特性决定的电话线路的带通是300--3KHz,当时HAYES先搞的modem,所以用的2400HZ信号,对应波特率是2400。
由于基本频率确定了,以后采用的提高通讯速率的方法都是在2400基础上倍频的,所以形成了9600,19200。
当然, 实际原因就是大家通用标准都一样了, 慢慢淘汰下来非主流的, 就是这样了, 其实很多行业都是这样, 为什么要这么做, 或许有一定的理由, 但追根究底还是历史惯性, 大家都这么做了, 更改起来没有必要而且成本太大, 所以就一直延续了, 比如键盘的qwerty布局, 220v等等另外12m不如11.0592M好分频2013-12-038 条评论感谢分享收藏·没有帮助·举报4王俊楠上面说的有些复杂,本人没有不敬的意思,说一下我在书上看的吧。
标准的51单片机晶振是1.2M-12M,一般由于一个机器周期是12个时钟周期,所以先12M时,一个机器周期是1US,好计算,而且速度相对是最高的(当然现在也有更高频率的单片机)。
11.0592M是因为在进行通信时,12M频率进行串行通信不容易实现标准的波特率,比如9600,4800,而11.0592M 计算时正好可以得到,因此在有通信接口的单片机中,一般选11.0592M2013-09-23添加评论感谢分享收藏·没有帮助·举报2马千里,我是学电信的,我不是走这条路的楼上说的大体上都是对的:这么奇葩的频率目的是————分频,产生通信用的同步信号(同步信号的频率,就是那个波特率)但是为什么是11.0592而不是12?原因是——12分不出整数的波特率,或者说常用的整数波特率。
舵机的控制

//调节舵机使之转动5个角度0 45 90 135 180 PWM信号周期为20ms,//控制高电平的持续时间即可控制舵机停止制动的角度,0.5ms-0度1-45 1.5-90 2-135 2.5-180 //程序流程是:开机时舵机角度自动转为0度,按下P3.7则转到45度,以后就根据两个按键的按下而转动#include "reg52.h"unsigned char count; //0.5ms次数标识sbit pwm =P2^0 ; //PWM信号输出sbit jia =P3^7; //角度增加按键检测IO口sbit jan =P3^6; //角度减少按键检测IO口unsigned char jd; //角度标识void delay(unsigned char i)//延时{unsigned char j,k;for(j=i;j>0;j--)for(k=125;k>0;k--);}void Time0_Init() //定时器初始化{TMOD = 0x01; //定时器0工作在方式1IE = 0x82;TH0 = 0xfe;TL0 = 0x33; //11.0592MZ晶振,0.5msTR0=1; //定时器开始}void Time0_Int() interrupt 1 //中断程序{TH0 = 0xfe; //重新赋值TL0 = 0x33;if(count<jd) //判断0.5ms次数是否小于角度标识pwm=1; //确实小于,PWM输出高电平elsepwm=0; //大于则输出低电平count=(count+1); //0.5ms次数加1count=count%40; //次数始终保持为40 即保持周期为20ms}void keyscan() //按键扫描{if(jia==0) //角度增加按键是否按下{delay(10); //按下延时,消抖if(jia==0) //确实按下{jd++; //角度标识加1count=0; //按键按下则20ms周期从新开始if(jd==6)jd=5; //已经是180度,则保持while(jia==0); //等待按键放开}}if(jan==0) //角度减小按键是否按下{delay(10);if(jan==0){jd--; //角度标识减1count=0;if(jd==0)jd=1; //已经是0度,则保持while(jan==0);}}}void main(){jd=1;count=0;Time0_Init();while(1){keyscan(); //按键扫描}}。
不同晶振频率时1MS延时程序

for(y=314; y>0; y--);
}
/********************(STC12C5608AD 4.9152MHZ z=1时精确延时1ms)****************/
void delay_1ms(uint z)
{
uint x,y;
for(x=z; x>0; x--)
for(y=848; y>0; y--);
}
/********************(STC12C5608AD 12MHZ z=1时精确延时1ms)*******************/
void delay_1ms(uint z)
{
uint x,y;
for(x=z; x>0; x--)
for(y=920; y>0; y--);
void delay_1ms(uint z)
{
uinபைடு நூலகம் x,y;
for(x=z; x>0; x--)
for(y=1228; y>0; y--);
}
/******************(STC12C5608AD 16.384MHZ z=1时精确延时1ms)******************/
void delay_1ms(uint z)
{
uint x,y;
for(x=z; x>0; x--)
for(y=306; y>0; y--);
}
/********************(STC12C5608AD 4.096MHZ z=1时精确延时1ms)****************/
void delay_1ms(uint z)
TM1650读写程序

*文 件 名:TM1650-V2.0
*当前版本:V3.0
*MCU 型号:STC8F2K64S2
*开发环境:Keil uVision4
*晶震频率:11.0592MHZ
********************************************************************* ***********/
*********************************************/ void main() {
LD=1;//1 级亮度 TM1650_SystemCmd();//8 段模式+正常工作模式+开显示 TM1650_send(0x68,0x00);//清显示 TM1650_send(0x6a,0x00); TM1650_send(0x6c,0x00); TM1650_send(0x6e,0x00); while(1)// {
//KI3+DIG1 //KI3+DIG2 //KI3+DIG3 //KI3+DIG4
//KI4+DIG1 //KI4+DIG2 //KI4+DIG3 //KI4+DIG4
//KI5+DIG1 //KI5+DIG2 //KI5+DIG3 //KI5+DIG4
//KI6+DIG1 //KI6+DIG2 //KI6+DIG3 //KI6+DIG4
//数据线
//读取按键值存储
uint8 keya;
//定义读出按键返回值
uint8 bdata LED;//1 为亮//定义 8 个灯
sbit LED0 = LED^0; //指示灯
单片机原理及其应用实验报告

用导线将实验箱中的P1.0~P1.7分别与LED发光二极管L1~L8相连。INT0
与负脉冲相连(硬件在实验箱的具体位置可以参照文档最后面的附图)。
程序:
C语言程序
# include<regx51.h>
unsigned char STATE;
unsigned char s0;
/*---延时子程序(有参函数),t=n*10ms---*/
/*---定时器0中断程序---*/
ET0P:DEC A ;A减1
MOV TH0,#4CH
MOV TL0,#00H
RETI
END
实验现象:
可以看到用P1口所接的8路LED表示的二进制数每隔0.5s加1。
P1=P1<<1;
if(P0_1!=0|P0_0!=0)
break;
}
}
if(P0_1==0&P0_0==1)
{
P1=0x80;
for(i=1;i<=8;i++)
{delay(100);
P1=P1>>1;
if(P0_1!=0|P0_0!=1)
break;
}
}
if(P0_1==1&P0_0==0)
{
P1=0x01;
END
实验现象:
可以看到LED1大致亮1s后灭1s,如此循环。
(2)实验内容:
I/O口做输入口,一个I/O口接一个拨动开关,另一个I/O口接一个LED发光二极管,单片机读取开关的状态并通过LED显示出来。
有关说明:P0口是一组漏极开路型双向I/O口,也即地址/数据总线复用口。
对端口写“1”可作为高阻抗输入端用。
两种单片机定时器延时程序常见问题解答
两种单片机定时器延时程序常见问题解答单片机定时器在51单片机的应用过程中,具有控制程序时间的重要作用,一些延时程序或中断程序也都是需要通过单片机定时器来完成操作的。
在今天的文章中,我们将会为大家分享两种定时器延时程序的常见问题解答,希望能够对新人工程师的程序学习和实际操作有所帮助。
第一个问题:单片机延时程序的延时时间怎幺计算的? 这个问题是很多新手在学习单片机程序时都会遇到的。
如果想要用循环语句实现的循环,那是没法计算的,智能通过软件仿真看到具体时间,但是一般精精确延时是没法用循环语句实现的。
如果想精确延时,那幺就必须合理的利用单片机定时器来完成设置了。
通常来说,定时器延时时间与晶振有关系,单片机系统一般常选用11.059,2MHz、12MHz或6MHz晶振。
第一种更容易产生各种标准的波特率,后两种的一个机器周期分别为1μs和2μs,便于精确延时。
本程序中假设使用频率为12MHz的晶振。
最长的延时时间可以达到216=65536 μs。
若定时器工作在方式2,则可实现极短时间的精确延时。
如使用其他定时方式,则要考虑重装定时初值的时间,这里需要注意一个问题,那就是重装定时器初值占用2个机器周期,计算时需要加以考虑。
第二个问题:有没有可以让单片机89S51,12M定时器延时10分钟、控制1个灯的方法? 这一问题是定时器在进行延时程序的编写时,非常常见的一个基础性问题。
面对这种情况时,我们可以设50ms中断一次,定时初值,TH0=0x3c、TL0=0xb0,中断20次为1S。
如果需要让定时器延时10分钟的话,那幺需要中断12000次。
计12000次后,给IO口一个低电平。
如功率不够,可再加扩展,这时就可以控制灯了。
C51精确延时
C:0x080C 22 RET
计算分析:
程序共有三层循环
一层循环n:R5*2 = 81*2 = 162us DJNZ 2us
二层循环m:R6*(n+3) = 202*165 = 33330us DJNZ 2us + R5赋值1us = 3us
三层循环: R7*(m+3) = 15*33333 = 499995us DJNZ 2us + R6赋值1us = 3us
C:0x080A DDFA DJNZ R5,C:0806
C:0x080C DEF6 DJNZ R6,C:0804
C:0x080E DFF2 DJNZ R7,C:0802
C:0x0810 22 RET
五._nop_指令
可以利用intrins.h所带的头文件中的_nop_指令实现us级得延时,当主程序调用delay()函数时,首先执行LCALL指令占用2个机器周期,然后执行_nop_函数,相当于汇编中的NOP指令,占用一个机器周期,最后执行一个RST指令占用两个机器周期,所以一个_nop_指令延时5个机器周期。要增加延时时间,可以多添加几个_nop_函数指令,进行计算,两个_nop_指令延时6个机器周期。
for(j=116;j>0;j--)
for(k=214;k>0;k--);
}
产生的汇编
C:0x0800 7F05 MOV R7,#0x05
C:0x0802 7E04 MOV R6,#0x04
C:0x0804 7D74 MOV R5,#0x74
C:0x0806 7CD6 MOV R4,#0xD6
C:0x0808 DCFE DJNZ R4,C:0808
单片机延时程序怎么写(一)
单片机延时程序怎么写(一)引言概述:在单片机编程中,延时程序是非常常见且重要的一部分。
延时程序用于控制程序的执行时间,比如延时一定时间后进行下一步操作,实现定时或者延时功能。
本文将介绍如何编写单片机延时程序,帮助读者理解延时程序的基本原理和实现方法。
正文内容:1. 使用循环实现延时1.1 初始化相关寄存器和计数器1.2 进入延时循环1.3 设置循环次数或延时时间1.4 循环减计数器1.5 延时完成后退出循环2. 使用定时器实现延时2.1 初始化定时器相关设置2.2 设定定时器计数值2.3 开启定时器2.4 等待定时器中断或达到设定时间2.5 定时结束后关闭定时器3. 使用外部晶振实现延时3.1 初始化外部晶振相关设置3.2 计算延时对应的晶振周期3.3 使用循环控制延时时钟数3.4 延时完成后恢复晶振设置3.5 注意外部晶振频率与延时精度的关系4. 使用中断实现延时4.1 初始化中断相关设置4.2 设定中断触发时间或循环次数4.3 进入主循环等待中断触发4.4 中断处理程序执行延时操作4.5 中断结束后继续执行主循环5. 延时程序的注意事项5.1 延时精度和误差控制5.2 选择合适的延时方法和计算方式5.3 防止延时程序过长导致其他功能受阻5.4 注意延时程序对系统时钟和其他模块的影响5.5 调试和优化延时程序总结:编写单片机延时程序需要根据具体应用需求选择合适的方法,并考虑延时精度、系统资源占用等因素。
循环、定时器、外部晶振和中断等是常见的延时实现方式,开发者应根据具体情况进行选择和优化。
同时,在编写延时程序时要注意避免影响系统其他功能的正常运行,并进行必要的调试和优化工作,以确保延时程序的可靠性和稳定性。
51单片机精确延时程序
51 单片机精确延时程序51 单片机精确延时程序(晶振12MHz,一个机器周期1us.)几个精确延时程序:在精确延时的计算当中,最容易让人忽略的是计算循环外的那部分延时,在对时间要求不高的场合,这部分对程序不会造成影响.一. 500ms 延时子程序程序:.(晶振12MHz,一个机器周期1us.)void delay500ms(void){unsigned char i,j,k;for(i=15;i>0;i--)for(j=202;j>0;j--)for(k=81;k>0;k--);}计算分析:程序共有三层循环一层循环n:R5*2 = 81*2 = 162us DJNZ 2us二层循环m:R6*(n+3) = 202*165 = 33330us DJNZ 2us + R5 赋值1us = 3us 三层循环: R7*(m+3) = 15*33333 = 499995us DJNZ 2us + R6 赋值1us = 3us 循环外: 5us 子程序调用2us + 子程序返回2us + R7 赋值1us = 5us延时总时间= 三层循环+ 循环外= 499995+5 = 500000us =500ms计算公式:延时时间=[(2*R5+3)*R6+3]*R7+5二. 200ms 延时子程序程序:void delay200ms(void){unsigned char i,j,k;for(i=5;i>0;i--)for(j=132;j>0;j--)for(k=150;k>0;k--);}三. 10ms 延时子程序程序: void delay10ms(void){unsigned char i,j,k;for(i=5;i>0;i--)for(j=4;j>0;j--)for(k=248;k>0;k--);}四. 1s 延时子程序程序:void delay1s(void){unsigned char h,i,j,k;for(h=5;h>0;h--)for(i=4;i>0;i--)for(j=116;j>0;j--)for(k=214;k>0;k--);}void delay1s(void)//12M 晶振,延时999999.00us {unsigned char i,j,k;for(i=46;i>0;i--)for(j=152;j>0;j--)for(k=70;k>0;k--);}扩展阅读:单片机延时问题20 问。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
精确的C语言延时子程序表/自己测试,11.0592M晶振ms延时程序,绝对精确
51单片机,需要用MS 延时程序的时候才发现网上的好多程序不好用,
下面这个忘记从哪里找的,但是已经相当精确,keil亲测。
=======================================================
/*--------------------ms延时函数-----------------------*/
void delay_ms(unsigned int ms_number) // ms延时函数(AT89C51 @ 11.0592MHz)
{
unsigned int i;
unsigned char j;
for(i=0;i<ms;i++)
{
for(j=0;j<200;j++);
for(j=0;j<102;j++);
}
}
/--------------------------------------------------------------------
用法:在参数传入时填上几就是几毫秒啦
比如,想延时100ms,就把ms_number赋值为50
×××××××××××××××××××××××××××××××××××××××××××××
=============================================
以下为原来转载的资料
=============================================
文章转自Proteus仿真社区作者:liaoguobao00
未作验证,如有问题请和原作者联系:lsygrzzh@
=============================================
用C语言写出来程序非常的简练,它是一种模块化的语言,一种比汇编更高级的语言,但是就是这样一种语言也还是有它不足之处:它的延时很不好控制,我们常常很难知道一段延时程序它的精确延时到底是多少,这和汇编延时程序没法比。
但有时后写程序又不得不要用到比较精确的延时,虽然说可以用混合编程的方式解决,但这种方式不是每个人都能掌握,且写起来也麻烦。
所以,通过测试我给大家提供一个延时子程序模块,并以此给一个出我们经常用到的延时的数据表格。
(注意:表格中的数据只适合我的延时模块,对其他的延时程序不适用,切忌!!!!!!!!别到时候延时不对来骂我)
延时模块:其中问号代表要填的数,要延时多少,到表格中去找数据,然后填上就OK!切忌3条FOR语句不能颠倒顺序
void Delay()
{
unsigned char a,b,c;
for(a=0;a<?;a++)
for(b=0;b<?;b++)
for(c=0;c<?;c++);
}
数据表如下
/****************************************************************************************************** ****************/
延时时间a的值b的值c的值延时误差(us)
10us 1 1 1 -0.5
20us 1 1 8 0
30us 1 1 15 +0.5
40us 2 1 9 0
50us 1 1 28 0
60us 1 1 35 +0.5
70us 1 1 42 +1
80us 1 1 48 0
90us 1 1 55 +0.5
100us 1 1 61 -0.5
200us 1 1 128 0
300us 3 1 63 +1.5
400us 2 1 129 0
500us 5 1 63 +0.5
600us 6 1 63 0
700us 7 1 63 -0.5
800us 1 3 175 +0.5
900us 9 1 63 -1.5
1ms 1 3 219 -1.5
2ms 2 3 220 +3
3ms 3 3 220 +3
Xms X 3 220 +3
(X的范围为2到255)
基本上我们平时用到的延时都在这里了,每种延时的误差都很小,最大也不过3us,有的甚至没有误差,已经很精确了,如果想延时1秒钟,你可以连续调用延时250ms的程序4次,总共延时误差12us,这样的误差已经不算误差了,用汇编语言编写还达不到这个程度。
现在你不再为延时不精确担忧了,参照表中的数据写延时,想延时多少就能延时多少。
再次重申:此表格是根据我的延时模块编写,这也是大多数朋友都习惯用的一个模块,如果你用其他模块或是改动了我的模块,延时都不准的,不信大家可以试试!!!。