初级会员

- 积分
- 140
- 金钱
- 140
- 注册时间
- 2015-5-5
- 在线时间
- 0 小时
|
5金钱
想采集温度和光强,在中断中用顺序结构采集这两个数据,但是采集一个数据没有问题采集两个就是有问题,大神可以帮我看看吗,采集两个的程序应该怎么编写,问题应该就是在中断那段里面
#include "avr/io.h" //包含AVR单片机寄存器定义的头文件
#include "NBCAVR.h" //包含位操作的头文件
#include <avr/interrupt.h>
#define uchar unsigned char
#define uint unsigned int
#define LE1 PIOC0 //位选573锁存器使能
#define LE2 PIOC1 //段选573锁存器使能
#define Dataport PORTB //数据口定义
#define LED   IOA5 //定义LED控制IO
#define bz PIOA0 //定义蜂鸣器控制IO
#define K2 PIOA1 //定义继电器控制IO
#define Fosc 1000000 //不修改熔丝的情况下,单片机出厂默认时钟为内部1M时钟
uchar dis[16]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
// 0 1 2 3 4 5 6 7
0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};//0~F的段码
// 8 9 A B C D E F
//const表示定义在ROM内
const uint vt_table[]= //电压与实际温度对照表
{
4132,4098,4063,4026,3988,3949,3908,3866,3823,3779, //-9-0
3733,3686,3639,3590,3540,3489,3437,3385,3331,3277, //1-10
3222,3166,3110,3054,2997,2940,2882,2824,2767,2709, //11-20
2651,2593,2536,2478,2421,2365,2309,2253,2198,2143, //21-30
2089,2036,1984,1932,1881,1831,1782,1734,1686,1640, //31-40
1594,1550,1506,1464,1422,1381,1341,1303,1265,1228, //41-50
};
extern uchar Read_AD(uchar chn);
extern void delay(uint time);
uchar value;
uchar flag; //正负符号位
//***********************************************************************************
//IO初始化操作
//***********************************************************************************
void IO_init(void)
{
DIRD6=1;DIRD7=1; //PD6,PD7设置为输出
PIOD6=1 IOD7=1; //初始化为高
DDRB =0xff; //PB设置为输出
PORTB=0xff; //初始化为高
DIRC0 =1; DIRC1 =1; //设置LE1、LE2为输出
PIOC0 =1; PIOC1 =1; //设置LE1、LE2初始化数据为高电平
DIRA5=1; //设置PA5口为输出口
PIOA5=1; //设置PA5初始化数据为高电平
DIRA0 =1; //设置PA0为输出
PIOA0 =0; //设置PA0初始化数据为高电平
DIRA1 =1; //设置PA1为输出
PIOA1 =0; //设置PA1初始化数据为低电平
}
//**************************************************************************************************
//数码管显示函数(光强)
//**************************************************************************************************
void smg_show_l(uchar n)
{
//百位
Dataport=0xdf; //0xbf=1101 1111,即选通个位
LE1=1; //锁存位
LE1=0; //断开锁存,位选573的Q7~Q0仍保持
Dataport=dis[n/100]; //dis[n/10]为0~9的编码
LE2=1; //锁存段码
LE2=0; //断开锁存,段选573的Q7~Q0仍保持
delay(10); //延时保持一下,延时过大会闪动,延时过小会有重影
Dataport=0x00;LE2=1;LE2=0;//清除Dataport口数据,以免造重影
//显示十位
Dataport=0xbf; //0xbf=1011 1111,即选通个位
LE1=1; //锁存位
LE1=0; //断开锁存,位选573的Q7~Q0仍保持
Dataport=dis[(n%100)/10]; //dis[n/10]为0~9的编码
LE2=1; //锁存段码
LE2=0; //断开锁存,段选573的Q7~Q0仍保持
delay(10); //延时保持一下,延时过大会闪动,延时过小会有重影
Dataport=0x00;LE2=1;LE2=0; //清除Dataport口数据,以免造重影
//显示个位
Dataport=0x7f; //0xbf=0111 1111,即选通十分位
LE1=1; //锁存位
LE1=0; //断开锁存,位选573的Q7~Q0仍保持
Dataport=dis[n%10]; //0~9的编码
LE2=1; //锁存段码
LE2=0; //断开锁存,段选573的Q7~Q0仍保持
delay(10); //延时保持一下,延时过大会闪动,延时过小会有重影
Dataport=0x00;LE2=1;LE2=0; //清除Dataport口数据,以免造重影
if(n>250)
LED=0;
else
LED=1;
}
//**************************************************************************************************
//数码管显示函数(温度)
//***************************************************************************************************void smg_show_t(uchar m)
void smg_show_t(uchar m)
{
//显示符号位
Dataport=0xfd; //0xbf=1111 1101,即选通个位
LE1=1; //锁存位
LE1=0; //断开锁存,位选573的Q7~Q0仍保持
if(flag){Dataport=0x40;flag=0;}//为负,显示"-"号
else Dataport=0x00; //为正,不显示
LE2=1; //锁存段码
LE2=0; //断开锁存,段选573的Q7~Q0仍保持
delay(10); //延时保持一下,延时过大会闪动,延时过小会有重影
Dataport=0x00;LE2=1;LE2=0;//清除P1口数据,以免造重影
//显示十位
Dataport=0xfb; //0xbf=1111 1011,即选通个位
LE1=1; //锁存位
LE1=0; //断开锁存,位选573的Q7~Q0仍保持
Dataport=dis[m/10]; //dis[n/10]为0~9的编码
LE2=1; //锁存段码
LE2=0; //断开锁存,段选573的Q7~Q0仍保持
delay(10); //延时保持一下,延时过大会闪动,延时过小会有重影
Dataport=0x00;LE2=1;LE2=0;//清除P1口数据,以免造重影
//显示个位
Dataport=0xf7; //0xbf=1111 0111,即选通十分位
LE1=1; //锁存位
LE1=0; //断开锁存,位选573的Q7~Q0仍保持
Dataport=dis[m%10]; //0~9的编码
LE2=1; //锁存段码
LE2=0; //断开锁存,段选573的Q7~Q0仍保持
delay(10); //延时保持一下,延时过大会闪动,延时过小会有重影
Dataport=0x00;LE2=1;LE2=0;//清除P1口数据,以免造重影
if(m>40)
{
K2=0;
bz=1; //打开蜂鸣器
delay(1000); //延时
bz=0; //关闭蜂鸣器
delay(1000); //延时
}
if(m>20&&m<40)
{
K2=1; //导通继电器
}
}
//***********************************************************************************
//中断服务子程序
//***********************************************************************************
// Timer1 interrupt service routine
ISR (TIMER1_OVF_vect)
{
uchar i;
uint temp;
TCNT1H = 0xE1; //中断一次对TMR1重新赋初值
TCNT1L = 0x7B;
temp=Read_AD(0); //采集0通道模拟电压值
temp=19*(temp&0x00ff); //temp&0x00ff为提取8位AD采集结果,再乘以电阻特性参数
for(i=0;(vt_table>temp)&&(i<60);i++);//查表得到温度对应参数
if(i<10) {value=10-i;flag=1;}//如果是负温度,符号标志置1,表示为负
else value=i-10; //如果为正,去掉10个负数
//value=Read_AD(1)&0x00ff; //采集1通道模拟电压值
}
//***********************************************************************************
//timer1初始化
//***********************************************************************************
void timer1_init(void)//频率:Fosc/64=1M/64=15625,计数周期(计数加1用时)为1/15625=64us
{
TCCR1B = 0x00; //停止定时器1工作
//定时0.5s,需计数次数为500000us/64=7812次,初值:65535-7812=57723即0xE17B
TCNT1H = 0xE1;
TCNT1L = 0x7B;
TIMSK |= 0x04; //T1中断允许
SREG |= 0x80; //开总中断
TCCR1B = 0x03; //启动定时器1,64分频
}
//**************************************************************************************************
//主函数
//**************************************************************************************************
int main()
{
IO_init(); //IO初始化
timer1_init();
while(1) //死循环
{
// smg_show_l(value); //显示光强
smg_show_t(value); //显示温度值
}
}
|
|