📄 xunxiandongzuo8._c
字号:
//ICC-AVR application builder : 2005-12-22 22:30:20
// Target : M8
// Crystal: 8.0000Mhz
#include <iom8v.h>
#include <macros.h>
#include "Main8.h"
#include "L_PID.c"
#include "Slave_SPI.c"
#include "TIMEDELAY8.C"
void port_init(void)
{
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x00; //m103 output only
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0x00;
PORTB |= 0x02; //OC1A output ,high level
DDRB |= 0x02;
PORTC &= ~0x02;
DDRC |= 0x02;
PORTC |= 0x08; //PC3 输出,控制电机方向,1->正转,0->反转 0000 1000
DDRC |= 0x38; //PC4,PC5输出
PORTD |= 0X0C; //INT0,INT1设置为输入,PD2,PD3
DDRD &= ~0X0C;
PORTD &=~0x80; //PD7置低
DDRD |= 0x80;
PORTD &=~0x40;//PD6置低
DDRD |= 0x40;
PORTD |= 0x10; //T0设为带上拉输入,码盘脉冲输入
DDRD &= ~0x10;
}
//TIMER0 initialize - prescale:falling edge
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x00 /*INVALID SETTING*/; //set count
TCCR0 = 0x06; //start timer
}
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
num_H++; //低字节逸溢出,高字节加一
}
//TIMER1 initialize - prescale:1
// WGM: 7) PWM 10bit fast, TOP=0x03FF
// desired value: 7.813KHz
// actual value: 7.813KHz (0.0%)
void timer1_init(void)
{
TCCR1B = 0x00; //stop
TCNT1H = 0xFC; //setup
TCNT1L = 0x01;
OCR1AH = 0x00; //初始占空比为0,停机
OCR1AL = 0x00;
OCR1BH = 0x00;
OCR1BL = 0x00;
ICR1H = 0x03;
ICR1L = 0xFF;
TCCR1A = 0xC3; //OC1A输出PWM波形
TCCR1B = 0x09; //start Timer
}
/*INT0下降沿触发, INT1上升沿触发,
INT0触发时方向电平为1,表正转,INT1触发时方向电平为0,表正转,*/
#pragma interrupt_handler int0_isr:2
void int0_isr(void)
{
//external interupt on INT0 Dir GO_AHEAD-> GO_BACK, 存贮并清零
unsigned int temp_int = 0x0000;
unsigned char temp_char = 0x00;
temp_char = TCNT0; //读取脉冲计数低字节
TCNT0=0;
temp_int = num_H; //读取脉冲计数高字节
num_H = 0;
temp_int <<=8; //计算脉冲数
temp_int += temp_char;
Num_Speed += temp_int; //累计脉冲数
}
#pragma interrupt_handler int1_isr:3
void int1_isr(void)
{
//external interupt on INT0 //Dir GO_BACK -> GO_AHEAD, 存贮并清零
unsigned int temp_int = 0x0000;
unsigned char temp_char = 0x00;
temp_char = TCNT0; //读取脉冲计数低字节
TCNT0=0;
temp_int = num_H; //读取脉冲计数高字节
num_H = 0;
temp_int <<=8; //计算脉冲数
temp_int += temp_char;
Num_Speed -= temp_int; //累计脉冲数
}
//TIMER2 initialize - prescale:1024
// WGM: Normal
// desired value: 20mSec
// actual value: 19.968mSec (0.2%)
void timer2_init(void)
{
TCCR2 = 0x00; //stop
TCNT2 = 0x64; //setup
TCCR2 = 0x07; //start
}
/* 定时进行PID运算 */
#define Dir ( (PIND)&(1<<2) ) //方向输入,“非零”为GO_AHEAD,“0”为GO_BACK
#pragma interrupt_handler timer2_ovf_isr:5
void timer2_ovf_isr(void)
{
unsigned int temp_int = 0x0000;
unsigned char temp_char = 0x00;
signed int temp_sint=0;
TCNT2 = 0x64; //reload counter value
SEI();
temp_char = TCNT0; //读取脉冲计数低字节
TCNT0=0;
temp_int = num_H; //读取脉冲计数高字节
num_H = 0;
temp_int <<=8; //计算脉冲数
temp_int += temp_char;
if(Dir) //计数累加
Num_Speed += temp_int;
else
Num_Speed -= temp_int;
L_sPID.vi_FeedBack = Num_Speed; //储存当前速速值
/**************************************/
switch( PID_choice )
{
case SPEED_SET :
{
temp_sint = v_PIDCalc ( &L_sPID);
break;
}
case DISTANCE_SET :
{
temp_sint = s_PIDCalc( &L_sPID );
break;
}
}
//temp_sint = v_PIDCalc ( &L_sPID);
Num_Speed = 0;
send_PWM( temp_sint ); //调节PWM的占空比
}
/*pwm脉宽调节*/
void send_PWM(signed int num_pwm)
{
if( num_pwm >= 0 )
now_dir = GO_AHEAD;
else
now_dir = GO_BACK;
if( now_dir == GO_AHEAD ) //判断正反转
{
//now_dir=GO_AHEAD,正向,
if(pre_dir != now_dir) //pre_dir!=now_dir,换成正向,
{
PORTC |= 0x08; //PC3->1,转向变为正
pre_dir = now_dir; //重载pre_dir
}
OCR1A = num_pwm; //重载OCR1A
TCNT1H = 0x03; //隔一定时间更新OCR1A的值,改变PWM信号,保护18200
TCNT1L = 0xF0;
}
else
{
//now_dir=GO_BACK,负方向,
if(pre_dir != now_dir) //pre_dir!=now_dir,换成负向
{
PORTC &= ~0x08; //PC3->0,转向变为负
pre_dir = now_dir; //重载pre_dr
}
OCR1A = 0 - num_pwm; //赋负转占空比
TCNT1H = 0x03; //隔一定时间更新OCR1A的值,改变PWM信号,保护18200
TCNT1L = 0xF0;
}
}
void free_stop (void) //立即停机
{
now_dir = GO_STOP;
pre_dir = GO_STOP;
PORTC |= 0x08; //正向输出占空比为零。
OCR1A = 0x0000; //使占空比为0
TCNT1H = 0x03; //隔一定时间更新OCR1A的值,改变PWM信号,保护18200
TCNT1L = 0xF0;
PID_choice = 0xFF;
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer0_init();
timer1_init();
timer2_init();
//init_7279();
spi_init();
L_PIDInit();
MCUCR = 0x0E; //INT0 下降沿触发,INT1上升沿触发,INT0 为高电平时表电机正转
GICR = 0xC0;
TIMSK = 0x41; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void main()
{
unsigned char i ;
unsigned long temp_long = 0;
init_devices();
//TCCR2 = 0x07;
//PID_choice = SPEED_SET;//选择PID方式
//L_sPID.vi_Ref= 300; //给定参考速度
//delay_s(2);
//L_sPID.vi_Ref= -300;
while (1)
{
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -