二轮平衡机器人控制器代码

发布者:VelvetDreamer最新更新时间:2019-11-09 来源: 51hei关键字:二轮平衡机器人  控制器  Mega16 手机看文章 扫描二维码
随时随地手机看文章

//MCU:Mega16;晶振:8MHz;


//PWM:4KHz;滤波器频率:100Hz;系统频率:100Hz;10ms;


//二轮平衡机器人项目


#include


#include


#include


//#define checkbit(var,bit)     (var&(0x01<<(bit)))     /*定义查询位函数*/


//#define setbit(var,bit)     (var|=(0x01<<(bit)))     /*定义置位函数*/


//#define clrbit(var,bit)     (var&=(~(0x01<<(bit)))) /*定义清零位函数*/


//-------------------------------------------------------


//输出端口初始化


void PORT_initial(void)


{


DDRA=0B00000000;


PINA=0X00;


PORTA=0X00;


DDRB=0B00000000;


PINB=0X00;


PORTB=0X00;


DDRC=0B00010000;


PINC=0X00;


PORTC=0X00;


DDRD=0B11110010;


PIND=0X00;


PORTD=0X00;


}


//-------------------------------------------------------


//定时器1初始化


void T1_initial(void)        


{


TCCR1A|=(1<

TCCR1B|=(1<

}


//-------------------------------------------------------


//定时器2初始化


void T2_initial(void)        //T2:计数至OCR2时产生中断


{


OCR2=0X4E;        //T2:计数20ms(0X9C)10ms(0X4E)时产生中断;


TIMSK|=(1<

TCCR2|=(1<

}


//-------------------------------------------------------


//外部中断初始化


void INT_initial(void)


{


MCUCR|=(1<

GICR|=(1<

}


//-------------------------------------------------------


//串口初始化;


void USART_initial( void )


{        


UBRRH = 0X00;


UBRRL = 51;        //f=8MHz;设置波特率:9600:51;19200:25;


UCSRB = (1<

UCSRC = (1<

UCSRB|=(1<


//-------------------------------------------------------


//串口发送数据;


void USART_Transmit( unsigned char data )


{


while ( !( UCSRA & (1<缓冲器为空;


UDR = data;        //将数据放入缓冲器,发送数据;



//-------------------------------------------------------


//串口接收数据中断,确定数据输出的状态;


#pragma interrupt_handler USART_Receive_Int:12


static char USART_State;


void USART_Receive_Int(void)


{


USART_State=UDR;//USART_Receive();


}


//-------------------------------------------------------


//计算LH侧轮速:INT0中断;


//-------------------------------------------------------


static int speed_real_LH;


//-------------------------------------------------------


#pragma interrupt_handler SPEEDLHINT_fun:2


void SPEEDLHINT_fun(void)


{


if (0==(PINB&BIT(0)))


{


speed_real_LH-=1;


}


else


{


speed_real_LH+=1;



}


//-------------------------------------------------------


//计算RH侧轮速,:INT1中断;


//同时将轮速信号统一成前进方向了;


//-------------------------------------------------------


static int speed_real_RH;


//-------------------------------------------------------


#pragma interrupt_handler SPEEDRHINT_fun:3


void SPEEDRHINT_fun(void)


{


if (0==(PINB&BIT(1)))


{


speed_real_RH+=1;


}


else


{


speed_real_RH-=1;



}


//-------------------------------------------------------


//ADport采样:10位,采样基准电压Aref


//-------------------------------------------------------


static int AD_data;


//-------------------------------------------------------


int ADport(unsigned char port)


{


ADMUX=port;


ADCSRA|=(1<

while(!(ADCSRA&(BIT(ADIF))));


AD_data=ADCL;


AD_data+=ADCH*256;


AD_data-=512;


return (AD_data);


}


//*


//-------------------------------------------------------


//Kalman滤波,8MHz的处理时间约1.8ms;


//-------------------------------------------------------


static float angle, angle_dot; //外部需要引用的变量


//-------------------------------------------------------


static const float Q_angle=0.001, Q_gyro=0.003, R_angle=0.5, dt=0.01;


//注意:dt的取值为kalman滤波器采样时间;


static float P[2][2] = {


{ 1, 0 },


{ 0, 1 }


};


static float Pdot[4] ={0,0,0,0};


static const char C_0 = 1;


static float q_bias, angle_err, PCt_0, PCt_1, E, K_0, K_1, t_0, t_1;


//-------------------------------------------------------


void Kalman_Filter(float angle_m,float gyro_m)        //gyro_m:gyro_measure


{


angle+=(gyro_m-q_bias) * dt;


Pdot[0]=Q_angle - P[0][1] - P[1][0];


Pdot[1]=- P[1][1];


Pdot[2]=- P[1][1];


Pdot[3]=Q_gyro;


P[0][0] += Pdot[0] * dt;


P[0][1] += Pdot[1] * dt;


P[1][0] += Pdot[2] * dt;


P[1][1] += Pdot[3] * dt;


angle_err = angle_m - angle;


PCt_0 = C_0 * P[0][0];


PCt_1 = C_0 * P[1][0];


E = R_angle + C_0 * PCt_0;


K_0 = PCt_0 / E;


K_1 = PCt_1 / E;


t_0 = PCt_0;


t_1 = C_0 * P[0][1];


P[0][0] -= K_0 * t_0;


P[0][1] -= K_0 * t_1;


P[1][0] -= K_1 * t_0;


P[1][1] -= K_1 * t_1;


angle        += K_0 * angle_err;


q_bias        += K_1 * angle_err;


angle_dot = gyro_m-q_bias;


}


//*/


/*


//-------------------------------------------------------


//互补滤波


//-------------------------------------------------------


static float angle,angle_dot; //外部需要引用的变量


//-------------------------------------------------------        


static float bias_cf;


static const float dt=0.01;


//-------------------------------------------------------


void complement_filter(float angle_m_cf,float gyro_m_cf)


{


bias_cf*=0.998;        //陀螺仪零飘低通滤波;500次均值;


bias_cf+=gyro_m_cf*0.002;


angle_dot=gyro_m_cf-bias_cf;


angle=(angle+angle_dot*dt)*0.90+angle_m_cf*0.05;        


//加速度低通滤波;20次均值;按100次每秒计算,低通5Hz;


}


*/        


//-------------------------------------------------------


//AD采样;


//以角度表示;


//加速度计:1.2V=1g=90°;满量程:1.3V~3.7V;


//陀螺仪:0.5V~4.5V=-80°~+80°;满量程5V=200°=256=200°;


//-------------------------------------------------------


static float gyro,acceler;


//-------------------------------------------------------


void AD_calculate(void)


{


acceler=ADport(2)+28;        //角度校正


gyro=ADport(3);        


acceler*=0.004069;        //系数换算:2.5/(1.2*512); // 5/(1.2*1024);5为参考电压5V;1.2V灵敏度对应加速度1g;1024为AD精度


acceler=asin(acceler);        //反正弦求角度


gyro*=0.00341;        //角速度系数:(3.14/180)* 100/512=0.01364;//(3.14/180)*    (200*0.025)/1024*0.025既5/1024*0.025        


//求得角速度 单位 角度/秒


Kalman_Filter(acceler,gyro);        //卡尔曼滤波 带入角度。角速度


//complement_filter(acceler,gyro);


}


//-------------------------------------------------------


//PWM输出


//-------------------------------------------------------


void PWM_output (int PWM_LH,int PWM_RH)


{


if (PWM_LH<0)


{


PORTD|=BIT(6);


PWM_LH*=-1;


}


else


{


PORTD&=~BIT(6);


}


if (PWM_LH>252)


{


PWM_LH=252;


}


if (PWM_RH<0)


{


PORTD|=BIT(7);


PWM_RH*=-1;


}


else


{


PORTD&=~BIT(7);


}


if (PWM_RH>252)


{


PWM_RH=252;


}


OCR1AH=0;


OCR1AL=PWM_LH;        //OC1A输出;


OCR1BH=0;


OCR1BL=PWM_RH;        //OC1B输出;


}


//-------------------------------------------------------


//计算PWM输出值


//车辆直径:76mm; 12*64pulse/rev; 1m=3216pulses;


//-------------------------------------------------------        


//static int speed_diff,speed_diff_all,speed_diff_adjust;


//static float K_speed_P,K_speed_I;


static float K_voltage,K_angle,K_angle_dot,K_position,K_position_dot;


static float K_angle_AD,K_angle_dot_AD,K_position_AD,K_position_dot_AD;


static float position,position_dot;


static float position_dot_filter;


static float PWM;


static int speed_output_LH,speed_output_RH;


static int Turn_Need,Speed_Need;


//-------------------------------------------------------        


void PWM_calculate(void)        


{


if ( 0==(~PINA&BIT(1)) )        //左转


{


Turn_Need=-40;


}


else if ( 0==(~PINB&BIT(2)) ) //右转


{


Turn_Need=40;


}


else        //不转


{


Turn_Need=0;


}


if ( 0==(~PINC&BIT(0)) )        //前进


{


Speed_Need=-2;


}


else if ( 0==(~PINC&BIT(1)) )        //后退 


{


Speed_Need=2;


}


else        //不动


{


Speed_Need=0;


}


K_angle_AD=ADport(4)*0.007;


K_angle_dot_AD=ADport(5)*0.007;


K_position_AD=ADport(6)*0.007;


K_position_dot_AD=ADport(7)*0.007;


position_dot=PWM*0.04;


position_dot_filter*=0.9;        //车轮速度滤波


position_dot_filter+=position_dot*0.1;        


position+=position_dot_filter;


//position+=position_dot;        


position+=Speed_Need;


if (position<-768)        //防止位置误差过大导致的不稳定


{


position=-768;


}


else if  (position>768)


{


position=768;


}


PWM = K_angle*angle *K_angle_AD + K_angle_dot*angle_dot *K_angle_dot_AD + 


K_position*position *K_position_AD + K_position_dot*position_dot_filter *K_position_dot_AD;


speed_output_RH = PWM;// - Turn_Need;


speed_output_LH = - PWM;// - Turn_Need ;


/*


speed_diff=speed_real_RH-speed_real_LH;        //左右轮速差PI控制;


speed_diff_all+=speed_diff;


speed_diff_adjust=(K_speed_P*speed_diff+K_speed_I*speed_diff_all)/2;


*/


PWM_output (speed_output_LH,speed_output_RH);        


}


//-------------------------------------------------------


//定时器2中断处理


//-------------------------------------------------------


static unsigned char temp;


//-------------------------------------------------------


#pragma interrupt_handler T2INT_fun:4


void T2INT_fun(void)        


{


AD_calculate();


PWM_calculate();


if(temp>=4)        //10ms即中断;每秒计算:100/4=25次;


{        


if (USART_State==0X30)        //ASCII码:0X30代表字符'0'


{


USART_Transmit(angle*57.3+128);


USART_Transmit(angle_dot*57.3+128);


USART_Transmit(128);        


}


else if(USART_State==0X31)        //ASCII码:0X30代表字符'1'


{


USART_Transmit(speed_output_LH+128);


USART_Transmit(speed_output_RH+128);        


USART_Transmit(128);


}


else if(USART_State==0X32)        //ASCII码:0X30代表字符'2'

[1] [2]
关键字:二轮平衡机器人  控制器  Mega16 引用地址:二轮平衡机器人控制器代码

上一篇:AVR单片机经典使用经验
下一篇:ATMEGA16L实现时间和温度的循环显示程序分享

推荐阅读最新更新时间:2024-11-01 15:39

瑞萨电子RL78/G1F微控制器简化无传感器无刷直流电机控制
RL78/G1F微控制器集成高速定时器、比较器和增强的外围设备,实现高转速电机控制和更低的系统成本 全球领先的半导体及解决方案供应商瑞萨电子株式会社(TSE:6723)发布了RL78/G1F系列多功能微控制器,为RL78族的低功耗微控制器系列增添20个新成员。增强了外围设备的功能并且兼容所有RL78/G1x系列微控制器,新产品进一步简化了无传感器无刷直流电机(BLDC电机)控制,为注重能效的家用电器和电动工具应用提供高速和高精度的精确电机控制。 随着真空吸尘器、洗碗机和冰箱等电机驱动设备和电动工具对节能和系统成本的要求日益提高,传统内置位置传感器电机正逐渐被无位置传感器无刷直流电机所取代。新发布的RL78/G1F微控制器
[家用电子]
Intersil推出高效灵活的单相异步降压控制器
Intersil推出单相异步降压控制器ISL8107,可为通讯和工业设计提供高效率和灵活性。该组件具有超宽的输入电压范围9V~75V,内部的1.192V参考电压在整个产业温度范围内的精密度为±1%。 ISL8107整合了一个上位N信道MOSFET驱动器,可用来驱动连接正电源且没有参考地的MOSFET。透过使用电压模式控制和前馈补偿,ISL8107实现了最佳的瞬态响应,在整个输入电压范围内都可保持恒定的回路增益。该IC可使用外置电阻器和电容器,将开关频率编程设定为100kHz~600kHz。开关频率可透过SYNC接脚与外部频率讯号同步。 ISL8107还提供了可程序的软启动、打嗝模式,用于短路保护和过温保护
[电源管理]
Exar大功率COT交换控制器提供1%输出准确率
XRP6141简化系统设计,增加设计空间 高性能模拟混合信号部件与数据管理解决方案的领先供应商公司(纽交所:EXAR)近日推出新型大功率交换控制器,该产品隶属于DC-DC电源转换产品家族。XRP6141同步降压控制器支持高达35A的分布式供电(POL),并采用Exar的专有仿电流模式恒定导通时间(COT)控制环路,实现出色的瞬态响应与输出准确性。该设备为通信、网络与工业市场上的ASIC(专用集成电路)、FPGA(现场可编程门阵列)、DSP(数字信号处理器)和网络处理器提供核心电压轨(voltage rails)。 XRP6141拥有4.5伏至22伏的宽输入电压范围,提供0.6伏至18伏可调节输出电压。XRP6141在整个输入电
[电源管理]
32针STM32微控制器系列产品中增加Nucleo开发板
意法半导体(STMicroelectronics,简称ST;纽约证券交易所代码:STM)持续扩大其STM32 Nucleo开发板组合,新增三款可扩展、可支持32针的小型STM32微控制器开发板。新款STM32 Nucleo-32开发板拥有各种集成开发环境(IDE)的直接支持,允许开发人员直接使用mbed在线资源。搭载STM32微控制器,通过Arduino Nano接口插入各种可用硬件,STM32 Nucleo开放平台有助于简化原型开发过程,从而降低开发成本。 开发人员还可充分利用STM32软件库及STM32Cube开发工具,不仅简化了应用软件的开发过程,更可在不同型号的STM32微控制器之间移植应用设计。STM32
[单片机]
家用智能控制器的设计
自从1876年贝尔发明电话以后,电话通信变成我们日常生活中最常见、最广泛的通信方式。目前电话网的地理范围覆盖率在我国已经达到了90%以上,并且大多数人现在都有手机或固定电话,如此可以利用现有的电话网传输控制信号,实现家用电器的控制。现有的可利用的数据传输方式有调制解调器(MODEM)传输和简单的双音多频(DTMF)传输。 本设计就采用后者作为控制信号的通信方式。本文主要介绍一种可以远程控制传统家电的电话控制系统的设计方案。 1 智能控制器的工作状况 智能控制器的工作过程描述如下: 1)当用户拨通家庭电话后,智能控制器要求用户输入管理密码。 2)用户输入密码正确,则允许进行设置各种控制功能;如果用户密码错误,则提示
[单片机]
家用智能<font color='red'>控制器</font>的设计
NEC电子推出78款超低功耗32位微控制器
    NEC电子推出78款超低功耗内置闪存32位微控制器。产品中优化配置的外部引脚数量及内置闪存容量,以满足高性能、小型设备的需求。     新产品的样品价格根据存储容量、封装种类及引脚数的差别而不同,以16KB闪存、8KBRAM、40pin、QFN封装的“V850ES/JC3-L”为例。     近年来,从电脑周边设备扩展到保健设备等通过电池及USB供电驱动的电子产品,皆因供电条件的限制,对低功耗及小型化提出较高要求。此外,在工业仪器中,以太网、USB等通信功能也使低功耗及小型化面临更多挑战。     另一方面,整机厂商提出希望能够统一上位机和下位机的开发平台,更有软件资源通用、缩短产品开发周期、降低开发成本
[单片机]
   恩智浦半导体NXP Semiconductors N.V.近日发布了LPC1788微控制器,这是业界首款采用ARM® Cortex™-
   QNX软件系统有限公司今日宣布QNX® Neutrino® RTOS Secure Kernel™6.5.0版本正式商用,该产品是该公司共通准则认证实时操作系统的增强版。QNX® Neutrino® RTOS Secure Kernel™6.5.0版本主要针对发电厂、防御系统,地铁控制中心、政府网络及其它关键性任务应用所设计,使开发人员在基于ARM、Power和x86架构的单核或多核处理器方面有更多的选择,并充分利用QNX操作系统技术的最新功能和增强性能。    QNX Neutrino RTOS Secure Kernel是唯一由共通准则ISO/IEC 15408评估保证级别(EAL)4+授权并能够支持自适应分区的实时操作系
[工业控制]
基于ARM和DSP的竹节纱控制系统伺服控制器
   引 言   ARM微处理器具有体积小、低功耗、低成本、高性能的特点,基于ARM核的微控制器芯片不但占据了高端微控制器市场的大部分市场份额,同时也逐渐向低端微控制器应用领域扩展,ARM微控制器的低功耗、高性价比,向传统的8位/16位微控制器基。提出了挑战。ARM微处理器及技术应用到了许多不同的领域,如工业控制领域、无线电通讯领域、网譬络应用、消费类电子产品以及数字成象与安全产品当中,凭借其优点将来还会得到更加广泛的应用。本文通过分析竹节纱装置的工艺要求,设计了具有竹独立控制结构的永磁同步电机伺服控制系统,由ARM和触摸屏构成控制器,并在ARM核中移植嵌入式操作系统Windows CE,使其具有图形化的人机丕界面操作功能
[嵌入式]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved