Atmega16单片机12MHz延时函数

合集下载

51单片机C程序标准延时函数

51单片机C程序标准延时函数

51单片机C程序标准延时函数在此,我用的是12M晶振,一个时钟周期是1/12us,一个机器周期为12个时钟周期,则机器周期为1us,而51单片机执行一条语句,为1,2,4个机器周期不等,根据语句的长度来定,一般为1个机器周期。

而_nop_()为一条空语句,执行一次需要一个机器周期。

1us#include<intrins.h>_nop_();执行了一条_nop_();所以延时为1us;10usvoid delay10us(){_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}执行了6条_nop_(),延时6us,主函数调用delay10us 时,先执行了LCALL指令2us,然后执行6条_nop_()语句6us,最后执行一条RET指令2us,所以总共延时10us。

100usvoid delay100us(){delay10us();delay10us();delay10us();delay10us();delay10us();delay10us();delay10us();delay10us();delay10us();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}与上面的一样,主函数调用delay100us();先执行了LCALL语句2us,再调用9个delay10us()函数90us,然后执行了6条_nop_()语句6us,最后执行了一条RET语句2us,总共100us。

1msvoid delay1ms(){f=1;TH0=0xe1;TL0=0X13;TR0=1;while(f);}void T0_3() interrupt 1{TR0=0;f=0;}这里就直接用51单片机内部定时器延时了,如果用_nop_();如果要做到微妙不差,那程序就太长了。

这里我用的是定时器0的方式0,13位定时器,这里为了方便,我就没就EA=1;ET0=1;TM0D=0X00;写在延时函数里。

步进电机的控制程序

步进电机的控制程序

mega16的,16和32管脚兼容,只不过flash大小不一样,不过中断向量号也不一样,你看下自己改改。

时钟频率:内部RC 1M 芯片:ULN2003 键值:0 小角度快正转。

1 小角度快倒。

2 大角度快转。

3 大角度快倒。

4 小角度正慢转。

5 小角度倒慢转。

6 大角度正慢转。

7 大角度倒慢转。

********************************************************************/#include<iom16v.h>#include <macros.h>#define uchar unsigned char#define uint unsigned intuchar a=0,b=0;uchar KEY_num=0xe1;unsigned int m=9000;const uchar f1[]={0x02,0x06,0x04,0x0c,0x08,0x09,0x01,0x03}; //正转时序3.75度const uchar f2[]={0x04,0x06,0x02,0x03,0x01,0x09,0x08,0x0c}; //倒转时序3.75度const uchar f3[]={0x01,0x02,0x04,0x08}; //正转时序7.5度const uchar f4[]={0x01,0x08,0x04,0x02}; //倒转时序7.5度void delay(int k) //延时{ int i; for(i=0;i<k;i++); }void delay_10ms(uint data){ uint m=2; while(data) { data--; m=2; while(m)m--; } }void zhengzhuan1(void) //正转3.75度{ unsigned char j; for (j=0;j<8;j++) { PORTC=f1[j]; delay(m); } }void daozhuan1(void) //倒转3.75度{ unsigned char j; for (j=0;j<8;j++) { PORTC=f2[j]; delay(m); } }void zhengzhuan2(void) //正转7.5度{ unsigned char j; for (j=0;j<4;j++) { PORTC=f3[j]; delay(m); } }void daozhuan2(void) //倒转7.5度{ unsigned char j; for (j=0;j<4;j++) { PORTC=f4[j]; delay(m); } }void port_int() //初始化端口{ PORTB = 0xf0; DDRB = 0x0F; DDRC=0xff; PORTC=0x01; }void init_devices(void){ CLI(); //禁止所有中断MCUCR = 0x00; MCUCSR = 0x80;//禁止JTAG GICR = 0x00; port_int();SEI();//开全局中断}//按键键值读取程序//返回按键键值,如果没有按键则返回0.void KYY_read(){ //定义按键值存放内存PORTB=0xf0; //行全部送高电平PORTB=0xf0;if((PINB&0xf0)!=0xf0) //有按键{ delay_10ms(1);//延时消抖if((PINB&0xf0)!=0xf0) //确定有按键按下{ PORTB=0xfe; //扫描第一行PORTB=0xfe;if((PINB&0xf0)!=0xf0){ KEY_num=(PINB&0xf0)+1; a=9; }PORTB=0xfd; //扫描第二行PORTB=0xfd;if((PINB&0xf0)!=0xf0){ KEY_num=(PINB&0xf0)+2; } PORTB=0xfb; //扫描第三行PORTB=0xfb;if((PINB&0xf0)!=0xf0){ KEY_num=(PINB&0xf0)+4; } PORTB=0xf7; //扫描第四行PORTB=0xf7;if((PINB&0xf0)!=0xf0){ KEY_num=(PINB&0xf0)+8; } } } //没有按键返回0 }//按键执行程序//送如参数:按键键值KEY_do(uchar data){ uchar KEY_number=data;switch(KEY_number){ case 0xe1:a=0;b=0;daozhuan1();m=5000;break;case 0xd1:a=0;b=1;daozhuan1();m=6000;break;case 0xb1:a=0;b=2;daozhuan1();m=7000;break;case 0x71:a=0;b=3;daozhuan1();m=8000;break;case 0xe2:a=0;b=4;daozhuan2();m=5000;break;case 0xd2:a=0;b=5;daozhuan2();m=6000;break;case 0xb2:a=0;b=6;daozhuan2();m=7000;break;case 0x72:a=0;b=7;daozhuan2();m=8000;break;case 0xe4:a=0;b=8;zhengzhuan1();m=5000;break;case 0xd4:a=0;b=9;zhengzhuan1();m=6000;break;case 0xb4:a=1;b=0;zhengzhuan1();m=7000;break;case 0x74:a=1;b=1;zhengzhuan1();m=8000;break;case 0xe8:a=1;b=2;zhengzhuan2();m=5000;break;case 0xd8:a=1;b=3;zhengzhuan2();m=6000;break;case 0xb8:a=1;b=4;zhengzhuan2();m=7000;break;case 0x78:a=1;b=5;zhengzhuan2();m=8000;break; default:b=0;break;}}void main (void)//主程序{ init_devices();while(1){ KYY_read(); KEY_do(KEY_num); }}#include <reg51.h> //51芯片管脚定义头文件#include <intrins.h> //内部包含延时函数_nop_();#define uchar unsigned char#define uint unsigned intuchar code FFW[8]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9}; uchar code REV[8]={0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0xf3,0xf1};sbit K1 = P3^4; //正转sbit K2 = P3^5; //反转sbit K3 = P3^6; //停止sbit K4 = P3^7;sbit BEEP = P0^6; //蜂鸣器/********************************************************//*/* 延时t毫秒/* 11.0592MHz时钟,延时约1ms/*/********************************************************/void delay(uint t){uint k;while(t--){for(k=0; k<125; k++){ }}}/**********************************************************/void delayB(uchar x) //x*0.14MS{uchar i;while(x--)for (i=0; i<13; i++){ }}}/**********************************************************/ void beep(){uchar i;for (i=0;i<180;i++){delayB(5);BEEP=!BEEP; //BEEP取反}BEEP=1; //关闭蜂鸣器}/********************************************************/ /*/*步进电机正转/*/********************************************************/ void motor_ffw(){uchar i;uint j;for (j=0; j<12; j++) //转1*n圈{if(K4==0){break;} //退出此循环程序for (i=0; i<8; i++) //一个周期转30度{P0 = FFW[i]; //取数据delay(15); //调节转速}}}/********************************************************/ /*/*步进电机反转/********************************************************/ void motor_rev(){uchar i;uint j;for (j=0; j<12; j++) //转1×n圈{if(K4==0){break;} //退出此循环程序for (i=0; i<8; i++) //一个周期转30度{P0 = REV[i]; //取数据delay(15); //调节转速}}}/********************************************************** 主程序**********************************************************/main(){uchar r,N=5; //N 步进电机运转圈数P2=0xDF;while(1){if(K1==0){beep();for(r=0;r<N;r++){motor_ffw(); //电机正转if(K4==0){beep();break;} //退出此循环程序}}else if(K2==0){beep();for(r=0;r<N;r++){motor_rev(); //电机反转if(K4==0){beep();break;} //退出此循环程序}}elseP0 = 0xf0;}}/********************************************************/ULN2803是8路NPN达林顿连接晶体管系列,特别适用于低逻辑电平数字电路,如:TTL,COMS或PMOS/NMOS,和较高的电压/电流要求之间的接口,广泛应用与计算机、打印机、继电器、灯等类似负载中。

冰檐教程系列之ATMEGA16入门篇 (2)

冰檐教程系列之ATMEGA16入门篇 (2)

片内经过标定的 RC 振荡器 片内/片外中断源 6 种睡眠模式: 空闲模式、ADC 噪声抑制模式、省电模式、掉电模式、Standby 模式以及扩展的 Standby 模 式 u I/O 和封装 32 个可编程的 I/O 口 40 引脚 PDIP 封装, 44 引脚 TQFP 封装, 与 44 引脚 MLF 封装 大家有可能对上面特性和外设的某些概念不理解,不用着急,大家会在后面慢慢理解的,我会在后面详细介绍, 那现在正式踏入 ATMEGA16 的学习之旅!
然后我们按照需求和设计设置好熔丝表,将<只读>的勾去掉,点<写入>,此时熔丝就设置好了,为了防止以后 误操作,将<只读>打上勾。这样就可以烧录程序了。下面介绍熔丝的具体设置规则: BODLEVEL: BOD 电平选择 1:2.7V 电平; 0:4.0V 电平---------本开发板设置为 1 (未打勾) BODEN: BOD 功能控制 1:BOD 功能禁止;0:BOD 功能允许---------本开发板设置为 1 注:BOD(Brown-out Detection) 掉电检测电路,如果 BODEN 使能(打勾)启动掉电检测,检测电平由 BODLEVEL 决定,一旦 VCC 下降到触发电平(2.7v 或 4.0v)以下,MUC 复位。 JTAGEN: 1:JTAG 禁止; 0:JTAG 允许 ---------本开发板设置为 1 OCDEN: 1:OCD 功能禁止;0:OCD 允许---------本开发板设置为 1 注:OCDEN(On-chip Debug)片上调试使能位 JTAGEN:使能 JTAG 测试访问端口。 SPIEN: 1:SPI 下载禁止;0:SPI 下载使能---------本开发板设置为 0 CKOPT: CKOPT=0:高幅度振荡输出;CKOPT=1:低幅度振荡输出 ---------本开发板设置为 0 EEAVE: 烧录时 EEPROM 数据保留 1:不保留;0:保留---------本开发板设置为 0 BOOTRST: 复位入口选择 1:程序从 0x0000 地址开始 0:复位后从 BOOT 区执行(设置为 1) BOOTSZ1/0: 引导区程序大小及入口 00: 1024Word/0xc00; 01: 512Word/0xe00; 10: 256Word/0xf00; 11: 128Word/0xf80 本开发板设置为 00 SUT1/0: 和复位启动的一个延时有关,本开发板设置为 11 CKSEL3/0: 时钟源选择,本开发板使用的是外接 11.0592M 的晶体,所以设置为 1111 最后是锁定位,LB0 和 LB1,本开发板设置为 1,即未锁定,设置这两位需谨慎。 下面是时钟配置表:

51单片机延时函数

51单片机延时函数

51单片机延时函数在嵌入式系统开发中,51单片机因其易于学习和使用、成本低廉等优点被广泛使用。

在51单片机的程序设计中,延时函数是一个常见的需求。

通过延时函数,我们可以控制程序的执行速度,实现定时器功能,或者在需要的时候进行延时操作。

本文将介绍51单片机中常见的延时函数及其实现方法。

一、使用for循环延时这种方法不精确,但是对于要求不高的场合,可以用来估算延时。

cvoid delay(unsigned int time){unsigned int i,j;for(i=0;i<time;i++)for(j=0;j<1275;j++);}这个延时函数的原理是:在第一个for循环中,我们循环了指定的时间次数(time次),然后在每一次循环中,我们又循环了1275次。

这样,整个函数的执行时间就是time乘以1275,大致上形成了一个延时效果。

但是需要注意的是,这种方法因为硬件和编译器的不同,延时时间会有很大差异,所以只适用于对延时时间要求不精确的场合。

二、使用while循环延时这种方法比使用for循环延时更精确一些,但是同样因为硬件和编译器的不同,延时时间会有差异。

cvoid delay(unsigned int time){unsigned int i;while(time--)for(i=0;i<1275;i++);}这个延时函数的原理是:我们先进入一个while循环,在这个循环中,我们循环指定的时间次数(time次)。

然后在每一次循环中,我们又循环了1275次。

这样,整个函数的执行时间就是time乘以1275,大致上形成了一个延时效果。

但是需要注意的是,这种方法因为硬件和编译器的不同,延时时间会有差异,所以只适用于对延时时间要求不精确的场合。

三、使用定时器0实现精确延时这种方法需要在单片机中开启定时器0,并设置定时器中断。

在中断服务程序中,我们进行相应的操作来实现精确的延时。

这种方法需要使用到单片机的定时器中断功能,相对复杂一些,但是可以实现精确的延时。

ATMEGA16单片机实验

ATMEGA16单片机实验

实验一软件和硬件的认识一、实验目的:1、掌握硬件原理。

2、初步掌握实验板的使用方法。

3、熟悉软件工作界面。

二、实验仪器:ATmage16实验板一块PC机一台三、实验内容及步骤:1、插上电源,按下开关。

观察批示灯是否点亮。

电源(可输入7~12V)ATmega16管脚图2、由原理可知I/O口的批示灯为低电平亮,在实验板上取地与I/O口相接,观察是否点亮。

I/O口LED显示与接口3、打开编程界面,点击各栏,认识各栏的用途。

A VRICC IDE 软件的工作界面4、输入以下程序:#include <iom16v.h>int main(void){DDRA = 0xff;/* all outputs */DDRB = 0xff;/* all outputs */DDRC = 0xff; /*all outputs */DDRD = 0xff; /*all outputs */PORTA = 0x00; /* 输出低电平*/PORTB = 0x00; /* 输出低电平*/PORTC = 0x00; /* 输出低电平*/PORTD = 0x00; /* 输出低电平*/while(1);}观察I/O口的灯是否被点亮。

实验二I/O口的输入与输出一、实验目的:1、了解IO口的结构;2、熟悉IO口的特性;3、掌握IO口的控制。

二、实验仪器:ATmage16实验板一块PC机一台三、实验原理:作为通用数字I/O 使用时,A VR 所有的I/O 端口都具有真正的读-修改-写功能。

这意味着用SBI 或CBI 指令改变某些管脚的方向( 或者是端口电平、禁止/ 使能上拉电阻) 时不会改变其他管脚的方向( 或者是端口电平、禁止/ 使能上拉电阻)。

输出缓冲器具有对称的驱动能力,可以输出或吸收大电流,直接驱动LED。

所有的端口引脚都具有与电压无关的上拉电阻。

并有保护二极管与VCC 和地相连,如Figure23 所示。

在控制I/O时,分别由方向寄存器DDRX与数据寄存器PORTX控制I/O的状态,如下表。

关于avr_atmega16

关于avr_atmega16

else HC164_send_byte(temp); PORTC = position[i]; delay_ms(2); PORTC = 0xff; } } 。。。。。。。。。
三、AVR通用I/O口 (3)、数码管显示(并行)
三、AVR通用I/O口 (3)、数码管显示(并行)
void display(void) // 扫描显示函数,执行时间12ms { char i; for(i=0;i<=5;i++) { PORTA = led_7[dis_buff[i]]; if (point_on && ( i==2 || i==4 )) PORTA |= 0x80; // (1) PORTC = position[i]; delay_ms(2); // (2) PORTC = 0xff; // (3) } }
三、AVR通用I/O口 (3)、数码管显示(并行)
三、AVR通用I/O口 (3)、数码管显示(并行)
假设PA.0-a…PA.7-h 要显示数字‘1’ 共阴极:PA输出? 共阳级:PA输出? 与此同时,公共端接法? 欲连续显示数字0-9该如 何?
三、AVR通用I/O口 (3)、数码管显示(并行)
三、AVR通用I/O口 (4)、字符LCD
/*显示屏初始化函数*/ void LCD_init(void) { DDRB = 0xFF; /*I/O口方向设置*/ DDRD |= (1 << PD3) | (1 << PD4) | (1 << PD6); LCD_write_com(0x38); /*显示模式设置*/ delay_ms(5); LCD_write_com(0x38); delay_ms(5); LCD_write_com(0x38); delay_ms(5); LCD_write_com(0x38); LCD_write_com(0x08); /*显示关闭*/ LCD_write_com(0x01); /*显示清屏*/ LCD_write_com(0x06); /*显示光标移动设置*/ delay_ms(5); LCD_write_com(0x0C); /*显示开及光标设置*/ }

·单片机晶振为12mhs延时1ms计算依据

一、单片机晶振的作用与原理单片机晶振是单片机系统中的一个重要部件,它通过振荡产生稳定的时钟信号,为单片机的运行提供基准。

在单片机系统中,晶振的频率对系统的稳定性、精度和速度有着重要的影响。

二、晶振频率为12MHz的延时计算在单片机系统中,为了实现延时操作,一般需要通过编程来控制计时器或者循环延时的方式来实现。

对于晶振频率为12MHz的单片机系统,延时1ms的计算依据如下:1. 首先需要计算出12MHz晶振的周期,即一个晶振振荡周期的时间。

12MHz晶振的周期为1/12MHz=0.0833us。

2. 接下来将1ms转换成晶振周期数。

1ms=1000us,将1000us除以0.0833us得到12000。

即延时1ms需要进行12000个晶振周期的振荡。

3. 最后根据单片机的指令周期和频率来确定代码延时的实现方法。

以常见的晶振频率为12MHz的单片机为例,根据单片机的指令周期(一般为1/12MHz=0.0833us)和延时周期数(12000),可以编写相应的延时函数或者循环来实现1ms的延时操作。

三、12MHz晶振延时1ms的应用场景在实际的单片机应用中,常常需要进行一定时间的延时操作,例如驱动液晶屏显示、控制外围设备响应等。

12MHz晶振延时1ms的应用场景包括但不限于:LED闪烁控制、按键消抖、舵机控制、多任务调度等。

四、晶振频率选择与延时精度的关系晶振频率的选择对延时精度有着直接的影响。

一般来说,晶振频率越高,对延时精度要求越高的应用场景,而对于一般的延时控制,12MHz的晶振已经能够满足大多数的要求。

延时的精度还受到单片机的指令执行速度的影响,需要在实际应用中进行综合考量与测试。

五、总结在单片机系统中,晶振的频率选择与延时操作密切相关,12MHz晶振延时1ms的计算依据可以帮助工程师们更好地进行单片机程序的设计与开发。

需要根据实际应用场景和需求来选择合适的晶振频率,并对延时精度进行充分的考量和测试,以确保单片机系统的稳定可靠性。

ATmega16实验板使用说明书

Atmega16实验板说明书硬件资料介绍 (2)调试软件安装 (3)编译环境的使用 (8)建立新的工程 (15)资料和例程 (18)注意:使用时先把调试器和开发板用数据线连起来,再插上USB线;停止使用时应先断开USB线切断电源,才能拔下数据线,否则可能会损坏调试器。

硬件资料介绍实验套件共分3部分,开发板,调试器,数据线(1根usb线,1根串口线)。

开发板文件夹图片/原理图里面有开发板的原理图图片和protel dxp 原理图文件。

如果开发板是没有焊好的套件可以对照元器件参数表和已焊好的图片(图片文件夹里有)先把开发板焊接完成。

焊接完成后先用万用表测量一下5V 与GND 之间是否短路,确定没有短路之后,插上USB 线接到电脑上,弹上开关SW1电源指示灯D1亮,说明电源已接通。

调试器调试软件安装要实现开发调试需要安装三个软件:PL2303驱动,avr studio 4,WinAVR。

这三个软件都在软件这个文件夹里。

首先安装usb驱动PL2303,如图点下一步。

点完成就可以了。

然后把调试器和电脑通过USB线联机。

如图这时调试器上的电源指示灯和信号指示灯都亮,而且电脑开始发现新硬件,新硬件可以安装使用。

这说明已经建立起连接,然后右击我的电脑—>属性—>硬件—>设备管理器,打开设备管理器界面,点开端口(COM和LPT)的“+”如图。

其中的Prolific usb-to-Serial Comm Port(COMx)就是调试器的usb设备。

端口号是多少根据个人电脑情况可能有差异。

下面我们要修改端口号,因为调试器里只提供COM1-COM3的通讯。

双击Prolific usb-to-Serial Comm Port(COMx)选项,弹出端口设置对话框,如图然后选端口设置—>高级,在端口号中选一个没有被占用且3以内的COM口,我的电脑上没有串口,我选的是COM1,如图然后点确定,重新打开设备管理器再看一下端口情况。

单片机ATMega16-的1602液晶显示两行字母

#include "iom16v.h" //ICC AVR环境下的ATmega16库函数定义了所有的寄存器及其位的标号#include "macros.h"#define LCM_RS_1 PORTB|=(1<<7) //RS为1,定义为PB口的第7位#define LCM_RS_0 PORTB&=(~(1<<7)) //RS为0,定义为PB口的第7位#define LCM_RW_1 PORTB|=(1<<6) //RW为1,定义为PB口的6位#define LCM_RW_0 PORTB&=(~(1<<6)) //RW为0,定义为PB口的6位#define LCM_E_1 PORTB|=(1<<5) //E为1,定义为PB口的第5位#define LCM_E_0 PORTB&=(~(1<<5)) //E为1,定义为PB口的第5位const unsigned char LCM_Dis_String[]="hello hcit";const unsigned char LCM_Dis_WJ[]="welcome to txx";/****************************************************************************** 函数功能:延时1us(4M晶振,0.25微秒的指令执行周期)入口参数:无函数说明:4*0.25=1(微秒)******************************************************************************/ void Delay_1_us(void){NOP();NOP();NOP();NOP();}/****************************************************************************** ********函数功能:延时若干微秒*********************************************************************入口参数:n_us******************/void Delay_n_us(unsigned int n_us){unsigned int cnt_i;for(cnt_i=0;cnt_i<n_us;cnt_i++){Delay_1_us();}}/****************************************************************************** ********函数功能:延时1ms(4M晶振,0.25微秒的指令执行周期)入口参数:无函数说明:(3×cnt_j+2)×cnt_i=(3×33+2)×40*0.25=1010(微秒),可以近似认为是1毫秒******************************************************************************* ********/void Delay_1_ms(void){unsigned char cnt_i,cnt_j;for(cnt_i=0;cnt_i<40;cnt_i++){for(cnt_j=0;cnt_j<33;cnt_j++){}}}/****************************************************************************** ********函数功能:延时若干毫秒入口参数:n_ms******************************************************************************* ********/void Delay_n_ms(unsigned int n_ms){unsigned int cnt_i;for(cnt_i=0;cnt_i<n_ms;cnt_i++){Delay_1_ms();}}/****************************************************************************** ********函数功能:读取忙标志和AC的值入口参数:无******************************************************************************* ********/unsigned char LCM_Re_BAC(){unsigned char status;//LCM_Dat为输入DDRA=0x00;//选择命令通道LCM_RS_0;//选择读操作LCM_RW_1;//使能线置1LCM_E_1;//等待信号线稳定Delay_n_us(1);//读入status=PINA;//使能线置0LCM_E_0;return status;}/****************************************************************************** ********函数功能:写入命令入口参数:命令代码******************************************************************************* ********/void LCM_Wr_CMD(unsigned char cmd_dat){//判忙while(LCM_Re_BAC()>=0x80);//LCM_Dat为输出DDRA=0xFF;//选择命令通道LCM_RS_0;//选择写操作LCM_RW_0;//使能线置1LCM_E_1;//设置命令数据PORTA=cmd_dat;//等待信号线稳定Delay_n_us(1);//送命令数据LCM_E_0;}/****************************************************************************** ********函数功能:写入数据入口参数:数据代码******************************************************************************* ********/void LCM_Wr_DAT(unsigned char dis_dat){//判忙while(LCM_Re_BAC()>=0x80);//LCM_Dat为输出DDRA=0xFF;//选择数据通道LCM_RS_1;//选择写操作LCM_RW_0;//使能线置1LCM_E_1;//设置数据数据PORTA=dis_dat;//等待信号线稳定Delay_n_us(1);//送数据数据LCM_E_0;Delay_n_us(40);}/****************************************************************************** ********函数功能:初始化入口参数:无******************************************************************************* ********/void LCM_1602_Init(void){LCM_Wr_CMD(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口Delay_n_ms(5); //延时5msLCM_Wr_CMD(0x38);Delay_n_ms(5);LCM_Wr_CMD(0x38);Delay_n_ms(5);LCM_Wr_CMD(0x0f); //显示模式设置:显示开,无光标,光标无闪烁Delay_n_ms(5);LCM_Wr_CMD(0x06); //显示模式设置:光标右移,字符不移Delay_n_ms(5);LCM_Wr_CMD(0x01); //清屏幕指令,将以前的显示内容清除Delay_n_ms(5);}unsigned char Get_Key_Val(){unsigned char Key_Val;Key_Val=PINC;switch(Key_Val){case 0xfe:Key_Val=1;break;case 0xfd:Key_Val=2;break;case 0xfb:Key_Val=3;break;default:Key_Val=0;break;}while(PINC==0xFF);return Key_Val;}void main(void){unsigned char cnt_temp,Key_Val;DDRB=0xFF;DDRA=0xFF;DDRC=0x00;PORTC=0xFF;while(1){LCM_1602_Init();Key_Val=Get_Key_Val();switch(Key_Val){case 1:{cnt_temp=0;LCM_Wr_CMD(0x80);while(LCM_Dis_String[cnt_temp]!='\0'){LCM_Wr_DAT(LCM_Dis_String[cnt_temp++]);Delay_n_ms(100);}break;}case 2:{cnt_temp=0;LCM_Wr_CMD(0xC0);while(LCM_Dis_WJ[cnt_temp]!='\0'){LCM_Wr_DAT(LCM_Dis_WJ[cnt_temp++]);Delay_n_ms(100);}break;}case 3:{cnt_temp=0;LCM_Wr_CMD(0x80);while(LCM_Dis_String[cnt_temp]!='\0'){LCM_Wr_DAT(LCM_Dis_String[cnt_temp++]);Delay_n_ms(100);}cnt_temp=0;LCM_Wr_CMD(0xC0);while(LCM_Dis_WJ[cnt_temp]!='\0'){LCM_Wr_DAT(LCM_Dis_WJ[cnt_temp++]);Delay_n_ms(100);}break;}}}}。

单片机延时计算

单片机C51延时时间怎样计算?C程序中可使用不同类型的变量来进行延时设计。

经实验测试,使用unsigned char类型具有比unsigned int 更优化的代码,在使用时应该使用unsigned char作为延时变量。

以某晶振为12MHz的单片机为例,晶振为12MHz即一个机器周期为1us。

void delay__ms(void) //x,y,z位固定值,故不能接受参数{unsigned char i,j,k;for(i=x;i>0;i--)for(j=y;j>0;j--)for(k=z;k>0;k--);}【Delay_Time=[(2z+3)*y+3]*x+5】一. 500ms延时子程序程序: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--);}应用单片机的时候,经常会遇到需要短时间延时的情况。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档