高级会员
主题
帖子
积分921
阅读权限30
注册时间2010-1-29
最后登录1970-1-1
在线时间 小时
|
本帖最后由 mfkyygt 于 2014-9-21 14:03 编辑
//=============================
//项目名称:监测电压延时控制
//主控芯片: T13
//晶振频率: 内部9.6000Mhz
//Design by MFK
//Start 2014-09-10
//Modify 2014-09-16
//=============================
#include <iot13v.h>
#include <AVRdef.h>
#define RLY PB0
#define LED PB1
#define uint unsigned int
#define uchar unsigned char
#define input DDRB &=0b11111011
#define output DDRB |=0b00000100
volatile uint t1,t2,tdelay,v_real,v_set,v_delay;
volatile uchar l_ch,l_adok,l_timer;
//---- 主程序 ----
void main(void)
{
uint i;
PORTB =0xFE; //PB初始端口置高
DDRB =0xE3; //1110 0011 PB2,3,4设为AD输入,其他设为输出
ADCSRA =0x00; //关闭 ADC
ADMUX =0x21; //使用VCC作为参考电压,采用ADC1 PB2,左对齐
ACSR =0x80; //禁止模拟比较器
ADCSRB =0x00; //连续转换模式
ADCSRA =0xE9; //打开 ADC
timer0_init(); //定时器初始化
MCUCR = 0x00;
TIMSK0 = 0x02; //timer interrupt sources
GIMSK = 0x00; //interrupt sources
SEI(); //允许中断
l_adok =0; //初始化ADC转换标志
l_ch =1; //默认AD通道为1
//tdelay =2; //延时默认为5秒,可通过设置eeprom记录
while (1) //等待中断
{
delay_ms(100); //每隔100ms扫描一次AD通道
if ((l_adok==1)&&(l_ch==1))
{
l_adok =0; //清除AD转换完成标志
l_ch =2; //切换AD通道
ADMUX =0x22; //使用VCC作为参考电压,采用ADC2 PB4,左对齐
ADCSRA = 0xE9; //再次启动AD转换
}
//----
if ((l_adok==1)&&(l_ch==2))
{
l_adok =0; //清除AD转换完成标志
l_ch =3; //切换AD通道
ADMUX =0x23; //使用VCC作为参考电压,采用ADC2 PB4,左对齐
ADCSRA = 0xE9; //再次启动AD转换
}
//----
if ((l_adok==1)&&(l_ch==3))
{
l_adok =0; //清除AD转换完成标志
l_ch =1; //切换AD通道
ADMUX =0x21; //使用VCC作为参考电压,采用ADC2 PB4,左对齐
ADCSRA = 0xE9; //再次启动AD转换
}
//---计算延时时间,由时间变阻器获取
tdelay =v_delay * 30/255;
//---监测电压是否达到设定值
if (v_real>=v_set)
{
l_timer =1; //设置定时器启动标志
TCCR0B = 0x05; //启动定时器
CLR(PORTB,LED); //指示灯亮
SET(PORTB,RLY); //启动继电器
}
}
}
//---- 定时器初始化 ----
//TIMER0 initialize - prescale:1024
// WGM: Normal
// desired value: 10mSec
// actual value: 9.920mSec (0.8%)
void timer0_init(void)
{
TCCR0B = 0x00; //stop
OCR0A = 0x5D;
OCR0B = 0x5D;
TCNT0 = 0xA3; //set count
TCCR0A = 0x00;
//TCCR0B = 0x05; //start timer
}
//---- 10ms定时中断 ----
#pragma interrupt_handler timer0_ovf_isr:iv_TIM0_OVF
void timer0_ovf_isr(void)
{
TCNT0 = 0xA3; //定时器重新赋值
if (l_timer==1)
{
if (t2<tdelay) //延时时间到否
{
if (t1<100)
{t1++;}
else
{
t1 =0;
t2++;
}
}
else //延时时间到
{
t2 =0;
if (v_real<v_set)
{
TCCR0A = 0x00; //停止定时器
TCNT0 = 0xA3;
CLR(PORTB,RLY); //断开继电器
SET(PORTB,LED); //指示灯灭
l_timer =0; //清除定时器启动标志
}
}
}
}
//---- AD转换完成中断相应程序 ----
#pragma interrupt_handler adc_isr:iv_ADC
void adc_isr(void)
{
if (l_ch==1)
{v_real =ADCH;}
if (l_ch==2)
{v_set =ADCH;}
if (l_ch==3)
{v_delay =ADCH;}
l_adok =1; //标记为AD转换完成
}
//---- ms级延时 ----
delay_ms(unsigned int s) //这里ms级延时,可以用仿真测试频率
{
unsigned int a,b,c;
for (a=1; a<=s; a++)
{ for (b=0; b<4; b++)
{ for (c=0;c<240;c++)
{;}
}
}
}
|
|