关于AVR定时器中断的问题
我在定时器中断里加了几个IF()语句定时器为什么就出现这么大的偏差,//包含所需头文件#include<ioM16v.h>#include<macros.h>#inclu...
我在定时器中断里加了几个IF()语句定时器为什么就出现这么大的偏差,
//包含所需头文件
#include <ioM16v.h>
#include <macros.h>
#include "led8_spi1.h"
/*------宏定义------*/
#define uchar unsigned char
#define uint unsigned int
#define Z11 PORTC|=BIT(6)
#define Z10 PORTC&=~BIT(6)
#define Z21 PORTC|=BIT(7)
#define Z20 PORTC&=~BIT(7)
#define Z31 PORTD|=BIT(6)
#define Z30 PORTD&=~BIT(6)
#define Z41 PORTD|=BIT(7)
#define Z40 PORTD&=~BIT(7)
#define Z1 PORTC|=BIT(5)
#define Z0 PORTC&=~BIT(5)
#define K1 (PIND&BIT(2)) //数据线的状态
#define K2 (PIND&BIT(3)) //数据线的状态
#define K3 (PIND&BIT(4)) //数据线的状态
#define K4 (PIND&BIT(5)) //数据线的状态
uchar ZS1,ZS2,ZS3,ZS4,ZKB=25,flag;
//端口初始化
void port_init(void)
{
PORTA = 0x00;
DDRA = 0x00;
PORTB = 0x00;
DDRB = 0xBF;
PORTC = 0x00;
DDRC = 0xe0;
PORTD = 0x00;
DDRD = 0xC0;
}
//定时器T0初始化
void timer0_init(void)
{
TCCR0 = 0x00;//停止定时器
TCNT0 = 0xCB;//初始值
OCR0 = 0xCA;//匹配值
TIMSK |= 0x01;//中断允许
TCCR0 = 0x01;//启动定时器
}
//T0溢出中断服务程序
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
TCNT0 = 0xCB;
ZS1++;
ZS2=ZS1-64;
ZS3=ZS1-128;
ZS4=ZS1-191;
if(ZS1==0) Z11;
if(ZS2==0) Z21;
if(ZS3==0) Z31;
if(ZS4==0) Z41;
if(ZS1==ZKB)Z10;
if(ZS2==ZKB)Z20;
if(ZS3==ZKB)Z30;
if(ZS4==ZKB)Z40;
if(flag){Z1;flag=0;}else {Z0;flag=1;}
}
void adc_init(void)
{
//adc转换初始化
ADCSRA = 0x00; //禁止AD转换
ADMUX = 0x04;
SFIOR |= 0x00;
ACSR = 0x80; //禁止模拟比较器
ADCSRA = 0x87;
}
uchar adc_calc(void)
{
uchar value=0; //电压单位为(mV)
value=ADCL>>2; //首先读低位
value|=ADCH << 6; //然后读高位
return value;
}
void init_devices(void)
{
CLI(); //禁止所有中断
MCUCR = 0x00;
MCUCSR = 0x80;//禁止JTAG
GICR = 0x00;
port_init();
timer0_init();
adc_init();
SEI();//开全局中断
}
//主函数
void main(void)
{
init_devices();
//在这继续添加你的代码
while(1)
{
NOP();
ZKB=adc_calc();
ADCSRA|=BIT(ADSC);
convdata(ZKB);
display();
}
}
谢谢你能回答我的问题,我做实验得出的结果也像你说的那样,但我的单片机用的晶振是8M的,定时周期才200KHZ,以AVR的速度执行这几条语句应该是不成问题的。还有我的中断你语句加到15条左右其它的中断就执行不了了,不知是为什么,请高手指点指点。 展开
//包含所需头文件
#include <ioM16v.h>
#include <macros.h>
#include "led8_spi1.h"
/*------宏定义------*/
#define uchar unsigned char
#define uint unsigned int
#define Z11 PORTC|=BIT(6)
#define Z10 PORTC&=~BIT(6)
#define Z21 PORTC|=BIT(7)
#define Z20 PORTC&=~BIT(7)
#define Z31 PORTD|=BIT(6)
#define Z30 PORTD&=~BIT(6)
#define Z41 PORTD|=BIT(7)
#define Z40 PORTD&=~BIT(7)
#define Z1 PORTC|=BIT(5)
#define Z0 PORTC&=~BIT(5)
#define K1 (PIND&BIT(2)) //数据线的状态
#define K2 (PIND&BIT(3)) //数据线的状态
#define K3 (PIND&BIT(4)) //数据线的状态
#define K4 (PIND&BIT(5)) //数据线的状态
uchar ZS1,ZS2,ZS3,ZS4,ZKB=25,flag;
//端口初始化
void port_init(void)
{
PORTA = 0x00;
DDRA = 0x00;
PORTB = 0x00;
DDRB = 0xBF;
PORTC = 0x00;
DDRC = 0xe0;
PORTD = 0x00;
DDRD = 0xC0;
}
//定时器T0初始化
void timer0_init(void)
{
TCCR0 = 0x00;//停止定时器
TCNT0 = 0xCB;//初始值
OCR0 = 0xCA;//匹配值
TIMSK |= 0x01;//中断允许
TCCR0 = 0x01;//启动定时器
}
//T0溢出中断服务程序
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
TCNT0 = 0xCB;
ZS1++;
ZS2=ZS1-64;
ZS3=ZS1-128;
ZS4=ZS1-191;
if(ZS1==0) Z11;
if(ZS2==0) Z21;
if(ZS3==0) Z31;
if(ZS4==0) Z41;
if(ZS1==ZKB)Z10;
if(ZS2==ZKB)Z20;
if(ZS3==ZKB)Z30;
if(ZS4==ZKB)Z40;
if(flag){Z1;flag=0;}else {Z0;flag=1;}
}
void adc_init(void)
{
//adc转换初始化
ADCSRA = 0x00; //禁止AD转换
ADMUX = 0x04;
SFIOR |= 0x00;
ACSR = 0x80; //禁止模拟比较器
ADCSRA = 0x87;
}
uchar adc_calc(void)
{
uchar value=0; //电压单位为(mV)
value=ADCL>>2; //首先读低位
value|=ADCH << 6; //然后读高位
return value;
}
void init_devices(void)
{
CLI(); //禁止所有中断
MCUCR = 0x00;
MCUCSR = 0x80;//禁止JTAG
GICR = 0x00;
port_init();
timer0_init();
adc_init();
SEI();//开全局中断
}
//主函数
void main(void)
{
init_devices();
//在这继续添加你的代码
while(1)
{
NOP();
ZKB=adc_calc();
ADCSRA|=BIT(ADSC);
convdata(ZKB);
display();
}
}
谢谢你能回答我的问题,我做实验得出的结果也像你说的那样,但我的单片机用的晶振是8M的,定时周期才200KHZ,以AVR的速度执行这几条语句应该是不成问题的。还有我的中断你语句加到15条左右其它的中断就执行不了了,不知是为什么,请高手指点指点。 展开
全测科技
2024-12-19 广告
2024-12-19 广告
SMBV100B信号发生器是罗德与施瓦茨公司的一款矢量信号发生器,兼具卓越的性能特性。其频率范围介于8kHz至6GHz,覆盖数字无线通信的所有重要射频频段,调制带宽高达500MHz,满足四代和五代通信标准的严苛要求。同时,它可在极高功率电平...
点击进入详情页
本回答由全测科技提供
展开全部
我没用过avr单片机
但你这个原因我可以猜测到
你定时器定时较短在执行 下面那些语句是 也许已经出现了一次或者几次中断而这时候你的程序还在这次中断没跳出来 其实就是错过了一些中断 理论上中断服务子程序里面的指令时越少越好的 实际你只要把握好指令运行需要的时间就可以 你可以设置一个标志位 把下面的语句弄到中断外面去
if(ZS1==0) Z11;
if(ZS2==0) Z21;
if(ZS3==0) Z31;
if(ZS4==0) Z41;
if(ZS1==ZKB)Z10;
if(ZS2==ZKB)Z20;
if(ZS3==ZKB)Z30;
if(ZS4==ZKB)Z40;
if(flag){Z1;flag=0;}else {Z0;flag=1;}
但你这个原因我可以猜测到
你定时器定时较短在执行 下面那些语句是 也许已经出现了一次或者几次中断而这时候你的程序还在这次中断没跳出来 其实就是错过了一些中断 理论上中断服务子程序里面的指令时越少越好的 实际你只要把握好指令运行需要的时间就可以 你可以设置一个标志位 把下面的语句弄到中断外面去
if(ZS1==0) Z11;
if(ZS2==0) Z21;
if(ZS3==0) Z31;
if(ZS4==0) Z41;
if(ZS1==ZKB)Z10;
if(ZS2==ZKB)Z20;
if(ZS3==ZKB)Z30;
if(ZS4==ZKB)Z40;
if(flag){Z1;flag=0;}else {Z0;flag=1;}
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询