New
This commit is contained in:
22
User/app/inc/demo_i2c_eeprom.h
Normal file
22
User/app/inc/demo_i2c_eeprom.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* 模块名称 : EEPROM读写演示模块。
|
||||
* 文件名称 : demo_i2c_eeprom.h
|
||||
* 版 本 : V1.0
|
||||
* 说 明 : 头文件
|
||||
*
|
||||
* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _EEDEMO_H
|
||||
#define _EEDEMO_H
|
||||
|
||||
/* 供外部调用的函数声明 */
|
||||
void DemoEEPROM(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
21
User/app/inc/main.h
Normal file
21
User/app/inc/main.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* 模块名称 : main模块
|
||||
* 文件名称 : main.h
|
||||
* 版 本 : V1.0
|
||||
*
|
||||
* Copyright (C), 2015-2016, 安富莱电子 www.armfly.com
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _MAIN_H_
|
||||
#define _MAIN_H_
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/
|
||||
|
||||
215
User/app/src/demo_i2c_eeprom.c
Normal file
215
User/app/src/demo_i2c_eeprom.c
Normal file
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* 模块名称 : EEPROM读写演示模块。
|
||||
* 文件名称 : eeDemo.c
|
||||
* 版 本 : V1.1
|
||||
* 说 明 : EERPOM (24xx)读写例程。安富莱STM32-F4开发板标配的EEPROM型号为 AT24C128 (16K字节,128Kbit)
|
||||
*
|
||||
* 修改记录 :
|
||||
* 版本号 日期 作者 说明
|
||||
* V1.0 2013-02-01 armfly 正式发布
|
||||
* V1.1 2013-06-20 armfly 更换读取串口命令的写法,不采用 getchar() 阻塞方式。
|
||||
*
|
||||
* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#include "bsp.h"
|
||||
|
||||
/* 仅允许本文件内调用的函数声明 */
|
||||
static void ee_DispMenu(void);
|
||||
static void ee_ReadTest(void);
|
||||
static void ee_WriteTest(void);
|
||||
static void ee_Erase(void);
|
||||
|
||||
uint8_t buf[EE_SIZE]; /* 数据测试用缓冲区 16KB */
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: DemoEEPROM
|
||||
* 功能说明: 串行EEPROM读写例程
|
||||
* 形 参:无
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
void DemoEEPROM(void)
|
||||
{
|
||||
uint8_t cmd;
|
||||
|
||||
if (ee_CheckOk() == 0)
|
||||
{
|
||||
/* 没有检测到EEPROM */
|
||||
printf("没有检测到串行EEPROM!\r\n");
|
||||
|
||||
while (1); /* 停机 */
|
||||
}
|
||||
|
||||
printf("已经检测到串行EEPROM : \r\n");
|
||||
printf("型号: %s, 容量 = %d 字节, 页面大小 = %d\r\n", EE_MODEL_NAME, EE_SIZE, EE_PAGE_SIZE);
|
||||
|
||||
ee_DispMenu(); /* 打印命令提示 */
|
||||
while(1)
|
||||
{
|
||||
bsp_Idle(); /* 这个函数在bsp.c文件。用户可以修改这个函数实现CPU休眠和喂狗 */
|
||||
|
||||
//cmd = getchar(); /* 从串口读入一个字符 (阻塞方式) */
|
||||
if (comGetChar(COM1, &cmd)) /* 从串口读入一个字符(非阻塞方式) */
|
||||
{
|
||||
switch (cmd)
|
||||
{
|
||||
case '1':
|
||||
printf("\r\n【1 - 读 EEPROM 测试】\r\n");
|
||||
ee_ReadTest(); /* 读EEPROM数据,并打印出来数据内容 */
|
||||
break;
|
||||
|
||||
case '2':
|
||||
printf("\r\n【2 - 写 EEPROM 测试】\r\n");
|
||||
ee_WriteTest(); /* 写EEPROM数据,并打印写入速度 */
|
||||
break;
|
||||
|
||||
case '3':
|
||||
printf("\r\n【3 - 擦除 EEPROM】\r\n");
|
||||
ee_Erase(); /* 擦差EEPROM数据,实际上就是写入全0xFF */
|
||||
break;
|
||||
|
||||
default:
|
||||
ee_DispMenu(); /* 无效命令,重新打印命令提示 */
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: ee_ReadTest
|
||||
* 功能说明: 读串行EEPROM全部数据,并打印出来
|
||||
* 形 参:无
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
static void ee_ReadTest(void)
|
||||
{
|
||||
uint16_t i;
|
||||
int32_t iTime1, iTime2;
|
||||
|
||||
/* 读EEPROM, 起始地址 = 0, 数据长度为 256 */
|
||||
iTime1 = bsp_GetRunTime(); /* 记下开始时间 */
|
||||
if (ee_ReadBytes((uint8_t *)buf, 0, EE_SIZE) == 0)
|
||||
{
|
||||
printf("读eeprom出错!\r\n");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
iTime2 = bsp_GetRunTime(); /* 记下结束时间 */
|
||||
printf("读eeprom成功,数据如下:\r\n");
|
||||
}
|
||||
|
||||
/* 打印数据 */
|
||||
for (i = 0; i < EE_SIZE; i++)
|
||||
{
|
||||
printf(" %02X", buf[i]);
|
||||
|
||||
if ((i & 31) == 31)
|
||||
{
|
||||
printf("\r\n"); /* 每行显示16字节数据 */
|
||||
}
|
||||
else if ((i & 31) == 15)
|
||||
{
|
||||
printf(" - ");
|
||||
}
|
||||
}
|
||||
|
||||
/* 打印读速度 */
|
||||
printf("读耗时: %dms, 读速度: %dB/s\r\n", iTime2 - iTime1, (EE_SIZE * 1000) / (iTime2 - iTime1));
|
||||
}
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: ee_ReadTest
|
||||
* 功能说明: 写串行EEPROM全部数据
|
||||
* 形 参:无
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
static void ee_WriteTest(void)
|
||||
{
|
||||
uint16_t i;
|
||||
int32_t iTime1, iTime2;
|
||||
|
||||
/* 填充测试缓冲区 */
|
||||
for (i = 0; i < EE_SIZE; i++)
|
||||
{
|
||||
buf[i] = i;
|
||||
}
|
||||
|
||||
/* 写EEPROM, 起始地址 = 0,数据长度为 256 */
|
||||
iTime1 = bsp_GetRunTime(); /* 记下开始时间 */
|
||||
if (ee_WriteBytes(buf, 0, EE_SIZE) == 0)
|
||||
{
|
||||
printf("写eeprom出错!\r\n");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
iTime2 = bsp_GetRunTime(); /* 记下结束时间 */
|
||||
printf("写eeprom成功!\r\n");
|
||||
}
|
||||
|
||||
|
||||
/* 打印读速度 */
|
||||
printf("写耗时: %dms, 写速度: %dB/s\r\n", iTime2 - iTime1, (EE_SIZE * 1000) / (iTime2 - iTime1));
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: ee_ReadTest
|
||||
* 功能说明: 读串行EEPROM全部数据,并打印出来
|
||||
* 形 参:无
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
static void ee_Erase(void)
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
/* 填充缓冲区 */
|
||||
for (i = 0; i < EE_SIZE; i++)
|
||||
{
|
||||
buf[i] = 0xFF;
|
||||
}
|
||||
|
||||
/* 写EEPROM, 起始地址 = 0,数据长度为 256 */
|
||||
if (ee_WriteBytes(buf, 0, EE_SIZE) == 0)
|
||||
{
|
||||
printf("擦除eeprom出错!\r\n");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("擦除eeprom成功!\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 函 数 名: ee_DispMenu
|
||||
* 功能说明: 显示操作提示菜单
|
||||
* 形 参:无
|
||||
* 返 回 值: 无
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
static void ee_DispMenu(void)
|
||||
{
|
||||
printf("\r\n------------------------------------------------\r\n");
|
||||
printf("请选择操作命令:\r\n");
|
||||
printf("1 - 读EEPROM (%d 字节)\r\n", EE_SIZE);
|
||||
printf("2 - 写EEPROM (%d 字节,0x00-0xFF)\r\n", EE_SIZE);
|
||||
printf("3 - 擦除EEPROM\r\n");
|
||||
printf("4 - 显示命令提示\r\n");
|
||||
}
|
||||
|
||||
/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/
|
||||
547
User/app/src/main-MF-MC-Design03.c
Normal file
547
User/app/src/main-MF-MC-Design03.c
Normal file
@@ -0,0 +1,547 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 模块名称:main
|
||||
// 文件名称:main
|
||||
// 版本名称:V1.0
|
||||
// 文件说明:旋转样品杆主文件
|
||||
// 日期时间:2018年8月16日21点38分
|
||||
// 文件作者:Jackie Chan
|
||||
// 修改记录:
|
||||
// 版本号 日期 作者 说明
|
||||
// V1.0 2018.08.16 J.C 正式发布
|
||||
//
|
||||
// 公司名称:多场低温科技有限公司
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include "bsp.h" /* 底层硬件驱动 */
|
||||
uint8_t Flag_100ms = 0;
|
||||
extern DIGITIAL_TUBE_T g_tTube;
|
||||
extern MOTO_T g_tMoto;
|
||||
#define IS_ZERO_BUF_VALID() (g_RxBuf[1]=='z' && \
|
||||
g_RxBuf[2]==',' && g_RxBuf[4]==',' && \
|
||||
(g_RxBuf[3]=='1' || g_RxBuf[3]=='0'))
|
||||
#define IS_MF_VALID (g_RxBuf[1]=='M' && g_RxBuf[2]=='F')
|
||||
static void Delay_ms(uint16_t us)
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
/*
|
||||
CPU主频168MHz时,在内部Flash运行, MDK工程不优化。用台式示波器观测波形。
|
||||
循环次数为5时,SCL频率 = 1.78MHz (读耗时: 92ms, 读写正常,但是用示波器探头碰上就读写失败。时序接近临界)
|
||||
循环次数为10时,SCL频率 = 1.1MHz (读耗时: 138ms, 读速度: 118724B/s)
|
||||
循环次数为30时,SCL频率 = 440KHz, SCL高电平时间1.0us,SCL低电平时间1.2us
|
||||
|
||||
上拉电阻选择2.2K欧时,SCL上升沿时间约0.5us,如果选4.7K欧,则上升沿约1us
|
||||
|
||||
实际应用选择400KHz左右的速率即可
|
||||
*/
|
||||
for (i = 0; i < (300*us); i++);
|
||||
}
|
||||
void key1_long_task(void);
|
||||
void key1_task(void);
|
||||
void key2_task(void);
|
||||
void uart_msg_idle(void);
|
||||
// #include "bsp_adc.h"
|
||||
// #include "delay.h"
|
||||
|
||||
//初始化ADC
|
||||
//这里我们仅以规则通道为例
|
||||
//我们默认将开启通道0~3
|
||||
void Adc_Init(void)
|
||||
{
|
||||
ADC_InitTypeDef ADC_InitStructure;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE ); //使能ADC1通道时钟
|
||||
|
||||
|
||||
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
|
||||
|
||||
//PA1 作为模拟通道输入引脚
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
|
||||
|
||||
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
|
||||
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //模数转换工作在单通道模式
|
||||
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模数转换工作在单次转换模式
|
||||
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动
|
||||
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
|
||||
ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目
|
||||
ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
|
||||
|
||||
|
||||
ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1
|
||||
|
||||
ADC_ResetCalibration(ADC1); //使能复位校准
|
||||
|
||||
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
|
||||
|
||||
ADC_StartCalibration(ADC1); //开启AD校准
|
||||
|
||||
while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
|
||||
|
||||
// ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
|
||||
|
||||
}
|
||||
//获得ADC值
|
||||
//ch:通道值 0~3 ADC_Channel_1
|
||||
u16 Get_Adc(u8 ch)
|
||||
{
|
||||
//设置指定ADC的规则组通道,一个序列,采样时间
|
||||
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
|
||||
|
||||
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
|
||||
|
||||
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
|
||||
|
||||
return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果
|
||||
}
|
||||
|
||||
u16 Get_Adc_Average(u8 ch,u8 times)
|
||||
{
|
||||
u32 temp_val=0;
|
||||
u8 t;
|
||||
for(t=0;t<times;t++)
|
||||
{
|
||||
temp_val+=Get_Adc(ch);
|
||||
Delay_ms(5);
|
||||
}
|
||||
return temp_val/times;
|
||||
}
|
||||
|
||||
u16 get_key4_adc(void)
|
||||
{
|
||||
u16 key4_adc = 0;
|
||||
u16 ad_value;
|
||||
|
||||
ad_value = Get_Adc_Average(ADC_Channel_1,10);
|
||||
|
||||
// electric_quantity_percent = ((ad_value*3.3/4096.0)-1.846)*100/0.52;
|
||||
// key4_adc = (ad_value*3.3/4096.0);
|
||||
|
||||
key4_adc = ad_value;
|
||||
if(key4_adc > 2100)
|
||||
{
|
||||
key4_adc = 2;//前进
|
||||
}
|
||||
else if(key4_adc <= 1100)
|
||||
{
|
||||
key4_adc = 1;//后退
|
||||
}
|
||||
else if((key4_adc > 1100)&&(key4_adc <= 2100))
|
||||
{
|
||||
key4_adc = 0;//后退
|
||||
}
|
||||
return key4_adc;
|
||||
}
|
||||
u16 get_key5_adc(void)
|
||||
{
|
||||
u16 key5_adc = 0;
|
||||
u16 ad_value;
|
||||
|
||||
ad_value = Get_Adc_Average(ADC_Channel_2,10);
|
||||
|
||||
// electric_quantity_percent = ((ad_value*3.3/4096.0)-1.846)*100/0.52;
|
||||
key5_adc = (ad_value*3.3/4096.0);
|
||||
|
||||
if(key5_adc >= 2800)
|
||||
{
|
||||
key5_adc = 1;//前进
|
||||
}
|
||||
else if(key5_adc <= 600)
|
||||
{
|
||||
key5_adc = 2;//后退
|
||||
}
|
||||
else if((key5_adc > 600)&&(key5_adc < 2800))
|
||||
{
|
||||
key5_adc = 0;//后退
|
||||
}
|
||||
return key5_adc;
|
||||
}
|
||||
|
||||
void motor_dir(uint32_t freq, uint8_t _dir, int32_t _stpes)
|
||||
{
|
||||
// [r,1,1500,108288]
|
||||
// freq = get_run_freq();
|
||||
// pulse = get_pulse();
|
||||
if(g_tTube.state == WORK)
|
||||
{
|
||||
if(_dir == 1)
|
||||
{
|
||||
_dir = 1;
|
||||
g_tMoto.sv_pulse = g_tMoto.sv_pulse+100;
|
||||
}
|
||||
else if(_dir == 0)
|
||||
{
|
||||
_dir = 0;
|
||||
g_tMoto.sv_pulse = g_tMoto.sv_pulse-100;
|
||||
}
|
||||
|
||||
if(g_tMoto.pv_pulse<g_tMoto.sv_pulse)
|
||||
{
|
||||
if (g_tMoto.sv_pulse > 55600)
|
||||
{
|
||||
g_tMoto.sv_pulse = 55600;
|
||||
}
|
||||
else if(g_tMoto.sv_pulse <= 55600)
|
||||
{
|
||||
MOTO_Start(freq, 0, 100);
|
||||
}
|
||||
}
|
||||
else if(g_tMoto.pv_pulse>g_tMoto.sv_pulse)
|
||||
{
|
||||
if (g_tMoto.sv_pulse < -1600)
|
||||
{
|
||||
g_tMoto.sv_pulse = -1600;
|
||||
}
|
||||
else if(g_tMoto.sv_pulse >= -1600)
|
||||
{
|
||||
MOTO_Start(freq, 1, 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int main(void)
|
||||
{
|
||||
uint8_t ucKeyCode;
|
||||
uint32_t freq = 1500;
|
||||
uint16_t motor_move1 = 0;
|
||||
uint16_t motor_move2 = 0;
|
||||
bsp_Init(); /* 硬件初始化 */
|
||||
Adc_Init(); //ADC初始化
|
||||
BEEP_Start(freq, 20, 1, 1);
|
||||
|
||||
//g_tTube.state = WORK;
|
||||
// MOTO_Stop();
|
||||
//g_tMoto.CurrentStep = 0;
|
||||
|
||||
/* 主程序大循环 */
|
||||
while (1)
|
||||
{
|
||||
bsp_Idle(); /* CPU空闲时执行的函数,在 bsp.c */
|
||||
uart_msg_idle();
|
||||
if(Flag_100ms == 1)
|
||||
{
|
||||
Flag_100ms = 0;
|
||||
motor_move1 = get_key4_adc();
|
||||
motor_move2 = get_key5_adc();
|
||||
if(motor_move1 == 1)//key4
|
||||
{
|
||||
motor_move1 = 0;
|
||||
//前进
|
||||
motor_dir(1500, 0, 3000);
|
||||
}
|
||||
else if(motor_move1 == 2)
|
||||
{
|
||||
motor_move1 = 0;
|
||||
//后退
|
||||
motor_dir(1500, 1, 3000);
|
||||
}
|
||||
}
|
||||
/* 处理按键事件 */
|
||||
ucKeyCode = bsp_GetKey();
|
||||
|
||||
if (ucKeyCode > 0)
|
||||
{
|
||||
/* 有键按下 */
|
||||
switch (ucKeyCode)//key6
|
||||
{
|
||||
case KEY_DOWN_K6: //key6 短按
|
||||
{
|
||||
BEEP_KeyTone(); // 按键提示音
|
||||
key1_long_task(); // 短按按键一仅用来切换数码管显示角度还是脉冲数
|
||||
break;
|
||||
}
|
||||
|
||||
case KEY_DOWN_K1: //Key1 短按
|
||||
{
|
||||
BEEP_KeyTone(); // 按键提示音
|
||||
bsp_ToogleDispMode(); // K1按键用来做零点搜索时候的限位
|
||||
break;
|
||||
}
|
||||
case KEY_DOWN_K2: //Key2 短按
|
||||
{
|
||||
BEEP_KeyTone(); // 按键提示音
|
||||
|
||||
key2_task(); // K2按键用来做零点搜索时候的限位
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case KEY_LONG_K1://
|
||||
{
|
||||
//BEEP_Start(freq, 5, 5, 3); // 长按K1发出三声嘀嘀声
|
||||
key1_long_task(); //
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void key1_long_task(void)
|
||||
{ // 转速:10度每秒
|
||||
if(IsKeyDown2())
|
||||
{
|
||||
BEEP_Start(1500, 5, 5, 3);
|
||||
// 如果已经在零点了,发出提醒,不转动,位置归零
|
||||
}
|
||||
if(g_tTube.state == IDLE)
|
||||
{
|
||||
g_tTube.state = SEARCH; // 上电后,长按K1进入搜索零点模式
|
||||
if(g_tTube.disp_mode == MODE_PULSE)
|
||||
{
|
||||
bsp_drv8880_config_dir(DIR_CW);
|
||||
MOTO_Start(1504, 1, 67680); // 67680个脉冲,无限位防护最大旋转1.25圈
|
||||
} // 转速:10度每秒
|
||||
else if(g_tTube.disp_mode == MODE_ANGLE)
|
||||
{
|
||||
bsp_drv8880_config_dir(DIR_CCW);
|
||||
MOTO_Start(1504,1, 67680); // 67680个脉冲,无限位防护最大旋转1.25圈
|
||||
}
|
||||
}
|
||||
else if(g_tTube.state == WORK && g_tMoto.CurrentStep != 0)
|
||||
{
|
||||
g_tTube.state = SEARCH; // 上电后,长按K1进入搜索零点模式
|
||||
if(g_tTube.disp_mode == MODE_PULSE)
|
||||
{
|
||||
bsp_drv8880_config_dir(DIR_CW);
|
||||
MOTO_Start(1504, 1, 67680); // 67680个脉冲,无限位防护最大旋转1.25圈
|
||||
} // 转速:10度每秒
|
||||
else if(g_tTube.disp_mode == MODE_ANGLE)
|
||||
{
|
||||
bsp_drv8880_config_dir(DIR_CCW);
|
||||
MOTO_Start(1504,1, 67680); // 67680个脉冲,无限位防护最大旋转1.25圈
|
||||
}
|
||||
}
|
||||
// 转速:10度每秒
|
||||
}
|
||||
|
||||
void key2_task(void)
|
||||
{
|
||||
DISABLE_INT();
|
||||
if(g_tTube.state == SEARCH)
|
||||
{
|
||||
g_tTube.state = WORK;
|
||||
MOTO_Stop();
|
||||
g_tMoto.CurrentStep = 0;
|
||||
}
|
||||
ENABLE_INT();
|
||||
}
|
||||
|
||||
uint32_t get_run_freq(void) // [r,1,1500,108288]
|
||||
{
|
||||
uint32_t i=0;
|
||||
i += (g_RxBuf[5]-'0')*1000;
|
||||
i += (g_RxBuf[6]-'0')*100;
|
||||
i += (g_RxBuf[7]-'0')*10;
|
||||
i += (g_RxBuf[8]-'0')*1;
|
||||
return i;
|
||||
}
|
||||
|
||||
uint32_t get_zero_freq(void) // [z,1,1500]
|
||||
{
|
||||
uint32_t i=0;
|
||||
i += (g_RxBuf[5]-'0')*1000;
|
||||
i += (g_RxBuf[6]-'0')*100;
|
||||
i += (g_RxBuf[7]-'0')*10;
|
||||
i += (g_RxBuf[8]-'0')*1;
|
||||
return i;
|
||||
}
|
||||
|
||||
uint32_t get_pulse(void)
|
||||
{
|
||||
uint32_t i=0;
|
||||
i += (g_RxBuf[10]-'0')*100000;
|
||||
i += (g_RxBuf[11]-'0')*10000;
|
||||
i += (g_RxBuf[12]-'0')*1000;
|
||||
i += (g_RxBuf[13]-'0')*100;
|
||||
i += (g_RxBuf[14]-'0')*10;
|
||||
i += (g_RxBuf[15]-'0')*1;
|
||||
return i;
|
||||
}
|
||||
|
||||
void search_zero(uint8_t dir,uint32_t freq)
|
||||
{
|
||||
if(g_tMoto.Running == 1) // 如果电机在运动中,先停止电机
|
||||
{
|
||||
MOTO_Stop();
|
||||
}
|
||||
|
||||
// 转速:10度每秒
|
||||
if(IsKeyDown2())
|
||||
{
|
||||
BEEP_Start(1500, 5, 5, 3);
|
||||
// 如果已经在零点了,发出提醒,不转动,位置归零
|
||||
}
|
||||
if(g_tTube.state == IDLE)
|
||||
{
|
||||
g_tTube.state = SEARCH; // 上电后,长按K1进入搜索零点模式
|
||||
if(g_tTube.disp_mode == MODE_PULSE)
|
||||
{
|
||||
bsp_drv8880_config_dir(DIR_CW);
|
||||
MOTO_Start(1504, 1, 67680); // 67680个脉冲,无限位防护最大旋转1.25圈
|
||||
} // 转速:10度每秒
|
||||
else if(g_tTube.disp_mode == MODE_ANGLE)
|
||||
{
|
||||
bsp_drv8880_config_dir(DIR_CCW);
|
||||
MOTO_Start(1504,1, 67680); // 67680个脉冲,无限位防护最大旋转1.25圈
|
||||
}
|
||||
}
|
||||
else if(g_tTube.state == WORK && g_tMoto.CurrentStep != 0)
|
||||
{
|
||||
g_tTube.state = SEARCH; // 上电后,长按K1进入搜索零点模式
|
||||
if(g_tTube.disp_mode == MODE_PULSE)
|
||||
{
|
||||
bsp_drv8880_config_dir(DIR_CW);
|
||||
MOTO_Start(1504, 1, 67680); // 67680个脉冲,无限位防护最大旋转1.25圈
|
||||
} // 转速:10度每秒
|
||||
else if(g_tTube.disp_mode == MODE_ANGLE)
|
||||
{
|
||||
bsp_drv8880_config_dir(DIR_CCW);
|
||||
MOTO_Start(1504,1, 67680); // 67680个脉冲,无限位防护最大旋转1.25圈
|
||||
}
|
||||
}
|
||||
// 转速:10度每秒
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void send_sv_2_uart(void)
|
||||
{
|
||||
if(g_tMoto.pv_pulse>=0)
|
||||
{
|
||||
printf("[w,1,%06d]",g_tMoto.pv_pulse);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[w,0,%06d]",-g_tMoto.pv_pulse);
|
||||
}
|
||||
}
|
||||
|
||||
void print_sys_info(void)
|
||||
{
|
||||
printf("\r\n");
|
||||
printf("----------------------------->\r\n");
|
||||
printf("-> 设备名称:旋转样品杆控制器\r\n");
|
||||
printf("-> software verson: V1.1\r\n");
|
||||
printf("-> compile time: %s\r\n",__TIME__);
|
||||
printf("-> compile date: %s\r\n",__DATE__);
|
||||
printf("-> [多场低温科技有限公司]\r\n");
|
||||
printf("------------------------------\r\n");
|
||||
printf("->可用命令:\r\n");
|
||||
printf("1. [s] // 停止电机转动\r\n");
|
||||
printf("2. [?] // 读取当前位置脉冲数量\r\n");
|
||||
printf("3. [MF] // 打印系统信息\r\n");
|
||||
printf("4. [z,1,1500] // 零点搜索命令,1为顺时针转动,0为逆时针转动,1500为脉冲频率\r\n");
|
||||
printf("5. [r,1,1500,108288] // 转动命令,1为顺时针转动,0为逆时针转动,1500为脉冲频率,108288为要转动的脉冲\r\n");
|
||||
printf("<-----------------------------\r\n");
|
||||
}
|
||||
|
||||
void uart_msg_idle(void)
|
||||
{
|
||||
uint8_t n=0;
|
||||
uint32_t freq=0;
|
||||
uint32_t pulse=0;
|
||||
uint8_t _dir=0;
|
||||
|
||||
if(g_ucRxRcvNewFlag)
|
||||
{
|
||||
g_ucRxRcvNewFlag = 0;
|
||||
|
||||
n = strlen((char*)g_RxBuf);
|
||||
if(n==3)
|
||||
{
|
||||
switch(g_RxBuf[1])
|
||||
{
|
||||
//case '?': printf("%d\r\n",g_tTube.pulse); break;
|
||||
//case '?': printf("[w,1,054050]"); break;
|
||||
case '?': send_sv_2_uart(); break;
|
||||
case 's': MOTO_Stop(); break;
|
||||
//case 'z': search_zero(1); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
else if(n==4)
|
||||
{
|
||||
if(IS_MF_VALID)
|
||||
{
|
||||
print_sys_info();
|
||||
}
|
||||
}
|
||||
else if(n==10) // [z,1,1500]
|
||||
{
|
||||
freq = get_zero_freq();
|
||||
if(IS_ZERO_BUF_VALID() && freq<=1504)
|
||||
{
|
||||
if(g_RxBuf[3]=='1')
|
||||
{
|
||||
search_zero(1,freq); // 顺时针搜索
|
||||
}
|
||||
else
|
||||
{
|
||||
search_zero(0,freq); // 逆时针搜索
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BEEP_Start(1500, 5, 5, 3);
|
||||
}
|
||||
}
|
||||
else if((n==17)&&(g_RxBuf[1]=='r'))
|
||||
{
|
||||
// [r,1,1500,108288]
|
||||
freq = get_run_freq();
|
||||
pulse = get_pulse();
|
||||
g_tMoto.sv_pulse = pulse;
|
||||
|
||||
if(g_RxBuf[3]=='1')
|
||||
{
|
||||
_dir = 1;
|
||||
g_tMoto.sv_pulse = -g_tMoto.sv_pulse;
|
||||
}
|
||||
else if(g_RxBuf[3]=='0')
|
||||
{
|
||||
_dir = 0;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
BEEP_Start(1500, 5, 5, 3);
|
||||
return ;
|
||||
}
|
||||
|
||||
if(g_tMoto.pv_pulse<g_tMoto.sv_pulse)
|
||||
{
|
||||
//MOTO_Start(freq, _dir, 123);
|
||||
MOTO_Start(freq, 0, 123);
|
||||
}
|
||||
else if(g_tMoto.pv_pulse>g_tMoto.sv_pulse)
|
||||
{
|
||||
//MOTO_Start(freq, _dir, 123);
|
||||
MOTO_Start(freq, 1, 123);
|
||||
}
|
||||
else
|
||||
{
|
||||
BEEP_Start(1500, 5, 5, 3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BEEP_Start(1500, 5, 5, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------- End of file ---------------------------------
|
||||
447
User/app/src/main.c
Normal file
447
User/app/src/main.c
Normal file
@@ -0,0 +1,447 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 模块名称:main
|
||||
// 文件名称:main
|
||||
// 版本名称:V1.0
|
||||
// 文件说明:旋转样品杆主文件
|
||||
// 日期时间:2018年8月16日21点38分
|
||||
// 文件作者:Jackie Chan
|
||||
// 修改记录:
|
||||
// 版本号 日期 作者 说明
|
||||
// V1.0 2018.08.16 J.C 正式发布
|
||||
//
|
||||
// 公司名称:多场低温科技有限公司
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include "bsp.h" /* 底层硬件驱动 */
|
||||
#include "bsp_key.h"
|
||||
#include "stdint.h"
|
||||
#include "main.h"
|
||||
|
||||
uint8_t Flag_100ms = 0;
|
||||
extern DIGITIAL_TUBE_T g_tTube;
|
||||
extern MOTO_T g_tMoto;
|
||||
#define IS_ZERO_BUF_VALID() (g_RxBuf[1] == 'z' && \
|
||||
g_RxBuf[2] == ',' && g_RxBuf[4] == ',' && \
|
||||
(g_RxBuf[3] == '1' || g_RxBuf[3] == '0'))
|
||||
#define IS_MF_VALID (g_RxBuf[1] == 'M' && g_RxBuf[2] == 'F')
|
||||
static void Delay_ms(uint16_t us)
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
/*
|
||||
CPU主频168MHz时,在内部Flash运行, MDK工程不优化。用台式示波器观测波形。
|
||||
循环次数为5时,SCL频率 = 1.78MHz (读耗时: 92ms, 读写正常,但是用示波器探头碰上就读写失败。时序接近临界)
|
||||
循环次数为10时,SCL频率 = 1.1MHz (读耗时: 138ms, 读速度: 118724B/s)
|
||||
循环次数为30时,SCL频率 = 440KHz, SCL高电平时间1.0us,SCL低电平时间1.2us
|
||||
|
||||
上拉电阻选择2.2K欧时,SCL上升沿时间约0.5us,如果选4.7K欧,则上升沿约1us
|
||||
|
||||
实际应用选择400KHz左右的速率即可
|
||||
*/
|
||||
for (i = 0; i < (300 * us); i++)
|
||||
;
|
||||
}
|
||||
void key1_task(void);
|
||||
void key2_task(void);
|
||||
void uart_msg_idle(void);
|
||||
// #include "bsp_adc.h"-
|
||||
// #include "delay.h"
|
||||
|
||||
// 初始化ADC
|
||||
// 这里我们仅以规则通道为例
|
||||
// 我们默认将开启通道0~3
|
||||
void Adc_Init(void)
|
||||
{
|
||||
ADC_InitTypeDef ADC_InitStructure;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE); // 使能ADC1通道时钟
|
||||
|
||||
RCC_ADCCLKConfig(RCC_PCLK2_Div6); // 设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
|
||||
|
||||
// PA1 作为模拟通道输入引脚
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // 模拟输入引脚
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
ADC_DeInit(ADC1); // 复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
|
||||
|
||||
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; // ADC工作模式:ADC1和ADC2工作在独立模式
|
||||
ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 模数转换工作在单通道模式
|
||||
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // 模数转换工作在单次转换模式
|
||||
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // 转换由软件而不是外部触发启动
|
||||
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // ADC数据右对齐
|
||||
ADC_InitStructure.ADC_NbrOfChannel = 1; // 顺序进行规则转换的ADC通道的数目
|
||||
ADC_Init(ADC1, &ADC_InitStructure); // 根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
|
||||
|
||||
ADC_Cmd(ADC1, ENABLE); // 使能指定的ADC1
|
||||
|
||||
ADC_ResetCalibration(ADC1); // 使能复位校准
|
||||
|
||||
while (ADC_GetResetCalibrationStatus(ADC1))
|
||||
; // 等待复位校准结束
|
||||
|
||||
ADC_StartCalibration(ADC1); // 开启AD校准
|
||||
|
||||
while (ADC_GetCalibrationStatus(ADC1))
|
||||
; // 等待校准结束
|
||||
|
||||
// ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
|
||||
}
|
||||
// 获得ADC值
|
||||
// ch:通道值 0~3 ADC_Channel_1
|
||||
u16 Get_Adc(u8 ch)
|
||||
{
|
||||
// 设置指定ADC的规则组通道,一个序列,采样时间
|
||||
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5); // ADC1,ADC通道,采样时间为239.5周期
|
||||
|
||||
ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 使能指定的ADC1的软件转换启动功能
|
||||
|
||||
while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC))
|
||||
; // 等待转换结束
|
||||
|
||||
return ADC_GetConversionValue(ADC1); // 返回最近一次ADC1规则组的转换结果
|
||||
}
|
||||
|
||||
u16 Get_Adc_Average(u8 ch, u8 times)
|
||||
{
|
||||
u32 temp_val = 0;
|
||||
u8 t;
|
||||
for (t = 0; t < times; t++)
|
||||
{
|
||||
temp_val += Get_Adc(ch);
|
||||
Delay_ms(5);
|
||||
}
|
||||
return temp_val / times;
|
||||
}
|
||||
|
||||
u16 get_key4_adc(void)
|
||||
{
|
||||
u16 key4_adc = 0;
|
||||
u16 ad_value;
|
||||
|
||||
ad_value = Get_Adc_Average(ADC_Channel_1, 10);
|
||||
|
||||
key4_adc = ad_value;
|
||||
if (key4_adc > 3000)
|
||||
{
|
||||
key4_adc = 2; // 前进
|
||||
}
|
||||
else if (key4_adc <= 1200)
|
||||
{
|
||||
key4_adc = 1; // 后退
|
||||
}
|
||||
else if ((key4_adc > 1200) && (key4_adc <= 3000))
|
||||
{
|
||||
key4_adc = 0; // 后退
|
||||
}
|
||||
return key4_adc;
|
||||
}
|
||||
u16 get_key5_adc(void)
|
||||
{
|
||||
u16 key5_adc = 0;
|
||||
u16 ad_value;
|
||||
|
||||
ad_value = Get_Adc_Average(ADC_Channel_2, 10);
|
||||
|
||||
// electric_quantity_percent = ((ad_value*3.3/4096.0)-1.846)*100/0.52;
|
||||
key5_adc = (ad_value * 3.3 / 4096.0);
|
||||
|
||||
if (key5_adc >= 3000)
|
||||
{
|
||||
key5_adc = 1; // 前进
|
||||
}
|
||||
else if (key5_adc <= 1200)
|
||||
{
|
||||
key5_adc = 2; // 后退
|
||||
}
|
||||
else if ((key5_adc > 1200) && (key5_adc < 3000))
|
||||
{
|
||||
key5_adc = 0; // 后退
|
||||
}
|
||||
return key5_adc;
|
||||
}
|
||||
|
||||
void motor_dir(uint32_t freq, uint8_t _dir, int64_t _stpes)
|
||||
{
|
||||
// [r,1,1500,108288]
|
||||
|
||||
if (g_tTube.state == WORK)
|
||||
{
|
||||
if (_dir == 1)
|
||||
{
|
||||
_dir = 1;
|
||||
if (g_tMoto.sv_pulse + 100 < INT64_MAX)
|
||||
g_tMoto.sv_pulse = g_tMoto.sv_pulse + 100;
|
||||
}
|
||||
else if (_dir == 0)
|
||||
{
|
||||
_dir = 0;
|
||||
if (g_tMoto.sv_pulse - 100 > INT64_MIN)
|
||||
g_tMoto.sv_pulse = g_tMoto.sv_pulse - 100;
|
||||
}
|
||||
|
||||
if (g_tMoto.pv_pulse < g_tMoto.sv_pulse)
|
||||
{
|
||||
|
||||
if (g_tMoto.sv_pulse > INT64_MAX)
|
||||
{
|
||||
g_tMoto.sv_pulse = INT64_MAX;
|
||||
}
|
||||
else if (g_tMoto.sv_pulse <= INT64_MAX)
|
||||
{
|
||||
MOTO_Start(1500, 0, 100);
|
||||
}
|
||||
}
|
||||
else if (g_tMoto.pv_pulse > g_tMoto.sv_pulse)
|
||||
{
|
||||
if (g_tMoto.sv_pulse < INT64_MIN)
|
||||
{
|
||||
g_tMoto.sv_pulse = INT64_MIN;
|
||||
}
|
||||
else if (g_tMoto.sv_pulse >= INT64_MIN)
|
||||
{
|
||||
MOTO_Start(1500, 1, 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int main(void)
|
||||
{
|
||||
uint8_t ucKeyCode;
|
||||
uint32_t freq = 1500;
|
||||
uint16_t motor_move1 = 0;
|
||||
uint32_t g_sysclk_src = 0, g_pll_mul = 0;
|
||||
// uint16_t motor_move2 = 0;
|
||||
|
||||
SCB->VTOR = 0x08008000;
|
||||
|
||||
/* === MCO 测试: PA8 输出 PLLCLK/2,示波器测量 PA8 === */
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
||||
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
|
||||
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_MCO) | RCC_CFGR_MCO_PLL;
|
||||
/* MCO 输出 PLL/2:72MHz 系统 = 36MHz, 48MHz 系统 = 24MHz */
|
||||
}
|
||||
|
||||
/* 运行时检测实际系统时钟 */
|
||||
{
|
||||
g_sysclk_src = RCC->CFGR & RCC_CFGR_SWS;
|
||||
if (g_sysclk_src == 0x08)
|
||||
{
|
||||
g_pll_mul = (RCC->CFGR & RCC_CFGR_PLLMULL) >> 18;
|
||||
g_pll_mul = g_pll_mul + 2;
|
||||
}
|
||||
}
|
||||
|
||||
bsp_Init(); /* 硬件初始化 */
|
||||
|
||||
/* 打印调试信息(需在串口初始化后) */
|
||||
{
|
||||
if (g_sysclk_src == 0x00)
|
||||
printf("SYSCLK = HSI 8MHz\r\n");
|
||||
else if (g_sysclk_src == 0x04)
|
||||
printf("SYSCLK = HSE\r\n");
|
||||
else if (g_sysclk_src == 0x08)
|
||||
{
|
||||
printf("PLL MUL = %u, PLL = 8MHz * %u = %uMHz\r\n", g_pll_mul, g_pll_mul, 8 * g_pll_mul);
|
||||
}
|
||||
printf("SystemCoreClock var = %lu\r\n", SystemCoreClock);
|
||||
printf("RCC->CFGR = 0x%08lX, PPRE1=%lu\r\n", RCC->CFGR, (RCC->CFGR >> 8) & 0x7);
|
||||
printf("TIM6 PSC = %u, ARR = %u\r\n", TIM6->PSC, TIM6->ARR);
|
||||
}
|
||||
|
||||
Adc_Init(); // ADC初始化
|
||||
BEEP_Start(freq, 20, 1, 1);
|
||||
|
||||
g_tTube.state = WORK;
|
||||
MOTO_Stop();
|
||||
|
||||
/* 主程序大循环 */
|
||||
while (1)
|
||||
{
|
||||
bsp_Idle(); /* CPU空闲时执行的函数,在 bsp.c */
|
||||
uart_msg_idle();
|
||||
if (Flag_100ms == 1)
|
||||
{
|
||||
Flag_100ms = 0;
|
||||
motor_move1 = get_key4_adc();
|
||||
// motor_move2 = get_key5_adc();
|
||||
if (motor_move1 == 1) // key4
|
||||
{
|
||||
motor_move1 = 0;
|
||||
// 前进
|
||||
motor_dir(1500, 0, 3000);
|
||||
}
|
||||
else if (motor_move1 == 2)
|
||||
{
|
||||
motor_move1 = 0;
|
||||
// 后退
|
||||
motor_dir(1500, 1, 3000);
|
||||
}
|
||||
}
|
||||
/* 处理按键事件 */
|
||||
ucKeyCode = bsp_GetKey();
|
||||
|
||||
if (ucKeyCode > 0)
|
||||
{
|
||||
/* 有键按下 */
|
||||
switch (ucKeyCode) // key6
|
||||
{
|
||||
case KEY_DOWN_K6: // key6 短按
|
||||
{
|
||||
MOTO_ZorePos();
|
||||
break;
|
||||
}
|
||||
|
||||
case KEY_DOWN_K1: // Key1 短按
|
||||
{
|
||||
BEEP_KeyTone(); // 按键提示音
|
||||
bsp_ToogleDispMode();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void send_sv_2_uart(void)
|
||||
{
|
||||
float angle = g_tTube.pulse * 360.0f / STEP_PER_LAP; // 22 * 16 * 24
|
||||
printf("[w,%.2f]\r\n", angle);
|
||||
}
|
||||
|
||||
void print_sys_info(void)
|
||||
{
|
||||
printf("\r\n");
|
||||
printf("----------------------------->\r\n");
|
||||
printf("-> 设备名称:无限旋转控制器\r\n");
|
||||
printf("-> software verson: V1.0\r\n");
|
||||
printf("-> compile time: %s\r\n", __TIME__);
|
||||
printf("-> compile date: %s\r\n", __DATE__);
|
||||
printf("-> [多场低温科技有限公司]\r\n");
|
||||
printf("------------------------------\r\n");
|
||||
printf("->可用命令:\r\n");
|
||||
printf("1. [s] // 停止电机转动\r\n");
|
||||
printf("2. [?] // 读取当前位置角度\r\n");
|
||||
printf("3. [z] // 设置当前位置为零点\r\n");
|
||||
printf("4. [MF] // 打印系统信息\r\n");
|
||||
printf("5. [r:10:360] // 转动命令,10为转动角速度,360为目标角度\r\n");
|
||||
printf("6. [rr:10:20] // 转动命令,10为转动角速度,20为相对转动角度\r\n");
|
||||
printf("<-----------------------------\r\n");
|
||||
}
|
||||
|
||||
void uart_msg_idle(void)
|
||||
{
|
||||
uint8_t n = 0;
|
||||
float freq = 0;
|
||||
float pulse = 0;
|
||||
float angle = 0;
|
||||
|
||||
if (g_ucRxRcvNewFlag)
|
||||
{
|
||||
g_ucRxRcvNewFlag = 0;
|
||||
|
||||
n = strlen((char *)g_RxBuf);
|
||||
if (n == 3)
|
||||
{
|
||||
switch (g_RxBuf[1])
|
||||
{
|
||||
case '?':
|
||||
send_sv_2_uart();
|
||||
break;
|
||||
case 's':
|
||||
MOTO_Stop();
|
||||
break;
|
||||
case 'z':
|
||||
MOTO_ZorePos();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (n == 4)
|
||||
{
|
||||
if (IS_MF_VALID)
|
||||
{
|
||||
print_sys_info();
|
||||
}
|
||||
}
|
||||
else if (g_RxBuf[1] == 'r')
|
||||
{
|
||||
// [r,10,100] // 10°/s 转到100°
|
||||
if (sscanf((char *)g_RxBuf, "[r:%f:%f]", &freq, &angle) == 2)
|
||||
{
|
||||
if (freq < 0.01f)
|
||||
freq = 0.01f;
|
||||
else if (freq > MAX_SPEED)
|
||||
freq = MAX_SPEED;
|
||||
pulse = (angle / 360) * STEP_PER_LAP; // angle所有需要的脉冲
|
||||
freq = freq * (STEP_PER_LAP / 360.0f); // 角速度所需要的脉冲频率
|
||||
g_tMoto.sv_pulse = (int64_t)pulse;
|
||||
|
||||
printf("[r] freq=%lu, angle=%f, pulse=%ld, sv_pulse=%lld\r\n", (unsigned long)freq, angle, (long)pulse, g_tMoto.sv_pulse);
|
||||
printf("TIM6 before start: PSC=%u, ARR=%u\r\n", TIM6->PSC, TIM6->ARR);
|
||||
|
||||
if (g_tMoto.pv_pulse < g_tMoto.sv_pulse)
|
||||
{
|
||||
MOTO_Start(freq, 0, 123);
|
||||
}
|
||||
else if (g_tMoto.pv_pulse > g_tMoto.sv_pulse)
|
||||
{
|
||||
MOTO_Start(freq, 1, 123);
|
||||
}
|
||||
else
|
||||
{
|
||||
BEEP_Start(1500, 5, 5, 3);
|
||||
}
|
||||
printf("TIM6 after start: PSC=%u, ARR=%u\r\n", TIM6->PSC, TIM6->ARR);
|
||||
}
|
||||
else if (sscanf((char *)g_RxBuf, "[rr:%f:%f]", &freq, &angle) == 2)
|
||||
{
|
||||
if (pulse < 0.01f)
|
||||
pulse = 0.01f;
|
||||
else if (pulse > MAX_SPEED)
|
||||
pulse = MAX_SPEED;
|
||||
pulse = (angle / 360) * STEP_PER_LAP; // angle所有需要的脉冲
|
||||
freq = freq * (STEP_PER_LAP / 360.0f); // 角速度所需要的脉冲频率
|
||||
g_tMoto.sv_pulse += (int64_t)pulse;
|
||||
|
||||
printf("[rr] freq=%lu, angle=%f, pulse=%ld, sv_pulse=%lld\r\n", (unsigned long)freq, angle, (long)pulse, g_tMoto.sv_pulse);
|
||||
printf("TIM6 before start: PSC=%u, ARR=%u\r\n", TIM6->PSC, TIM6->ARR);
|
||||
|
||||
if (g_tMoto.pv_pulse < g_tMoto.sv_pulse)
|
||||
{
|
||||
MOTO_Start(freq, 0, 123);
|
||||
}
|
||||
else if (g_tMoto.pv_pulse > g_tMoto.sv_pulse)
|
||||
{
|
||||
MOTO_Start(freq, 1, 123);
|
||||
}
|
||||
else
|
||||
{
|
||||
BEEP_Start(1500, 5, 5, 3);
|
||||
}
|
||||
printf("TIM6 after start: PSC=%u, ARR=%u\r\n", TIM6->PSC, TIM6->ARR);
|
||||
}
|
||||
else
|
||||
{
|
||||
BEEP_Start(1500, 5, 5, 3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BEEP_Start(1500, 5, 5, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------- End of file ---------------------------------
|
||||
Reference in New Issue
Block a user