crossok 发表于 2016-1-21 22:15:32

STM8控制TMC2660驱动步进电机 电机不正常

大家好,小弟最近在用STM8+TMC2660驱动步进电机,采用SPI通讯,脉冲控制方式
测试下来,一开始脉冲能控制,但是过了几分钟,电机就不转了,重新上电电机也无法锁住,是我配置还是硬件问题呢,大侠帮我看看吧,搞的头都大了
#define        INTPOL                0
#define DEDGE                0
ulong        DRVCTRL;

#define        TBL                        0
#define        CHM                        0
#define        RNDTF                0
#define        HDEC                0
#define        HEND                0
#define        HSTRT                0
#define        TOFF                0
ulong        CHOPCONF;

#define        SEIMIN                0
#define        SEDN                0
#define        SEMAX                0
#define        SEUP                0
#define        SEMIN                0
ulong        SMARTEN;

#define        SFILT                0
#define        SGT                        0
ulong        SGCSCONF;

#define        TST                        0
#define        SLPH                0
#define        SLPL                0
#define        DISS2G                0
#define        TS2G                0
#define        SDOFF                0                //0:enable step and dir 1:disable step and dir
#define        VSENSE                0               
#define        RDSEL                0
ulong        DRVCONF;

//*************************************
#define        read_address_key()        (( PD_IDR&0X0C)>>1)|(( PC_IDR&0X80)>>7)                                        //地址开关PD3 PD2 PC7
#define        read_encoded_key()        (( PC_IDR&0X30)>>2)|(( PC_IDR&0X40)>>5)|(( PC_IDR&0X08)>>3) //编码开关PC5 PC4 PC6 PC3

//*************************************
_Bool        PD4                        @PD_IDR:4;
_Bool        PD5                        @PD_ODR:5;
_Bool        PD6                        @PD_ODR:6;
_Bool        PA3                        @PA_ODR:3;

_Bool        PB4                        @PB_IDR:4;

//*************************************
#define        SPI_MISO        PD4
#define        SPI_MOSI        PD5
#define        SPI_CLK                PD6
#define        SPI_CS                PA3

#define        SG_TST                PB4

//*************************************
uchar        bit_1ms;
uchar        bit_encoded_key;
uchar        bit_address_key;

uchar        count_5ms;                                               

uchar        address_key_state;
uchar        encoded_key_state;
uchar        address_key_count;
uchar        encoded_key_count;

uchar        reg_mres;
uchar        reg_cs;

uchar        new_encoded_key;
uchar        new_address_key;

ulong        read_data;

ulong         test_tmp;
//*************************************
const        uchar        current_code={2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32};

//*************************************
void port_init(void)
{       
        PA_DDR = 0B00001000;
        PA_CR1 = 0B00001000;
        PA_CR2 = 0B00000000;

        PB_DDR = 0B00000000;
        PB_CR1 = 0B00010000;
        PB_CR2 = 0B00000000;       

        PC_DDR = 0B00000000;
        PC_CR1 = 0B11111000;
        PC_CR2 = 0B00000000;               

        PD_DDR = 0B01100000;                //PD4 MISO 输入无上拉
        PD_CR1 = 0B01101100;
        PD_CR2 = 0B00000000;
}

//*************************************
void clk_init(void)
{
        CLK_SWR   = 0xE1;   // 选择芯片内部的16MHZ的RC振荡器为主时钟
        CLK_CKDIVR= 0X08;          // 16M,2分频8M
        CLK_PCKENR1 = 0X10;   // 开TIM4 其他关闭
        CLK_PCKENR2 = 0X08;   // 开ADC其他关闭
}

//*************************************
void time4_init(void)
{
        TIM4_PSCR = 0X05;        // 32分频
        TIM4_IER= 0X01;        // 更新中断使能
        TIM4_ARR= 5;                // 自动重装载,向上计数,250*8/32us = 1ms
        TIM4_CNTR = 0;                // 计数值
        TIM4_CR1= 0x01;         // b0 = 1,允许计数器工作
                                                // b1 = 0,允许更新
                                                // 设置控制器,启动定时器
}

//*************************************
void iwdg_init(void)
{
        IWDG_KR= 0xCC;         //启动IWDG   
        IWDG_KR= 0x55;         //解除 PR 及 RLR 的写保护   
        IWDG_RLR = 0xff;         //看门狗计数器重装载数值         
        IWDG_PR= 0x06;         //分频系数为256 1.02s   
        IWDG_KR= 0xAA;         //刷新IDDG,避免产生看门狗复位,同时恢复 PR 及 RLR 的写保护状态
}
//*************************************
void delay_nus(uchar dat)
{
        for(;dat>0;dat--);
}
//*************************************
ulong       read_write_spi(ulong dat)
{
        uchar i;       
        ulong tmp=0;

        test_tmp = dat;
       
        SPI_CS = 0;

        for(i=0;i<20;i++)        
        {       
                SPI_CLK = 0;
               
                if((dat&0x80000)==0x80000)
                        SPI_MOSI=1;
                else
                        SPI_MOSI=0;
                dat <<= 1;

                tmp <<= 1;       
                SPI_CLK = 1;
               
                if(SPI_MISO==1)
                        tmp |= 0x00000001;
                else
                        tmp &= ~0x00000001;
               
        }               

        SPI_CS = 1;

        return        tmp;
}
//*************************************
void feed_iwdg(void)
{
        IWDG_KR = 0xAA;//刷新IDDG
}

//*************************************
void main_init(void)
{       
        _asm("sim");        //关总中断
       
        clk_init();
        port_init();
        time4_init();
        iwdg_init();

        SPI_CLK = 1;        //CLK上电先拉高
        SPI_CS= 1;        //失能TMC2660

        reg_mres = 7;
        reg_cs   = current_code;

        DRVCTRL   = 0X00;
        DRVCTRL <<= 8;
        DRVCTRL|=(INTPOL<<1)|DEDGE;
        DRVCTRL <<= 8;
        DRVCTRL|= reg_mres;

        CHOPCONF   = 0X04;
        CHOPCONF <<= 2;
        CHOPCONF|= TBL;
        CHOPCONF <<= 8;
        CHOPCONF|= (CHM<<7)|(RNDTF<<6)|(HDEC<<4)|(HEND);
        CHOPCONF <<= 7;
        CHOPCONF|= (HSTRT<<4)|(TOFF);
       
        SMARTEN   = 0X0A;
        SMARTEN <<= 8;
        SMARTEN|= (SEIMIN<<7)|(SEDN<<5)|(SEMAX);
        SMARTEN <<= 8;
        SMARTEN|= (SEUP<<5)|(SEMIN);
       
        SGCSCONF   = 0X06;
        SGCSCONF <<= 1;
        SGCSCONF|= SFILT;
        SGCSCONF <<= 8;
        SGCSCONF|= SGT;
        SGCSCONF <<= 8;
        SGCSCONF|= reg_cs;
       
        DRVCONF   = 0X07;
        DRVCONF <<= 1;
        DRVCONF|= TST;
        DRVCONF <<= 8;
        DRVCONF|=(SLPH<<6)|(SLPL<<4)|(DISS2G<<2)|(TS2G);
        DRVCONF <<= 8;
        DRVCONF|= (SDOFF<<7)|(VSENSE<<6)|(RDSEL<<4);

        address_key_state = 0x07;
        encoded_key_state = 0x0f;

//        read_data = read_write_spi(DRVCTRL);
//        read_data = read_write_spi(CHOPCONF);
//        read_data = read_write_spi(SMARTEN);
//        read_data = read_write_spi(SGCSCONF);
//        read_data = read_write_spi(DRVCONF);

        read_data = read_write_spi(0x901b4);
        read_data = read_write_spi(0xd001f);
        read_data = read_write_spi(0xe0010);
        read_data = read_write_spi(0x00000);
        read_data = read_write_spi(0xa8202);
       
        _asm("rim");        //开总中断
}

//*************************************
char function_getline(int x0,int x,int x1,char y0,chary1)
{
        char y;
        y = (x - x0)*(y1 - y0)/(x1 - x0) + y0;
        return y;
}
//*************************************
void time_mainloop(void)
{
        if(bit_1ms == 0)return;
        bit_1ms = 0;
       
        count_5ms++;
        if(count_5ms == 5)
        {
                bit_address_key = 1;
        }
        else if(count_5ms >= 10)
        {
                count_5ms = 0;
                bit_encoded_key = 1;
        }
}
//*************************************
void addresskey_mainloop(void)                //设置细分系数
{
        if(bit_address_key == 0)return;
       
        bit_address_key = 0;
        new_address_key = read_address_key();
       
        if(new_address_key != address_key_state)
        {
                if(++address_key_count >= 10)
                {
                        address_key_count = 0;
                        address_key_state = new_address_key;
                        reg_mres          = new_address_key;

                        DRVCTRL= 0X00;
                        DRVCTRL <<= 8;
                        DRVCTRL |=(INTPOL<<1)|DEDGE;
                        DRVCTRL <<= 8;
                        DRVCTRL |= reg_mres;
                       
                        read_write_spi(DRVCTRL);
                }
        }
}
//*************************************
void encodedkey_mainloop(void)                //设置电流大小
{
        if(bit_encoded_key == 0)return;
       
        bit_encoded_key = 0;
        new_encoded_key = read_encoded_key();
       
        if(new_encoded_key != encoded_key_state)
        {
                if(++encoded_key_count >= 10)
                {
                        encoded_key_count = 0;
                        encoded_key_state = new_encoded_key;
                        reg_cs            = current_code;
                       
                        SGCSCONF = 0X06;
                        SGCSCONF <<= 1;
                        SGCSCONF |= SFILT;
                        SGCSCONF <<= 8;
                        SGCSCONF |= SGT;
                        SGCSCONF <<= 8;
                        SGCSCONF |= reg_cs;
                        read_write_spi(SGCSCONF);
                }
        }
}
//*************************************
void main()
{       
        main_init();

        while(1)
        {
                time_mainloop();
                addresskey_mainloop();
                encodedkey_mainloop();
                feed_iwdg();
        }
}
//*************************************
@far @interrupt time4_IRQ(void)
{
        TIM4_SR = 0X00;
        bit_1ms = 1;
       
}


页: [1]
查看完整版本: STM8控制TMC2660驱动步进电机 电机不正常