avatar_Кулибин

Самодельный контроллер полноприводный.

Автор Кулибин, 20 Июль 2015 в 14:42

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

Кулибин

Всем привет.
Наверное были идеи спроектировать альтернативу инфинеону с открытым кодом и всеми схемами но или тема заглохла или никому не надо?
Мне бы вот хотелось бы полноприводный контроллер сваять и сразу что бы там маршрутник был.
Чета мне не везло последнее время с контроллерами 2 раза чип выпаливал и даже не мог причину найти.
Хочу давно уже свой. Если что и поправить код можно и легко отремонтировать.
Только кроме PIC контролеров я больше ничего не знаю и уже нет сил чего то новое осваивать.
А самая загвоздка это управление самим мотором.
Умею платы травить, паять smd мелкие выводы, шарушить BGA если надо но с теорией беда.
Пока не могу понять как работает рекупер в программном плане, даже на уровне электроники и как заставить ровно вращать колесо на полном КПД.
Возможно я и допру и сделаю что бы МК закрутилось но не уверен что оно будет вращаться как надо.
Если бы кто с теорией помог..
Ваттметр давно собрал, юзается, радует но вот с контроллерами беда. Прошиваются не удобно, хотел сделать прошивку с мобилы да перегорел, настроил всё и не надо больше ничего трогать. Хотя часть кода написал и спаял общалку с инфинеоном. )) Да так и бросил.
А вот свой контроллер со всеми наворотами у меня есть желание собрать, причём оно появилось ещё 2 года назад, зимой соберу драйвер спи.....ный с инфинеона и попробую повращать колесо.
Буду делать полный привод. Боюсь только что брошу это потому что не разберусь в теории управления МК. ))
Если бы я целыми днями ничего не делал другое дело, ещё приходится зарабатывать деньги.
Может кто подсоединится к созданию альтернативы инфинеона?
Разработать надо полноприводник но детали то не обязательно запаивать на полный привод.
Можно и 2 версии нарисовать и прошивку на 2 версии сделать.
Мне важны только размеры. Мне надо что бы вешался сбоку самоката Rhino то есть скорее будет длинный по 12 фет на каждое колесо. 100 вольт 5квт на каждый привод.
Всякое видео самокатное.
http://www.youtube.com/user/VakuumTonus/videos

Поехали вместе кататься если живешь рядом?

SolarRay

[user]18f46k20[/user], на сфере есть, вроде бы даже несколько. Есть ли в них поддержка двух моторов, не знаю.

Кулибин

Я не знаю что такое сфера. ))
То есть там алгоритмы управления колесом прям можно поглядеть?
Всякое видео самокатное.
http://www.youtube.com/user/VakuumTonus/videos

Поехали вместе кататься если живешь рядом?

SolarRay

http://endless-sphere.com/forums/viewtopic.php?f=30&t=57877
По этому же контроллеру, где то там есть ещё и другие темы.

Кулибин

Всякое видео самокатное.
http://www.youtube.com/user/VakuumTonus/videos

Поехали вместе кататься если живешь рядом?

tehnik

Вот еще код под PIC16F877 хотя вначале пишут, что под PIC16F72. Ноя думаю это не важно, главное - правильный алгоритм ;-)
С помощью гугла переводил на английский и читал, т.к. на русский выходит бредятина.
Спойлер
#include
//电动车双闭环程序,采用双闭环方式控制电机,以得到最好的zh 转速性能,并且可以
//限制电机的最大电流。本应用程序用到两个CCP 部件,其中CCP1 用于PWM 输出,以控
//制电机电压;CCP2 用于触发AD,定时器TMR2、TMR1,INT 中断,RB 口电平变化中断,
//看门狗以及6 个通用I/O 口
#define AND 0xe0 //状态采集5,6,7 位
#define CURA 0X0a //电流环比例和积分系数之和
#define CURB 0X09 //电流环比例系数
#define THL 0X6400 //电流环最大输出
#define FULLDUTY 0X0FF //占空比为1 时的高电平时间
#define SPEA 0X1d //转速环比例和积分系数之和
#define SPEB 0X1c //转速环比例系数
#define GCURHILO 0X0330 //转速环最大输出
#define GCURH 0X33 //最大给定电流
#define GSPEH 0X67 //最大转速给定
#define TSON 0X38 //手柄开启电压1.1 V,TSON*2 为刹车后手柄开启电压,即
//2.2 V
#define VOLON 0X4c //低电压保护重开电压3.0 V 即33 V
#define VOLOFF 0X49 //低电压保护关断电压2.86 V 即31.5 V
volatile unsigned char DELAYH,DELAYL,oldstate,speed,
speedcount,tsh,count_ts,count_vol,gcur,currenth,
voltage; //寄存器定义
static bit sp1,spe,ts,volflag,spepid,lowpower,
off,shutdown,curpid; //标志位定义
static volatile unsigned char new[10]={0xaf,0xbe,0xff,0x7e,0xcf,
0xff,0xd7,0x77,0xff,0xff}; //状态寄存器表
//------------PIC16F877 初始化子程序------------
void INIT877()
{
PORTC=0X0FF; //关断所有MOSFET
TRISC=0X02; //设置C 口输出
PIE1=0X00; //中断寄存器初始化,关断所有中断
TRISA=0XCF; //设置RA4,RA5 输出
TRISB=0XEF; //RB 口高三位输入,采集电机三相的霍尔信号
PORTC=new[(PORTB&AND)>>5]; //采集第一次霍尔信号,并输出相应的信号,导通
//两个MOS 管
T2CON=0X01; //TMR2 4 分频
CCPR1L=0X0FF; //初始时PWM 输出全高
CCP1CON=0X0FF; //CCP1 设置为PWM 方式
CCP2CON=0X0B; //CCP2 设置为特殊方式,以触发AD
ADCON0=0X81; //AD 时钟为32 分频,且AD 使能,选择AN0 通道采集手
//柄电压
TMR2=0X00; //TMR2 寄存器初始化
TMR1H=0X00; //TMR1 寄存器初始化
TMR1L=0X00;
T1CON=0X00; //TMR1 为1 分频
CCPR2H=0X08;
CCPR2L=0X00; //电流采样周期设置为TAD=512 μs
PR2=0XC7; //PWM 频率设置为5 kHz
ADCON1=0X02; //AD 结果左移
OPTION=0XFB; //INT 上升沿触发
TMR2ON=1; //PWM 开始工作
INTCON=0XD8; //中断设置GIE=1,PEIE=1,RBIE=1
ADIE=1; //AD中断使能
speedcount=0x00; //转速计数寄存器
speed=0x7f; //转速保持寄存器
spe=1; //低速标志位
sp1=1; //低速标志位
oldstate=0x0ff; //初始状态设置,区别于其他状态
count_ts=0x08; //电流采样8 次,采集1 次手柄
count_vol=0x00; //采样256 次手柄,采集1 次电池电压
ts=1; //可以采集手柄值的标志位
ADGO=1; //AD采样使能
TMR1ON=1; //CCP2 部件开始工作
}
//------------延时子程序---------------
#pragma interrupt_level 1
void DELAY1(x)
char x;
{
DELAYH=x; //延时参数设置
#asm
DELAY2 MOVLW 0X06
MOVWF _DELAYL
DELAY1 DECFSZ _DELAYL
GOTO DELAY1
DECFSZ _DELAYH
GOTO DELAY2
#endasm
}
//-----------状态采集子程序----------------------
void sample()
{
char state1,state2,state3,x;
do {
x=1;
state1=(PORTB&AND); //霍尔信号采集
DELAY1(x);
state2=(PORTB&AND);
}while(state1-state2); //当三次采样结果不相同时继续采集状态
if(state1-oldstate!=0) //看本次采样结果是否与上次相同,不同
//则执行
{oldstate=state1; //将本次状态设置为旧状态
state1=(oldstate>>5);
PORTC=new[state1]; //C 口输出相应的信号触发两个MOS 管
if(sp1==1){spe=1;sp1=0;}
else { //如果转速很低,则spe 置1
spe=0;sp1=0;
speedcount<<=1;
state3=(TMR1H>>2); //否则,spe=0,计转速
speed=speedcount+state3; //speed 寄存器为每256 μs 加1
}
speedcount=0;
}
}
//-----------------AD 采样子程序----------------------
void AD()
{
char x;
ADIF=0; //清AD 中断标志位
if(ts==1){ //如果为手柄采样,则采样手柄值
CHS0=1; //选择电流采样通道
count_vol=count_vol+1; //电池采样计数寄存器
spepid=1; //置转速闭环运算标志
ts=0;tsh=ADRESH; //存手柄值
if(count_vol==0) { //如果电池采样时间到,则选择AN2 通道,采集电池电压
CHS0=0;CHS1=1;volflag=1;x=1;DELAY1(x);ADGO=1;
}
}
else if(volflag==1) { //电池采样完毕,进行相应的处理
CHS1=0;CHS0=1;volflag=0;voltage=ADRESH;lowpower=1;
}
else { //否则,中断为采样电流中断
speedcount=speedcount+1; //speedcount 寄存器加1,作为测量转速用
if(speedcount>0x3d) sp1=1; //如果转速低于1 000 000 μs/(512 μs*3eh*3)
// 则认为为低速状态
currenth=ADRESH;
curpid=1;
count_ts=count_ts-1;
if(count_ts==0) { //如果手柄时间到,则转入手柄采样通道
CHS0=0;count_ts=0x08;ts=1;x=1;DELAY1(x);ADGO=1;
}
}
}
//-------------刹车处理子程序------------------
void BREAKON()
{
char x;
off=0; //off清零,如果是干扰则不复位
shutdown=0;
if(RB0==1) { //如果刹车信号为真,则停止输出电压
ADIE=0; //关AD 中断
INTE=0; //关刹车中断
CCPR1L=FULLDUTY; //输出电压0
TMR1ON=0; //关CCP2,不再触发AD
for(;ADGO==1;) continue;//如正在采样,则等待采样结束
ADIF=0; //ADIF 位清零
CHS0=0; //选择通道0 采样手柄
CHS1=0;
x=1;
DELAY1(x);
do {
ADGO=1;
for(;ADIF==0;)continue;
ADIF=0;
CCPR1L=FULLDUTY;
asm("CLRWDT");
tsh=(ADRESH>>1);
}while(tsh>TSON||RB0==1); //当手柄值大于2.2 V 或刹车仍旧继续时,执行以
//上语句
off=1; //置复位标志
}
}
//---------欠保护子程序-------------------
void POWER()
{
char x;
lowpower=0;
voltage>>=1; //电压值换为7 位,以利于单字节运算
if(voltageADIE=0;
INTE=0;
TMR1ON=0;
CCPR1L=FULLDUTY;
for(;ADGO==1;)continue;
ADIF=0;
CHS0=0;CHS1=1;
x=1;
DELAY1(x);
do{ADGO=1;
for(;ADIF==0;)continue;
ADIF=0;
voltage=(ADRESH>>1);
CCPR1L=FULLDUTY;
asm("CLRWDT");
}while(voltageoff=1; //置复位标志
}
}
//------------电流环运算子程序-----------------
void CURPI()
{ static int curep=0x00,curek=0x00,curuk=0x00;
union data{int pwm;
char a[2];}b; //定义电流环运算寄存器
curpid=0; //清电流运算标志
curep=curek*CURB; //计算上一次偏差与比例系数的积
if(currenth<2)currenth=2; //如果采样电流为零,则认为有一个小电流以利于
//使转速下降
currenth>>=1;
curek=gcur-currenth; //计算本次偏差
curuk=curuk+curek*CURA-curep; //按闭环PI 运算方式得到本次输出结果,下
//面对结果进行处理
if(curuk<0x00) { //如果输出小于零,则认为输出为零
curuk=0;CCPR1L=FULLDUTY;CCP1X=0;CCP1Y=0;
}
else if(curuk-THL>=0) { //如果输出大于限幅值,则输出最大电压
curuk=THL;CCPR1L=0;CCP1X=0;CCP1Y=0;
}
else { //否则,按比例输出相应的高电平时间到CCPR1 寄存器
b.pwm=THL-curuk;
b.pwm<<=1;
CCPR1L=b.a[1]; //CCPR1L=(b.pwm>>8)&0x0ff;将PWM 寄存器的高半字节
if(b.pwm&0x80!=0) CCP1X=1;
else CCP1X=0;
if(b.pwm&0x40!=0) CCP1Y=1;
else CCP1Y=0;
}
}
//---------------转速环运算子程序-----------------------
void SPEPI()
{ static int speep=0x00,speek=0x00,speuk=0x00;
int tsh1,speed1; //转速寄存器定义
spepid=0; //清转速运算标志
if(spe==1) speed1=0x00; //若转速太低,则认为转速为零
else speed1=0x7f-speed; //否则计算实际转速
if(speed1<0) speed1=0;
speep=speek*SPEB;
tsh1=tsh-0x38; //得到计算用的手柄值
speek=tsh1-speed1;
if(tsh1<0) {speuk=0;gcur=0;} //当手柄值低于1.1 V 时,则认为手柄给定为零
else { //否则,计算相应的转速环输出
if(tsh1>=GSPEH) //限制最大转速
tsh1=GSPEH;
speuk=speuk+speek*SPEA-speep; //计算得转速环输出
if(speuk<=0X00) {speuk=0x00;gcur=0x00;}//转速环输出处理
else if(speuk>GCURHILO) { //转速环输出限制,即限制最大电流约12 A
speuk=GCURHILO;gcur=GCURH;}
else { //调速状态时的输出
gcur=(speuk>>4)&0x0ff;
}
}
}
//-----------主程序-------------------------
main()
{
for(;;){
INIT877(); //单片机复位后,先对其进行初始化
off=0; //清复位标志
for(;off==0;) { //复位标志为零,则执行下面程序,否则复位
if(curpid==1) CURPI(); //电流PI 运算
else if(spepid==1) SPEPI(); //转速PI 运算
else if(lowpower==1) POWER();
else if(shutdown==1) BREAKON();
asm("CLRWDT");
}
}
}
//---------中断服务子程序---------------------
#pragma interrupt_level 1
void interrupt INTS(void)
{
if(RBIF==1) {RBIF=0;sample();}
else if(ADIF==1) AD();
else if(INTF==1) {shutdown=1;INTF=0;} //刹车中断来,置刹车标志



http://www.cebike.com/bbs/xiangxi.asp?lbid=47&id=37646&page=1
по схеме очень похож на мой контроллер https://electrotransport.ru/index.php?msg=615350
У самого возникала идея написать свой код, токо под AVR на синусе или векторное управление. Эсть апноуты, там все расписано и примеры есть. Пока катаюсь на купленом :-).

Кулибин

Отличненько, с миру по нитке наберётся что то толковое.. ))
Всякое видео самокатное.
http://www.youtube.com/user/VakuumTonus/videos

Поехали вместе кататься если живешь рядом?

Кулибин

#7
Цитата: tehnik от 20 Июль 2015 в 21:06
Вот еще код под PIC16F877 хотя вначале пишут, что под PIC16F72. Ноя думаю это не важно, главное - правильный алгоритм ;-)
С помощью гугла переводил на английский и читал, т.к. на русский выходит бредятина.
Спойлер
#include
//电动车双闭环程序,采用双闭环方式控制电机,以得到最好的zh 转速性能,并且可以
//限制电机的最大电流。本应用程序用到两个CCP 部件,其中CCP1 用于PWM 输出,以控
//制电机电压;CCP2 用于触发AD,定时器TMR2、TMR1,INT 中断,RB 口电平变化中断,
//看门狗以及6 个通用I/O 口
#define AND 0xe0 //状态采集5,6,7 位
#define CURA 0X0a //电流环比例和积分系数之和
#define CURB 0X09 //电流环比例系数
#define THL 0X6400 //电流环最大输出
#define FULLDUTY 0X0FF //占空比为1 时的高电平时间
#define SPEA 0X1d //转速环比例和积分系数之和
#define SPEB 0X1c //转速环比例系数
#define GCURHILO 0X0330 //转速环最大输出
#define GCURH 0X33 //最大给定电流
#define GSPEH 0X67 //最大转速给定
#define TSON 0X38 //手柄开启电压1.1 V,TSON*2 为刹车后手柄开启电压,即
//2.2 V
#define VOLON 0X4c //低电压保护重开电压3.0 V 即33 V
#define VOLOFF 0X49 //低电压保护关断电压2.86 V 即31.5 V
volatile unsigned char DELAYH,DELAYL,oldstate,speed,
speedcount,tsh,count_ts,count_vol,gcur,currenth,
voltage; //寄存器定义
static bit sp1,spe,ts,volflag,spepid,lowpower,
off,shutdown,curpid; //标志位定义
static volatile unsigned char new[10]={0xaf,0xbe,0xff,0x7e,0xcf,
0xff,0xd7,0x77,0xff,0xff}; //状态寄存器表
//------------PIC16F877 初始化子程序------------
void INIT877()
{
PORTC=0X0FF; //关断所有MOSFET
TRISC=0X02; //设置C 口输出
PIE1=0X00; //中断寄存器初始化,关断所有中断
TRISA=0XCF; //设置RA4,RA5 输出
TRISB=0XEF; //RB 口高三位输入,采集电机三相的霍尔信号
PORTC=new[(PORTB&AND)>>5]; //采集第一次霍尔信号,并输出相应的信号,导通
//两个MOS 管
T2CON=0X01; //TMR2 4 分频
CCPR1L=0X0FF; //初始时PWM 输出全高
CCP1CON=0X0FF; //CCP1 设置为PWM 方式
CCP2CON=0X0B; //CCP2 设置为特殊方式,以触发AD
ADCON0=0X81; //AD 时钟为32 分频,且AD 使能,选择AN0 通道采集手
//柄电压
TMR2=0X00; //TMR2 寄存器初始化
TMR1H=0X00; //TMR1 寄存器初始化
TMR1L=0X00;
T1CON=0X00; //TMR1 为1 分频
CCPR2H=0X08;
CCPR2L=0X00; //电流采样周期设置为TAD=512 μs
PR2=0XC7; //PWM 频率设置为5 kHz
ADCON1=0X02; //AD 结果左移
OPTION=0XFB; //INT 上升沿触发
TMR2ON=1; //PWM 开始工作
INTCON=0XD8; //中断设置GIE=1,PEIE=1,RBIE=1
ADIE=1; //AD中断使能
speedcount=0x00; //转速计数寄存器
speed=0x7f; //转速保持寄存器
spe=1; //低速标志位
sp1=1; //低速标志位
oldstate=0x0ff; //初始状态设置,区别于其他状态
count_ts=0x08; //电流采样8 次,采集1 次手柄
count_vol=0x00; //采样256 次手柄,采集1 次电池电压
ts=1; //可以采集手柄值的标志位
ADGO=1; //AD采样使能
TMR1ON=1; //CCP2 部件开始工作
}
//------------延时子程序---------------
#pragma interrupt_level 1
void DELAY1(x)
char x;
{
DELAYH=x; //延时参数设置
#asm
DELAY2 MOVLW 0X06
MOVWF _DELAYL
DELAY1 DECFSZ _DELAYL
GOTO DELAY1
DECFSZ _DELAYH
GOTO DELAY2
#endasm
}
//-----------状态采集子程序----------------------
void sample()
{
char state1,state2,state3,x;
do {
x=1;
state1=(PORTB&AND); //霍尔信号采集
DELAY1(x);
state2=(PORTB&AND);
}while(state1-state2); //当三次采样结果不相同时继续采集状态
if(state1-oldstate!=0) //看本次采样结果是否与上次相同,不同
//则执行
{oldstate=state1; //将本次状态设置为旧状态
state1=(oldstate>>5);
PORTC=new[state1]; //C 口输出相应的信号触发两个MOS 管
if(sp1==1){spe=1;sp1=0;}
else { //如果转速很低,则spe 置1
spe=0;sp1=0;
speedcount<<=1;
state3=(TMR1H>>2); //否则,spe=0,计转速
speed=speedcount+state3; //speed 寄存器为每256 μs 加1
}
speedcount=0;
}
}
//-----------------AD 采样子程序----------------------
void AD()
{
char x;
ADIF=0; //清AD 中断标志位
if(ts==1){ //如果为手柄采样,则采样手柄值
CHS0=1; //选择电流采样通道
count_vol=count_vol+1; //电池采样计数寄存器
spepid=1; //置转速闭环运算标志
ts=0;tsh=ADRESH; //存手柄值
if(count_vol==0) { //如果电池采样时间到,则选择AN2 通道,采集电池电压
CHS0=0;CHS1=1;volflag=1;x=1;DELAY1(x);ADGO=1;
}
}
else if(volflag==1) { //电池采样完毕,进行相应的处理
CHS1=0;CHS0=1;volflag=0;voltage=ADRESH;lowpower=1;
}
else { //否则,中断为采样电流中断
speedcount=speedcount+1; //speedcount 寄存器加1,作为测量转速用
if(speedcount>0x3d) sp1=1; //如果转速低于1 000 000 μs/(512 μs*3eh*3)
// 则认为为低速状态
currenth=ADRESH;
curpid=1;
count_ts=count_ts-1;
if(count_ts==0) { //如果手柄时间到,则转入手柄采样通道
CHS0=0;count_ts=0x08;ts=1;x=1;DELAY1(x);ADGO=1;
}
}
}
//-------------刹车处理子程序------------------
void BREAKON()
{
char x;
off=0; //off清零,如果是干扰则不复位
shutdown=0;
if(RB0==1) { //如果刹车信号为真,则停止输出电压
ADIE=0; //关AD 中断
INTE=0; //关刹车中断
CCPR1L=FULLDUTY; //输出电压0
TMR1ON=0; //关CCP2,不再触发AD
for(;ADGO==1;) continue;//如正在采样,则等待采样结束
ADIF=0; //ADIF 位清零
CHS0=0; //选择通道0 采样手柄
CHS1=0;
x=1;
DELAY1(x);
do {
ADGO=1;
for(;ADIF==0;)continue;
ADIF=0;
CCPR1L=FULLDUTY;
asm("CLRWDT");
tsh=(ADRESH>>1);
}while(tsh>TSON||RB0==1); //当手柄值大于2.2 V 或刹车仍旧继续时,执行以
//上语句
off=1; //置复位标志
}
}
//---------欠保护子程序-------------------
void POWER()
{
char x;
lowpower=0;
voltage>>=1; //电压值换为7 位,以利于单字节运算
if(voltageADIE=0;
INTE=0;
TMR1ON=0;
CCPR1L=FULLDUTY;
for(;ADGO==1;)continue;
ADIF=0;
CHS0=0;CHS1=1;
x=1;
DELAY1(x);
do{ADGO=1;
for(;ADIF==0;)continue;
ADIF=0;
voltage=(ADRESH>>1);
CCPR1L=FULLDUTY;
asm("CLRWDT");
}while(voltageoff=1; //置复位标志
}
}
//------------电流环运算子程序-----------------
void CURPI()
{ static int curep=0x00,curek=0x00,curuk=0x00;
union data{int pwm;
char a[2];}b; //定义电流环运算寄存器
curpid=0; //清电流运算标志
curep=curek*CURB; //计算上一次偏差与比例系数的积
if(currenth<2)currenth=2; //如果采样电流为零,则认为有一个小电流以利于
//使转速下降
currenth>>=1;
curek=gcur-currenth; //计算本次偏差
curuk=curuk+curek*CURA-curep; //按闭环PI 运算方式得到本次输出结果,下
//面对结果进行处理
if(curuk<0x00) { //如果输出小于零,则认为输出为零
curuk=0;CCPR1L=FULLDUTY;CCP1X=0;CCP1Y=0;
}
else if(curuk-THL>=0) { //如果输出大于限幅值,则输出最大电压
curuk=THL;CCPR1L=0;CCP1X=0;CCP1Y=0;
}
else { //否则,按比例输出相应的高电平时间到CCPR1 寄存器
b.pwm=THL-curuk;
b.pwm<<=1;
CCPR1L=b.a[1]; //CCPR1L=(b.pwm>>8)&0x0ff;将PWM 寄存器的高半字节
if(b.pwm&0x80!=0) CCP1X=1;
else CCP1X=0;
if(b.pwm&0x40!=0) CCP1Y=1;
else CCP1Y=0;
}
}
//---------------转速环运算子程序-----------------------
void SPEPI()
{ static int speep=0x00,speek=0x00,speuk=0x00;
int tsh1,speed1; //转速寄存器定义
spepid=0; //清转速运算标志
if(spe==1) speed1=0x00; //若转速太低,则认为转速为零
else speed1=0x7f-speed; //否则计算实际转速
if(speed1<0) speed1=0;
speep=speek*SPEB;
tsh1=tsh-0x38; //得到计算用的手柄值
speek=tsh1-speed1;
if(tsh1<0) {speuk=0;gcur=0;} //当手柄值低于1.1 V 时,则认为手柄给定为零
else { //否则,计算相应的转速环输出
if(tsh1>=GSPEH) //限制最大转速
tsh1=GSPEH;
speuk=speuk+speek*SPEA-speep; //计算得转速环输出
if(speuk<=0X00) {speuk=0x00;gcur=0x00;}//转速环输出处理
else if(speuk>GCURHILO) { //转速环输出限制,即限制最大电流约12 A
speuk=GCURHILO;gcur=GCURH;}
else { //调速状态时的输出
gcur=(speuk>>4)&0x0ff;
}
}
}
//-----------主程序-------------------------
main()
{
for(;;){
INIT877(); //单片机复位后,先对其进行初始化
off=0; //清复位标志
for(;off==0;) { //复位标志为零,则执行下面程序,否则复位
if(curpid==1) CURPI(); //电流PI 运算
else if(spepid==1) SPEPI(); //转速PI 运算
else if(lowpower==1) POWER();
else if(shutdown==1) BREAKON();
asm("CLRWDT");
}
}
}
//---------中断服务子程序---------------------
#pragma interrupt_level 1
void interrupt INTS(void)
{
if(RBIF==1) {RBIF=0;sample();}
else if(ADIF==1) AD();
else if(INTF==1) {shutdown=1;INTF=0;} //刹车中断来,置刹车标志



http://www.cebike.com/bbs/xiangxi.asp?lbid=47&id=37646&page=1
по схеме очень похож на мой контроллер https://electrotransport.ru/index.php?msg=615350
А ещё есть схема? А можно ссылку? Интересно было бы собрать, залить и попробовать. А уж допилить проще. Даже можно вообще всё постепенно перепилить.
Схему нашел на другой странице. Странно сперва код потом схема. ))
Всякое видео самокатное.
http://www.youtube.com/user/VakuumTonus/videos

Поехали вместе кататься если живешь рядом?

acyd

что-то толковое получится  у программера и инженера схемотехника 80lvl, но обычно такие люди сильно заняты и, если этот контроллер не их работа или хобби, то предпочтут купить готовый.

Хотя для самообразования собрать самопал, для "покрутить движок" может быть полезно, но осетра (100в 5квт) лучше урезать, чревато фейервеками  :kidding:

Кулибин

Ну это не важно на каком напряжении экспериментировать, можно и 20 вольт взять с блока питания.
И сделать можно всё что угодно, дело во времени.
Если к следующему лету будет всё крутится как надо то это и хорошо.
Зимой не особо буду кататься скорее всего. Много планов разных. ))
Главное есть на чём кататься, так что торопиться не куда. Только бы МК найти какое нибудь для экспериментов.
Всякое видео самокатное.
http://www.youtube.com/user/VakuumTonus/videos

Поехали вместе кататься если живешь рядом?

batson

я вот задумался над своим, на stm32, "черные ящики" я уже раскритиковал, ну их в топку, больше не куплю.
вобще главное не настройки блоков контроллера, а алгоритм формирования выходных сигналов, а он же на СИ, так что можно легко портировать на любой контроллер.

сейчас близится к завершению мой велокомп, пока сделаю в том виде в котором запланировал чтоб было на чем ездить, а потом по мере свободного времени думаю начать заниматься контроллером
Самоходный аппарат из нержавейки: нержавеющий чоботар, инфинеон 12, MXUS 1000

batson

я предлангаю сосредоточиться не на конкретном контроллере, а на так скажем "ядре", алгоритме управления, которое каждый портирует под свой микроконтроллер
Самоходный аппарат из нержавейки: нержавеющий чоботар, инфинеон 12, MXUS 1000

Кулибин

Проблема народного контроллера может быть только в том что разные люди захотят разную конфигурацию.
Я хочу сразу встроенный ваттметр с блютузом на телефон. В общем что бы сразу всё.
Один разъём под термометры, можно навешать хоть 200 на одну шину. Адреса только сосканировать.
Акселерометр запхать. Ведь развести дорожки на него ничего не стоит. Закрыть код обработки его тоже ерунда, можно не впаивать.
Но зато можно с помощью его что то мутить в горки.
Датчик давления не помешает, тоже мелкая работа дорожки развести, а вот в лесу или в горах может быть полезен.
Мелочи мелочи а когда всё заложено это приятно. Появилось время побаловаться с акселерометром, сел попрограммил и вот уже что то заработало дополнительное в контроллере.
Я уже привык к ваттметру и не понимаю как без ваттметра ездить.
В принципе можно и просто иметь вольтметр и одометр. Но если делать то сразу всё. Не обязательно всё впаивать.
АЦП точно 12 бит должен быть это я уже понял когда амперметр лепил. ))
Всякое видео самокатное.
http://www.youtube.com/user/VakuumTonus/videos

Поехали вместе кататься если живешь рядом?

batson

нет, ты не понял, наша всеобщая задача - заставить крутиться двигатель наилучшим способом
свистелок-перделок прикрутить не проблема, датчики, ваттметры и прочее...

P.S.
к слову, я планирую на руль только экран, все остальное вычисляется и измеряется в контроллере, в принципе тот же мини-е, или китайские контроллеры с дисплеями
Самоходный аппарат из нержавейки: нержавеющий чоботар, инфинеон 12, MXUS 1000

Кулибин

Аа ну если только создать просто крутилку колеса но отработанную с плавным рекупером то это хорошая идея.
Потом любой может создать своё и долепить чего угодно.
Вот я бы давно уже свой контроллер спаял если бы готовые алгоритмы были.
В программировании не силён особо, только в плане автоматики и некоторых измерений.
Но разобраться с датчиками и доворотить функций это совсем не сложно.
Всякое видео самокатное.
http://www.youtube.com/user/VakuumTonus/videos

Поехали вместе кататься если живешь рядом?

batson

в качестве подопытных уже выбрал двигатели от hdd, заказал у знакомых нахаляву.
покручу их небольшими токами и напряжениями, а потом можно и на двигатели с датчиками переходить.
Самоходный аппарат из нержавейки: нержавеющий чоботар, инфинеон 12, MXUS 1000

batson

Самоходный аппарат из нержавейки: нержавеющий чоботар, инфинеон 12, MXUS 1000

Кулибин

а как дело с нагрузками??
По идее у меня есть токарник, ну фрезерник какой никакой.
Можно попробовать нагрузочный стенд собрать для мелкого движка.
Под нагрузками ведь они может по другому себя вести.
Специально всё лето не занимался электроникой что бы соскучится и что то крупное замутить. )))
Всякое видео самокатное.
http://www.youtube.com/user/VakuumTonus/videos

Поехали вместе кататься если живешь рядом?