电动车控制器C语言源代码
mpc控制c代码源码csdn

多变量预测控制(MPC)是一种用于控制多变量系统的算法,它可以根据系统的当前状态和未来的预测来优化系统的性能。
下面是一个简单的MPC控制器的C代码源码示例,用于控制一个简单的多变量系统。
```c#include <stdio.h>#include <stdlib.h>// 系统模型参数double A[3][3] = { {1, 1, 0}, {0, 1, 1}, {0, 0, 1} };double B[3][1] = { {0}, {0}, {0} };double C[1][1] = { {1} };double D[1][1] = { {0} };// MPC控制器参数double K[3] = {0}; // 控制增益double q_min = -1; // 参考输入下限double q_max = 1; // 参考输入上限double q_ref = 0; // 参考输入double q_next_ref = 0; // 下一步参考输入double dt = 0.02; // 时间步长double control_timeout = 5; // 控制周期// MPC控制器状态变量double state[3] = {0};// MPC控制器算法函数void mpc_control(double q) {// MPC算法实现过程...// 这里省略具体算法实现过程...}int main() {// 设置系统模型参数// 设置MPC控制器参数和状态变量...for (int i = 0; i < control_timeout; i++) {// 系统当前状态double x[3] = {state[0], state[1], state[2]};// 系统参考输入double u = q_ref;// 系统当前输出double y[1] = {0};y[0] = C[0][0]*x[0] + C[0][1]*x[1] + C[0][2]*x[2];// 根据当前状态和参考输入计算MPC控制器的下一步参考输入和目标值...q_next_ref = mpc_control(q); // 控制器的输出是一个新的参考输入q_next_ref和目标值T(x, u)(通过系统模型转换为输入和状态约束的等式)// 根据目标值和约束条件更新参考输入和状态变量...q_ref = q_next_ref; // 更新当前参考输入为下一步参考输入q_next_refstate[0] += A[0][0]*dt + K[0]; // 根据状态方程更新状态变量x[0]state[1] += A[1][1]*dt + K[1]; // 根据状态方程更新状态变量x[1]state[2] += A[2][2]*dt + K[2]; // 根据状态方程更新状态变量x[2]}return 0;}```以上代码是一个简单的MPC控制器的C代码源码示例,它可以根据系统的当前状态和未来的预测来优化系统的性能。
电动车控制器C语言源代码讲解

******************************************************************************/
void main(void)
{
Init(); //初始化
Init_IO(); //初始化端口
H_Sample(); //霍尔信号采样
{
Speed_Buffer[i]=0;
}
for (i=0;i<16;i++)
{
Voltage_Buffer[i]=0;
}
Current_P=0;
Speed_P=0;
Voltage_P=0;;
Speed_SUM=0;
// PWM_MAX=0;
Current_SUM=0;
Voltage_SUM=0;
H_State=0;
KS_Finish();
}
}
//***Function Set***//
if(AH_Count >= 100)
{
AutoHelp(); //自助力
AH_Count = 0;
}
if(KS_CNT >= 3000)
{
KS_CNT = 0;
Keep_Speed(); //巡航定速
}
Volt_Low(); //欠压保护
*/
while(1)
{
_nop_();
//AutoHelpEN(0,0x1AA,100);
//Keep_SpeedEN(1,0x20,6);
//Current_Lim(0xB50);
//LowVoltage_Lim(0x9B0);
//EABS_Set(0,0);
C8051F02X系列例程源代码

AN022
相关器件
此应用笔记适用于下列器件 C8051F020 C8051F021 C8051F022 C8051F023
C8051F02X系列带注释
C
例程
引言
本应用笔记包含用C语言编写的例程代码是使用C8051F02X系列器件应用软件开发的起点
按外设划分的程序索引
下面的简要描述提供了附件程序的索引 按外设划分
DAC0_DTMF1.c
次例程源代码在ADC0输出双音多频音调 用定时器4管理和定时 根据常数<SAMPLERATED>确定的速率定时更新DAC0的输出 并使
振荡_Cry1.c
此例程说明如何配置外部振荡器驱动22.1184Mhz晶体 及如何选择此外部振荡器作为系统时钟 同时使能 丢失时钟检测器复位功能 假定22.1184Mhz晶体连接在XTAL1和XTAL2之间
C
例程
ADC0转换的结果经计算得温度值从UART0传输
ADC0_Poll1.c
此例程说明了ADC0在查询模式的操作 ADC0设置为写AD0BUSY作为其转换开始信号 器的输出 温度传感器的输出转换成摄氏度并从UART0传输 并测量片内温度传感
DAC0举例
下面是DAC0的使用例程 如果有必要很容易将其变成DAC1的例程
ADC0_Int1.c
此程序为使用ADC0的例程 在中断模式使用定时器3溢出作为开始启动信号测量片内温度传感器的输出 ADC0的转化结果经计算的温度从UART0传输
ADC0_Int2m.c
此程序为使用ADC0的例程 在中断模式使用定时器3溢出作为开始启动信号测量从AIN0到AIN7的电压和温 度传感器 ADC0转换结果经计算从UART0传输
ADC0_OSA1.c
c语言实现单片机控制步进电机加减速源程序

C 语言实现单片机控制步进电机加减速源程序1. 引言在现代工业控制系统中,步进电机作为一种常见的执行元件,广泛应用于各种自动化设备中。
而作为一种常见的嵌入式软件开发语言,C 语言在单片机控制步进电机的加减速过程中具有重要的作用。
本文将从单片机控制步进电机的加减速原理入手,结合 C 语言的编程技巧,介绍如何实现单片机控制步进电机的加减速源程序。
2. 单片机控制步进电机的加减速原理步进电机是一种能够精确控制角度的电机,它通过控制每个步骤的脉冲数来实现旋转。
在单片机控制步进电机的加减速过程中,需要考虑步进电机的加速阶段、匀速阶段和减速阶段。
在加速阶段,需要逐渐增加脉冲的频率,使步进电机的转速逐渐增加;在匀速阶段,需要保持恒定的脉冲频率,使步进电机以匀速旋转;在减速阶段,需要逐渐减小脉冲的频率,使步进电机的转速逐渐减小。
这一过程需要通过单片机的定时器和输出控制来实现。
3. C 语言实现步进电机加减速的源程序在 C 语言中,可以通过操作单片机的 GPIO 来控制步进电机的旋转。
在编写源程序时,需要使用单片机的定时器模块来生成脉冲信号,以控制步进电机的旋转角度和速度。
以下是一个简单的 C 语言源程序,用于实现步进电机的加减速控制:```c#include <reg52.h>void main() {// 初始化定时器// 设置脉冲频率,控制步进电机的加减速过程// 控制步进电机的方向// 控制步进电机的启停}```4. 总结与回顾通过本文的介绍,我们了解了单片机控制步进电机的加减速原理和 C 语言实现步进电机加减速源程序的基本思路。
掌握这些知识之后,我们可以更灵活地应用在实际的嵌入式系统开发中。
在实际项目中,我们还可以根据具体的步进电机型号和控制要求,进一步优化 C 语言源程序,实现更加精准和稳定的步进电机控制。
希望本文能为读者在单片机控制步进电机方面的学习和应用提供一定的帮助。
5. 个人观点与理解在我看来,掌握 C 语言实现单片机控制步进电机加减速源程序的技术是非常重要的。
无刷直流电机调速--C语言源程序

无刷直流电机调速--C语言源程序附录1. C语言源程序:#include"stdio.h"#include"myapp.h"#include"ICETEK-VC5502-EDU.h"#include"scancode.h"#include"lcd.h"#define CTRSTATUS (*(unsigned int * )0x608000) //port8000 #define CTRLED (*(unsigned int * )0x608004) //port8004#define MCTRKEY (*(unsigned int * )0x608005) //port8005 #define CTRCLKEY (*(unsigned int * )0x608006) //port8006 #define CTRMOTORBSPEED (*(unsigned int * )0x608003)void InitMcBSP();void INTR_init( void );void InitForMotorB( void );void showparameters();void LCDPutString(unsigned int * pData,int x,int y,unsigned int nCharNumber,unsigned color);void PIDControl(int rk,int yk);void PrintParameters();//定时器分频参数#define T100 99 // 100个时钟周期中断一次#define T2Hz 20000 // 20000个时钟周期读取速度一次//工作变量usigned int uWork,uN,nCount,nCount1,nCount2,nCount3,nCount4;int nSSS,nJSSpeed,pwm1;int md,wc;unsigned int nScreenBuffer[30*128];float a=0.6f,b=0.2f,c=0.1f,duk;int ek,ek1,ek2,tz;int nInput;unsigned int *www=(unsigned int *)0x608003;Int m_nSpeed,m_bPCSet;// 主函数main(){unsigned char ccc;int speed[100],sp,lj;float ljh;int i,w1,w2,w3;unsigned int uWork1;unsigned int bWork1,*pWork;int breakflage;// 初始化工作变量for ( sp=0;sp<100;sp++ )speed[sp]=0;for ( sp=0;sp<1024;sp++ ) nScreenBuffer[sp]=0;sp=nSSS=nCount=nCount1=nCount2=nCount3=nCount4= nJSSpeed=0;nInput=tz=wc =0;ek=ek1=ek2=0;uN=40;md=70;pwm1=60;m_nSpeed=70;m_bPCSet=0;inputspeed=0;uWork1=0;breakflage=0;initemif();CLK_init();*(int*)0x400001=1;CREG=1; //使能外部总线接口InitCTR();CTRGR=0x80;CTRGR=0;CTRGR=0x80;LCDTurnoff();// 设置显示参数和内容LCDSetDelay(1); //设置延时等待参数LCDSetScreenBuffer(nScreenBuffer); // 显示缓冲区for (bWork=0,pWork=nScreenBuffer;bWork<30*128;bWork++,pWork++) (*pWork=0)LCDTurnOn();//打开显示LCDCLS();//清除显示内存LCDPutCString(str1,0,127,8,0);LCDPutCString(str2,0,111,2,1);LCDPutCString(str3,68,111,2,1);LCDPutCString(str4,68,79,2,1);LCDPutCString(str5,68,95,2,1);LCDPutCString(str6,0,95,2,1);LCDPutCString(str7,0,79,3,1);ShowParamctors();//参数显示InitMcBSP();INTR-init();InitForMotorB();While(!breakflage){if(nCount==0) //读取键盘标志{uWork=MCTRKEY;CTRCLKEY=0;Switch(uWork1){Casc 128;if(inputspecd!=0){Md=inputspecd;Inputspecd=0;LCDPutCString(numbers+104,104,79,1,1); LCDPutCString(numbers+104,112,79,1,1); LCDPutCString(numbers+104,120,79,1,1); LCDRefreshScreen();}break;case 64;breakflage=1;case 1;inputspeed=inputspeed+1break;case 2;inputspeed=inputspeed-1;break;case 4;inputspeed=inputspeed+10;break;case 8;inputspeed=inputspeed-10;break;}if(inputspeed>90){inputspeed=90;}if(inputspeed<0){inputspeed=0;}w1=inputspeed%1000/100;w2=inputspeed%100/10;w3=in putspeed%10; LCDPutString(numbers+w1*8,104,79,1,1);LCDPutString(numbers+w2*8,112,79,1,1);LCDPutString(numbers+w3*8,120,79,1,1);LCDRefreshScreen();}if(m-bPCSet){m-bPCSst=0;if (m-nSpeed>=0&&m-nSpeed<256){md=m-nSpeed;LCDPutCString(numbers+104,104,79,1,1); LCDPutCString(numbers+104,112,79,1,1);LCDPutCString(numbers+104,120,79,1,1); LCDRefreshScreen();printparameters();}}if(nJSSpeed==0) //读取速度标志{LED=1;nJSSpeed=0;ccc=CTRMOTORBSPEED; //读取端口速度计数ccc=ccc&0xff;nSSS=ccc;if(nSSS>=0 && nSSS<400) //合法性检测{speed(sp)=Nssssp++;sp%=33;}if(sp==0) //读取实际速度{lj=0;ljh=0;for(i=0;i<33;i++){if(speed(i)>=0&&speed(i)<400){ljh+=speed(i);lj++;}}nCount3++;nCount3%=3;if(nCount3==2){PIDControl(md,wc); //调用PID算法控制程序uN=100-pwml; //利用占空比调整控制Showparameters(); //显示各参数到LCD }CloseCTR();exit(0);}//PID算法控制子程序void PIDControl(int rk,int yk){ek=rk-yk;duk=a*ek+b*ek1+c*ek2; //计算控制输出ek2=ek1; ek1=ek;tz=(int)duk;pwm1+=tz; //计算当前占空比if(pwml<0) pwml=0;else if(pwml>99) pwml=99;}void interrupt Timer(){uWork=PCR1; //pwml输出if(nCont1>u N){uWork=4; //根据占空比设置FSR状态}else{uWork&=0x0fffb;}PCR1=uWork;//设置中断控制寄存器void INTR-init(void){asm(“BSET INTM”);IVPD=0x01;IVPH=0x01;IERO=0x10;DBIERO=0x10;IFRO=0xffff;asm(“BCLR INTM”);}void InitForMotorB(void)ioport unsigned int *GPTCTL1-0;ioport unsigned int *GPTPRD1-0;ioport unsigned int *GPTGCTL1-0;*GPTCTL1-0=0;*GPTPRD1-0=0x1d8;*GPTGCTL1-0=0x3;}//显示参数到LCDvoid ShowParameters(){int w1,w2,w3;w1=md%1000/100;w2=md%100/10,w3=md%10; LCDPutString(numbers+w1*8,36,111,1,1); LCDPutString(numbers+w2*8,44,111,1,1); LCDPutString(numbers+w3*8,52,111,1,1);if (ek>=0){LCDPutString(numbers+88,36,95,1,1);w3=((int)ek)%100;}else{LCDPutString(numbers+96,36,95,1,1);w3=((int)(-ek))%100;}for (j=0;j<16;j++,k<<=1){if (color==2) mcolor=2;elsemcolor=(pData(1*8+i)&k)(1):(0);if(color==0) mcolor=1-mcolor;}LCDPutPixel(x+1*8+I,y-j,mcolor);}int wwss;void PrintParameters(){wwcc=wc-md;printf(“测速(%3d) 设置(%3d) 误差(%+4d) PID调整量(%+3d) 占空比(%3d%%)\n”,wc,md,wwcc,tz,pwm1);}。
C语言实现控制电机加减速正反转(飞思卡尔C代码)

用单片机控制直流电动机的正反转、加减速的程序如何用C语言写参考一下这个例子吧。
#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit PW1=P2^0 ;sbit PW2=P2^1 ; //控制电机的两个输入sbit accelerate=P2^2 ; //调速按键sbit stop=P2^3 ; //停止按键sbit left=P2^4 ; //左转按键sbit right=P2^5 ; //右转按键#define right_turn PW1=0;PW2=1 //顺时针转动#define left_turn PW1=1;PW2=0 //逆向转动#define end_turn PW1=1;PW2=1 //停转uint t0=25000,t1=25000; //初始时占空比为50%uint a=25000; // 设置定时器装载初值 25ms 设定频率为20Hz uchar flag=1; //此标志用于选择不同的装载初值uchar dflag; //左右转标志uchar count; //用来标志速度档位void keyscan(); //键盘扫描void delay(uchar z);void time_init(); //定时器的初始化void adjust_speed(); //通过调整占空比来调整速度//**********************************//void main(){time_init(); //定时器的初始化while(1){keyscan(); //不断扫描键盘程序,以便及时作出相应的响应}}//*************************************//void timer0() interrupt 1 using 0{if(flag){flag=0;end_turn;a=t0; //t0的大小决定着低电平延续时间TH0=(65536-a)/256;TL0=(65536-a)%256; //重装载初值}else{flag=1; //这个标志起到交替输出高低电平的作用if(dflag==0){right_turn; //右转}else{left_turn; //左转}a=t1; //t1的大小决定着高电平延续时间TH0=(65536-a)/256;TL0=(65536-a)%256; //重装载初值}}void time_init(){TMOD=0x01; //工作方式寄存器软件起动定时器定时器功能方式1 定时器0TH0=(65536-a)/256;TL0=(65536-a)%256; //装载初值ET0=1; //开启定时器中断使能EA=1; // 开启总中断TR0=0;}//****************************************//void delay(uchar z) //在12M下延时z毫秒{uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}//******************************//void keyscan(){if(stop==0){TR0=0; //关闭定时器0 即可停止转动 end_turn;}if(left==0){TR0=1;dflag=1; //转向标志置位则左转}if(right==0){TR0=1;dflag=0; //转向标志复位则右转}if(accelerate==0){delay(5) ; //延时消抖if(accelerate==0){while(accelerate==0) ; //等待松手count++;if(count==1){t0=20000;t1=30000; //占空比为百分之60}if(count==2){t0=15000;t1=35000; //占空比为百分之70}if(count==3){t0=10000;t1=40000; //占空比为百分之80}if(count==4){t0=5000;t1=45000; //占空比为百分之90}if(count==5){count=0;}}}}功能特点:1)总线速度高达40 M Hz,CAN总线:3个1Mbps的CAN总线,兼容CAN2.0 A/B;2)128 KB程序Flash和8 KB DataFlash,用于实现程序和数据存储,均带有错误校正码(E CC);3)可配置A/D:16通道模数转换器;可选8位10位和12位精度,3μs的转换时间4)内嵌MS CAN模块用于CAN节点应用,内嵌支持LIN协议的增强型SIC模块和SPI模块;5)4通道16位计数器,CRG时钟和复位发生器:锁相环、看门狗、实时中断;增强型捕捉定时器;6)出色的低功耗特性,带有中断唤醒功能的10,实现唤醒休眠系统的功能;7)通道PWM:8位8通道或16位4通道PWM,易于实现电机控制。
c8051无刷直流电动机基本驱动代码

附录D -无刷直流电动机代码//------------------------------------------------------------------- //例子4//无刷直流电机控制//------------------------------------------------------------------- //版权所有2004 Silicon Laboratories公司////认证:KAB//日期:2004.05.24////这一程序规定,无刷直流电动机控制使用PCA为8位PWM模式。
一个单一的PCA模块生成//一个8位PWM 。
引脚跳过xbr0使PWM之间的三个输出p1.0,p1.1&p1.2多元化。
这三//个输出用于驱动下晶体管3相桥的配置。
p0.4p0.5&p0.6用来驱动上晶体管。
////ADC用来读取电位器p0.6上的电压。
ADC使用查询模式和64样品平均。
////p0.0,p0.1,p0.2用于霍尔效应传感器输入。
这个引脚用于确定转子位置。
The//readHalls() function需要三个相同的样本,并返回the hall code。
从//hallpattern发现电机的通讯状况,这种状况然后用于使电机方向转换。
////单步和使用断点只与电机电线断开是安全的。
不要通过代码单步与电机电线连接。
PWM输出//当CPU停止工作时仍然存在。
尤其不要单步越过那些产生PWM的电线。
这些电线应该在所//有盒式磁带程序设计系统中用注释标记好////目标: c8051f33x////工具链:KEIL Eval ‘c’//-----------------------------------------------------------------------------// Includes//-----------------------------------------------------------------------------#include <c8051f330.h> // SFR声明//-----------------------------------------------------------------------------// MACROS//-----------------------------------------------------------------------------#define GSAMP 3//-----------------------------------------------------------------------------// Hall-effect and commutation patterns霍尔效应和整流模式//-----------------------------------------------------------------------------const unsigned char code hallPattern[7]={ 0x00, 0x01, 0x03, 0x02, 0x06, 0x04, 0x05};const unsigned char code skipPattern[7]={~0x01,~0x01,~0x01,~0x02,~0x02,~0x04,~0x04};const unsigned char code P1Pattern[7]={~0x00,~0x20,~0x40,~0x40,~0x10,~0x10,~0x20};//-----------------------------------------------------------------------------// Function PROTOTYPES函数原型//-----------------------------------------------------------------------------void SYSCLK_Init (void);void PORT_Init (void);void PCA0_Init (void);void PCA0_ISR (void);void ADC_Init (void);unsigned char readVin(void);unsigned char avgVin(void);unsigned char readHalls(void);unsigned char hallPosition(void);void commutate(unsigned char);void coast(void);//-----------------------------------------------------------------------------// MAIN Routine主要例行//-----------------------------------------------------------------------------void main (void) {unsigned char h,p;bit start;PCA0MD &= ~0x40; // Disable Watchdog Timer禁用看门狗定时器SYSCLK_Init (); // initialize system clock初始化系统时钟PORT_Init (); // initialize i/o初始化输入/输出PCA0_Init (); // configure PCA0 to 8-bit PWM配置pca0至8位PWMADC_Init(); // initialize i/o初始化输入/输出EA = 1; // enable global interrupts使全球中断p = 0; // clear p清晰pstart = 1; // set start bit设定起始位while (1){h = hallPosition(); // h=霍尔位置if(h) //如果好的位置{if ((h != p)||(start)) //如果新的位置或启动{p = h; //更新p// DO NOT SINGLE-STEP PAST THE NEXT 不要单步过去THE NEXT// LINE WITH MOTOR WIRES CONNECTED 线路与电机电线连接commutate(p); // commutate motor, enables PWM commutate电机,使脉宽调制start = 0;}PCA0CPH0 = avgVin(); // get avg reading and output to PWM获得平均阅读和输出的PWM }else{ coast(); // coast until good reading coast直至良好的阅读start = 1; // set start bit to restart motor设定起始位,以重新启动马达}}}//-----------------------------------------------------------------------------// SYSCLK_Init//-----------------------------------------------------------------------------void SYSCLK_Init (void){OSCICN = 0x83; // configure for 24.5 MHz配置为24.5兆赫}//-----------------------------------------------------------------------------// PORT_Init//-----------------------------------------------------------------------------//// Configure the Crossbar and GPIO ports.配置了横梁和GPIO端口// P0.0 - HA// P0.1 - HB// P0.2 - HC// P0.3 -// P0.4 -// P0.5 -// P0.6 -// P0.7 - Vin - analog input//// P1.0 - Abottom - push-pull output// P1.1 - Bbot - push-pull output// P1.2 - Cbot - push-pull output// P1.3 -// P1.4 - Atop - push-pull output// P1.5 - Btop - push-pull output// P1.6 - Ctop - push-pull output// P1.7 -//void PORT_Init (void){XBR0 = 0x00; // enable nothing on XBR0 使XBR0=0XBR1 = 0x01; // enable PCA CEX0P0SKIP = 0xFF; // skip all pins on P0跳过P0所有管脚P0MDIN =~0x80; // P0.7 analog input p0.7模拟输入P1SKIP =~0x01; // skip all except P1.0除p1.0其余跳过P1MDOUT = 0x77; // enable P1 outputsXBR1 |= 0x40; // enable crossbarP1 = 0xff; // P1 all high}//-----------------------------------------------------------------------------// PCA0_Init//-----------------------------------------------------------------------------void PCA0_Init (void){PCA0MD = 0x02; // PCA uses sysclk/4, no CF intPCA0CPM0 = 0x00; // clear mode, pin highPCA0L = 0x00; // reset the timer重置计时器PCA0H = 0x00;PCA0CPH0 = 0x00; // initial to 0%CR = 1; // START PCA0 timer开始pca0计时器}//-----------------------------------------------------------------------------// coast function//-----------------------------------------------------------------------------void coast(void){PCA0CPM0 = 0x00; // disable PWM禁用PWMP1 = 0xff; // disable upper transistors禁用上晶体管}//-----------------------------------------------------------------------------// readHalls function//-----------------------------------------------------------------------------// reads and debounces Hall-Sensor inputs读取并debounces霍尔传感器输入unsigned char readHalls(void){unsigned char g,h,i;g = 0;h = 0;while (g<GSAMP) // while less that 3 good samples{i = P0 & 0x07; // read hallsif (h == i) // if the sameg++; // one more goodelseg = 0; // else start overh = i; // update h}return h; // return good hall code}//-----------------------------------------------------------------------------// hallPosition function//----------------------------------------------------------------------------- unsigned char hallPosition (void){unsigned char h,p;h = readHalls(); // get debounced hall reading// find corresponding pattern index寻找相应的模式指数for (p=6;(h != hallPattern[p])&&(p!=0);p--);return p;}//-----------------------------------------------------------------------------// hallPosition function//-----------------------------------------------------------------------------void commutate (unsigned char i){ PCA0CPM0 = 0x00; // disable PWMP1 = 0xFF;XBR1 &= ~0x40; // disable crossbarP1SKIP = skipPattern[i];P1 = P1Pattern[i];XBR1 |= 0x40; // enable crossbar// DO NOT SINGLE-STEP PAST THE NEXT// LINE WITH MOTOR WIRES CONNECTEDPCA0CPM0 = 0x42; // enable 8-bit PWM mode}//-----------------------------------------------------------------------------// ADC functions//-----------------------------------------------------------------------------void ADC_Init(void){AMX0P = 0x07; // positive input P0.7AMX0N = 0x11; // single ended mode单端模式ADC0CF = 0xC4; // 1MHz clock, left justified 1MHz的时钟,左有道理ADC0CN = 0x80; // configure ADC for polled mode配置ADC为调查模式REF0CN = 0x08; // use Vdd as ADC full scale}unsigned char readVin(void){AD0INT = 0; // clear ADC0 end-of-conversionAD0BUSY = 1; // initiate conversion启动转换while (!AD0INT); // wait for conversion to complete等待转换完成return ADC0H;}unsigned char avgVin(void){unsigned char i, result;unsigned int sum;sum = 0;for (i = 64; i != 0; i--) // repeat 64 times重复64次{sum += readVin(); // read ADC and add to sum读取ADC和与sum相加}result = (unsigned char)(sum>>6); // divide by 64 and cast to uchar除以64并设为uchar数据return result; // return average reading回到average reading}。
基于 STM32 的电动车控制器软件-源代码

while (1)
{
if(write_finish)
{
__HAL_UART_DISABLE_IT(&husartx,UART_IT_IDLE);
printf("字库烧写完成,按下KEY2读取验证\r\n");
while(KEY2_StateRead()==KEY_UP);
while(KEY2_StateRead()==KEY_DOWN);
}
#include "stm32f1xx_hal.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* Initializes the Global MSP.
*/
void HAL_MspInit(void)
{
/* USER CODE BEGIN MspInit 0 */
printf(" 2.按下KEY1开始擦除串行flash扇区空间,并且必须等待擦除完成\r\n");
printf(" 3.点击sscom串口调试助手发送烧写字库文件\r\n");
printf(" 4.漫长的等待烧写完成过程\r\n");
printf(" 5.烧写完成后按下KEY2读取验证\r\n");
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; // 9倍频,得到72MHz主时钟
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
电动车控制器C语言源代码.#define _E_BIKE_W79E83X_C_ #include "intrins.h"#include "E_BIKE_W79E83X.H" #include"W79E834.h"/******************************************************************** ********** 主函数******************************************************************** **********/void main(void){Init(); // 初始化Init_IO(); // 初始化端口H_Sample(); // 霍尔信号采样Phase_Change(); // 相位变换AutoHelpEN(1,0x1AA,200);/*第一个参数设定助力功能允许不否,1为允许,0为禁止第二个参数设定助力力量(PWM占空比),数值围:0~0x355,数值越大,力量越大第三个参数设定助力时间,数值越大,时间越长*/Keep_SpeedEN(1,0x20,6);/*第一个参数设定定速巡航功能允许不否,1为允许,0为禁止第二个参数设定定速巡航最低速设置..第三个参数设定在巡航点保持多长时间后才进入巡航*/Current_Lim(0xB48);/*过流保护上限值设定0xB00对应限电流最大大约为2.6A0xB80对应限流值最大大约为3.8A*/LowVoltage_Lim(0x9B0);/*欠压保护下限值设定电池电压为47.9V时ADC采样值为0xB6 ==> 0xB60 推算电池电压为41V时的采样值为0x9B ==> 0x9B0推算电池电压为40V时的采样值为0x98 ==> 0x980 */EABS_Set(1,1);/*第一个参数为滑行充电功能使能,1为允许,0为禁止第二个参数为电刹车功能使能,1为允许,0为禁止*/Speed_LimHW(0,0,0,1);/*硬件控制最大速度参数只能有一个为1。
第一个参数对应15km/h第二个参数对应20km/h..第三个参数对应30km/h第四个参数对应40km/h*/Speed_LimSW(0x01);/*软件控制最大速度参数数值由0x00~0x20,数值越小速度越大,反之则越小*/while(1){_nop_();//AutoHelpEN(0,0x1AA,100);//Keep_SpeedEN(1,0x20,6);//Current_Lim(0xB50);//LowVoltage_Lim(0x9B0);//EABS_Set(0,0);//Speed_LimHW(0,0,0,1);}}/******************************************************************** *********** I/O端口初始化******************************************************************** **********/void Init_IO(void){//------P0端口设置------//P0M1=0xBE;..P0M2=0x01;/*P0M1.Y P0M2.Y=00 设置I/O端口为普通双向模式P0M1.Y P0M2.Y=01 设置I/O端口为推拉模式P0M1.Y P0M2.Y=10 设置I/O端口为输入,高阻,模式P0M1.Y P0M2.Y=11 设置I/O端口为开漏模式*///P0ID=0x78; // 设置四个AD端口0数字输入禁止P0=0xFF;//------P1端口设置------//P1M1=0x1C;P1M2=0xC0;P1=0xFF;//------P2端口设置------//P2M1=0x01;P2M2=0x1E;P2=0xFF;}/******************************************************************** *********** 初始化程序******************************************************************** **********/void Init(void){unsigned char i;//------PWM设置------//..// PWMP > PWMn 高电平,反之低电平PWMPH=0X03;PWMPL=0X55;PWM0H=0X00;PWM0L=0X00;PWM1H=0X00;PWM1L=0X00;PWM2H=0X00;PWM2L=0X00;PWMCON1=0XC7; // 打开PWM电路,三个PWM口反相输出PWMCON3=0xF0;//------飞车保护--------//EA=1;/*do {ADCCON=1;ADCCON&=0xef;ADCCON|=0x08;ADC_Ready=0;while(ADC_Ready);}while (ADCH>0x60);*///-----相位检测-------//while(P02==0){H_Sample();Phase_Detect(); ..}//------变量初始化------// for (i=0;i<32;i++) {Current_Buffer[i]=0; }for (i=0;i<20;i++) {Speed_Buffer[i]=0;}for (i=0;i<16;i++) {Voltage_Buffer[i]=0; }Current_P=0;Speed_P=0;Voltage_P=0;;Speed_SUM=0;// PWM_MAX=0; Current_SUM=0; Voltage_SUM=0;H_State=0;Old_State=0;PWM_Duty=0;// PWM_MAX=0;Count_Current=0;Count_Speed=0;Count_Voltage=0; ..Speed_REQ=0;Current_REQ=0;Voltage_REQ=0;ADC_Ready=0;//PWM_Duty=0;PWM_Duty_min=0;//*********************KeepSpeed_Flag = 0;KS_Z1 = 0;KS_Z2 = 0;Motor_Speed = 0x50;//*********************AutoHelp_Flag = 0;Current_Max=0xcffe;Speed_Low=0x0500;//Speed_High=0x1c37;//Speed_MAX=0x1c00; //-----定时器的设置-----//TH0=0x50;TL0=0x50; // 设定定时器的初值TH1=0xE0;TL1=0xE0; // 设定定时器的初值TMOD=0x22; // T0选为定时器,八位,模式2,TL0自动加载TH0中的初值CKCON&=0X00; // 定时器选择为1/12系统时钟ET0=1; // 允许定时器中断TR0=1; // 启动定时器ET1=1;TR1=1;..//-----外部中断设定-----//EX1 = 1; // 允许外部中断1IT1 = 0; // 电平触収中断1AUXR1|=0x04; // 打开ADC电路EADC=1; // 允许ADC中断ADCCON &= 0xE7;// Settings of Timer2 capture modeCKCON=0x60;CAPCON0=0xA8;CAPCON1=0x00;T2MOD=0xF0;IE1 |= 0x80; // enable capture mode interruptRCAP2L = 0x00; //自动重装载低位RCAP2H = 0x00; //自动重装载高位IE1 |= 0x40;//EA=1; // enable interruptT2CON |= 0x04;//enable timer2//***************************//KS_EN = 1;KS_Time = 8;//***************************// }/******************************************************************** **********..* ADC中断处理程序******************************************************************** **********/void ADC_ISR(void) interrupt 11{//UB=~UB;UB=~UB;//EADC=0;ADC_Ready=1;ADCCON &= 0xE7;if(Current_REQ) // 电流采样{Current_REQ=0;if(Current_SUM>Current_Buffer[Current_P]) Current_SUM -= Current_Buffer[Current_P]; Current_Buffer[Current_P]=ADCH;Current_SUM += ADCH;Current_P++;if(Current_P>31)Current_P=0;}if(Speed_REQ) // 转把电压采样{Speed_REQ=0;if(Speed_SUM>Speed_Buffer[Speed_P]) Speed_SUM-=Speed_Buffer[Speed_P]; Speed_Buffer[Speed_P]=ADCH;Speed_SUM+=ADCH;Speed_P++;..if(Speed_P == 14)Speed_P=0;}if(Voltage_REQ) // 电源电压采样{Voltage_REQ=0;if(Voltage_SUM>Voltage_Buffer[Voltage_P])Voltage_SUM -= Voltage_Buffer[Voltage_P];Voltage_Buffer[Voltage_P]=ADCH;Voltage_SUM += ADCH;Voltage_P++;if(Voltage_P>15)Voltage_P=0;}//PWM_ADJ();//UB=~UB;}/******************************************************************** *********** 定时器0中断处理函数******************************************************************** **********/// ========== Interrupt Cycle: 100uS===================void T0M1_ISR(void) interrupt 1{//UB=~UB;//UB=~UB;ADC_Ready=0;Current_REQ=1;..Speed_REQ=0;Voltage_REQ=0;ADCCON=2;Count_Speed++;KS_CNT++;AH_Count++;if(Count_Speed>5)//17{ADCCON=4;Current_REQ=0;Speed_REQ=1;Count_Speed=0;Count_Voltage++;if( Count_Voltage>5)//50{ADCCON=3;Speed_REQ=0;Voltage_REQ=1;Count_Voltage=0;//******** Keep Speed Setting ******// KS_Finish();}}//***Function Set***//if(AH_Count >= 100){AutoHelp(); // 自助力AH_Count = 0;}..if(KS_CNT >= 3000){KS_CNT = 0;Keep_Speed(); // 巡航定速}Volt_Low(); // 欠压保护if(P02==0)Brake_Setting(); // 刹车ADCCON&=0xef;ADCCON|=0x08;EADC=1;PWM_ADJ();}/******************************************************************** *********** 定时器1中断处理函数******************************************************************** **********/void T1M1_ISR(void) interrupt 3 {_nop_();}/******************************************************************** *********** 定时器2捕获模式中断处理函数******************************************************************** **********/void Timer2_ISR() interrupt 13 using 2 ..{//*******Motor Speed*******//Motor_Speed = TH2;TH2 = 0;TL2 = 0;H_Sample(); // 霍尔信号采集Phase_Change(); // 相位变换}/******************************************************************************* 定时器2溢出中断处理函数******************************************************************** **********/void T2_ISR() interrupt 8 {TF2 = 0;Motor_Speed = 0x50;Block_Detect(); // 堵转保护}/******************************************************************** *********** 外部中断处理函数,过流中断******************************************************************** **********/void INT1_ISR() interrupt 2 {CurrentOver_Count++;if(CurrentOver_Count >= 5) // 防抖处理..{PWM_Duty_min = 1;CurrentOver_Count = 0;}}/******************************************************************** *********** 定时器3中断处理函数,采叏捕获模式********************************************************************* *********/void H_Sample(void) {CAPCON1 &= 0xF8;H1=P12;H2=P07;H3=P20;do{State1=H1<<2;State1+=H2<<1;State1+=H3;_nop_();_nop_();State2=H1<<2;State2+=H2<<1;State2+=H3;}while(State1!=State2); // 状态去抖H_State=State1; .. }/******************************************************************** *********** 根据电机霍尔换向信号给出相应控制信号 * 上桥臂:VT,UT,WT* 下桥臂:VB,UB,WB******************************************************************** **********/void Phase_Change(void) {if(EABS_Flag){if(!AutoHelp_Flag){UB = 1;VB = 1;WB = 1;_nop_();UT = 1;VT = 1;WT = 1;}}else if(PWM_Duty_min){UT=0;VT=0;WT=0;UB=1;VB=1;WB=1; // 电机停转}else..{switch(H_State){case 6: // 110,V3,V4VT=0;UT=0;VB=1;WB=1;_nop_();WT=1;UB=0;break;case 2: // ,V4,V5case 7:UT=0;WB=0;VB=1;WB=1;_nop_();VT=1;UB=0;break;case 3: // 011,V5,V6UT=0;WT=0;UB=1;VB=1;_nop_();VT=1;WB=0;break;case 1: // 001,V6,V1WT=0;VT=0;UB=1;VB=1; _nop_();UT=1;WB=0;break;case 5: // 101,V1,V2case 0:WT=0;VT=0;UB=1;WB=1; _nop_();VB=0;UT=1;break;..case 4: // 100,V2,V3UT=0;VT=0;UB=1;WB=1; _nop_();WT=1;VB=0;break;case 9:UT=0;VT=0;WT=0;UB=1;VB=1;WB=1; break;default:break;}}/*if(PWM_Duty_min){UT=0;VT=0;WT=0;UB=1;VB=1;WB=1; // 电机停转}*/}/******************************************************************** *********** 相位检测程序* 上桥臂:VT,UT,WT* 下桥臂:VB,UB,WB******************************************************************** **********/void Phase_Detect(void){WT=0;UT=0;VT=0;switch(H_State)..{case 6: // 110,V3,V4UB=0;VB=1;WB=1;break;case 2: // ,V4,V5case 7:UB=0;VB=1;WB=1;break;case 3: // 011,V5,V6UB=1;VB=1;WB=0;break;case 1: // 001,V6,V1UB=1;VB=1;WB=0;break;case 5: // 101,V1,V2case 0:UB=1;VB=0;WB=1;break;case 4: // 100,V2,V3UB=1;VB=0;WB=1;break;default:break;}}/******************************************************************************* PWM值转换程序* 在限流允许下,将转把电压ADC值转换为PWMn的值 * 电流超过限流值时,做限流处理..******************************************************************** **********/void PWM_ADJ(void){//=====没有超过限流最大值的情冴====//if(Current_SUM < Current_Max){if(Speed_SUM < Speed_Low){ //---没有转把电压,由Speed_Low的值决定转把电压最小值---//if(!KeepSpeed_Flag){if(!AutoHelp_Flag){ // 定速,助力功能下电机正常转动,否则电机停转//PWM_Duty=0;//PWM_Duty_min=1; // 停转标志//PWM_Duty_Max = 0;if(Motor_Speed < 0x010){if(P02==1){if(EABS_SlipEN){EABS_Flag = 1;if(PWM_Duty_Max<0x55)PWM_Duty_Max = 0x055; // 滑行充电}else{PWM_Duty_Max = 0; ..PWM_Duty_min=1; // 停转标志PWM_Duty=0;}}else{PWM_Duty_Max = 0;PWM_Duty_min=1; // 停转标志PWM_Duty=0;}}else{PWM_Duty_Max = 0;PWM_Duty_min=1; // 停转标志PWM_Duty=0;}}}Block_Flag = 0;}else if(P02 == 1){ //---转把电压有效---//PWM_Duty_Max=Speed_SUM-Speed_Low; // 对应转把电压的最大计算值EABS_Flag = 0;if(PWM_Duty_min){if(!Block_Flag){..PWM_Duty_min = 0; // 退出无有效转把电压状冴Phase_Change(); // 相序对应}}/*if(LowNoise_Flag){PWM_Duty_Max += 0x200;}*/if(PWM_Duty_Max>0x06F0)PWM_Duty_Max = 0x06E8; // 最大值限制PWM_Duty_Max=PWM_Duty_Max>>1; // 由转把电压转换为PWMn的值}if(AutoHelp_Flag){PWM_Duty_Max=AH_Duty; // 助力下为PWMn赋值EABS_Flag = 0;}if(KeepSpeed_Flag){PWM_Duty_Max=KS_PWM_Duty; // 定速模式下为PWMn赋值AutoHelp_Flag = 0; // 定速巡航状态时无助力}if(PWM_Duty < PWM_Duty_Max){if(Motor_Speed > SP_Lim)PWM_Duty++; // 转把电压相对应的PWMn值缓慢增加 ..}else{if(PWM_Duty > 3)PWM_Duty--; // 转把电压相对应的PWMn值缓慢减小elsePWM_Duty = 0;}}//======超过限流最大值的情冴======//else{if(PWM_Duty > 0x02){PWM_Duty--; // PWMn值减小}else{PWM_Duty=0;}}PWM_Duty_H = PWM_Duty>>8;PWM_Duty_L = (PWM_Duty & 0x0FF); // 对应PWMn的值,高、低位,if (Power_Off)PWM_Duty_min = 1; // 欠压保护//PWM_Duty_H = 0x01; ..//PWM_Duty_L = 0x20; //测试之用PWM_Setting();}/******************************************************************** *********** 过流保护上限值设定* 0x1600对应限电流最大大约为2.6A* 0x1700对应限流值最大大约为3.8A******************************************************************** **********/void Current_Lim(unsigned int CM) {Current_Max = CM;}/******************************************************************** *********** 欠压保护程序******************************************************************** **********/void Volt_Low(void){if(Voltage_SUM < Voltage_Min){ // 欠压状态Voltage_Count++;if(Voltage_Count > 200)Power_Off=1;}else..{Power_Off=0;Voltage_Count = 0;}}/******************************************************************** *********** 欠压保护下限值设定* 电池电压为47.9V时ADC采样值为0xB6 ==> 0xB60 * 推算电池电压为41V时的采样值为0x9B ==> 0x9B0 * 推算电池电压为40V时的采样值为0x98 ==> 0x980********************************************************************* *********/void LowVoltage_Lim(unsigned int CM) {Voltage_Min = CM;}/******************************************************************** *********** 软件控制最大速度* 分为四个档位1,2,3,4分别对应15km/h,20km/h,30km/h,40km/h********************************************************************* *********/void Speed_LimSW(unsigned char SG) {SP_Lim = SG;}../******************************************************************** *********** 硬件控制最大速度* 分为四个档位SG1,SG2,SG3,SG4分别对应15km/h,20km/h,30km/h,40km/h ******************************************************************** **********/void Speed_LimHW(bit SG1,bit SG2,bit SG3,bit SG4){SP_Lim = 0x01;if(SG4)SP_Lim = 0x01;else if(SG3)SP_Lim = 0x03;else if(SG2)SP_Lim = 0x05;else if(SG1)SP_Lim = 0x08;}/******************************************************************** *********** 堵转保护程序******************************************************************** **********/void Block_Detect(void){if(Current_SUM > Current_Max - 0x80){Block_CNT++;}..elseBlock_CNT = 0;if(Block_CNT >= 20){PWM_Duty_min = 1;Block_Flag = 1;AutoHelp_Flag = 0;KeepSpeed_Flag = 0;UT=0;VT=0;WT=0;UB=1;VB=1;WB=1; // 电机停转}}/******************************************************************** *********** 刹车功能******************************************************************** **********/void Brake_Setting(void) {unsigned char i;KeepSpeed_Flag = 0;AutoHelp_Flag = 0;PWM_Duty_min = 1;Block_Flag = 0;UB = 1;VB = 1;WB = 1;Speed_SUM = 0;for(i=0;i<20;i++){..Speed_Buffer[i] = 0;}if(EABS_BrakeEN) // 电子刹车{if(Speed_SUM < Speed_Low) {PWM_Duty_H = 0x01; PWM_Duty_L = 0x00; EABS_Flag = 1;UT = 1;VT = 1;WT = 1;}else{UT = 0;VT = 0;WT = 0;}PWM_Setting();}}/******************************************************************** *********** 滑行充电功能******************************************************************** **********//*void Slip_Setting(void) {..if(EABS_SlipEN){UB = 1;VB = 1;WB = 1;_nop_();EABS_Flag = 1;UT = 1;VT = 1;WT = 1;}}/******************************************************************** *********** 电刹车功能使能* EBS_EN:滑行充电功能使能* EBB_EN:电刹车功能使能******************************************************************** **********/void EABS_Set(bit EBS_EN,bit EBB_EN) {EABS_SlipEN = EBS_EN;EABS_BrakeEN = EBB_EN;}/******************************************************************** *********** 1:1自动程序助力* 电动车中轴速度传感器(单开关霍尔信号),当转动中轴时产生高低电平信号。