delay2
movlw 0x06 //0X06给W
movwf_delay //W寄存器的值6给DELAY(应该是DELAYL吧)
delay1
decfsz_delayl //此句是 DECFSZ DELAYL,1
goto delay1 //DELAYL不等与0则跳转到delay1
decfsz_delayh //DELAYL=0在这里执行 DELAYH-1 判断是否为0为0
goto delay2 //不等于0 则跳转到DELAY2
//等于0 汇编程序执行完毕
什么编程环境啊,感觉有问题一样。。
[(2+1)6+2+1+2]x 个机器周期 你一个机器周期是1US 就是这么多US
#include<pich>//用中断法,让TMR0的T0IF是否有溢出中断,让LED二极管一秒钟闪动,因为PIC单片机如果写有定时计数器则从一上电开始计时
//在使用定时计数器时一定要设置选项寄存器(OPTION_REG)和中断控制寄存器(INTCON)
#define uchar unsigned char
#define uint unsigned int
__CONFIG(0x3B31);
uint initnum;//定义一个溢出中断的变量
void init()//初始化接LED的RD端口为输出,及设置OPTION寄存器关闭TMR0定时计时器
{
TRISD=0;//输出状态
PORTD=0;//关闭
OPTION=0x07;//设置选项寄存器为00000111是设置PSA选择为0,PS2-PS0为111:分频比是1:256其他的为零
INTCON=0xa0;//设置中断控制寄存器为10100000,开总中断,开允许中断,和T0IF在初始化中还不能溢出
TMR0=61;//因为PIC单片机定时计数器从一上电开始计时了,我们设置它每50ms产生溢出中断即是50000除以256等于195,也就说加了195个数后就到50ms了,那么要溢出就得加满所以要先装256-195=61个数
}
void main()//在主函数里中断函数不需要调用和判断是否产生中断溢出标志T0IF,因为从一上电就自动运行,一到50ms中断会自动溢出加1
{
init();
while(1)
{
if(initnum==20)//它每50ms产生溢出中断,20次则是一秒
{
initnum=0;//到了1s后清零
RD0=!RD0;//取反,再到第二次溢出又取反电平
}
}
}
void interrupt time0()//定时器的程序,后面不用写和51单片机那样的序号,也不用就算写在主函数的后面也不用声明
{ //例如:如果是T0IF置位才能知用是TMR0定时器,如果是T1IF置位才能知道是TMR1定时器
T0IF=0;//先置零,同时知道是用TMR0定时器
TMR0=61;//也要重新装一次初值
initnum++;//加一
}
软件延时是通过使用空运算来消耗芯片的一定运算周期来实现延时的,比如采用循环体进行
硬件延时是通过硬件上的计时模块或中断模块来实现一定的延时的,这种方法可以提高CPU的工作效率,也能做到精确延时;
可以用任何定时器,如TMR0,设置它基本延时时间为50ms,延时20次就是1s了!
因为你用的是4M晶振,指令周期为1us,TMR0的延时50ms延时常数计算如下:
先计算TMR0的分频系数K:
50000=2561K,K=1953,取K=256(只能取略大的计算值,不能四舍五入!),这是的1是指令周期,下周
再计算TMR0的延时常数X:
5000=(256-X)1K,K用256代入,得X=61
程序设计时用一个累计TMR0中断次数的变量T0_N,每中断一次T0_N+1,并判断其值>=20时就是1秒了。
注意,TMR0中断时要清TMR0IF,并要重新对TMR0赋初值61。
用几种办法:
1、直接用软件延时用下DELAY()延时子程序要延时5ms,直接调用DELAY(5)好了种纯软件延时
//======延时(n)ms4MHz晶振下
void
DELAY(uint
n)
{
uint
j;
uchar
k;
for
(j=0;j<n;j++)
for
(k=246;k>0;k--)
NOP();
}
2、用定时器延时要通过计算延时时间来确定延时常数(分频比和定时器初值)
这个程序无法算,因为是C程序,其中延时的时间没法计算!
要用仿真来确定,可能用SIM仿真或PROTEUS仿真,最好看一下北航的《PIC16系列单片机C程序设计与PROTEUS仿真》一书,里面有这个程序及参数确定的说明。下面是书中用4MHz晶振(不是晶震!)时延时若干ms的通用程序,如想延时10ms,就调用DELAY(10),想延时1s,就调用DELAY(1000)。
//======延时(n)ms
void DELAY(unsigned int n)
{
unsigned int j;
char k;
for (j=0;j<n;j++)
for (k=246;k>0;k--)
NOP();
}
unsigned char rev_data = 0;
unsigned char send_data = 0;
void interrupt ISR()
{
if (RCIE & RCIF) //判断是否为串口接收中断
{
rev_data = RCREG; //将接收缓存器中数据读取出来
if(TRMT == 1)
{
TXREG = rev_data;
}
PORTD = ~PORTD;
}
}
单片机最好不要直接寄存器的值赋给寄存器,对串口接收中断必须将缓存器数据读取出来才能清空。另外main函数中while(1)当中要作长延时,不然数据看不到你从串口助手发送后,单片机返回的数据,你尝试一下,不能保证一定可以。
以上就是关于PIC单片机延迟函数汇编语言全部的内容,包括:PIC单片机延迟函数汇编语言、如何用pic单片机写用中断法,让TMR0的T0IF是否有溢出中断,让LED二极管一秒钟闪动、pic单片机,软件延时与硬件延时主要有哪些区别等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)