|
发表于 2008-4-5 12:19:12
|
显示全部楼层
#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
//******************引脚信号定义***************************//
#define up (PINC&0x01) //PC0=0X01
#define down (PINC&0x02) //PC1=0X02
#define left (PINC&0x40) //PC6=0X40
#define right (PINC&0x80) //PC7=0X80
#define x_on (PORTD|= (1<<5 )) //x高 PD5
#define x_off (PORTD&= ~(1<<5)) //x低
#define y_on (PORTD|= (1<<6 )) //y高 PD6
#define y_off (PORTD&= ~(1<<6)) //y低
#define DOG_on (PORTB|= (1<<2 ))
#define DOG_off (PORTB&= ~(1<<2))
#define led_on (PORTB&= ~(1<<0))
#define led_off (PORTB|= (1<<0 ))
#define led1_on (PORTB&= ~(1<<1))
#define led1_off (PORTB|= (1<<1 ))
#define TCNT0_temp 0xb0
#define first_temp 62
//******************全居变量*************************//
uchar x_value; //X轴角度
uchar y_value; //Y轴角度 范围:0-180 初始化的时候为90度
uint x_delay_temp; //x轴延时时间(T0中断次数)
uint y_delay_temp; //y轴延时时间(T0中断次数)
uchar new_key_flag=0;
uchar key_value;
uint tab_temp;
const uint tab[181]={63,64,65,67,68,69,71,72,74,75,76,78,79,81,82,83,85,86,
87,89,90,92,93,94,96,97,99,100,101,103,104,106,107,108,110,111,112,114,115,
117,118,119,121,122,124,125,126,128,129,131,132,133,135,136,137,139,140,142,
143,144,146,147,149,150,151,153,154,156,157,158,160,161,162,164,165,167,168,
169,171,172,174,175,176,178,179,181,182,183,185,186,187,189,190,192,193,194,
196,197,199,200,201,203,204,206,207,208,210,211,212,214,215,217,218,219,221,
222,224,225,226,228,229,231,232,233,235,236,237,239,240,242,243,244,246,247,
249,250,251,253,254,256,257,258,260,261,262,264,265,267,268,269,271,272,274,
275,276,278,279,281,282,283,285,286,287,289,290,292,293,294,296,297,299,300,
301,303,304,306,307,308,310,311,312};
//**************************端口初始化*************************//
void IO_Init(void)
{
PORTA = 0x00;
DDRA = 0x00;
PORTB = 0x00;
DDRB = 0x03;
PORTC = 0x00;
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0x60;
DOG_off; //
x_off;
y_off;
led1_off;
led_off;
WDR(); //this prevents a timout on enabling
WDTCR = 0x0F; //WATCHDOG ENABLED - dont forget to issue WDRs
}
//TIMER0 initialize - prescale:1
// WGM: Normal
// desired value: 8uSec
// actual value: 8.000uSec (0.0%)
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = TCNT0_temp; //set count
OCR0 = 0x60; //set compare
TCCR0 = 0x01; //start timer
}
//**********************长延时程序50ms**************************//
void delay50ms(uint t)
{
uint i;
for(;t>0;t--)
for(i=0;i<5000;i++)
;
}
//******************装置复位 27H*******************//
void reload(void)
{
CLI();
delay50ms(1000); //长延时,停止喂狗
}
//********************喂狗>50ns*****************************//
void dog(void)
{
CLI();
WDR();
DOG_on;
asm("nop");
asm("nop");
asm("nop");
DOG_off;
SEI();
}
void led(void)
{
led_on;
delay50ms(5);
dog();
led_off;
delay50ms(5);
dog();
}
//**********************角度-延时时间**************************//
uint get_delay_time(uchar t)
{
// ulong j=0;
uint b_temp,i;
/*
j=t;
j=j*20000;
j=j/1800;
j=j+500; //j=500+t*20000/1800;500+t*11.111111
b_temp=j&0x0000ffff; //低16位有效,
//因为定时器的时间周期为8us,所以此数据需/8;
b_temp=b_temp/8;
*/
b_temp=tab[t];
tab_temp=b_temp;
return b_temp;
}
//************************键盘获取程序********************//
uchar getkey(void)
{
uchar back_temp;
back_temp=PINC&0xc3; //PC0-1--6-7
key_value=back_temp;
return back_temp;
}
//************键盘处理*****************
//通讯扩展:串口接收到0x01 0x02 0x40 0x80 相应表示对应的键按下,
//接口方便,亮灯程序处,发送超限指示
void key_work(void)
{ uchar key_value;
key_value=getkey();
switch(key_value)
{
case 0xc2: //上
y_value=y_value+1;
if(y_value>123)
{
y_value=123; // 最大123度
led();//亮灯表示到限
}
new_key_flag=1; // 键盘更新标志
break;
case 0xc1: //下
y_value=y_value-1;
if(y_value<1)
{
y_value=1; // 最小1
led();//亮灯表示到限
}
new_key_flag=1; // 键盘更新标志
break;
case 0x83: //左
x_value=x_value+1;
if(x_value>123)
{
x_value=123; // 最小1
led();//亮灯表示到限
}
new_key_flag=1; // 键盘更新标志
break;
case 0x43: //右
x_value=x_value-1;
if(x_value<1)
{
x_value=1; // 最小1
led();//亮灯表示到限
}
new_key_flag=1; // 键盘更新标志
break;
default:
new_key_flag=0; // 键盘更新标志
break;
}
}
//***************开机,xy方向都是90度,处于中间位置
void xy_first(void)
{
x_value=first_temp; //开机为90度位置,中间
y_value=first_temp;
x_on;
y_on;
x_delay_temp=get_delay_time(x_value);//定时器需要中断的次数
y_delay_temp=get_delay_time(y_value);
timer0_init(); //开定时器0,开始延时
delay50ms(5);
}
//************************主程序**************************//
void main(void)
{
uchar main_ch=0;
CLI(); //关总中断
IO_Init(); //I/O口初始化
//timer0_init(); //定时器0初始化,有键盘按下的时候打开
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x01; //T/C0 溢出中断使能
SEI(); //开总中断
//开机初始化云台xy的位置,均为90度,镜头指向中心位置
led();
xy_first();
led();
asm("nop");
//timer0_init();
while(1)
{
// led();
// xy_first();
// timer0_init();
key_work(); //处理键盘
if(new_key_flag==1) //有键按下,输出对应的方向
{
x_delay_temp=get_delay_time(x_value);//定时器需要中断的次数
y_delay_temp=get_delay_time(y_value);
x_on;
y_on;
timer0_init(); //开定时器0,开始延时
delay50ms(5);
}
delay50ms(20);
dog();
asm("nop");
}
}
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
TCNT0 = TCNT0_temp; //重新加载数据,
//PORTD=~PORTD;
//定时器的计数周期内,下面的计算必须完成,否则定时时间不准确
//x方向延时计数
if(x_delay_temp>0)
{
x_delay_temp=x_delay_temp-1;
if(x_delay_temp==0)
{
x_delay_temp=0;
x_off; //延时时间到,拉低输出x
}
}
//y方向延时计数
if(y_delay_temp>0)
{
y_delay_temp=y_delay_temp-1;
if(y_delay_temp==0)
{
y_delay_temp=0;
y_off; //延时时间到,拉低输出y
}
}
//xy方向都结束,关闭定时器
if((y_delay_temp==0)&(x_delay_temp==0)) //xy方向延时计数结束关闭定时器
{
TCCR0 = 0x00; //stop
TCNT0 = 0x00;
}
asm("nop");
} |
|