📄 60e9a2b2be63001d13affd0d86873efd
字号:
/*This file has been prepared for Doxygen automatic documentation generation.*/
#include "header/includes.h"
#include "altera_avalon_uart.h"
alt_u8 led = 0x2;
alt_u8 dir = 0;
void led_flash(void)
{
if (led & 0x81)
{
dir = (dir ^ 0x1);
}
if (dir)
{
led = led >> 1;
}
else
{
led = led << 1;
}
IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE, led);
}
/********************************************************************
PID计算相关参数定义
*********************************************************************/
#define PID_PERIOD 8000
//#define PID_PERIOD 8000
#define HOERF 0
#define HOERM 1
#define HOERL 2
volatile long counter=0; //编码器的计数器
uchar go_en=0; //使能走
//int clk_cnt=0; //输出脉冲计数器
volatile long locate = 0; //位置信息,调节用
volatile long Initposition = 0; //初始化后的位置
volatile int vd = -30,vq = 30;
volatile int Speed=0; //速度参数
struct PID_DATA piddata;
alt_16 timeren;
alt_16 timercnt;
alt_16 timeren10;
/********************************************************************
电机控制和定时中断函数
*********************************************************************/
long get_addr(void)
{
int addr,circle;
addr = IORD_ALTERA_AVALON_PIO_DATA(ABADDR_BASE);
circle = IORD_ALTERA_AVALON_PIO_DATA(CIRCLES_BASE);
counter = (circle - 0x800)*1500L + addr;
return counter;
}
void Mspeed(int spd) //调速
{
//为了不超调,将vd和vq的值都限制在-600~600之间。
//spd = -spd;
if(spd >= 0)
{
if(spd > 600)
spd = 600;
vd = -spd*3/2;
vq = spd;
}
else
{
if(spd < -600)
spd = -600;
vd = -spd*6/5;
vq = spd;
}
IOWR_ALTERA_AVALON_PIO_DATA(VD_BASE, vd);
IOWR_ALTERA_AVALON_PIO_DATA(VQ_BASE, vq);
}
void timer_0_IRQ(void *context, alt_u32 id)
{
//alt_putstr("Hello from Nios II!\n");
static long e[2];
long deta;
char limit_tmp;
//IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE, 1);
IOWR_ALTERA_AVALON_TIMER_STATUS( TIMER_0_BASE,0 );
timeren = 1;
timercnt++;
//get_addr();
deta = get_addr() - locate;
/*
//if(temp >= -1 && temp <= 1) pid_Reset_Integrator(&piddata);
//if(temp == 0) pid_Reset_Integrator(&piddata);
//disp(temp,8);
e[1] = deta - e[0];
e[0] = deta;
fuzzy_step(e);
pid_factor(crisp_scale[0],crisp_scale[1], crisp_scale[2], &piddata);
*/
//Speed = pid_Controller(locate,counter,&piddata);
//pid_factor(100, 50, 10, &piddata);
//deta = get_addr() - locate;
Speed = pid_Controller(locate,counter,&piddata);
if(deta >= -1 && deta <= 1)
//if(deta == 0)
{
//if(deta == 0)
pid_Reset_Integrator(&piddata);
Speed = 0;
}
//else
{
}
limit_tmp = IORD_ALTERA_AVALON_PIO_DATA(LIMIT_BASE);
if(limit_tmp & (1<<HOERL)) //最后的霍尔元件报警,速度只能为负
{
if(Speed > 0)
{
Mspeed(0);
Speed = 0;
}
else
Mspeed(Speed);
}
else if(limit_tmp & ((1<<HOERM)|(1<<HOERF)))
{
if(Speed < 0)
{
Mspeed(0);
Speed = 0;
}
else
Mspeed(Speed);
}
else
Mspeed(Speed);
if(timercnt == 100000000/PID_PERIOD)
{
timercnt = 0;
timeren10 = 1;
}
//IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE, 0);
}
/********************************************************************
步进电机控制函数
*********************************************************************/
alt_16 Stlocation;
void Stepper(void)
{
char i;
alt_16 st_limit, st_position;
st_limit = IORD_ALTERA_AVALON_PIO_DATA(STLIMIT_BASE);
if(st_limit)
{
st_position = IORD_ALTERA_AVALON_PIO_DATA(STPOSITION_BASE);
if(st_limit & 0x01) //底下开关关闭,限制往下走
{
if(Stlocation > st_position)
{
IOWR_ALTERA_AVALON_PIO_DATA(STSTOP_BASE, 1);
IOWR_ALTERA_AVALON_PIO_DATA(STLOCATE_BASE, Stlocation);
IOWR_ALTERA_AVALON_PIO_DATA(STLE_BASE, 0);
for(i=0;i<4;i++)
{
IOWR_ALTERA_AVALON_PIO_DATA(STLE_BASE, 0);
IOWR_ALTERA_AVALON_PIO_DATA(STLE_BASE, 0);
IOWR_ALTERA_AVALON_PIO_DATA(STLE_BASE, 1);
IOWR_ALTERA_AVALON_PIO_DATA(STLE_BASE, 1);
}
}
}
else if(st_limit & 0x02)//顶部开关关闭,限制往上走
{
if(Stlocation < st_position)
{
IOWR_ALTERA_AVALON_PIO_DATA(STSTOP_BASE, 1);
IOWR_ALTERA_AVALON_PIO_DATA(STLOCATE_BASE, Stlocation);
IOWR_ALTERA_AVALON_PIO_DATA(STLE_BASE, 0);
for(i=0;i<4;i++)
{
IOWR_ALTERA_AVALON_PIO_DATA(STLE_BASE, 0);
IOWR_ALTERA_AVALON_PIO_DATA(STLE_BASE, 0);
IOWR_ALTERA_AVALON_PIO_DATA(STLE_BASE, 1);
IOWR_ALTERA_AVALON_PIO_DATA(STLE_BASE, 1);
}
}
}
}
else
{
IOWR_ALTERA_AVALON_PIO_DATA(STSTOP_BASE, 1);
IOWR_ALTERA_AVALON_PIO_DATA(STLOCATE_BASE, Stlocation);
IOWR_ALTERA_AVALON_PIO_DATA(STLE_BASE, 0);
for(i=0;i<4;i++)
{
IOWR_ALTERA_AVALON_PIO_DATA(STLE_BASE, 0);
IOWR_ALTERA_AVALON_PIO_DATA(STLE_BASE, 0);
IOWR_ALTERA_AVALON_PIO_DATA(STLE_BASE, 1);
IOWR_ALTERA_AVALON_PIO_DATA(STLE_BASE, 1);
}
}
}
void Stepper_init(void)
{
char i;
IOWR_ALTERA_AVALON_PIO_DATA(STRST_BASE, 0);
for(i=0;i<100;i++);
IOWR_ALTERA_AVALON_PIO_DATA(STRST_BASE, 1);
IOWR_ALTERA_AVALON_PIO_DATA(STSTOP_BASE, 1);
}
/********************************************************************
主机串口处理函数
*********************************************************************/
alt_16 tmp=0,rcvcnt=0,chk0 = 0;
alt_16 state0 = 0;
alt_16 xaa,x55; //识别0x55和0xaa用
alt_16 update;
char rcv[10];
alt_16 rcvlength;
alt_16 Sttodo; //步进电机位置更新未执行为1
void do_receive(void)
{
alt_16 i;
alt_32 rcvtmp;
rcvtmp = 0;
for(i=0;i<4;i++)
{
rcvtmp <<= 8;
rcvtmp |= rcv[i];
}
locate = rcvtmp + Initposition; //伺服电机位置更新
rcvtmp = 0;
for(i=0;i<2;i++)
{
rcvtmp <<= 8;
rcvtmp |= rcv[i+4];
}
Stlocation = rcvtmp; //步进电机位置更新
Stepper();
}
void usart0_do(void)
{
if(rx_counter0)
{
tmp = get_char0();
if(state0 == 0)
{
if(tmp == 0x55) //接收到数据包起始标志位
{
state0 = 1;
rcvcnt = 0; //准备接收数据
rcvlength = 0;
xaa = 0;
x55 = 0;
chk0 = 0;
}
}
else if(state0 == 1)
{
rcvlength = tmp; //以第一个数据为有效数据长度,有校验
chk0 += tmp;
state0 = 2;
}
else if(state0 == 2) //接收数据状态
{
if(tmp != 0xaa)
{
if(xaa == 0xaa) //说明前一个数是0xaa
{
rcv[rcvcnt] = x55;
rcvcnt++; //接收计数器
xaa = 0;
}
rcv[rcvcnt] = tmp;
chk0 += tmp; //校验
rcvcnt++; //接收计数器
xaa = 0;
if(rcvcnt >= rcvlength)
state0 = 4;
if(tmp == 0x55) //出错
state0 = 0;
}
else
{
if(xaa == 0xaa) //说明接收到连续两个0xaa,否则aa为0
{
x55 = 0xaa;
chk0 += 0xaa; //校验
}
else //第一次接到0xaa
{
x55 = 0x55;
chk0 += 0xaa; //校验
xaa = 0xaa;
}
}
}
else if(state0 == 3) //暂时没有校验
{
if(chk0 == tmp)
state0 = 4;
else
state0 = 0;
}
else if(state0 == 4)
{
if(tmp == 0x55)
{
state0 = 0; //结束,回到起始状态
update = 1; //完成一次接收,准备数据更新
chk0 = 0;
put_char0(0x55);
}
}
else
{
state0 = 0;
}
}
//数据更新
if(update)
{
update = 0;
do_receive();
}
}
/********************************************************************
初始化
*********************************************************************/
void timer_init(void) //100Hz
{
alt_irq_register(TIMER_0_IRQ,0,timer_0_IRQ);
//初始化周期寄存器
IOWR_ALTERA_AVALON_TIMER_PERIODL(TIMER_0_BASE,PID_PERIOD&0x0000FFFF);
IOWR_ALTERA_AVALON_TIMER_PERIODH(TIMER_0_BASE,(PID_PERIOD>>16)&0x0000FFFF);
//打开中断、循环计数、定时开始
IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER_0_BASE,(ALTERA_AVALON_TIMER_CONTROL_ITO_MSK|ALTERA_AVALON_TIMER_CONTROL_START_MSK|ALTERA_AVALON_TIMER_CONTROL_CONT_MSK));
}
/********************************************************************
显示读取的sin值
*********************************************************************/
void disp_long(long temp)
{
alt_16 bit[7];
alt_16 i = 0;
for(;i<6;i++)
{
bit[5-i] = temp%10;
temp /= 10;
}
for(i=0;i<6;i++)
{
put_char0(bit[i]+'0');
}
}
void disp(void)
{
put_str0("\nlocate = ");
disp_long(locate);
put_str0("; counter = ");
disp_long(counter);
put_str0("; speed = ");
disp_long(Speed);
put_str0("; Initposition = ");
disp_long(Initposition);
}
/********************************************************************
主函数
*********************************************************************/
char Init_PMSM_succeed = 0;
char Init_Stepper_succeed = 0;
void Init(void)
{
pid_Init(100, 100, 50, &piddata);
timer_init();
uart0_init();
Stepper_init();
locate = 0;
Stlocation = -0x8000;
Stepper();
}
int main(void)
{
char i;
alt_16 Itimer = 0;
alt_16 stlimit0 = 0, stlimit1 = 0;
alt_putstr("Hello from Nios II!\n");
Init();
while(1)
{
//led_flash();
if(Init_PMSM_succeed && Init_Stepper_succeed)
{
usart0_do();
}
if(IORD_ALTERA_AVALON_PIO_DATA(STBUSY_BASE))
IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE, 1);
else
IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE, 0);
//检测到有开关信号,停止步进电机
stlimit1 = stlimit0;
stlimit0 = IORD_ALTERA_AVALON_PIO_DATA(STLIMIT_BASE);
if(stlimit0 != 0 && stlimit1 == 0) //上升沿
{
IOWR_ALTERA_AVALON_PIO_DATA(STSTOP_BASE, 0);
}
if( Init_PMSM_succeed == 0)
{
/*temp = IORD_ALTERA_AVALON_PIO_DATA(LIMIT_BASE);
if((temp & (1<<HOERM)) && (temp & (1<<HOERF)))*/
if(Itimer >= 5)
{
Initposition = get_addr();
locate = Initposition;
Init_PMSM_succeed = 1;
}
else
{
locate -= 1000;
}
}
if(Init_Stepper_succeed == 0)
{
if(stlimit0)
{
IOWR_ALTERA_AVALON_PIO_DATA(STRST_BASE, 0);
for(i=0;i<100;i++);
IOWR_ALTERA_AVALON_PIO_DATA(STRST_BASE, 1);
for(i=0;i<100;i++);
IOWR_ALTERA_AVALON_PIO_DATA(STRST_BASE, 0);
for(i=0;i<100;i++);
IOWR_ALTERA_AVALON_PIO_DATA(STRST_BASE, 1);
for(i=0;i<100;i++);
Init_Stepper_succeed = 1;
}
}
if(timeren10)
{
timeren10 = 0;
disp();
Itimer++;
}
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -