0.工程模板
复制《ALIENTEK MiniSTM32 实验1 跑马灯》到桌面,同时将源码中的BALANCE/HARDWARE全部复制到工程目录下,添加.c到相应目录和.h的路径/在sys.h中添加头文件包含和外部变量的声明。
1.LED
添加led.c添加到hardware文件夹中;#include "led.h"
修改代码即可实现LED的控制。其中默认引脚为高电平灯不亮。
2.KEY
添加key.c添加到hardware文件夹中;control.c到BALANCE文件夹中。#include "key.h" extern u8 Flag_Show;
KEY.C:
u8 click_N_Double (u8 time)
{
static u8 flag_key,count_key,double_key;
static u16 count_single,Forever_count;
if(KEY==0) Forever_count++; //长按标志位未置1
else Forever_count=0;
if(0==KEY&&0==flag_key) flag_key=1;
if(0==count_key)
{
if(flag_key==1) //单击一次进去一次
{
double_key++;
count_key=1;
}
if(double_key==2) //判断双击
{
double_key=0;
count_single=0;
return 2;//双击执行的指令
}
}
if(1==KEY) flag_key=0,count_key=0; //松开按钮
if(1==double_key)
{
count_single++;
if(count_single>time&&Forever_count
{
double_key=0;
count_single=0;
return 1;//单击执行的指令
}
if(Forever_count>time) //长按不放
{
double_key=0;
count_single=0;
return 3;//长按执行的指令
}
}
return 0;
}
这里的time还是很巧妙的一个设计,单机一次之后double_key等于1,然后再次循环进入后就让count_single一直累加直到等于100就判断为是单击;如果双击的话就相当于在count_single一直累加还没有等于100就判断为是双击;Forever_count一按就会累加,一松就为0,所以只要一直连按就在双击中推出另一种情况,判断为长按。
TEST.C:u8 Flag_Show=0; KEY_Init();
while(1)
{
u8 tmp;
tmp=click_N_Double(100);
if(tmp==1)Flag_Show=!Flag_Show;//单击控制显示模式
if(Flag_Show==0)
{
LED=0;
//delay_ms(500);
//LED=1;
//delay_ms(500);
}
else LED=1;
}
这里延时一定要屏蔽,因为按键是循环扫描不是中断,所以延时加上后严重影响程序的精度。
3.USART
添加usartx.c添加到hardware文件夹中;#include "usart.h" #include "usartx.h"
extern u8 Flag_Left,Flag_Right,Flag_Direction; //旋转两个和一个方向
extern int RC_Velocity,RC_Position;
extern u8 Run_Flag,PID_Send,Flash_Send,Turn_Flag;
extern u8 Urxbuf[8],CAN_ON_Flag,Usart_ON_Flag,Usart_Flag,PS2_ON_Flag;
extern float Position_KP,Position_KI,Position_KD; //位置控制PID参数
TEST.C:
u8 Run_Flag=0,Turn_Flag,Flag_Left,Flag_Right,Flag_Direction=0; //模式、方向还是旋转、旋转的两个、方向的一个
u8 Urxbuf[8],Usart_ON_Flag=0,Usart_Flag,CAN_ON_Flag=0,PS2_ON_Flag=0,PID_Send,Flash_Send; //串口3接收的三个、CAN、PS、串口2两个
float Position_KP=20,Position_KI=0,Position_KD=20; //位置控制PID参数
int RC_Velocity=800,RC_Position=5000; //设置遥控的速度和位置值
if(MODE==0)Run_Flag=1; //=====启动的过程中,根据模式选择开关确定进入位置模式还是速度模式
else Run_Flag=0; //=====启动的过程中,根据模式选择开关确定进入位置模式还是速度模式
uart_init(72,128000); //=====串口1初始化
uart2_init(36,9600); //=====串口2初始化
uart3_init(36,115200); //=====串口3初始化
usart.c:
if(Receive[3]==0x50) PID_Send=1;//将PID参数送到oled
else if(Receive[3]==0x57) Flash_Send=1;//将PID参数送到FLASH
usartx.c:
if(Usart_ON_Flag==0){if(++Usart_ON_Count>10)Usart_ON_Flag=1; //超过10次进入串口接收中断,使能串口控制}
if(Usart_Flag==1){ Urxbuf[count]=temp; //依次采集数据
count++; if(count==8)Usart_Flag=0;}
4.OLED
添加oled.c添加到hardware文件夹中;show.c,DataScope_DP.c到BALANCE文件夹中。#include "oled.h" #include "show.h" #include "DataScope_DP.h"
extern float Pitch,Roll,Yaw,Move_X,Move_Y,Move_Z; //三轴角度和XYZ轴目标速度
extern long int Target_A,Target_B,Target_C,Target_D; //电机目标值
extern int Encoder_A,Encoder_B,Encoder_C,Encoder_D; //速度
extern float Position_A,Position_B,Position_C,Position_D,Rate_A,Rate_B,Rate_C,Rate_D; //PID控制相关变量
extern int Voltage,Voltage_Zheng,Voltage_Xiao; //电池电压采样相关的变量
TEST.C:
OLED_Init(); //=====OLED初始化
if(Flag_Show==0) //使用MiniBalance APP和OLED显示屏
{
// APP_Show();
// oled_show(); //===显示屏打开
LED=0;
}
else
{
// DataScope(); //开启MiniBalance上位机
LED=1;
}
OLED.C:
使用IIC通信,重新定义了f103的接口,6个pin就行。
5.ADC
添加adc.c添加到hardware文件夹中。#include "adc.h"
无多余变量,只是为了获取电池电压
TEST.C:
Adc_Init();
adc.C:
int Get_battery_volt(void)
{
int Volt;//电池电压
Volt=Get_Adc(Battery_Ch)*3.3*11.0*100/1.0/4096; //电阻分压,具体根据原理图简单分析可以得到
return Volt;
添加oled.c添加到hardware文件夹中;show.c,DataScope_DP.c到BALANCE文件夹中。#include "oled.h" #include "show.h" #include "DataScope_DP.h"
extern float Pitch,Roll,Yaw,Move_X,Move_Y,Move_Z; //三轴角度和XYZ轴目标
1
TEST.C:
.C:
6.
添加oled.c添加到hardware文件夹中;show.c,DataScope_DP.c到BALANCE文件夹中。#include "oled.h" #include "show.h" #include "DataScope_DP.h"
extern float Pitch,Roll,Yaw,Move_X,Move_Y,Move_Z; //三轴角度和XYZ轴目标