#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
/******************************************************************************/
/********************************宏定义***************************************/
/******************************************************************************/
#define H595DDR_OUT DDRC |=BIT(0)|BIT(1)|BIT(2)|BIT(3)|BIT(4)|BIT(5)|BIT(6)
#define H595CTL PORTC //高低高平
#define H595_SER_H H595CTL |= BIT(PC6) //数据
#define H595_SER_L H595CTL &= ~BIT(PC6)
#define H595_RCK_H H595CTL |= BIT(PC5) //副寄存器时钟
#define H595_RCK_L H595CTL &= ~BIT(PC5)
#define H595_SCK_H H595CTL |= BIT(PC4) //主时钟
#define H595_SCK_L H595CTL &= ~BIT(PC4)
#define H595DDR_OUT1 DDRD |=BIT(0)|BIT(1)|BIT(2)
#define H595CTL1 PORTD //高低高平
#define H595_SER1_H H595CTL1 |= BIT(PD0) //数据
#define H595_SER1_L H595CTL1 &= ~BIT(PD0)
#define H595_RCK1_H H595CTL1 |= BIT(PD1) //副寄存器时钟
#define H595_RCK1_L H595CTL1 &= ~BIT(PD1)
#define H595_SCK1_H H595CTL1 |= BIT(PD2) //主时钟
#define H595_SCK1_L H595CTL1 &= ~BIT(PD2)
#define SEG_1_H H595CTL |= BIT(PC0)//数码管四个位选端
#define SEG_1_L H595CTL &= ~BIT(PC0)
#define SEG_2_H H595CTL |= BIT(PC1)
#define SEG_2_L H595CTL &= ~BIT(PC1)
#define SEG_3_H H595CTL |= BIT(PC2)
#define SEG_3_L H595CTL &= ~BIT(PC2)
#define SEG_4_H H595CTL |= BIT(PC3)
#define SEG_4_L H595CTL &= ~BIT(PC3)
#define BACK1_ON PORTB |= BIT(PD3) //前后//转向档瓶刂?
#define BACK1_OFF PORTB &= ~BIT(PD3)
#define BACK2_ON PORTB |= BIT(PD4)
#define BACK2_OFF PORTB &= ~BIT(PD4)
/******************************************************************************/
/**********************************end*****************************************/
/******************************************************************************/
uint count,ppp,count1,voltage;
uchar angle_flag1,angle_flag2=0;
uchar anglel,angleh;
uint i=0;
uchar sudu=0x40;
uchar AD_num1,AD_num=0;
static uchar black_flag;
static uchar online;
uint AD_get[8]={0,0,0,0,0,0,0,0};
uint AD_min[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
uint AD_max[8]={0,0,0,0,0,0,0,0};
uint AD_read[8]={0,0,0,0,0,0,0,0};
static uchar weiseg[4] = {0xfe,0xfd,0xfb,0xf7};
static uchar state[]={4,12,8,10,26,58,18,48,32,33,1,65,64,128};
static uchar shushow[11]={
0xFA,/*0*/
0x60,/*1*/
0xDC,/*2*/
0xF4,/*3*/
0x66,/*4*/
0xB6,/*5*/
0xBE,/*6*/
0xE0,/*7*/
0xFE,/*8*/
0xF6,/*9*/
0x00
};
static uchar taple[] = {
0xff,
0xe7,
0xc3,
0x81,
0x00,
0x18,
0x3c,
0x7e,
0xff,
0xaa,
0x55
};
static uint smg[11] = {
1,
12,
123,
1234,
2345,
3456,
4567,
5678,
6789,
9123,
3210
};
void AD_control();
void angle_control();
void set_angle(uchar agh,uchar agl);
void display(uint shuzhi);
void delay1(int k) ;
void set595(uchar s2);
void led_line(uchar s2);
/*******************************************************************************/
//////////////////////////////中断初始化函数/////////////////////////////////////
/*******************************************************************************/
/******************************************************************************
端口初始化函数
******************************************************************************/
void port_init(void)
{
DDRA = 0x00;
PORTB = 0x00;
DDRB = 0xff;
PORTC = 0x0F;
DDRC = 0x7F;
PORTD = 0x00;
DDRD = 0xff;
H595DDR_OUT ;
H595DDR_OUT1;
}
/******************************************************************************
AD初始化函数
******************************************************************************/
void adc_init(void)
{
ADCSRA = 0x00; //禁止AD转换
ADMUX = 0x60;
SFIOR |= 0x00;
ACSR = 0x80; //禁止模拟比较器
ADCSRA = 0xEE;
}
/**********************定时T1初始化******************************
模式:8位相位修正PWM模式
舵角控制: OCR1AL=0XCA时,左最大,0XD0时,中间位置,0XD7时右转最大
系统时钟:内部8MHZ,经256分频得61.275HZPWM频率
****************************************************************/
//定时T1初始化
void timer1_init(void)
{
TCCR1B = 0x00;//停止定时器
TIMSK |= 0x18;//中断允许
TCNT1H = 0x00;
TCNT1L = 0x00;//初始值
OCR1AH = 0x00;
OCR1AL = 0xC9;//匹配A值(C8-D0-DA)
OCR1BH = 0x00;
OCR1BL = 0x09;//匹配B值
TCCR1A = 0xf1;
// TCCR1B = 0x04;//启动定时器
TCCR1B = 0x04;//启动定时器
}
/******************************************************************************
串口初始化函数
******************************************************************************/
void uart0_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = BIT(URSEL) | 0x06;
UBRRL = 0x67;
UBRRH = 0x00;//set baud rate hi
UCSRB = 0x98;
}
/**********************************END****************************************/
/*****************************************************************************/
///////////////////////////////中断处理函数////////////////////////////////////
/*****************************************************************************/
void uart0_tx_isr( char x)
{
while(!(UCSRA&0x20));
UDR=x;
}
unsigned int adc_calc(void)
{
//计算实际电压
unsigned long value=0;
value = ADCL>>6; //首先读低位
value|=(int)ADCH << 2; //然后读高位
voltage = value;
return voltage;
}
/*************************************************
中断接受,同时发送接受到的内容
**************************************************/
#pragma interrupt_handler uart0_rx_isr:12
void uart0_rx_isr(void)
{
unsigned char x;
CLI();
x=UDR;
uart0_tx_isr(x);
SEI();
}
#pragma interrupt_handler adc_isr:15
void adc_isr(void)//转换完成后中断处理
{
uchar back_flag;
AD_num++;
ADMUX++;
if(AD_num>7)
{
AD_num = 0;
ADMUX = 0x60;
}
voltage=adc_calc();
AD_get[AD_num1]=voltage;
/*********************************AD转换值处理*****************************************/
/* AD_min[AD_num1]=(AD_get[AD_num1]<AD_min[AD_num1]) ? AD_min[AD_num1]:AD_get[AD_num1];
AD_max[AD_num1]=(AD_get[AD_num1]>AD_max[AD_num1]) ? AD_max[AD_num1]:AD_get[AD_num1];
AD_read[AD_num1]= (AD_min[AD_num1]+ AD_max[AD_num1])*3/4 ;
if(AD_get[AD_num1]>AD_read[AD_num1])
{
back_flag|=BIT(i);
black_flag=back_flag;
} */
/********************************此部分有待证实*****************************************/
AD_num1++;
if(AD_num1>7)
AD_num1=0;
}
/**************************************************/
/////////////////定时器T1匹配中断A服务程序/////////
/**************************************************/
#pragma interrupt_handler timer1_compa_isr:7
void timer1_compa_isr(void)
{
CLI();
if(angle_flag1==1)
{
angle_flag1=0;
OCR1AH = angleh;
OCR1AL = anglel;
}
SEI();
}
//定时器T1匹配中断B服务程序
#pragma interrupt_handler timer1_compb_isr:8
void timer1_compb_isr(void)
{
CLI();
if(angle_flag2==1)
{
angle_flag2=0;
OCR1BH = 0x00;
OCR1BL = sudu;
}
SEI();
}
/******************************************************************************/
///////////////////////////time delay funtion///////////////////////////////////
/******************************************************************************/
void delay1(int k) //延时
{
int i;
for(i=0;i<k;i++);
}
/******************************************************************************/
/*****************************595扫描流水灯函数********************************/
/******************************************************************************/
void set595(uchar s2)
{
uchar mid,j = 0;
CLI();
for (j=0;j<8;j++)
{
mid=s2&0x01;
H595_SCK_L ;
if (mid == 0)
H595_SER_L ;
else
H595_SER_H;
NOP();
H595_SCK_H;
NOP();
s2=s2>>1;
}
H595_RCK_L ;
NOP();
H595_RCK_H;
SEI();
}
void led_line(uchar s2)
{
uchar mid,j=0;
CLI();
for (j=0;j<8;j++)
{
mid=s2&0x01;
H595_SCK1_L ;
if (mid==0)
H595_SER1_L ;
else
H595_SER1_H;
NOP();
H595_SCK1_H;
NOP();
s2=s2>>1;
}
H595_RCK1_L ;
NOP();
H595_RCK1_H;
SEI();
}
void display(uint shuzhi)
{
uchar ge,shi,bai,qian;
if(shuzhi > 999)
{
ge=shuzhi%10;
shi=shuzhi%100/10;
bai=shuzhi%1000/100;
qian=shuzhi/1000;
}
else if(shuzhi>99)
{
ge=shuzhi%10;
shi=shuzhi%100/10;
bai=shuzhi/100;
qian=10;
}
else if(shuzhi>9)
{
ge = shuzhi%10;
shi = shuzhi/10;
bai = 10;
qian = 10;
}
else
{
ge = shuzhi;
shi = 10;
bai = 10;
qian = 10;
}
set595(shushow[ge]);
SEG_4_L;
delay1(200);
SEG_4_H;
set595(shushow[shi]);
SEG_3_L;
delay1(200);
SEG_3_H;
set595(shushow[bai]);
SEG_2_L;
delay1(200);
SEG_2_H;
set595(shushow[qian]);
SEG_1_L;
delay1(200);
SEG_1_H;
}
/******************************************************************************/
/**********************************END*****************************************/
/******************************************************************************/
/********************************角度,速度实时处理函数************************/
void set_angle(uchar agh,uchar agl)
{
angle_flag1=1;
angleh=agh;
anglel=agl;
}
void set_sudu(uchar sd)
{
angle_flag2=1;
sudu=sd;
}
/************************************end***************************************/
/*********************坡道处理函数,有待实践证实********************************/
void set_podao()
{
uint ii,iii;
if(i<100)//上坡
AD_control();
else
if(i>100)//下坡趋势//傍晚100快速50
{
for(ii=0;ii<6000;ii++ )
{
AD_control();
switch(black_flag)
{
case 4: set_angle(0x00,0xc8);set_sudu(0xca);BACK2_ON ;break; //2
case 6: set_angle(0x00,0xca);set_sudu(0xca);BACK2_ON ;break; //12
case 2 : set_angle(0x00,0xcb);set_sudu(0x9a);BACK2_ON ;break; //1
case 10: set_angle(0x00,0xcc);set_sudu(0x9a);BACK2_ON ;break; //13
case 8 : set_angle(0x00,0xcd);set_sudu(0x9a);break; //3
case 24: set_angle(0x00,0xce);set_sudu(0x9a);break; //34
case 56: set_angle(0x00,0xcf);set_sudu(0x90);break; //345
case 16: set_angle(0x00,0xcf);set_sudu(0x90);break; //4
case 48: set_angle(0x00,0xd0);set_sudu(0x91);break; //45
case 32: set_angle(0x00,0xd0);set_sudu(0x91);break; //5
case 96: set_angle(0x00,0xd1);set_sudu(0x91);break; //56
case 64: set_angle(0x00,0xd2);set_sudu(0x91);break; //6
case 65: set_angle(0x00,0xd4);set_sudu(0x91);break; //06
case 1: set_angle(0x00,0xd5);set_sudu(0x91);;BACK1_ON ;break; //0
case 129: set_angle(0x00,0xd7);set_sudu(0x91);;BACK1_ON ;break; //07
case 128: set_angle(0x00,0xd9);set_sudu(0xc1);;BACK1_ON ;break; //7
// default:i++;set_angle(0x00,0xd0);break;
default:set_angle(0x00,0xd0);break;
}
}
i=0;
}
}
/************************************end***************************************/
/******************************************************************************/
///
//// ///
/// ///////////////////
/// ///
///
//////// /////////////////////
///
// ///
/// /// ///
////// /////////////////////
////
/******************************************************************************/
void Online(uchar sd)
{
online++;
if(online==10)
{
online = 0;
set_sudu(sd);
}
set_sudu(0x90);
}
void angle_control()
{
BACK1_OFF ; //转向灯
BACK2_OFF ;
switch(black_flag)
{
case 4: set_angle(0x00,0xc8);set_sudu(0xaa);BACK2_ON ;break; //2
case 6: set_angle(0x00,0xcb);set_sudu(0x41);BACK2_ON ;break; //12
case 2 : set_angle(0x00,0xcd);set_sudu(0x20);BACK2_ON ;break; //1
case 10: set_angle(0x00,0xce);set_sudu(0x15);break; //13
case 8 : set_angle(0x00,0xcd);set_sudu(0x10);break; //3
case 24: set_angle(0x00,0xce);set_sudu(0x02);break; //34
case 56: set_angle(0x00,0xcf);set_sudu(0x01);break; //345
case 16: set_angle(0x00,0xcf);set_sudu(0x01);break; //4
case 48: set_angle(0x00,0xd0);set_sudu(0x01);break; //45
case 32: set_angle(0x00,0xd1);set_sudu(0x01);break; //5
case 96: set_angle(0x00,0xd1);set_sudu(0x02);break; //56
case 64: set_angle(0x00,0xd2);set_sudu(0x10);break; //6
case 65: set_angle(0x00,0xd4);set_sudu(0x15);break; //06
case 1: set_angle(0x00,0xd5);set_sudu(0x20);BACK1_ON;break; //0
case 129: set_angle(0x00,0xd7);set_sudu(0x41);BACK1_ON;break; //07
case 128: set_angle(0x00,0xd9);set_sudu(0xa1);BACK1_ON;break; //7
// case 0:set_sudu(0x5a);BACK1_ON ;break; //7
default:i++;set_angle(0x00,0xd0);set_podao();break;
}
}
void AD_control()
{
uchar i;
uchar back_flag=0;
for(i=0;i<8;i++)
{
AD_min[i]=(AD_get[i]<AD_min[i]) ? AD_min[i]:AD_get[i];
AD_max[i]=(AD_get[i]>AD_max[i]) ? AD_max[i]:AD_get[i];
AD_read[i]= (AD_min[i]+ AD_max[i])*7/10 ;
if(AD_get[i]>AD_read[i])
{
back_flag|=BIT(i);
black_flag=back_flag;
}
}
}
void init_devices(void)
{
CLI(); //禁止所有中断
MCUCR = 0x00;
MCUCSR = 0x80;//禁止JTAG
GICR = 0x00;
port_init();
adc_init();
// uart0_init();
timer1_init();
// OSCCAL=0Xff;// 内部8m时钟校正
SEI();//开全局中断
}
/******************************************************************************/
/********************************MAIN FUNTION**********************************/
/******************************************************************************/
void main()
{
uint Count,Count1;
uchar Count2;
init_devices();
while(1)
{
Count++;
if(Count>200)
{
Count=0;
Count1++;
if(Count1>11)
Count1=0;
Count2=Count1;
led_line(taple[Count2]);
}
//led_line(Count2);
display(8888);
//display(black_flag);
AD_control();
angle_control();
}
}
|