init
This commit is contained in:
85
HARDWARE/DataScope_DP.C
Normal file
85
HARDWARE/DataScope_DP.C
Normal file
@@ -0,0 +1,85 @@
|
||||
#include "DataScope_DP.h"
|
||||
unsigned char DataScope_OutPut_Buffer[42] = {0}; //串口发送缓冲区
|
||||
|
||||
|
||||
//函数说明:将单精度浮点数据转成4字节数据并存入指定地址
|
||||
//附加说明:用户无需直接操作此函数
|
||||
//target:目标单精度数据
|
||||
//buf:待写入数组
|
||||
//beg:指定从数组第几个元素开始写入
|
||||
//函数无返回
|
||||
void Float2Byte(float *target,unsigned char *buf,unsigned char beg)
|
||||
{
|
||||
unsigned char *point;
|
||||
point = (unsigned char*)target; //得到float的地址
|
||||
buf[beg] = point[0];
|
||||
buf[beg+1] = point[1];
|
||||
buf[beg+2] = point[2];
|
||||
buf[beg+3] = point[3];
|
||||
}
|
||||
|
||||
|
||||
//函数说明:将待发送通道的单精度浮点数据写入发送缓冲区
|
||||
//Data:通道数据
|
||||
//Channel:选择通道(1-10)
|
||||
//函数无返回
|
||||
void DataScope_Get_Channel_Data(float Data,unsigned char Channel)
|
||||
{
|
||||
if ( (Channel > 10) || (Channel == 0) ) return; //通道个数大于10或等于0,直接跳出,不执行函数
|
||||
else
|
||||
{
|
||||
switch (Channel)
|
||||
{
|
||||
case 1: Float2Byte(&Data,DataScope_OutPut_Buffer,1); break;
|
||||
case 2: Float2Byte(&Data,DataScope_OutPut_Buffer,5); break;
|
||||
case 3: Float2Byte(&Data,DataScope_OutPut_Buffer,9); break;
|
||||
case 4: Float2Byte(&Data,DataScope_OutPut_Buffer,13); break;
|
||||
case 5: Float2Byte(&Data,DataScope_OutPut_Buffer,17); break;
|
||||
case 6: Float2Byte(&Data,DataScope_OutPut_Buffer,21); break;
|
||||
case 7: Float2Byte(&Data,DataScope_OutPut_Buffer,25); break;
|
||||
case 8: Float2Byte(&Data,DataScope_OutPut_Buffer,29); break;
|
||||
case 9: Float2Byte(&Data,DataScope_OutPut_Buffer,33); break;
|
||||
case 10: Float2Byte(&Data,DataScope_OutPut_Buffer,37); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//函数说明:生成 DataScopeV1.0 能正确识别的帧格式
|
||||
//Channel_Number,需要发送的通道个数
|
||||
//返回发送缓冲区数据个数
|
||||
//返回0表示帧格式生成失败
|
||||
unsigned char DataScope_Data_Generate(unsigned char Channel_Number)
|
||||
{
|
||||
if ( (Channel_Number > 10) || (Channel_Number == 0) ) { return 0; } //通道个数大于10或等于0,直接跳出,不执行函数
|
||||
else
|
||||
{
|
||||
DataScope_OutPut_Buffer[0] = '$'; //帧头
|
||||
|
||||
switch(Channel_Number)
|
||||
{
|
||||
case 1: DataScope_OutPut_Buffer[5] = 5; return 6;
|
||||
case 2: DataScope_OutPut_Buffer[9] = 9; return 10;
|
||||
case 3: DataScope_OutPut_Buffer[13] = 13; return 14;
|
||||
case 4: DataScope_OutPut_Buffer[17] = 17; return 18;
|
||||
case 5: DataScope_OutPut_Buffer[21] = 21; return 22;
|
||||
case 6: DataScope_OutPut_Buffer[25] = 25; return 26;
|
||||
case 7: DataScope_OutPut_Buffer[29] = 29; return 30;
|
||||
case 8: DataScope_OutPut_Buffer[33] = 33; return 34;
|
||||
case 9: DataScope_OutPut_Buffer[37] = 37; return 38;
|
||||
case 10: DataScope_OutPut_Buffer[41] = 41; return 42;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
16
HARDWARE/DataScope_DP.h
Normal file
16
HARDWARE/DataScope_DP.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef __DATA_PRTOCOL_H
|
||||
#define __DATA_PRTOCOL_H
|
||||
#include "system.h"
|
||||
|
||||
extern unsigned char DataScope_OutPut_Buffer[42]; //待发送帧数据缓存区
|
||||
|
||||
|
||||
void DataScope_Get_Channel_Data(float Data,unsigned char Channel); // 写通道数据至 待发送帧数据缓存区
|
||||
|
||||
unsigned char DataScope_Data_Generate(unsigned char Channel_Number); // 发送帧数据生成函数
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
81
HARDWARE/LED.C
Normal file
81
HARDWARE/LED.C
Normal file
@@ -0,0 +1,81 @@
|
||||
#include "led.h"
|
||||
|
||||
int Led_Count=500; //LED flicker time control //LED闪烁时间控制
|
||||
|
||||
/**************************************************************************
|
||||
Function: LED interface initialization
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:LED接口初始化
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void LED_Init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOB时钟
|
||||
GPIO_InitStructure.GPIO_Pin = LED_PIN;//LED对应IO口
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
|
||||
GPIO_SetBits(GPIOA,GPIO_Pin_12);
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Buzzer interface initialized
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:蜂鸣器接口初始化
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void Buzzer_Init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOB时钟
|
||||
GPIO_InitStructure.GPIO_Pin = Buzzer_PIN;//LED对应IO口
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: LED light flashing task
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:LED灯闪烁任务
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void led_task(void *pvParameters)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
//The status of the LED is reversed. 0 is on and 1 is off
|
||||
//LED状态取反,0是点亮,1是熄灭
|
||||
LED=~LED;
|
||||
//The LED flicker task is very simple, requires low frequency accuracy, and uses the relative delay function
|
||||
//LED闪烁任务非常简单,对频率精度要求低,使用相对延时函数
|
||||
vTaskDelay(Led_Count);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: The LED flashing
|
||||
Input : none
|
||||
Output : blink time
|
||||
函数功能:LED闪烁
|
||||
入口参数:闪烁时间
|
||||
返 回 值:无
|
||||
**************************************************************************/
|
||||
void Led_Flash(u16 time)
|
||||
{
|
||||
static int temp;
|
||||
if(0==time) LED=0;
|
||||
else if(++temp==time) LED=~LED,temp=0;
|
||||
}
|
||||
|
||||
27
HARDWARE/LED.H
Normal file
27
HARDWARE/LED.H
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef __LED_H
|
||||
#define __LED_H
|
||||
#include "sys.h"
|
||||
#include "system.h"
|
||||
|
||||
#define LED_TASK_PRIO 3 //Task priority //任务优先级
|
||||
#define LED_STK_SIZE 128 //Task stack size //任务堆栈大小
|
||||
|
||||
|
||||
/*--------Buzzer control pin--------*/
|
||||
#define Buzzer_PORT GPIOA
|
||||
#define Buzzer_PIN GPIO_Pin_8
|
||||
#define Buzzer PAout(8)
|
||||
/*----------------------------------*/
|
||||
|
||||
/*--------LED control pin--------*/
|
||||
#define LED_PORT GPIOA
|
||||
#define LED_PIN GPIO_Pin_12
|
||||
#define LED PAout(12)
|
||||
/*----------------------------------*/
|
||||
|
||||
void LED_Init(void);
|
||||
void Buzzer_Init(void);
|
||||
void Led_Flash(u16 time);
|
||||
void led_task(void *pvParameters);
|
||||
extern int Led_Count;
|
||||
#endif
|
||||
352
HARDWARE/MPU6050/I2C.c
Normal file
352
HARDWARE/MPU6050/I2C.c
Normal file
@@ -0,0 +1,352 @@
|
||||
#include "I2C.h"
|
||||
/**************************************************************************
|
||||
Function: IIC pin initialization
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:IIC引脚初始化
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void I2C_GPIOInit(void)
|
||||
{
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOB时钟
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
|
||||
|
||||
IIC_SCL=1;
|
||||
IIC_SDA=1;
|
||||
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: Simulate IIC start signal
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:模拟IIC起始信号
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void I2C_Start(void)
|
||||
{
|
||||
SDA_OUT(); //sda线输出
|
||||
IIC_SDA=1;
|
||||
if(!READ_SDA)return ;
|
||||
IIC_SCL=1;
|
||||
delay_us(1);
|
||||
IIC_SDA=0;//START:when CLK is high,DATA change form high to low
|
||||
if(READ_SDA)return ;
|
||||
delay_us(1);
|
||||
IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
|
||||
return ;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: Analog IIC end signal
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:模拟IIC结束信号
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void I2C_Stop(void)
|
||||
{
|
||||
SDA_OUT();//sda线输出
|
||||
IIC_SCL=0;
|
||||
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
|
||||
delay_us(1);
|
||||
IIC_SCL=1;
|
||||
IIC_SDA=1;//发送I2C总线结束信号
|
||||
delay_us(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool I2C_WaiteForAck(void)
|
||||
{
|
||||
u8 ucErrTime=0;
|
||||
SDA_IN(); //SDA设置为输入
|
||||
IIC_SDA=1;
|
||||
delay_us(1);
|
||||
IIC_SCL=1;
|
||||
delay_us(1);
|
||||
while(READ_SDA)
|
||||
{
|
||||
ucErrTime++;
|
||||
if(ucErrTime>50)
|
||||
{
|
||||
I2C_Stop();
|
||||
return 0;
|
||||
}
|
||||
delay_us(1);
|
||||
}
|
||||
IIC_SCL=0;//时钟输出0
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: IIC response
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:IIC应答
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void I2C_Ack(void)
|
||||
{
|
||||
IIC_SCL=0;
|
||||
SDA_OUT();
|
||||
IIC_SDA=0;
|
||||
delay_us(1);
|
||||
IIC_SCL=1;
|
||||
delay_us(1);
|
||||
IIC_SCL=0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: IIC don't reply
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:IIC不应答
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void I2C_NAck(void)
|
||||
{
|
||||
IIC_SCL=0;
|
||||
SDA_OUT();
|
||||
IIC_SDA=1;
|
||||
delay_us(1);
|
||||
IIC_SCL=1;
|
||||
delay_us(1);
|
||||
IIC_SCL=0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool I2C_WriteOneBit(uint8_t DevAddr, uint8_t RegAddr, uint8_t BitNum, uint8_t Data)
|
||||
{
|
||||
uint8_t Dat;
|
||||
|
||||
Dat =I2C_ReadOneByte(DevAddr, RegAddr);
|
||||
Dat = (Data != 0) ? (Dat | (1 << BitNum)) : (Dat & ~(1 << BitNum));
|
||||
I2C_WriteOneByte(DevAddr, RegAddr, Dat);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool I2C_WriteBits(uint8_t DevAddr, uint8_t RegAddr, uint8_t BitStart, uint8_t Length, uint8_t Data)
|
||||
{
|
||||
|
||||
uint8_t Dat, Mask;
|
||||
|
||||
Dat = I2C_ReadOneByte(DevAddr, RegAddr);
|
||||
Mask = (0xFF << (BitStart + 1)) | 0xFF >> ((8 - BitStart) + Length - 1);
|
||||
Data <<= (8 - Length);
|
||||
Data >>= (7 - BitStart);
|
||||
Dat &= Mask;
|
||||
Dat |= Data;
|
||||
I2C_WriteOneByte(DevAddr, RegAddr, Dat);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: IIC sends a bit
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:IIC发送一个位
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void I2C_WriteByte(uint8_t Data)
|
||||
{
|
||||
u8 t;
|
||||
SDA_OUT();
|
||||
IIC_SCL=0;//拉低时钟开始数据传输
|
||||
for(t=0;t<8;t++)
|
||||
{
|
||||
IIC_SDA=(Data&0x80)>>7;
|
||||
Data<<=1;
|
||||
delay_us(1);
|
||||
IIC_SCL=1;
|
||||
delay_us(1);
|
||||
IIC_SCL=0;
|
||||
delay_us(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
u8 I2C_WriteOneByte(uint8_t DevAddr, uint8_t RegAddr, uint8_t Data)
|
||||
{
|
||||
I2C_Start();
|
||||
I2C_WriteByte(DevAddr | I2C_Direction_Transmitter);
|
||||
I2C_WaiteForAck();
|
||||
I2C_WriteByte(RegAddr);
|
||||
I2C_WaiteForAck();
|
||||
I2C_WriteByte(Data);
|
||||
I2C_WaiteForAck();
|
||||
I2C_Stop();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
bool I2C_WriteBuff(uint8_t DevAddr, uint8_t RegAddr, uint8_t Num, uint8_t *pBuff)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
if(0 == Num || NULL == pBuff)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
I2C_Start();
|
||||
I2C_WriteByte(DevAddr | I2C_Direction_Transmitter);
|
||||
I2C_WaiteForAck();
|
||||
I2C_WriteByte(RegAddr);
|
||||
I2C_WaiteForAck();
|
||||
|
||||
for(i = 0; i < Num; i ++)
|
||||
{
|
||||
I2C_WriteByte(*(pBuff + i));
|
||||
I2C_WaiteForAck();
|
||||
}
|
||||
I2C_Stop();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: IIC reads a bit
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:IIC读取一个位
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
uint8_t I2C_ReadByte(uint8_t Ack)
|
||||
{
|
||||
uint8_t i, RecDat = 0;
|
||||
|
||||
SDA_IN();
|
||||
for(i = 0; i < 8; i ++)
|
||||
{
|
||||
// I2C_SCL_Clr();
|
||||
IIC_SCL=0;
|
||||
delay_us(1);
|
||||
// I2C_SCL_Set();
|
||||
IIC_SCL=1;
|
||||
RecDat <<= 1;
|
||||
if(READ_SDA)
|
||||
RecDat |= 0x01;
|
||||
else
|
||||
RecDat &= ~0x01;
|
||||
delay_us(1);
|
||||
}
|
||||
if(I2C_ACK == Ack)
|
||||
I2C_Ack();
|
||||
else
|
||||
I2C_NAck();
|
||||
|
||||
return RecDat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
uint8_t I2C_ReadOneByte(uint8_t DevAddr, uint8_t RegAddr)
|
||||
{
|
||||
uint8_t TempVal = 0;
|
||||
|
||||
I2C_Start();
|
||||
I2C_WriteByte(DevAddr | I2C_Direction_Transmitter);
|
||||
I2C_WaiteForAck();
|
||||
I2C_WriteByte(RegAddr);
|
||||
I2C_WaiteForAck();
|
||||
I2C_Start();
|
||||
I2C_WriteByte(DevAddr | I2C_Direction_Receiver);
|
||||
I2C_WaiteForAck();
|
||||
TempVal = I2C_ReadByte(I2C_NACK);
|
||||
I2C_Stop();
|
||||
|
||||
return TempVal;
|
||||
}
|
||||
|
||||
bool I2C_ReadBuff(uint8_t DevAddr, uint8_t RegAddr, uint8_t Num, uint8_t *pBuff)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
if(0 == Num || NULL == pBuff)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
I2C_Start();
|
||||
I2C_WriteByte(DevAddr | I2C_Direction_Transmitter);
|
||||
I2C_WaiteForAck();
|
||||
I2C_WriteByte(RegAddr);
|
||||
I2C_WaiteForAck();
|
||||
I2C_Start();
|
||||
I2C_WriteByte(DevAddr | I2C_Direction_Receiver);
|
||||
I2C_WaiteForAck();
|
||||
|
||||
for(i = 0; i < Num; i ++)
|
||||
{
|
||||
if((Num - 1) == i)
|
||||
{
|
||||
*(pBuff + i) = I2C_ReadByte(I2C_NACK);
|
||||
}
|
||||
else
|
||||
{
|
||||
*(pBuff + i) = I2C_ReadByte(I2C_ACK);
|
||||
}
|
||||
}
|
||||
|
||||
I2C_Stop();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
///**************************************************************************
|
||||
//Function: IIC continuous reading data
|
||||
//Input : dev:Target device IIC address;reg:Register address;
|
||||
// length:Number of bytes;*data:The pointer where the read data will be stored
|
||||
//Output : count:Number of bytes read out-1
|
||||
//函数功能:IIC连续读数据
|
||||
//入口参数:dev:目标设备IIC地址;reg:寄存器地址;length:字节数;
|
||||
// *data:读出的数据将要存放的指针
|
||||
//返回 值:count:读出来的字节数量-1
|
||||
//**************************************************************************/
|
||||
//u8 IICreadBytes(u8 dev, u8 reg, u8 length, u8 *data){
|
||||
// u8 count = 0;
|
||||
//
|
||||
// IIC_Start();
|
||||
// IIC_Send_Byte(dev); //发送写命令
|
||||
// IIC_Wait_Ack();
|
||||
// IIC_Send_Byte(reg); //发送地址
|
||||
// IIC_Wait_Ack();
|
||||
// IIC_Start();
|
||||
// IIC_Send_Byte(dev+1); //进入接收模式
|
||||
// IIC_Wait_Ack();
|
||||
//
|
||||
// for(count=0;count<length;count++){
|
||||
//
|
||||
// if(count!=length-1) data[count]=IIC_Read_Byte(1); //带ACK的读数据
|
||||
// else data[count]=IIC_Read_Byte(0); //最后一个字节NACK
|
||||
// }
|
||||
// IIC_Stop();//产生一个停止条件
|
||||
// return count;
|
||||
//}
|
||||
|
||||
|
||||
|
||||
52
HARDWARE/MPU6050/I2C.h
Normal file
52
HARDWARE/MPU6050/I2C.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef _I2C_H_
|
||||
#define _I2C_H_
|
||||
|
||||
#include "system.h"
|
||||
#include "sys.h"
|
||||
#include "math.h"
|
||||
#include "stdbool.h"
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
|
||||
#define SDA_IN() {GPIOB->MODER&=~(3<<(11*2));GPIOB->MODER|=0<<11*2;} //PB5输入模式
|
||||
#define SDA_OUT() {GPIOB->MODER&=~(3<<(11*2));GPIOB->MODER|=1<<11*2;} //PB5输出模式
|
||||
|
||||
//IO操作函数
|
||||
#define IIC_SCL PBout(10) //SCL
|
||||
#define IIC_SDA PBout(11) //SDA
|
||||
#define READ_SDA PBin(11) //输入SDA
|
||||
|
||||
|
||||
#ifndef I2C_Direction_Transmitter
|
||||
#define I2C_Direction_Transmitter ((uint8_t)0x00)
|
||||
#endif
|
||||
|
||||
#ifndef I2C_Direction_Receiver
|
||||
#define I2C_Direction_Receiver ((uint8_t)0x01)
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
I2C_ACK,
|
||||
I2C_NACK
|
||||
};
|
||||
|
||||
void I2C_SDAMode(uint8_t Mode);
|
||||
void I2C_Start(void);
|
||||
void I2C_Stop(void);
|
||||
bool I2C_WaiteForAck(void);
|
||||
void I2C_Ack(void);
|
||||
void I2C_NAck(void);
|
||||
bool I2C_WriteOneBit(uint8_t DevAddr, uint8_t RegAddr, uint8_t BitNum, uint8_t Data);
|
||||
bool I2C_WriteBits(uint8_t DevAddr, uint8_t RegAddr, uint8_t BitStart, uint8_t Length, uint8_t Data);
|
||||
void I2C_WriteByte(uint8_t Data);
|
||||
uint8_t I2C_ReadByte(uint8_t Ack);
|
||||
u8 I2C_WriteOneByte(uint8_t DevAddr, uint8_t RegAddr, uint8_t Data);
|
||||
uint8_t I2C_ReadOneByte(uint8_t DevAddr, uint8_t RegAddr);
|
||||
bool I2C_WriteBuff(uint8_t DevAddr, uint8_t RegAddr, uint8_t Num, uint8_t *pBuff);
|
||||
bool I2C_ReadBuff(uint8_t DevAddr, uint8_t RegAddr, uint8_t Num, uint8_t *pBuff);
|
||||
|
||||
void I2C_GPIOInit(void);
|
||||
|
||||
#endif
|
||||
|
||||
545
HARDWARE/MPU6050/MPU6050.c
Normal file
545
HARDWARE/MPU6050/MPU6050.c
Normal file
@@ -0,0 +1,545 @@
|
||||
#include "MPU6050.h"
|
||||
#include "I2C.h"
|
||||
#include "usart.h"
|
||||
#define PRINT_ACCEL (0x01)
|
||||
#define PRINT_GYRO (0x02)
|
||||
#define PRINT_QUAT (0x04)
|
||||
#define ACCEL_ON (0x01)
|
||||
#define GYRO_ON (0x02)
|
||||
#define MOTION (0)
|
||||
#define NO_MOTION (1)
|
||||
#define DEFAULT_MPU_HZ (200)
|
||||
#define FLASH_SIZE (512)
|
||||
#define FLASH_MEM_START ((void*)0x1800)
|
||||
#define q30 1073741824.0f
|
||||
short gyro[3], accel[3], sensors;
|
||||
//零点漂移计数
|
||||
int Deviation_Count;
|
||||
|
||||
short sum_gyro[3];
|
||||
short sum_accel[3];
|
||||
|
||||
// Gyro static error, raw data
|
||||
//陀螺仪静差,原始数据
|
||||
short Deviation_gyro[3],Original_gyro[3];
|
||||
short Deviation_accel[3],Original_accel[3];
|
||||
float q0=1.0f,q1=0.0f,q2=0.0f,q3=0.0f;
|
||||
//static signed char gyro_orientation[9] = {-1, 0, 0,
|
||||
// 0,-1, 0,
|
||||
// 0, 0, 1};
|
||||
|
||||
//static unsigned short inv_row_2_scale(const signed char *row)
|
||||
//{
|
||||
// unsigned short b;
|
||||
|
||||
// if (row[0] > 0)
|
||||
// b = 0;
|
||||
// else if (row[0] < 0)
|
||||
// b = 4;
|
||||
// else if (row[1] > 0)
|
||||
// b = 1;
|
||||
// else if (row[1] < 0)
|
||||
// b = 5;
|
||||
// else if (row[2] > 0)
|
||||
// b = 2;
|
||||
// else if (row[2] < 0)
|
||||
// b = 6;
|
||||
// else
|
||||
// b = 7; // error
|
||||
// return b;
|
||||
//}
|
||||
|
||||
void MPU6050_task(void *pvParameters)
|
||||
{
|
||||
u32 lastWakeTime = getSysTickCnt();
|
||||
while(1)
|
||||
{
|
||||
//This task runs at 100Hz
|
||||
//此任务以100Hz的频率运行
|
||||
vTaskDelayUntil(&lastWakeTime, F2T(RATE_100_HZ));
|
||||
|
||||
//Read the gyroscope zero before starting
|
||||
//开机前,读取陀螺仪零点
|
||||
if(Deviation_Count<CONTROL_DELAY)
|
||||
{
|
||||
Deviation_Count++;
|
||||
sum_gyro[0]+=gyro[0];
|
||||
sum_gyro[1]+=gyro[1];
|
||||
sum_gyro[2]+=gyro[2];
|
||||
sum_accel[0]+=accel[0];
|
||||
sum_accel[1]+=accel[1];
|
||||
sum_accel[2]+=accel[2];
|
||||
for(int i=0;i<3;i++)
|
||||
{
|
||||
Deviation_gyro[i] = (short)(sum_gyro[i] / (short)Deviation_Count);
|
||||
}
|
||||
|
||||
// memcpy(Deviation_gyro,gyro,sizeof(gyro));
|
||||
memcpy(Deviation_accel,accel,sizeof(accel));
|
||||
}
|
||||
|
||||
MPU_Get_Gyroscope(); //得到陀螺仪数据
|
||||
MPU_Get_Accelscope(); //获得加速度计值(原始值)
|
||||
}
|
||||
}
|
||||
|
||||
//static unsigned short inv_orientation_matrix_to_scalar(
|
||||
// const signed char *mtx)
|
||||
//{
|
||||
// unsigned short scalar;
|
||||
// scalar = inv_row_2_scale(mtx);
|
||||
// scalar |= inv_row_2_scale(mtx + 3) << 3;
|
||||
// scalar |= inv_row_2_scale(mtx + 6) << 6;
|
||||
|
||||
|
||||
// return scalar;
|
||||
//}
|
||||
|
||||
//static void run_self_test(void)
|
||||
//{
|
||||
// int result;
|
||||
// long gyro[3], accel[3];
|
||||
|
||||
// result = mpu_run_self_test(gyro, accel);
|
||||
// if (result == 0x7) {
|
||||
// /* Test passed. We can trust the gyro data here, so let's push it down
|
||||
// * to the DMP.
|
||||
// */
|
||||
// float sens;
|
||||
// unsigned short accel_sens;
|
||||
// mpu_get_gyro_sens(&sens);
|
||||
// gyro[0] = (long)(gyro[0] * sens);
|
||||
// gyro[1] = (long)(gyro[1] * sens);
|
||||
// gyro[2] = (long)(gyro[2] * sens);
|
||||
// dmp_set_gyro_bias(gyro);
|
||||
// mpu_get_accel_sens(&accel_sens);
|
||||
// accel[0] *= accel_sens;
|
||||
// accel[1] *= accel_sens;
|
||||
// accel[2] *= accel_sens;
|
||||
// dmp_set_accel_bias(accel);
|
||||
// //printf("setting bias succesfully ......\r\n");
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
|
||||
uint8_t buffer[14];
|
||||
|
||||
int16_t MPU6050_FIFO[6][11];
|
||||
int16_t Gx_offset=0,Gy_offset=0,Gz_offset=0;
|
||||
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
Function: The new ADC data is updated to FIFO array for filtering
|
||||
Input : ax,ay,az:x,y, z-axis acceleration data;gx,gy,gz:x. Y, z-axis angular acceleration data
|
||||
Output : none
|
||||
函数功能:将新的ADC数据更新到 FIFO数组,进行滤波处理
|
||||
入口参数:ax,ay,az:x,y,z轴加速度数据;gx,gy,gz:x,y,z轴角加速度数据
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void MPU6050_newValues(int16_t ax,int16_t ay,int16_t az,int16_t gx,int16_t gy,int16_t gz)
|
||||
{
|
||||
unsigned char i ;
|
||||
int32_t sum=0;
|
||||
for(i=1;i<10;i++){ //FIFO 操作
|
||||
MPU6050_FIFO[0][i-1]=MPU6050_FIFO[0][i];
|
||||
MPU6050_FIFO[1][i-1]=MPU6050_FIFO[1][i];
|
||||
MPU6050_FIFO[2][i-1]=MPU6050_FIFO[2][i];
|
||||
MPU6050_FIFO[3][i-1]=MPU6050_FIFO[3][i];
|
||||
MPU6050_FIFO[4][i-1]=MPU6050_FIFO[4][i];
|
||||
MPU6050_FIFO[5][i-1]=MPU6050_FIFO[5][i];
|
||||
}
|
||||
MPU6050_FIFO[0][9]=ax;//将新的数据放置到 数据的最后面
|
||||
MPU6050_FIFO[1][9]=ay;
|
||||
MPU6050_FIFO[2][9]=az;
|
||||
MPU6050_FIFO[3][9]=gx;
|
||||
MPU6050_FIFO[4][9]=gy;
|
||||
MPU6050_FIFO[5][9]=gz;
|
||||
|
||||
sum=0;
|
||||
for(i=0;i<10;i++){ //求当前数组的合,再取平均值
|
||||
sum+=MPU6050_FIFO[0][i];
|
||||
}
|
||||
MPU6050_FIFO[0][10]=sum/10;
|
||||
|
||||
sum=0;
|
||||
for(i=0;i<10;i++){
|
||||
sum+=MPU6050_FIFO[1][i];
|
||||
}
|
||||
MPU6050_FIFO[1][10]=sum/10;
|
||||
|
||||
sum=0;
|
||||
for(i=0;i<10;i++){
|
||||
sum+=MPU6050_FIFO[2][i];
|
||||
}
|
||||
MPU6050_FIFO[2][10]=sum/10;
|
||||
|
||||
sum=0;
|
||||
for(i=0;i<10;i++){
|
||||
sum+=MPU6050_FIFO[3][i];
|
||||
}
|
||||
MPU6050_FIFO[3][10]=sum/10;
|
||||
|
||||
sum=0;
|
||||
for(i=0;i<10;i++){
|
||||
sum+=MPU6050_FIFO[4][i];
|
||||
}
|
||||
MPU6050_FIFO[4][10]=sum/10;
|
||||
|
||||
sum=0;
|
||||
for(i=0;i<10;i++){
|
||||
sum+=MPU6050_FIFO[5][i];
|
||||
}
|
||||
MPU6050_FIFO[5][10]=sum/10;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: Setting the clock source of mpu6050
|
||||
Input : source:Clock source number
|
||||
Output : none
|
||||
函数功能:设置 MPU6050 的时钟源
|
||||
入口参数:source:时钟源编号
|
||||
返回 值:无
|
||||
* CLK_SEL | Clock Source
|
||||
* --------+--------------------------------------
|
||||
* 0 | Internal oscillator
|
||||
* 1 | PLL with X Gyro reference
|
||||
* 2 | PLL with Y Gyro reference
|
||||
* 3 | PLL with Z Gyro reference
|
||||
* 4 | PLL with external 32.768kHz reference
|
||||
* 5 | PLL with external 19.2MHz reference
|
||||
* 6 | Reserved
|
||||
* 7 | Stops the clock and keeps the timing generator in reset
|
||||
**************************************************************************/
|
||||
void MPU6050_setClockSource(uint8_t source){
|
||||
I2C_WriteBits(devAddr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_CLKSEL_BIT, MPU6050_PWR1_CLKSEL_LENGTH, source);
|
||||
|
||||
}
|
||||
|
||||
/** Set full-scale gyroscope range.
|
||||
* @param range New full-scale gyroscope range value
|
||||
* @see getFullScaleRange()
|
||||
* @see MPU6050_GYRO_FS_250
|
||||
* @see MPU6050_RA_GYRO_CONFIG
|
||||
* @see MPU6050_GCONFIG_FS_SEL_BIT
|
||||
* @see MPU6050_GCONFIG_FS_SEL_LENGTH
|
||||
*/
|
||||
void MPU6050_setFullScaleGyroRange(uint8_t range) {
|
||||
I2C_WriteBits(devAddr, MPU6050_RA_GYRO_CONFIG, MPU6050_GCONFIG_FS_SEL_BIT, MPU6050_GCONFIG_FS_SEL_LENGTH, range);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: Setting the maximum range of mpu6050 accelerometer
|
||||
Input : range:Acceleration maximum range number
|
||||
Output : none
|
||||
函数功能:设置 MPU6050 加速度计的最大量程
|
||||
入口参数:range:加速度最大量程编号
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
//#define MPU6050_ACCEL_FS_2 0x00 //===最大量程+-2G
|
||||
//#define MPU6050_ACCEL_FS_4 0x01 //===最大量程+-4G
|
||||
//#define MPU6050_ACCEL_FS_8 0x02 //===最大量程+-8G
|
||||
//#define MPU6050_ACCEL_FS_16 0x03 //===最大量程+-16G
|
||||
void MPU6050_setFullScaleAccelRange(uint8_t range) {
|
||||
I2C_WriteBits(devAddr, MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_AFS_SEL_BIT, MPU6050_ACONFIG_AFS_SEL_LENGTH, range);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: Set mpu6050 to sleep mode or not
|
||||
Input : enable:1,sleep;0,work;
|
||||
Output : none
|
||||
函数功能:设置 MPU6050 是否进入睡眠模式
|
||||
入口参数:enable:1,睡觉;0,工作;
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void MPU6050_setSleepEnabled(uint8_t enabled) {
|
||||
I2C_WriteOneBit(devAddr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_SLEEP_BIT, enabled);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: Read identity
|
||||
Input : none
|
||||
Output : 0x68
|
||||
函数功能:读取 MPU6050 WHO_AM_I 标识
|
||||
入口参数:无
|
||||
返回 值:0x68
|
||||
**************************************************************************/
|
||||
uint8_t MPU6050_getDeviceID(void) {
|
||||
|
||||
|
||||
return I2C_ReadOneByte(devAddr,MPU6050_RA_WHO_AM_I);
|
||||
|
||||
// IICreadBytes(devAddr, MPU6050_RA_WHO_AM_I, 1, buffer);
|
||||
// return buffer[0];
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: Check whether mpu6050 is connected
|
||||
Input : none
|
||||
Output : 1:Connected;0:Not connected
|
||||
函数功能:检测MPU6050 是否已经连接
|
||||
入口参数:无
|
||||
返回 值:1:已连接;0:未连接
|
||||
**************************************************************************/
|
||||
uint8_t MPU6050_testConnection(void) {
|
||||
if(MPU6050_getDeviceID() == 0x68) //0b01101000;
|
||||
return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: Setting whether mpu6050 is the host of aux I2C cable
|
||||
Input : enable:1,yes;0;not
|
||||
Output : none
|
||||
函数功能:设置 MPU6050 是否为AUX I2C线的主机
|
||||
入口参数:enable:1,是;0:否
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void MPU6050_setI2CMasterModeEnabled(uint8_t enabled) {
|
||||
I2C_WriteOneBit(devAddr, MPU6050_RA_USER_CTRL, MPU6050_USERCTRL_I2C_MST_EN_BIT, enabled);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: Setting whether mpu6050 is the host of aux I2C cable
|
||||
Input : enable:1,yes;0;not
|
||||
Output : none
|
||||
函数功能:设置 MPU6050 是否为AUX I2C线的主机
|
||||
入口参数:enable:1,是;0:否
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void MPU6050_setI2CBypassEnabled(uint8_t enabled) {
|
||||
I2C_WriteOneBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_I2C_BYPASS_EN_BIT, enabled);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: initialization Mpu6050 to enter the available state
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:初始化 MPU6050 以进入可用状态
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
u8 MPU6050_initialize(void)
|
||||
{
|
||||
u8 res;
|
||||
//IIC_Init(); //Initialize the IIC bus //初始化IIC总线
|
||||
I2C_WriteOneByte(devAddr,MPU6050_RA_PWR_MGMT_1,0X80); //Reset MPUrobot_select_init.h //复位MPUrobot_select_init.h
|
||||
delay_ms(200); //Delay 200 ms //延时200ms
|
||||
I2C_WriteOneByte(devAddr,MPU6050_RA_PWR_MGMT_1,0X00); //Wake mpurobot_select_init.h //唤醒MPUrobot_select_init.h
|
||||
|
||||
//MPU6050_Set_Gyro_Fsr(1); //Gyroscope sensor //陀螺仪传感器,±500dps=±500°/s ±32768 (gyro/32768*500)*PI/180(rad/s)=gyro/3754.9(rad/s)
|
||||
MPU6050_setFullScaleGyroRange(MPU6050_GYRO_FS_500);
|
||||
//MPU6050_Set_Accel_Fsr(0); //Acceleration sensor //加速度传感器,±2g=±2*9.8m/s^2 ±32768 accel/32768*19.6=accel/1671.84
|
||||
MPU6050_setFullScaleAccelRange(MPU6050_ACCEL_FS_2);
|
||||
MPU6050_Set_Rate(50); //Set the sampling rate to 50Hz //设置采样率50Hz
|
||||
|
||||
I2C_WriteOneByte(devAddr,MPU6050_RA_INT_ENABLE,0X00); //Turn off all interrupts //关闭所有中断
|
||||
I2C_WriteOneByte(devAddr,MPU6050_RA_USER_CTRL,0X00); //The I2C main mode is off //I2C主模式关闭
|
||||
I2C_WriteOneByte(devAddr,MPU6050_RA_FIFO_EN,0X00); //Close the FIFO //关闭FIFO
|
||||
//The INT pin is low, enabling bypass mode to read the magnetometer directly
|
||||
//INT引脚低电平有效,开启bypass模式,可以直接读取磁力计
|
||||
I2C_WriteOneByte(devAddr,MPU6050_RA_INT_PIN_CFG,0X80);
|
||||
//Read the ID of MPU6050
|
||||
//读取MPU6050的ID
|
||||
res=I2C_ReadOneByte(devAddr,MPU6050_RA_WHO_AM_I);
|
||||
if(res==MPU6050_DEFAULT_ADDRESS) //The device ID is correct, The correct device ID depends on the AD pin //器件ID正确, 器件ID的正确取决于AD引脚
|
||||
{
|
||||
I2C_WriteOneByte(devAddr,MPU6050_RA_PWR_MGMT_1,0X01); //Set CLKSEL,PLL X axis as reference //设置CLKSEL,PLL X轴为参考
|
||||
I2C_WriteOneByte(devAddr,MPU6050_RA_PWR_MGMT_2,0X00); //Acceleration and gyroscope both work //加速度与陀螺仪都工作
|
||||
MPU6050_Set_Rate(50); //Set the sampling rate to 50Hz //设置采样率为50Hz
|
||||
}else return 1;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: Initialization of DMP in mpu6050
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:MPU6050内置DMP的初始化
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
//void DMP_Init(void)
|
||||
//{
|
||||
// u8 temp[1]={0};
|
||||
// i2cRead(0x68,0x75,1,temp);
|
||||
// printf("mpu_set_sensor complete ......\r\n");
|
||||
// if(temp[0]!=0x68)NVIC_SystemReset();
|
||||
// if(!mpu_init())
|
||||
// {
|
||||
// if(!mpu_set_sensors(INV_XYZ_GYRO | INV_XYZ_ACCEL))
|
||||
// printf("mpu_set_sensor complete ......\r\n");
|
||||
// if(!mpu_configure_fifo(INV_XYZ_GYRO | INV_XYZ_ACCEL))
|
||||
// printf("mpu_configure_fifo complete ......\r\n");
|
||||
// if(!mpu_set_sample_rate(DEFAULT_MPU_HZ))
|
||||
// printf("mpu_set_sample_rate complete ......\r\n");
|
||||
// if(!dmp_load_motion_driver_firmware())
|
||||
// printf("dmp_load_motion_driver_firmware complete ......\r\n");
|
||||
// if(!dmp_set_orientation(inv_orientation_matrix_to_scalar(gyro_orientation)))
|
||||
// printf("dmp_set_orientation complete ......\r\n");
|
||||
// if(!dmp_enable_feature(DMP_FEATURE_6X_LP_QUAT | DMP_FEATURE_TAP |
|
||||
// DMP_FEATURE_ANDROID_ORIENT | DMP_FEATURE_SEND_RAW_ACCEL | DMP_FEATURE_SEND_CAL_GYRO |
|
||||
// DMP_FEATURE_GYRO_CAL))
|
||||
// printf("dmp_enable_feature complete ......\r\n");
|
||||
// if(!dmp_set_fifo_rate(DEFAULT_MPU_HZ))
|
||||
// printf("dmp_set_fifo_rate complete ......\r\n");
|
||||
// run_self_test();
|
||||
// if(!mpu_set_dmp_state(1))
|
||||
// printf("mpu_set_dmp_state complete ......\r\n");
|
||||
// }
|
||||
|
||||
//}
|
||||
/**************************************************************************
|
||||
Function: Read the attitude information of DMP in mpu6050
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:读取MPU6050内置DMP的姿态信息
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
//void Read_DMP(void)
|
||||
//{
|
||||
// unsigned long sensor_timestamp;
|
||||
// unsigned char more;
|
||||
// long quat[4];
|
||||
|
||||
// dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors, &more); //读取DMP数据
|
||||
// if (sensors & INV_WXYZ_QUAT )
|
||||
// {
|
||||
// q0=quat[0] / q30;
|
||||
// q1=quat[1] / q30;
|
||||
// q2=quat[2] / q30;
|
||||
// q3=quat[3] / q30; //四元数
|
||||
// Roll = asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3; //计算出横滚角
|
||||
// Pitch = atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3; // 计算出俯仰角
|
||||
// Yaw = atan2(2*(q1*q2 + q0*q3),q0*q0+q1*q1-q2*q2-q3*q3) * 57.3; //计算出偏航角
|
||||
// }
|
||||
|
||||
//}
|
||||
/**************************************************************************
|
||||
Function: Read mpu6050 built-in temperature sensor data
|
||||
Input : none
|
||||
Output : Centigrade temperature
|
||||
函数功能:读取MPU6050内置温度传感器数据
|
||||
入口参数:无
|
||||
返回 值:摄氏温度
|
||||
**************************************************************************/
|
||||
int Read_Temperature(void)
|
||||
{
|
||||
float Temp;
|
||||
Temp=(I2C_ReadOneByte(devAddr,MPU6050_RA_TEMP_OUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_TEMP_OUT_L);
|
||||
if(Temp>32768) Temp-=65536; //数据类型转换
|
||||
Temp=(36.53f+Temp/340)*10; //温度放大十倍存放
|
||||
return (int)Temp;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: Initialize TIM2 as the encoder interface mode
|
||||
Input : LPF: Digital low-pass filtering frequency (Hz)
|
||||
Output : 0: Settings successful, others: Settings failed
|
||||
函数功能:设置MPUrobot_select_init.h的数字低通滤波器
|
||||
入口参数:lpf:数字低通滤波频率(Hz)
|
||||
返回 值:0:设置成功, 其他:设置失败
|
||||
**************************************************************************/
|
||||
unsigned char MPU6050_Set_LPF(u16 lpf)
|
||||
{
|
||||
u8 data=0;
|
||||
if(lpf>=188)data=1;
|
||||
else if(lpf>=98)data=2;
|
||||
else if(lpf>=42)data=3;
|
||||
else if(lpf>=20)data=4;
|
||||
else if(lpf>=10)data=5;
|
||||
else data=6;
|
||||
return I2C_WriteOneByte(devAddr,MPU6050_RA_CONFIG,data); //Set the digital lowpass filter//设置数字低通滤波器
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Initialize TIM2 as the encoder interface mode
|
||||
Input : rate:4~1000(Hz)
|
||||
Output : 0: Settings successful, others: Settings failed
|
||||
函数功能:设置MPUrobot_select_init.h的采样率(假定Fs=1KHz)
|
||||
入口参数:rate:4~1000(Hz)
|
||||
返回 值:0:设置成功, 其他:设置失败
|
||||
**************************************************************************/
|
||||
unsigned char MPU6050_Set_Rate(u16 rate)
|
||||
{
|
||||
u8 data;
|
||||
if(rate>1000)rate=1000;
|
||||
if(rate<4)rate=4;
|
||||
data=1000/rate-1;
|
||||
data=I2C_WriteOneByte(devAddr,MPU6050_RA_SMPLRT_DIV,data); //Set the digital lowpass filter//设置数字低通滤波器
|
||||
return MPU6050_Set_LPF(rate/2); //Automatically sets LPF to half of the sampling rate //自动设置LPF为采样率的一半
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: Initialize TIM2 as the encoder interface mode
|
||||
Input : Gx, Gy, Gz: raw readings (plus or minus) of the x,y, and z axes of the gyroscope
|
||||
Output : 0: success, others: error code
|
||||
函数功能:获得陀螺仪值(原始值)
|
||||
**************************************************************************/
|
||||
void MPU_Get_Gyroscope(void)
|
||||
{
|
||||
gyro[0]=(I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_XOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_XOUT_L); //读取X轴陀螺仪
|
||||
gyro[1]=(I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_YOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_YOUT_L); //读取Y轴陀螺仪
|
||||
gyro[2]=(I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_ZOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_ZOUT_L); //读取Z轴陀螺仪
|
||||
|
||||
if(Deviation_Count<CONTROL_DELAY) // 10 seconds before starting //开机前10秒
|
||||
{
|
||||
|
||||
Led_Count=1; //LED high frequency flashing //LED高频闪烁
|
||||
Flag_Stop=1; //The software fails to flag location 1 //软件失能标志位置1
|
||||
}
|
||||
else //10 seconds after starting //开机10秒后
|
||||
{
|
||||
if(Deviation_Count==CONTROL_DELAY)
|
||||
Flag_Stop=0; //The software fails to flag location 0 //软件失能标志位置0
|
||||
Led_Count=300; //The LED returns to normal flicker frequency //LED恢复正常闪烁频率
|
||||
|
||||
//Save the raw data to update zero by clicking the user button
|
||||
//保存原始数据用于单击用户按键更新零点
|
||||
Original_gyro[0] =gyro[0];
|
||||
Original_gyro[1] =gyro[1];
|
||||
Original_gyro[2]= gyro[2];
|
||||
|
||||
//Removes zero drift data
|
||||
//去除零点漂移的数据
|
||||
gyro[0] =Original_gyro[0]-Deviation_gyro[0];
|
||||
gyro[1] =Original_gyro[1]-Deviation_gyro[1];
|
||||
gyro[2]= Original_gyro[2]-Deviation_gyro[2];
|
||||
}
|
||||
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Initialize TIM2 as the encoder interface mode
|
||||
Input : Gx, Gy, Gz: raw readings (plus or minus) of the x,y, and z axes of the gyroscope
|
||||
Output : 0: success, others: error code
|
||||
函数功能:获得加速度计值(原始值)
|
||||
**************************************************************************/
|
||||
void MPU_Get_Accelscope(void)
|
||||
{
|
||||
accel[0]=(I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_XOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_XOUT_L); //读取X轴加速度计
|
||||
accel[1]=(I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_YOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_YOUT_L); //读取X轴加速度计
|
||||
accel[2]=(I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_ZOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_ZOUT_L); //读取Z轴加速度计
|
||||
|
||||
if(Deviation_Count<CONTROL_DELAY) // 10 seconds before starting //开机前10秒
|
||||
{
|
||||
|
||||
}
|
||||
else //10 seconds after starting //开机10秒后
|
||||
{
|
||||
//Save the raw data to update zero by clicking the user button
|
||||
//保存原始数据用于单击用户按键更新零点
|
||||
Original_accel[0] =accel[0];
|
||||
Original_accel[1] =accel[1];
|
||||
Original_accel[2]= accel[2];
|
||||
|
||||
//Removes zero drift data
|
||||
//去除零点漂移的数据
|
||||
accel[0] =Original_accel[0]-Deviation_accel[0];
|
||||
accel[1] =Original_accel[1]-Deviation_accel[1];
|
||||
accel[2]= Original_accel[2]-Deviation_accel[2]+16384;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------End of File----------------------------
|
||||
385
HARDWARE/MPU6050/mpu6050.h
Normal file
385
HARDWARE/MPU6050/mpu6050.h
Normal file
@@ -0,0 +1,385 @@
|
||||
#ifndef __MPU6050_H
|
||||
#define __MPU6050_H
|
||||
|
||||
#include "sys.h"
|
||||
#define devAddr 0xD0
|
||||
|
||||
#define MPU6050_ADDRESS_AD0_LOW 0x68 // address pin low (GND), default for InvenSense evaluation board
|
||||
#define MPU6050_ADDRESS_AD0_HIGH 0x69 // address pin high (VCC)
|
||||
#define MPU6050_DEFAULT_ADDRESS MPU6050_ADDRESS_AD0_LOW
|
||||
|
||||
#define MPU6050_RA_XG_OFFS_TC 0x00 //[7] PWR_MODE, [6:1] XG_OFFS_TC, [0] OTP_BNK_VLD
|
||||
#define MPU6050_RA_YG_OFFS_TC 0x01 //[7] PWR_MODE, [6:1] YG_OFFS_TC, [0] OTP_BNK_VLD
|
||||
#define MPU6050_RA_ZG_OFFS_TC 0x02 //[7] PWR_MODE, [6:1] ZG_OFFS_TC, [0] OTP_BNK_VLD
|
||||
#define MPU6050_RA_X_FINE_GAIN 0x03 //[7:0] X_FINE_GAIN
|
||||
#define MPU6050_RA_Y_FINE_GAIN 0x04 //[7:0] Y_FINE_GAIN
|
||||
#define MPU6050_RA_Z_FINE_GAIN 0x05 //[7:0] Z_FINE_GAIN
|
||||
#define MPU6050_RA_XA_OFFS_H 0x06 //[15:0] XA_OFFS
|
||||
#define MPU6050_RA_XA_OFFS_L_TC 0x07
|
||||
#define MPU6050_RA_YA_OFFS_H 0x08 //[15:0] YA_OFFS
|
||||
#define MPU6050_RA_YA_OFFS_L_TC 0x09
|
||||
#define MPU6050_RA_ZA_OFFS_H 0x0A //[15:0] ZA_OFFS
|
||||
#define MPU6050_RA_ZA_OFFS_L_TC 0x0B
|
||||
#define MPU6050_RA_XG_OFFS_USRH 0x13 //[15:0] XG_OFFS_USR
|
||||
#define MPU6050_RA_XG_OFFS_USRL 0x14
|
||||
#define MPU6050_RA_YG_OFFS_USRH 0x15 //[15:0] YG_OFFS_USR
|
||||
#define MPU6050_RA_YG_OFFS_USRL 0x16
|
||||
#define MPU6050_RA_ZG_OFFS_USRH 0x17 //[15:0] ZG_OFFS_USR
|
||||
#define MPU6050_RA_ZG_OFFS_USRL 0x18
|
||||
#define MPU6050_RA_SMPLRT_DIV 0x19
|
||||
#define MPU6050_RA_CONFIG 0x1A
|
||||
#define MPU6050_RA_GYRO_CONFIG 0x1B
|
||||
#define MPU6050_RA_ACCEL_CONFIG 0x1C
|
||||
#define MPU6050_RA_FF_THR 0x1D
|
||||
#define MPU6050_RA_FF_DUR 0x1E
|
||||
#define MPU6050_RA_MOT_THR 0x1F
|
||||
#define MPU6050_RA_MOT_DUR 0x20
|
||||
#define MPU6050_RA_ZRMOT_THR 0x21
|
||||
#define MPU6050_RA_ZRMOT_DUR 0x22
|
||||
#define MPU6050_RA_FIFO_EN 0x23
|
||||
#define MPU6050_RA_I2C_MST_CTRL 0x24
|
||||
#define MPU6050_RA_I2C_SLV0_ADDR 0x25
|
||||
#define MPU6050_RA_I2C_SLV0_REG 0x26
|
||||
# define MPU6050_RA_I2C_SLV0_CTRL 0x27
|
||||
#define MPU6050_RA_I2C_SLV1_ADDR 0x28
|
||||
#define MPU6050_RA_I2C_SLV1_REG 0x29
|
||||
#define MPU6050_RA_I2C_SLV1_CTRL 0x2A
|
||||
#define MPU6050_RA_I2C_SLV2_ADDR 0x2B
|
||||
#define MPU6050_RA_I2C_SLV2_REG 0x2C
|
||||
#define MPU6050_RA_I2C_SLV2_CTRL 0x2D
|
||||
#define MPU6050_RA_I2C_SLV3_ADDR 0x2E
|
||||
#define MPU6050_RA_I2C_SLV3_REG 0x2F
|
||||
#define MPU6050_RA_I2C_SLV3_CTRL 0x30
|
||||
#define MPU6050_RA_I2C_SLV4_ADDR 0x31
|
||||
#define MPU6050_RA_I2C_SLV4_REG 0x32
|
||||
#define MPU6050_RA_I2C_SLV4_DO 0x33
|
||||
#define MPU6050_RA_I2C_SLV4_CTRL 0x34
|
||||
#define MPU6050_RA_I2C_SLV4_DI 0x35
|
||||
#define MPU6050_RA_I2C_MST_STATUS 0x36
|
||||
#define MPU6050_RA_INT_PIN_CFG 0x37
|
||||
#define MPU6050_RA_INT_ENABLE 0x38
|
||||
#define MPU6050_RA_DMP_INT_STATUS 0x39
|
||||
#define MPU6050_RA_INT_STATUS 0x3A
|
||||
#define MPU6050_RA_ACCEL_XOUT_H 0x3B
|
||||
#define MPU6050_RA_ACCEL_XOUT_L 0x3C
|
||||
#define MPU6050_RA_ACCEL_YOUT_H 0x3D
|
||||
#define MPU6050_RA_ACCEL_YOUT_L 0x3E
|
||||
#define MPU6050_RA_ACCEL_ZOUT_H 0x3F
|
||||
#define MPU6050_RA_ACCEL_ZOUT_L 0x40
|
||||
#define MPU6050_RA_TEMP_OUT_H 0x41
|
||||
#define MPU6050_RA_TEMP_OUT_L 0x42
|
||||
#define MPU6050_RA_GYRO_XOUT_H 0x43
|
||||
#define MPU6050_RA_GYRO_XOUT_L 0x44
|
||||
#define MPU6050_RA_GYRO_YOUT_H 0x45
|
||||
#define MPU6050_RA_GYRO_YOUT_L 0x46
|
||||
#define MPU6050_RA_GYRO_ZOUT_H 0x47
|
||||
#define MPU6050_RA_GYRO_ZOUT_L 0x48
|
||||
#define MPU6050_RA_EXT_SENS_DATA_00 0x49
|
||||
#define MPU6050_RA_EXT_SENS_DATA_01 0x4A
|
||||
#define MPU6050_RA_EXT_SENS_DATA_02 0x4B
|
||||
#define MPU6050_RA_EXT_SENS_DATA_03 0x4C
|
||||
#define MPU6050_RA_EXT_SENS_DATA_04 0x4D
|
||||
#define MPU6050_RA_EXT_SENS_DATA_05 0x4E
|
||||
#define MPU6050_RA_EXT_SENS_DATA_06 0x4F
|
||||
#define MPU6050_RA_EXT_SENS_DATA_07 0x50
|
||||
#define MPU6050_RA_EXT_SENS_DATA_08 0x51
|
||||
#define MPU6050_RA_EXT_SENS_DATA_09 0x52
|
||||
#define MPU6050_RA_EXT_SENS_DATA_10 0x53
|
||||
#define MPU6050_RA_EXT_SENS_DATA_11 0x54
|
||||
#define MPU6050_RA_EXT_SENS_DATA_12 0x55
|
||||
#define MPU6050_RA_EXT_SENS_DATA_13 0x56
|
||||
#define MPU6050_RA_EXT_SENS_DATA_14 0x57
|
||||
#define MPU6050_RA_EXT_SENS_DATA_15 0x58
|
||||
#define MPU6050_RA_EXT_SENS_DATA_16 0x59
|
||||
#define MPU6050_RA_EXT_SENS_DATA_17 0x5A
|
||||
#define MPU6050_RA_EXT_SENS_DATA_18 0x5B
|
||||
#define MPU6050_RA_EXT_SENS_DATA_19 0x5C
|
||||
#define MPU6050_RA_EXT_SENS_DATA_20 0x5D
|
||||
#define MPU6050_RA_EXT_SENS_DATA_21 0x5E
|
||||
#define MPU6050_RA_EXT_SENS_DATA_22 0x5F
|
||||
#define MPU6050_RA_EXT_SENS_DATA_23 0x60
|
||||
#define MPU6050_RA_MOT_DETECT_STATUS 0x61
|
||||
#define MPU6050_RA_I2C_SLV0_DO 0x63
|
||||
#define MPU6050_RA_I2C_SLV1_DO 0x64
|
||||
#define MPU6050_RA_I2C_SLV2_DO 0x65
|
||||
#define MPU6050_RA_I2C_SLV3_DO 0x66
|
||||
#define MPU6050_RA_I2C_MST_DELAY_CTRL 0x67
|
||||
#define MPU6050_RA_SIGNAL_PATH_RESET 0x68
|
||||
#define MPU6050_RA_MOT_DETECT_CTRL 0x69
|
||||
#define MPU6050_RA_USER_CTRL 0x6A
|
||||
#define MPU6050_RA_PWR_MGMT_1 0x6B
|
||||
#define MPU6050_RA_PWR_MGMT_2 0x6C
|
||||
#define MPU6050_RA_BANK_SEL 0x6D
|
||||
#define MPU6050_RA_MEM_START_ADDR 0x6E
|
||||
#define MPU6050_RA_MEM_R_W 0x6F
|
||||
#define MPU6050_RA_DMP_CFG_1 0x70
|
||||
#define MPU6050_RA_DMP_CFG_2 0x71
|
||||
#define MPU6050_RA_FIFO_COUNTH 0x72
|
||||
#define MPU6050_RA_FIFO_COUNTL 0x73
|
||||
#define MPU6050_RA_FIFO_R_W 0x74
|
||||
#define MPU6050_RA_WHO_AM_I 0x75
|
||||
|
||||
#define MPU6050_TC_PWR_MODE_BIT 7
|
||||
#define MPU6050_TC_OFFSET_BIT 6
|
||||
#define MPU6050_TC_OFFSET_LENGTH 6
|
||||
#define MPU6050_TC_OTP_BNK_VLD_BIT 0
|
||||
|
||||
#define MPU6050_VDDIO_LEVEL_VLOGIC 0
|
||||
#define MPU6050_VDDIO_LEVEL_VDD 1
|
||||
|
||||
#define MPU6050_CFG_EXT_SYNC_SET_BIT 5
|
||||
#define MPU6050_CFG_EXT_SYNC_SET_LENGTH 3
|
||||
#define MPU6050_CFG_DLPF_CFG_BIT 2
|
||||
#define MPU6050_CFG_DLPF_CFG_LENGTH 3
|
||||
|
||||
#define MPU6050_EXT_SYNC_DISABLED 0x0
|
||||
#define MPU6050_EXT_SYNC_TEMP_OUT_L 0x1
|
||||
#define MPU6050_EXT_SYNC_GYRO_XOUT_L 0x2
|
||||
#define MPU6050_EXT_SYNC_GYRO_YOUT_L 0x3
|
||||
#define MPU6050_EXT_SYNC_GYRO_ZOUT_L 0x4
|
||||
#define MPU6050_EXT_SYNC_ACCEL_XOUT_L 0x5
|
||||
#define MPU6050_EXT_SYNC_ACCEL_YOUT_L 0x6
|
||||
#define MPU6050_EXT_SYNC_ACCEL_ZOUT_L 0x7
|
||||
|
||||
#define MPU6050_DLPF_BW_256 0x00
|
||||
#define MPU6050_DLPF_BW_188 0x01
|
||||
#define MPU6050_DLPF_BW_98 0x02
|
||||
#define MPU6050_DLPF_BW_42 0x03
|
||||
#define MPU6050_DLPF_BW_20 0x04
|
||||
#define MPU6050_DLPF_BW_10 0x05
|
||||
#define MPU6050_DLPF_BW_5 0x06
|
||||
|
||||
#define MPU6050_GCONFIG_FS_SEL_BIT 4
|
||||
#define MPU6050_GCONFIG_FS_SEL_LENGTH 2
|
||||
|
||||
#define MPU6050_GYRO_FS_250 0x00
|
||||
#define MPU6050_GYRO_FS_500 0x01
|
||||
#define MPU6050_GYRO_FS_1000 0x02
|
||||
#define MPU6050_GYRO_FS_2000 0x03
|
||||
|
||||
#define MPU6050_ACONFIG_XA_ST_BIT 7
|
||||
#define MPU6050_ACONFIG_YA_ST_BIT 6
|
||||
#define MPU6050_ACONFIG_ZA_ST_BIT 5
|
||||
#define MPU6050_ACONFIG_AFS_SEL_BIT 4
|
||||
#define MPU6050_ACONFIG_AFS_SEL_LENGTH 2
|
||||
#define MPU6050_ACONFIG_ACCEL_HPF_BIT 2
|
||||
#define MPU6050_ACONFIG_ACCEL_HPF_LENGTH 3
|
||||
|
||||
#define MPU6050_ACCEL_FS_2 0x00
|
||||
#define MPU6050_ACCEL_FS_4 0x01
|
||||
#define MPU6050_ACCEL_FS_8 0x02
|
||||
#define MPU6050_ACCEL_FS_16 0x03
|
||||
|
||||
#define MPU6050_DHPF_RESET 0x00
|
||||
#define MPU6050_DHPF_5 0x01
|
||||
#define MPU6050_DHPF_2P5 0x02
|
||||
#define MPU6050_DHPF_1P25 0x03
|
||||
#define MPU6050_DHPF_0P63 0x04
|
||||
#define MPU6050_DHPF_HOLD 0x07
|
||||
|
||||
#define MPU6050_TEMP_FIFO_EN_BIT 7
|
||||
#define MPU6050_XG_FIFO_EN_BIT 6
|
||||
#define MPU6050_YG_FIFO_EN_BIT 5
|
||||
#define MPU6050_ZG_FIFO_EN_BIT 4
|
||||
#define MPU6050_ACCEL_FIFO_EN_BIT 3
|
||||
#define MPU6050_SLV2_FIFO_EN_BIT 2
|
||||
#define MPU6050_SLV1_FIFO_EN_BIT 1
|
||||
#define MPU6050_SLV0_FIFO_EN_BIT 0
|
||||
|
||||
#define MPU6050_MULT_MST_EN_BIT 7
|
||||
#define MPU6050_WAIT_FOR_ES_BIT 6
|
||||
#define MPU6050_SLV_3_FIFO_EN_BIT 5
|
||||
#define MPU6050_I2C_MST_P_NSR_BIT 4
|
||||
#define MPU6050_I2C_MST_CLK_BIT 3
|
||||
#define MPU6050_I2C_MST_CLK_LENGTH 4
|
||||
|
||||
#define MPU6050_CLOCK_DIV_348 0x0
|
||||
#define MPU6050_CLOCK_DIV_333 0x1
|
||||
#define MPU6050_CLOCK_DIV_320 0x2
|
||||
#define MPU6050_CLOCK_DIV_308 0x3
|
||||
#define MPU6050_CLOCK_DIV_296 0x4
|
||||
#define MPU6050_CLOCK_DIV_286 0x5
|
||||
#define MPU6050_CLOCK_DIV_276 0x6
|
||||
#define MPU6050_CLOCK_DIV_267 0x7
|
||||
#define MPU6050_CLOCK_DIV_258 0x8
|
||||
#define MPU6050_CLOCK_DIV_500 0x9
|
||||
#define MPU6050_CLOCK_DIV_471 0xA
|
||||
#define MPU6050_CLOCK_DIV_444 0xB
|
||||
#define MPU6050_CLOCK_DIV_421 0xC
|
||||
#define MPU6050_CLOCK_DIV_400 0xD
|
||||
#define MPU6050_CLOCK_DIV_381 0xE
|
||||
#define MPU6050_CLOCK_DIV_364 0xF
|
||||
|
||||
#define MPU6050_I2C_SLV_RW_BIT 7
|
||||
#define MPU6050_I2C_SLV_ADDR_BIT 6
|
||||
#define MPU6050_I2C_SLV_ADDR_LENGTH 7
|
||||
#define MPU6050_I2C_SLV_EN_BIT 7
|
||||
#define MPU6050_I2C_SLV_BYTE_SW_BIT 6
|
||||
#define MPU6050_I2C_SLV_REG_DIS_BIT 5
|
||||
#define MPU6050_I2C_SLV_GRP_BIT 4
|
||||
#define MPU6050_I2C_SLV_LEN_BIT 3
|
||||
#define MPU6050_I2C_SLV_LEN_LENGTH 4
|
||||
|
||||
#define MPU6050_I2C_SLV4_RW_BIT 7
|
||||
#define MPU6050_I2C_SLV4_ADDR_BIT 6
|
||||
#define MPU6050_I2C_SLV4_ADDR_LENGTH 7
|
||||
#define MPU6050_I2C_SLV4_EN_BIT 7
|
||||
#define MPU6050_I2C_SLV4_INT_EN_BIT 6
|
||||
#define MPU6050_I2C_SLV4_REG_DIS_BIT 5
|
||||
#define MPU6050_I2C_SLV4_MST_DLY_BIT 4
|
||||
#define MPU6050_I2C_SLV4_MST_DLY_LENGTH 5
|
||||
|
||||
#define MPU6050_MST_PASS_THROUGH_BIT 7
|
||||
#define MPU6050_MST_I2C_SLV4_DONE_BIT 6
|
||||
#define MPU6050_MST_I2C_LOST_ARB_BIT 5
|
||||
#define MPU6050_MST_I2C_SLV4_NACK_BIT 4
|
||||
#define MPU6050_MST_I2C_SLV3_NACK_BIT 3
|
||||
#define MPU6050_MST_I2C_SLV2_NACK_BIT 2
|
||||
#define MPU6050_MST_I2C_SLV1_NACK_BIT 1
|
||||
#define MPU6050_MST_I2C_SLV0_NACK_BIT 0
|
||||
|
||||
#define MPU6050_INTCFG_INT_LEVEL_BIT 7
|
||||
#define MPU6050_INTCFG_INT_OPEN_BIT 6
|
||||
#define MPU6050_INTCFG_LATCH_INT_EN_BIT 5
|
||||
#define MPU6050_INTCFG_INT_RD_CLEAR_BIT 4
|
||||
#define MPU6050_INTCFG_FSYNC_INT_LEVEL_BIT 3
|
||||
#define MPU6050_INTCFG_FSYNC_INT_EN_BIT 2
|
||||
#define MPU6050_INTCFG_I2C_BYPASS_EN_BIT 1
|
||||
#define MPU6050_INTCFG_CLKOUT_EN_BIT 0
|
||||
|
||||
#define MPU6050_INTMODE_ACTIVEHIGH 0x00
|
||||
#define MPU6050_INTMODE_ACTIVELOW 0x01
|
||||
|
||||
#define MPU6050_INTDRV_PUSHPULL 0x00
|
||||
#define MPU6050_INTDRV_OPENDRAIN 0x01
|
||||
|
||||
#define MPU6050_INTLATCH_50USPULSE 0x00
|
||||
#define MPU6050_INTLATCH_WAITCLEAR 0x01
|
||||
|
||||
#define MPU6050_INTCLEAR_STATUSREAD 0x00
|
||||
#define MPU6050_INTCLEAR_ANYREAD 0x01
|
||||
|
||||
#define MPU6050_INTERRUPT_FF_BIT 7
|
||||
#define MPU6050_INTERRUPT_MOT_BIT 6
|
||||
#define MPU6050_INTERRUPT_ZMOT_BIT 5
|
||||
#define MPU6050_INTERRUPT_FIFO_OFLOW_BIT 4
|
||||
#define MPU6050_INTERRUPT_I2C_MST_INT_BIT 3
|
||||
#define MPU6050_INTERRUPT_PLL_RDY_INT_BIT 2
|
||||
#define MPU6050_INTERRUPT_DMP_INT_BIT 1
|
||||
#define MPU6050_INTERRUPT_DATA_RDY_BIT 0
|
||||
|
||||
// TODO: figure out what these actually do
|
||||
// UMPL source code is not very obivous
|
||||
#define MPU6050_DMPINT_5_BIT 5
|
||||
#define MPU6050_DMPINT_4_BIT 4
|
||||
#define MPU6050_DMPINT_3_BIT 3
|
||||
#define MPU6050_DMPINT_2_BIT 2
|
||||
#define MPU6050_DMPINT_1_BIT 1
|
||||
#define MPU6050_DMPINT_0_BIT 0
|
||||
|
||||
#define MPU6050_MOTION_MOT_XNEG_BIT 7
|
||||
#define MPU6050_MOTION_MOT_XPOS_BIT 6
|
||||
#define MPU6050_MOTION_MOT_YNEG_BIT 5
|
||||
#define MPU6050_MOTION_MOT_YPOS_BIT 4
|
||||
#define MPU6050_MOTION_MOT_ZNEG_BIT 3
|
||||
#define MPU6050_MOTION_MOT_ZPOS_BIT 2
|
||||
#define MPU6050_MOTION_MOT_ZRMOT_BIT 0
|
||||
|
||||
#define MPU6050_DELAYCTRL_DELAY_ES_SHADOW_BIT 7
|
||||
#define MPU6050_DELAYCTRL_I2C_SLV4_DLY_EN_BIT 4
|
||||
#define MPU6050_DELAYCTRL_I2C_SLV3_DLY_EN_BIT 3
|
||||
#define MPU6050_DELAYCTRL_I2C_SLV2_DLY_EN_BIT 2
|
||||
#define MPU6050_DELAYCTRL_I2C_SLV1_DLY_EN_BIT 1
|
||||
#define MPU6050_DELAYCTRL_I2C_SLV0_DLY_EN_BIT 0
|
||||
|
||||
#define MPU6050_PATHRESET_GYRO_RESET_BIT 2
|
||||
#define MPU6050_PATHRESET_ACCEL_RESET_BIT 1
|
||||
#define MPU6050_PATHRESET_TEMP_RESET_BIT 0
|
||||
|
||||
#define MPU6050_DETECT_ACCEL_ON_DELAY_BIT 5
|
||||
#define MPU6050_DETECT_ACCEL_ON_DELAY_LENGTH 2
|
||||
#define MPU6050_DETECT_FF_COUNT_BIT 3
|
||||
#define MPU6050_DETECT_FF_COUNT_LENGTH 2
|
||||
#define MPU6050_DETECT_MOT_COUNT_BIT 1
|
||||
#define MPU6050_DETECT_MOT_COUNT_LENGTH 2
|
||||
|
||||
#define MPU6050_DETECT_DECREMENT_RESET 0x0
|
||||
#define MPU6050_DETECT_DECREMENT_1 0x1
|
||||
#define MPU6050_DETECT_DECREMENT_2 0x2
|
||||
#define MPU6050_DETECT_DECREMENT_4 0x3
|
||||
|
||||
#define MPU6050_USERCTRL_DMP_EN_BIT 7
|
||||
#define MPU6050_USERCTRL_FIFO_EN_BIT 6
|
||||
#define MPU6050_USERCTRL_I2C_MST_EN_BIT 5
|
||||
#define MPU6050_USERCTRL_I2C_IF_DIS_BIT 4
|
||||
#define MPU6050_USERCTRL_DMP_RESET_BIT 3
|
||||
#define MPU6050_USERCTRL_FIFO_RESET_BIT 2
|
||||
#define MPU6050_USERCTRL_I2C_MST_RESET_BIT 1
|
||||
#define MPU6050_USERCTRL_SIG_COND_RESET_BIT 0
|
||||
|
||||
#define MPU6050_PWR1_DEVICE_RESET_BIT 7
|
||||
#define MPU6050_PWR1_SLEEP_BIT 6
|
||||
#define MPU6050_PWR1_CYCLE_BIT 5
|
||||
#define MPU6050_PWR1_TEMP_DIS_BIT 3
|
||||
#define MPU6050_PWR1_CLKSEL_BIT 2
|
||||
#define MPU6050_PWR1_CLKSEL_LENGTH 3
|
||||
|
||||
#define MPU6050_CLOCK_INTERNAL 0x00
|
||||
#define MPU6050_CLOCK_PLL_XGYRO 0x01
|
||||
#define MPU6050_CLOCK_PLL_YGYRO 0x02
|
||||
#define MPU6050_CLOCK_PLL_ZGYRO 0x03
|
||||
#define MPU6050_CLOCK_PLL_EXT32K 0x04
|
||||
#define MPU6050_CLOCK_PLL_EXT19M 0x05
|
||||
#define MPU6050_CLOCK_KEEP_RESET 0x07
|
||||
|
||||
#define MPU6050_PWR2_LP_WAKE_CTRL_BIT 7
|
||||
#define MPU6050_PWR2_LP_WAKE_CTRL_LENGTH 2
|
||||
#define MPU6050_PWR2_STBY_XA_BIT 5
|
||||
#define MPU6050_PWR2_STBY_YA_BIT 4
|
||||
#define MPU6050_PWR2_STBY_ZA_BIT 3
|
||||
#define MPU6050_PWR2_STBY_XG_BIT 2
|
||||
#define MPU6050_PWR2_STBY_YG_BIT 1
|
||||
#define MPU6050_PWR2_STBY_ZG_BIT 0
|
||||
|
||||
#define MPU6050_WAKE_FREQ_1P25 0x0
|
||||
#define MPU6050_WAKE_FREQ_2P5 0x1
|
||||
#define MPU6050_WAKE_FREQ_5 0x2
|
||||
#define MPU6050_WAKE_FREQ_10 0x3
|
||||
|
||||
#define MPU6050_BANKSEL_PRFTCH_EN_BIT 6
|
||||
#define MPU6050_BANKSEL_CFG_USER_BANK_BIT 5
|
||||
#define MPU6050_BANKSEL_MEM_SEL_BIT 4
|
||||
#define MPU6050_BANKSEL_MEM_SEL_LENGTH 5
|
||||
|
||||
#define MPU6050_WHO_AM_I_BIT 6
|
||||
#define MPU6050_WHO_AM_I_LENGTH 6
|
||||
|
||||
#define MPU6050_TASK_PRIO 3
|
||||
#define MPU6050_STK_SIZE 256
|
||||
|
||||
extern short gyro[3], accel[3];
|
||||
extern int Deviation_Count;
|
||||
extern short Deviation_gyro[3],Original_gyro[3];
|
||||
extern short Deviation_accel[3],Original_accel[3];
|
||||
extern int16_t Gx_offset,Gy_offset,Gz_offset;
|
||||
extern float Acc1G_Values;
|
||||
extern float Roll,Pitch,Yaw;
|
||||
//供外部调用的API
|
||||
u8 MPU6050_initialize(void); //初始化
|
||||
uint8_t MPU6050_testConnection(void); //检测MPU6050是否存在
|
||||
//读取ADC值
|
||||
void MPU6050_getMotion6(int16_t* ax, int16_t* ay, int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz);
|
||||
void MPU6050_getlastMotion6(int16_t* ax, int16_t* ay,
|
||||
int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz);
|
||||
uint8_t MPU6050_getDeviceID(void); //读取MPU6050的ID
|
||||
void MPU6050_InitGyro_Offset(void);//初始化陀螺仪偏置
|
||||
void DMP_Init(void);
|
||||
void Read_DMP(void);
|
||||
int Read_Temperature(void);
|
||||
void MPU6050_task(void *pvParameters);
|
||||
unsigned char MPU6050_Set_LPF(u16 lpf);
|
||||
unsigned char MPU6050_Set_Rate(u16 rate);
|
||||
void MPU_Get_Gyroscope(void);
|
||||
void MPU_Get_Accelscope(void);
|
||||
|
||||
#endif
|
||||
166
HARDWARE/adc.c
Normal file
166
HARDWARE/adc.c
Normal file
@@ -0,0 +1,166 @@
|
||||
#include "adc.h"
|
||||
|
||||
float Voltage,Voltage_Count,Voltage_All; //Variables related to battery voltage sampling //电池电压采样相关的变量
|
||||
const float Revise=0.99;
|
||||
|
||||
/**************************************************************************
|
||||
Function: ADC initializes battery voltage detection
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:ADC初始化电池电压检测
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void Adc_Init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
ADC_CommonInitTypeDef ADC_CommonInitStructure;
|
||||
ADC_InitTypeDef ADC_InitStructure;
|
||||
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOA时钟
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1时钟
|
||||
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//PB0 通道8
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
|
||||
|
||||
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE); //ADC1复位
|
||||
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE); //复位结束
|
||||
|
||||
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
|
||||
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//两个采样阶段之间的延迟5个时钟
|
||||
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA失能
|
||||
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div6;//预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz
|
||||
ADC_CommonInit(&ADC_CommonInitStructure);//初始化
|
||||
|
||||
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式
|
||||
ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式
|
||||
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换
|
||||
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//禁止触发检测,使用软件触发
|
||||
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐
|
||||
ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1
|
||||
ADC_Init(ADC1, &ADC_InitStructure);//ADC初始化
|
||||
ADC_Cmd(ADC1, ENABLE);//开启AD转换器
|
||||
}
|
||||
|
||||
|
||||
void Adc_POWER_Init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
ADC_CommonInitTypeDef ADC_CommonInitStructure;
|
||||
ADC_InitTypeDef ADC_InitStructure;
|
||||
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOA时钟
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); //使能ADC1时钟
|
||||
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//PB0 通道8
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
|
||||
|
||||
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2,ENABLE); //ADC2复位
|
||||
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2,DISABLE); //复位结束
|
||||
|
||||
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
|
||||
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//两个采样阶段之间的延迟5个时钟
|
||||
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA失能
|
||||
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div6;//预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz
|
||||
ADC_CommonInit(&ADC_CommonInitStructure);//初始化
|
||||
|
||||
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式
|
||||
ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式
|
||||
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换
|
||||
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//禁止触发检测,使用软件触发
|
||||
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐
|
||||
ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1
|
||||
ADC_Init(ADC2, &ADC_InitStructure);//ADC初始化
|
||||
ADC_Cmd(ADC2, ENABLE);//开启AD转换器
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: The AD sampling
|
||||
Input : The ADC channels
|
||||
Output : AD conversion results
|
||||
函数功能:AD采样
|
||||
入口参数:ADC的通道
|
||||
返回 值:AD转换结果
|
||||
**************************************************************************/
|
||||
u16 Get_Adc(u8 ch)
|
||||
{
|
||||
//Sets the specified ADC rule group channel, one sequence, and sampling time
|
||||
//设置指定ADC的规则组通道,一个序列,采样时间
|
||||
|
||||
//ADC1,ADC通道,采样时间为480周期
|
||||
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_480Cycles );
|
||||
//Enable the specified ADC1 software transformation startup function
|
||||
//使能指定的ADC1的软件转换启动功能
|
||||
ADC_SoftwareStartConv(ADC1);
|
||||
//Wait for the conversion to finish
|
||||
//等待转换结束
|
||||
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));
|
||||
//Returns the result of the last ADC1 rule group conversion
|
||||
//返回最近一次ADC1规则组的转换结果
|
||||
return ADC_GetConversionValue(ADC1);
|
||||
}
|
||||
|
||||
u16 Get_Adc2(u8 ch)
|
||||
{
|
||||
//Sets the specified ADC rule group channel, one sequence, and sampling time
|
||||
//设置指定ADC的规则组通道,一个序列,采样时间
|
||||
|
||||
//ADC2,ADC通道,采样时间为480周期
|
||||
ADC_RegularChannelConfig(ADC2, ch, 1, ADC_SampleTime_480Cycles );
|
||||
//Enable the specified ADC2 software transformation startup function
|
||||
//使能指定的ADC1的软件转换启动功能
|
||||
ADC_SoftwareStartConv(ADC2);
|
||||
//Wait for the conversion to finish
|
||||
//等待转换结束
|
||||
while(!ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC ));
|
||||
//Returns the result of the last ADC2 rule group conversion
|
||||
//返回最近一次ADC1规则组的转换结果
|
||||
return ADC_GetConversionValue(ADC2);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: Collect multiple ADC values to calculate the average function
|
||||
Input : ADC channels and collection times
|
||||
Output : AD conversion results
|
||||
函数功能:采集多次ADC值求平均值函数
|
||||
入口参数:ADC通道和采集次数
|
||||
返 回 值:AD转换结果
|
||||
**************************************************************************/
|
||||
u16 Get_adc_Average(u8 chn, u8 times)
|
||||
{
|
||||
u32 temp_val=0;
|
||||
u8 t;
|
||||
for(t=0;t<times;t++)
|
||||
{
|
||||
temp_val+=Get_Adc(chn);
|
||||
delay_ms(5);
|
||||
}
|
||||
return temp_val/times;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: Read the battery voltage
|
||||
Input : none
|
||||
Output : Battery voltage in mV
|
||||
函数功能:读取电池电压
|
||||
入口参数:无
|
||||
返回 值:电池电压,单位mv
|
||||
**************************************************************************/
|
||||
float Get_battery_volt(void)
|
||||
{
|
||||
float Volt;
|
||||
|
||||
//The resistance partial voltage can be obtained by simple analysis according to the schematic diagram
|
||||
//电阻分压,具体根据原理图简单分析可以得到
|
||||
Volt=Get_Adc2(Battery_Ch)*3.3*11.0*Revise/1.0/4096;
|
||||
return Volt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
16
HARDWARE/adc.h
Normal file
16
HARDWARE/adc.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef __ADC_H
|
||||
#define __ADC_H
|
||||
#include "sys.h"
|
||||
#include "system.h"
|
||||
#define Battery_Ch 8 //Battery voltage, ADC channel 8 //电池电压,ADC通道8
|
||||
#define Potentiometer 9 //Potentiometer, ADC channel 9 //电位器,ADC通道9
|
||||
void Adc_Init(void);
|
||||
void Adc_POWER_Init(void);
|
||||
u16 Get_Adc(u8 ch);
|
||||
u16 Get_Adc2(u8 ch);
|
||||
float Get_battery_volt(void) ;
|
||||
u16 Get_adc_Average(u8 chn, u8 times);
|
||||
extern float Voltage,Voltage_Count,Voltage_All;
|
||||
#endif
|
||||
|
||||
|
||||
413
HARDWARE/can.c
Normal file
413
HARDWARE/can.c
Normal file
@@ -0,0 +1,413 @@
|
||||
#include "can.h"
|
||||
#include "system.h"
|
||||
/**************************************************************************
|
||||
Function: CAN1 initialization
|
||||
Input : tsjw:Resynchronize the jump time unit, Scope: 1 ~ 3;
|
||||
tbs2:Time unit of time period 2, range :1~8;
|
||||
tbs1:Time unit of time period 1, range :1~16;
|
||||
brp :Baud rate divider, range :1 to 1024;(We're actually going to add 1, which is 1 to 1024) tq=(brp)*tpclk1
|
||||
mode:0, normal mode;1. Loop mode;
|
||||
Output : 0- Initialization successful;Other - initialization failed
|
||||
Note: none of the entry parameters (except mode) can be 0
|
||||
函数功能:CAN1初始化
|
||||
入口参数:tsjw:重新同步跳跃时间单元,范围:1~3;
|
||||
tbs2:时间段2的时间单元,范围:1~8;
|
||||
tbs1:时间段1的时间单元,范围:1~16;
|
||||
brp :波特率分频器,范围:1~1024;(实际要加1,也就是1~1024) tq=(brp)*tpclk1
|
||||
mode:0,普通模式;1,回环模式;
|
||||
返回 值:0-初始化成功; 其他-初始化失败
|
||||
注意:入口参数(除了mode)均不能为0
|
||||
波特率/Baud rate=Fpclk1/((tbs1+tbs2+1)*brp),Fpclk1为36M
|
||||
=42M/((3+2+1)*6)
|
||||
=1M
|
||||
**************************************************************************/
|
||||
u8 CAN1_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
u16 i=0;
|
||||
if(tsjw==0||tbs2==0||tbs1==0||brp==0)return 1;
|
||||
tsjw-=1; //Subtract 1 before setting //先减去1.再用于设置
|
||||
tbs2-=1;
|
||||
tbs1-=1;
|
||||
brp-=1;
|
||||
|
||||
//使能相关时钟
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);//使能PORTB时钟
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时钟
|
||||
//初始化GPIO
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0| GPIO_Pin_1;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
|
||||
GPIO_Init(GPIOD, &GPIO_InitStructure);//初始化PB8 PB9
|
||||
// //引脚复用映射配置
|
||||
GPIO_PinAFConfig(GPIOD,GPIO_PinSource0,GPIO_AF_CAN1); //GPIOB8复用为CAN1
|
||||
GPIO_PinAFConfig(GPIOD,GPIO_PinSource1,GPIO_AF_CAN1); //GPIOB9复用为CAN1
|
||||
|
||||
CAN1->MCR=0x0000; //Exit sleep mode (setting all bits to 0 at the same time) //退出睡眠模式(同时设置所有位为0)
|
||||
CAN1->MCR|=1<<0; //Request CAN1 to enter initialization mode //请求CAN1进入初始化模式
|
||||
while((CAN1->MSR&1<<0)==0)
|
||||
{
|
||||
i++;
|
||||
if(i>100)return 2; //Failed to enter initialization mode //进入初始化模式失败
|
||||
}
|
||||
//Non-time triggered communication mode
|
||||
//非时间触发通信模式
|
||||
CAN1->MCR|=0<<7;
|
||||
//Software automatic offline management
|
||||
//软件自动离线管理
|
||||
CAN1->MCR|=0<<6;
|
||||
//Sleep mode is awakened by software (clear CAN1- >;
|
||||
//睡眠模式通过软件唤醒(清除CAN1->MCR的SLEEP位)
|
||||
CAN1->MCR|=0<<5;
|
||||
//Disallow automatic message transmission
|
||||
//禁止报文自动传送
|
||||
CAN1->MCR|=1<<4;
|
||||
//Messages are not locked, the new overwrites the old
|
||||
//报文不锁定,新的覆盖旧的
|
||||
CAN1->MCR|=0<<3;
|
||||
//The priority is determined by the message identifier
|
||||
//优先级由报文标识符决定
|
||||
CAN1->MCR|=0<<2;
|
||||
//Clear the original Settings
|
||||
//清除原来的设置
|
||||
CAN1->BTR=0x00000000;
|
||||
//Mode set to 0, normal mode;1. Loop mode;
|
||||
//模式设置 0,普通模式;1,回环模式;
|
||||
CAN1->BTR|=mode<<30;
|
||||
//Resynchronization jump width (TSJW) is TSJW +1 time unit
|
||||
//重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位
|
||||
CAN1->BTR|=tsjw<<24;
|
||||
//Tbs2= Tbs2 +1 time unit
|
||||
//Tbs2=tbs2+1个时间单位
|
||||
CAN1->BTR|=tbs2<<20;
|
||||
//Tbs1= Tbs1 +1 time unit
|
||||
//Tbs1=tbs1+1个时间单位
|
||||
CAN1->BTR|=tbs1<<16;
|
||||
//Frequency division coefficient (Fdiv) is brp +1, boulder rate: Fpclk1/((Tbs1+Tbs2+1)*Fdiv)
|
||||
//分频系数(Fdiv)为brp+1,波特率:Fpclk1/((Tbs1+Tbs2+1)*Fdiv)
|
||||
CAN1->BTR|=brp<<0;
|
||||
//Request CAN1 to exit initialization mode
|
||||
//请求CAN1退出初始化模式
|
||||
CAN1->MCR&=~(1<<0);
|
||||
while((CAN1->MSR&1<<0)==1)
|
||||
{
|
||||
i++;
|
||||
if(i>0XFFF0)return 3; //Failed to exit initialization mode //退出初始化模式失败
|
||||
}
|
||||
/*** Filter initialization || 过滤器初始化 ***/
|
||||
//Filter groups work in initialization mode
|
||||
//过滤器组工作在初始化模式
|
||||
CAN1->FMR|=1<<0;
|
||||
//Filter 0 is not active
|
||||
//过滤器0不激活
|
||||
CAN1->FA1R&=~(1<<0);
|
||||
//The filter bit width is 32 bits
|
||||
//过滤器位宽为32位
|
||||
CAN1->FS1R|=1<<0;
|
||||
//Filter 0 works in identifier masking bit mode
|
||||
//过滤器0工作在标识符屏蔽位模式
|
||||
CAN1->FM1R|=0<<0;
|
||||
//Filter 0 is associated with FIFO0
|
||||
//过滤器0关联到FIFO0
|
||||
CAN1->FFA1R|=0<<0;
|
||||
//32 bit ID
|
||||
//32位ID
|
||||
CAN1->sFilterRegister[0].FR1=0X00000000;
|
||||
//32-bit MASK
|
||||
//32位MASK
|
||||
CAN1->sFilterRegister[0].FR2=0X00000000;
|
||||
//Activation filter 0
|
||||
//激活过滤器0
|
||||
CAN1->FA1R|=1<<0;
|
||||
//Filter group enters normal mode
|
||||
//过滤器组进入正常模式
|
||||
CAN1->FMR&=0<<0;
|
||||
|
||||
#if CAN1_RX0_INT_ENABLE
|
||||
//Enable to interrupt reception //使能中断接收
|
||||
|
||||
//FIFO0消息挂号中断允许
|
||||
CAN1->IER|=1<<1;
|
||||
|
||||
//Configure CAN to receive interrupts
|
||||
//配置CAN接收中断
|
||||
NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
|
||||
//Preemption priority
|
||||
//抢占优先级
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;
|
||||
//Son priority
|
||||
//子优先级
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
|
||||
//IRQ channel enablement
|
||||
//IRQ通道使能
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
//Initializes the VIC register according to the specified parameters
|
||||
//根据指定的参数初始化VIC寄存器
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
|
||||
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: CAN sends data
|
||||
Input : id:Standard ID(11 bits)/ Extended ID(11 bits +18 bits)
|
||||
ide:0, standard frame;1, extension frames
|
||||
rtr:0, data frame;1, remote frame
|
||||
len:Length of data to be sent (fixed at 8 bytes, valid data is 6 bytes in time-triggered mode)
|
||||
*dat:Pointer to the data
|
||||
Output : 0~3, mailbox number. 0xFF, no valid mailbox
|
||||
函数功能:CAN发送数据
|
||||
入口参数:id:标准ID(11位)/扩展ID(11位+18位)
|
||||
ide:0,标准帧;1,扩展帧
|
||||
rtr:0,数据帧;1,远程帧
|
||||
len:要发送的数据长度(固定为8个字节,在时间触发模式下,有效数据为6个字节)
|
||||
*dat:数据指针.
|
||||
返回 值:0~3,邮箱编号.0XFF,无有效邮箱
|
||||
**************************************************************************/
|
||||
u8 CAN1_Tx_Msg(u32 id,u8 ide,u8 rtr,u8 len,u8 *dat)
|
||||
{
|
||||
u8 mbox;
|
||||
if(CAN1->TSR&(1<<26))mbox=0; //Mailbox 0 is empty //邮箱0为空
|
||||
else if(CAN1->TSR&(1<<27))mbox=1; //Mailbox 1 is empty //邮箱1为空
|
||||
else if(CAN1->TSR&(1<<28))mbox=2; //Mailbox 2 is empty //邮箱2为空
|
||||
else return 0XFF; //No empty mailbox, cannot send //无空邮箱,无法发送
|
||||
|
||||
CAN1->sTxMailBox[mbox].TIR=0; //Clear the previous Settings //清除之前的设置
|
||||
if(ide==0) //The standard frame //标准帧
|
||||
{
|
||||
id&=0x7ff; //Take the low 11 bit STDID //取低11位stdid
|
||||
id<<=21;
|
||||
}else //Extend the frame //扩展帧
|
||||
{
|
||||
id&=0X1FFFFFFF; //Take a low 32-bit extid //取低32位extid
|
||||
id<<=3;
|
||||
}
|
||||
CAN1->sTxMailBox[mbox].TIR|=id;
|
||||
CAN1->sTxMailBox[mbox].TIR|=ide<<2;
|
||||
CAN1->sTxMailBox[mbox].TIR|=rtr<<1;
|
||||
len&=0X0F; //Get lower 4 bits //得到低四位
|
||||
CAN1->sTxMailBox[mbox].TDTR&=~(0X0000000F);
|
||||
CAN1->sTxMailBox[mbox].TDTR|=len; //Set the DLC //设置DLC
|
||||
//The data to be sent is stored in the mailbox
|
||||
//待发送数据存入邮箱
|
||||
CAN1->sTxMailBox[mbox].TDHR=(((u32)dat[7]<<24)|
|
||||
((u32)dat[6]<<16)|
|
||||
((u32)dat[5]<<8)|
|
||||
((u32)dat[4]));
|
||||
CAN1->sTxMailBox[mbox].TDLR=(((u32)dat[3]<<24)|
|
||||
((u32)dat[2]<<16)|
|
||||
((u32)dat[1]<<8)|
|
||||
((u32)dat[0]));
|
||||
CAN1->sTxMailBox[mbox].TIR|=1<<0; //Request to send mailbox data//请求发送邮箱数据
|
||||
return mbox;
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Get the send status
|
||||
Input : Mbox: mailbox number
|
||||
Output : 0, hang;0X05, send failed;0X07, successful transmission
|
||||
函数功能:获得发送状态
|
||||
入口参数:mbox:邮箱编号
|
||||
返回 值:0,挂起;0X05,发送失败;0X07,发送成功
|
||||
**************************************************************************/
|
||||
u8 CAN1_Tx_Staus(u8 mbox)
|
||||
{
|
||||
u8 sta=0;
|
||||
switch (mbox)
|
||||
{
|
||||
case 0:
|
||||
sta |= CAN1->TSR&(1<<0); //RQCP0
|
||||
sta |= CAN1->TSR&(1<<1); //TXOK0
|
||||
sta |=((CAN1->TSR&(1<<26))>>24); //TME0
|
||||
break;
|
||||
case 1:
|
||||
sta |= CAN1->TSR&(1<<8)>>8; //RQCP1
|
||||
sta |= CAN1->TSR&(1<<9)>>8; //TXOK1
|
||||
sta |=((CAN1->TSR&(1<<27))>>25); //TME1
|
||||
break;
|
||||
case 2:
|
||||
sta |= CAN1->TSR&(1<<16)>>16; //RQCP2
|
||||
sta |= CAN1->TSR&(1<<17)>>16; //TXOK2
|
||||
sta |=((CAN1->TSR&(1<<28))>>26); //TME2
|
||||
break;
|
||||
default:
|
||||
sta=0X05; //Wrong email number, failed //邮箱号不对,失败
|
||||
break;
|
||||
}
|
||||
return sta;
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Returns the number of packets received in FIFO0/FIFO1
|
||||
Input : Fifox: FIFO number (0, 1)
|
||||
Output : Number of packets in FIFO0/FIFO1
|
||||
函数功能:得到在FIFO0/FIFO1中接收到的报文个数
|
||||
入口参数:fifox:FIFO编号(0、1)
|
||||
返回 值:FIFO0/FIFO1中的报文个数
|
||||
**************************************************************************/
|
||||
u8 CAN1_Msg_Pend(u8 fifox)
|
||||
{
|
||||
if(fifox==0)return CAN1->RF0R&0x03;
|
||||
else if(fifox==1)return CAN1->RF1R&0x03;
|
||||
else return 0;
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Receive data
|
||||
Input : fifox:Email
|
||||
id:Standard ID(11 bits)/ Extended ID(11 bits +18 bits)
|
||||
ide:0, standard frame;1, extension frames
|
||||
rtr:0, data frame;1, remote frame
|
||||
len:Length of data received (fixed at 8 bytes, valid at 6 bytes in time-triggered mode)
|
||||
dat:Data cache
|
||||
Output : none
|
||||
函数功能:接收数据
|
||||
入口参数:fifox:邮箱号
|
||||
id:标准ID(11位)/扩展ID(11位+18位)
|
||||
ide:0,标准帧;1,扩展帧
|
||||
rtr:0,数据帧;1,远程帧
|
||||
len:接收到的数据长度(固定为8个字节,在时间触发模式下,有效数据为6个字节)
|
||||
dat:数据缓存区
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void CAN1_Rx_Msg(u8 fifox,u32 *id,u8 *ide,u8 *rtr,u8 *len,u8 *dat)
|
||||
{
|
||||
*ide=CAN1->sFIFOMailBox[fifox].RIR&0x04; //Gets the value of the identifier selection bit //得到标识符选择位的值
|
||||
if(*ide==0) //Standard identifier //标准标识符
|
||||
{
|
||||
*id=CAN1->sFIFOMailBox[fifox].RIR>>21;
|
||||
}else //Extended identifier //扩展标识符
|
||||
{
|
||||
*id=CAN1->sFIFOMailBox[fifox].RIR>>3;
|
||||
}
|
||||
*rtr=CAN1->sFIFOMailBox[fifox].RIR&0x02; //Gets the remote send request value //得到远程发送请求值
|
||||
*len=CAN1->sFIFOMailBox[fifox].RDTR&0x0F; //Get the DLC //得到DLC
|
||||
//*fmi=(CAN1->sFIFOMailBox[FIFONumber].RDTR>>8)&0xFF; //Get the FMI //得到FMI
|
||||
//Receive data //接收数据
|
||||
dat[0]=CAN1->sFIFOMailBox[fifox].RDLR&0XFF;
|
||||
dat[1]=(CAN1->sFIFOMailBox[fifox].RDLR>>8)&0XFF;
|
||||
dat[2]=(CAN1->sFIFOMailBox[fifox].RDLR>>16)&0XFF;
|
||||
dat[3]=(CAN1->sFIFOMailBox[fifox].RDLR>>24)&0XFF;
|
||||
dat[4]=CAN1->sFIFOMailBox[fifox].RDHR&0XFF;
|
||||
dat[5]=(CAN1->sFIFOMailBox[fifox].RDHR>>8)&0XFF;
|
||||
dat[6]=(CAN1->sFIFOMailBox[fifox].RDHR>>16)&0XFF;
|
||||
dat[7]=(CAN1->sFIFOMailBox[fifox].RDHR>>24)&0XFF;
|
||||
if(fifox==0)CAN1->RF0R|=0X20; //Free the FIFO0 mailbox //释放FIFO0邮箱
|
||||
else if(fifox==1)CAN1->RF1R|=0X20; //Free the FIFO1 mailbox //释放FIFO1邮箱
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: CAN receives interrupt service function, conditional compilation
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:CAN接收中断服务函数,条件编译
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
#if CAN1_RX0_INT_ENABLE //Enable RX0 interrupt //使能RX0中断
|
||||
void CAN1_RX0_IRQHandler(void)
|
||||
{
|
||||
u32 id;
|
||||
u8 ide,rtr,len;
|
||||
|
||||
u8 temp_rxbuf[8];
|
||||
|
||||
CAN1_Rx_Msg(0,&id,&ide,&rtr,&len,temp_rxbuf);
|
||||
if(id==0x181)
|
||||
{
|
||||
float Vz;
|
||||
CAN_ON_Flag=1, PS2_ON_Flag=0,Remote_ON_Flag=0,APP_ON_Flag=0,Usart1_ON_Flag=0,Usart5_ON_Flag=0;
|
||||
command_lost_count=0; //CAN/串口控制命令丢失计数清零
|
||||
|
||||
//Calculate the three-axis target velocity, unit: m/s
|
||||
//计算三轴目标速度,单位:m/s
|
||||
Move_X=((float)((short)((temp_rxbuf[0]<<8)+(temp_rxbuf[1]))))/1000;
|
||||
Move_Y=((float)((short)((temp_rxbuf[2]<<8)+(temp_rxbuf[3]))))/1000;
|
||||
Vz =((float)((short)((temp_rxbuf[4]<<8)+(temp_rxbuf[5]))))/1000;
|
||||
if(Car_Mode==Akm_Car)
|
||||
{
|
||||
Move_Z=Vz_to_Akm_Angle(Move_X, Vz);
|
||||
}
|
||||
else
|
||||
{
|
||||
Move_Z=((float)((short)((temp_rxbuf[4]<<8)+(temp_rxbuf[5]))))/1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
Function: CAN1 sends a set of data (fixed format :ID 0X601, standard frame, data frame)
|
||||
Input : msg:Pointer to the data
|
||||
len:Data length (up to 8)
|
||||
Output : 0, success, others, failure;
|
||||
函数功能:CAN1发送一组数据(固定格式:ID为0X601,标准帧,数据帧)
|
||||
入口参数:msg:数据指针
|
||||
len:数据长度(最大为8)
|
||||
返回 值:0,成功,其他,失败;
|
||||
**************************************************************************/
|
||||
u8 CAN1_Send_Msg(u8* msg,u8 len)
|
||||
{
|
||||
u8 mbox;
|
||||
u16 i=0;
|
||||
mbox=CAN1_Tx_Msg(0X601,0,0,len,msg);
|
||||
while((CAN1_Tx_Staus(mbox)!=0X07)&&(i<0XFFF))i++; //Waiting for the end of sending //等待发送结束
|
||||
if(i>=0XFFF)return 1; //Send failure //发送失败
|
||||
return 0; //Send a success //发送成功
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: The CAN1 port receives data queries
|
||||
Input : Buf: The data cache
|
||||
Output : 0, number of data received, other, length of data received
|
||||
函数功能:CAN1口接收数据查询
|
||||
入口参数:buf:数据缓存区
|
||||
返回 值:0,无数据被收到,其他,接收的数据长度
|
||||
**************************************************************************/
|
||||
u8 CAN1_Receive_Msg(u8 *buf)
|
||||
{
|
||||
u32 id;
|
||||
u8 ide,rtr,len;
|
||||
if(CAN1_Msg_Pend(0)==0)return 0; //No data received, exit directly //没有接收到数据,直接退出
|
||||
CAN1_Rx_Msg(0,&id,&ide,&rtr,&len,buf); //Read the data //读取数据
|
||||
if(id!=0x12||ide!=0||rtr!=0)len=0; //Receive error //接收错误
|
||||
return len;
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Can1 sends a set of data tests
|
||||
Input : msg:Pointer to the data
|
||||
len:Data length (up to 8)
|
||||
Output : 0, success, 1, failure
|
||||
函数功能:CAN1发送一组数据测试
|
||||
入口参数:msg:数据指针
|
||||
len:数据长度(最大为8)
|
||||
返回 值:0,成功,1,失败
|
||||
**************************************************************************/
|
||||
u8 CAN1_Send_MsgTEST(u8* msg,u8 len)
|
||||
{
|
||||
u8 mbox;
|
||||
u16 i=0;
|
||||
mbox=CAN1_Tx_Msg(0X701,0,0,len,msg);
|
||||
while((CAN1_Tx_Staus(mbox)!=0X07)&&(i<0XFFF))i++; //Waiting for the end of sending //等待发送结束
|
||||
if(i>=0XFFF)return 1; //Send failure //发送失败
|
||||
return 0; //Send a success //发送成功
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Sends an array to the given ID
|
||||
Input : id:ID no.
|
||||
msg:The transmitted data pointer
|
||||
Output : 0, success, 1, failure
|
||||
函数功能:给给定的id发送一个数组的命令
|
||||
入口参数:id:ID号
|
||||
msg:被输送数据指针
|
||||
返回 值:0,成功,1,失败
|
||||
**************************************************************************/
|
||||
u8 CAN1_Send_Num(u32 id,u8* msg)
|
||||
{
|
||||
u8 mbox;
|
||||
u16 i=0;
|
||||
mbox=CAN1_Tx_Msg(id,0,0,8,msg);
|
||||
while((CAN1_Tx_Staus(mbox)!=0X07)&&(i<0XFFF))i++; //Waiting for the end of sending //等待发送结束
|
||||
if(i>=0XFFF)return 1; //Send failure //发送失败
|
||||
return 0;
|
||||
}
|
||||
40
HARDWARE/can.h
Normal file
40
HARDWARE/can.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef __CAN_H
|
||||
#define __CAN_H
|
||||
#include "sys.h"
|
||||
#include "system.h"
|
||||
|
||||
//CAN1 receives RX0 interrupt enablement
|
||||
//CAN1接收RX0中断使能
|
||||
#define CAN1_RX0_INT_ENABLE 1 //0, not enabling;1, can make //0,不使能; 1,使能
|
||||
|
||||
u8 CAN1_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode);
|
||||
u8 CAN1_Tx_Msg(u32 id,u8 ide,u8 rtr,u8 len,u8 *dat);
|
||||
u8 CAN1_Msg_Pend(u8 fifox);
|
||||
void CAN1_Rx_Msg(u8 fifox,u32 *id,u8 *ide,u8 *rtr,u8 *len,u8 *dat);
|
||||
u8 CAN1_Tx_Staus(u8 mbox);
|
||||
u8 CAN1_Send_Msg(u8* msg,u8 len);
|
||||
u8 CAN1_Receive_Msg(u8 *buf);
|
||||
|
||||
u8 CAN1_Send_MsgTEST(u8* msg,u8 len);
|
||||
u8 CAN1_Send_Num(u32 id,u8* msg);
|
||||
|
||||
void can_data_transition(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
78
HARDWARE/dma.c
Normal file
78
HARDWARE/dma.c
Normal file
@@ -0,0 +1,78 @@
|
||||
#include "dma.h"
|
||||
#include "sys.h"
|
||||
|
||||
DMA_InitTypeDef DMA_InitStructure;
|
||||
u16 DMA1_MEM_LEN2;//保存DMA每次数据传送的长度
|
||||
|
||||
/**************************************************************************
|
||||
函数功能:串口2DMA初始化
|
||||
入口参数:DMA通道,数据的目标地址,数据的起始地址,发送的数据数量
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void MYDMA_Init2(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
|
||||
{
|
||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA传输
|
||||
|
||||
DMA_DeInit(DMA_CHx); //将DMA的通道1寄存器重设为缺省值
|
||||
DMA1_MEM_LEN2=cndtr; //数据传输量
|
||||
DMA_InitStructure.DMA_PeripheralBaseAddr = cpar; //DMA外设ADC基地址
|
||||
DMA_InitStructure.DMA_MemoryBaseAddr = cmar; //DMA内存基地址
|
||||
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //数据传输方向,从内存读取发送到外设
|
||||
DMA_InitStructure.DMA_BufferSize = cndtr; //DMA通道的DMA缓存的大小
|
||||
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变
|
||||
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增
|
||||
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //数据宽度为8位
|
||||
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位
|
||||
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式
|
||||
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x拥有高优先级
|
||||
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输
|
||||
DMA_Init(DMA_CHx, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
|
||||
}
|
||||
/**************************************************************************
|
||||
函数功能:开启一次DMA传输
|
||||
入口参数:DMA通道,数据的目标地址,数据的起始地址,发送的数据数量
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void MYDMA_Enable2(DMA_Channel_TypeDef*DMA_CHx)
|
||||
{
|
||||
DMA_Cmd(DMA_CHx, DISABLE ); //关闭USART1 TX DMA1 所指示的通道
|
||||
DMA_SetCurrDataCounter(DMA1_Channel7,DMA1_MEM_LEN2);//DMA通道的DMA缓存的大小
|
||||
DMA_Cmd(DMA_CHx, ENABLE); //使能USART1 TX DMA1 所指示的通道
|
||||
}
|
||||
|
||||
///**************************************************************************
|
||||
//函数功能:DMA方式的printf
|
||||
//入口参数:要打印的内容
|
||||
//返回 值:无
|
||||
//**************************************************************************/
|
||||
void DMA_printf(const char *format,...)
|
||||
{
|
||||
u32 length;
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
length = vsnprintf((char*)t2xbuf, sizeof(t2xbuf), (char*)format, args);
|
||||
va_end(args);
|
||||
USART_SendBuffer((const char*)t2xbuf,length);
|
||||
}
|
||||
|
||||
u32 USART_SendBuffer(const char* buffer, u32 length)
|
||||
{
|
||||
if( (buffer==NULL) || (length==0) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
DMA_Cmd(DMA1_Channel7, DISABLE); //失能DMA通道
|
||||
DMA_SetCurrDataCounter(DMA1_Channel7, length);
|
||||
DMA_Cmd(DMA1_Channel7, ENABLE); //使能DMA通道
|
||||
while(1)
|
||||
{
|
||||
if(DMA_GetITStatus(DMA1_IT_TC7)!=RESET) //判断通道7(uart2_tx)传输完成
|
||||
{
|
||||
DMA_ClearFlag(DMA1_IT_TC7);//清除通道7传输完成标志
|
||||
break;
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
21
HARDWARE/dma.h
Normal file
21
HARDWARE/dma.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/**************************************************************************
|
||||
作者:平衡小车之家
|
||||
我的淘宝小店:http://shop114407458.taobao.com/
|
||||
**************************************************************************/
|
||||
#ifndef __DMA_H
|
||||
#define __DMA_H
|
||||
|
||||
#include "stm32f10x_dma.h"
|
||||
#include "sys.h"
|
||||
#include "system.h"
|
||||
|
||||
void MYDMA_Init2(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar,u16 cndtr);
|
||||
void MYDMA_Enable2(DMA_Channel_TypeDef*DMA_CHx);
|
||||
|
||||
void DMA_printf(const char *format,...);
|
||||
u32 USART_SendBuffer(const char* buffer, u32 length);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
279
HARDWARE/encoder.c
Normal file
279
HARDWARE/encoder.c
Normal file
@@ -0,0 +1,279 @@
|
||||
#include "encoder.h"
|
||||
|
||||
/**************************************************************************
|
||||
Function: Initialize TIM2 as the encoder interface mode
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:把TIM2初始化为编码器接口模式
|
||||
入口参数:无
|
||||
返 回 值:无
|
||||
**************************************************************************/
|
||||
void Encoder_Init_TIM2(void)
|
||||
{
|
||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||
TIM_ICInitTypeDef TIM_ICInitStructure;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能定时器
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOB, ENABLE); //使用A B口
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; //PA15
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //PB3
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
GPIO_PinAFConfig(GPIOA,GPIO_PinSource15,GPIO_AF_TIM2); //复用为TIM2 编码器接口
|
||||
GPIO_PinAFConfig(GPIOB,GPIO_PinSource3,GPIO_AF_TIM2); //复用为TIM2 编码器接口
|
||||
|
||||
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
|
||||
|
||||
TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // No prescaling //不分频
|
||||
TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD; //设定计数器自动重装值
|
||||
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //选择时钟分频:不分频
|
||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数
|
||||
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //初始化定时器
|
||||
|
||||
TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用编码器模式3
|
||||
TIM_ICStructInit(&TIM_ICInitStructure);
|
||||
TIM_ICInitStructure.TIM_ICFilter = 0;
|
||||
TIM_ICInit(TIM2, &TIM_ICInitStructure);
|
||||
|
||||
TIM_ClearFlag(TIM2, TIM_FLAG_Update);//清除TIM的更新标志位
|
||||
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
|
||||
TIM_SetCounter(TIM2,0);
|
||||
TIM_Cmd(TIM2, ENABLE);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: Initialize TIM3 as the encoder interface mode
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:把TIM3初始化为编码器接口模式
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void Encoder_Init_TIM3(void)
|
||||
{
|
||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||
TIM_ICInitTypeDef TIM_ICInitStructure;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); //使用A口
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; //PB4 PB5
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
GPIO_PinAFConfig(GPIOB,GPIO_PinSource4,GPIO_AF_TIM3); //复用为TIM2 编码器接口
|
||||
GPIO_PinAFConfig(GPIOB,GPIO_PinSource5,GPIO_AF_TIM3); //复用为TIM2 编码器接口
|
||||
|
||||
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
|
||||
TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // No prescaling //不分频
|
||||
TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD; //设定计数器自动重装值
|
||||
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //选择时钟分频:不分频
|
||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数
|
||||
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //初始化定时器
|
||||
|
||||
TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用编码器模式3
|
||||
TIM_ICStructInit(&TIM_ICInitStructure);
|
||||
TIM_ICInitStructure.TIM_ICFilter = 0;
|
||||
TIM_ICInit(TIM3, &TIM_ICInitStructure);
|
||||
|
||||
TIM_ClearFlag(TIM3, TIM_FLAG_Update);//清除TIM的更新标志位
|
||||
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
|
||||
TIM_SetCounter(TIM3,0);
|
||||
TIM_Cmd(TIM3, ENABLE);
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Initialize TIM4 as the encoder interface mode
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:把TIM4初始化为编码器接口模式
|
||||
入口参数:无
|
||||
返 回 值:无
|
||||
**************************************************************************/
|
||||
void Encoder_Init_TIM4(void)
|
||||
{
|
||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||
TIM_ICInitTypeDef TIM_ICInitStructure;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);//使能定时器4的时钟
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能PB端口时钟
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;//端口配置
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB
|
||||
|
||||
GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_TIM4); //复用为TIM4 编码器接口
|
||||
GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_TIM4); //复用为TIM4 编码器接口
|
||||
|
||||
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
|
||||
|
||||
TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // No prescaling
|
||||
TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD; //设定计数器自动重装值
|
||||
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择时钟分频:不分频
|
||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数
|
||||
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
|
||||
|
||||
TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用编码器模式3
|
||||
TIM_ICStructInit(&TIM_ICInitStructure);
|
||||
TIM_ICInitStructure.TIM_ICFilter = 0;
|
||||
TIM_ICInit(TIM4, &TIM_ICInitStructure);
|
||||
|
||||
TIM_ClearFlag(TIM4, TIM_FLAG_Update);
|
||||
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
|
||||
TIM_SetCounter(TIM4,0);
|
||||
TIM_Cmd(TIM4, ENABLE);
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Initialize TIM5 as the encoder interface mode
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:把TIM5初始化为编码器接口模式
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void Encoder_Init_TIM5(void)
|
||||
{
|
||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||
TIM_ICInitTypeDef TIM_ICInitStructure;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);//使能定时器4的时钟
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能PB端口时钟
|
||||
|
||||
GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM5); //复用为TIM4 编码器接口
|
||||
GPIO_PinAFConfig(GPIOA,GPIO_PinSource1,GPIO_AF_TIM5); //复用为TIM4 编码器接口
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;//端口配置
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOB
|
||||
|
||||
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
|
||||
|
||||
TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // No prescaling
|
||||
TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD; //设定计数器自动重装值
|
||||
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择时钟分频:不分频
|
||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数
|
||||
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);
|
||||
|
||||
TIM_EncoderInterfaceConfig(TIM5, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用编码器模式3
|
||||
TIM_ICStructInit(&TIM_ICInitStructure);
|
||||
TIM_ICInitStructure.TIM_ICFilter = 0;
|
||||
TIM_ICInit(TIM5, &TIM_ICInitStructure);
|
||||
|
||||
TIM_ClearFlag(TIM5, TIM_FLAG_Update);
|
||||
TIM_ITConfig(TIM5, TIM_IT_Update, ENABLE);
|
||||
TIM_SetCounter(TIM5,0);
|
||||
TIM_Cmd(TIM5, ENABLE);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: Read the encoder count
|
||||
Input : The timer
|
||||
Output : Encoder value (representing speed)
|
||||
函数功能:读取编码器计数
|
||||
入口参数:定时器
|
||||
返回 值:编码器数值(代表速度)
|
||||
**************************************************************************/
|
||||
int Read_Encoder(u8 TIMX)
|
||||
{
|
||||
int Encoder_TIM;
|
||||
switch(TIMX)
|
||||
{
|
||||
case 2: Encoder_TIM= (short)TIM2 -> CNT; TIM2 -> CNT=0; break;
|
||||
case 3: Encoder_TIM= (short)TIM3 -> CNT; TIM3 -> CNT=0; break;
|
||||
case 4: Encoder_TIM= (short)TIM4 -> CNT; TIM4 -> CNT=0; break;
|
||||
case 5: Encoder_TIM= (short)TIM5 -> CNT; TIM5 -> CNT=0; break;
|
||||
default: Encoder_TIM=0;
|
||||
}
|
||||
return Encoder_TIM;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: Tim2 interrupt service function
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:TIM2中断服务函数
|
||||
入口参数:无
|
||||
返 回 值:无
|
||||
**************************************************************************/
|
||||
void TIM2_IRQHandler(void)
|
||||
{
|
||||
if(TIM2->SR&0X0001) //Overflow interrupt //溢出中断
|
||||
{
|
||||
}
|
||||
TIM2->SR&=~(1<<0); //Clear the interrupt flag bit //清除中断标志位
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Tim3 interrupt service function
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:TIM3中断服务函数
|
||||
入口参数:无
|
||||
返 回 值:无
|
||||
**************************************************************************/
|
||||
void TIM3_IRQHandler(void)
|
||||
{
|
||||
if(TIM3->SR&0X0001) //Overflow interrupt //溢出中断
|
||||
{
|
||||
}
|
||||
TIM3->SR&=~(1<<0); //Clear the interrupt flag bit //清除中断标志位
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Tim4 interrupt service function
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:TIM4中断服务函数
|
||||
入口参数:无
|
||||
返 回 值:无
|
||||
**************************************************************************/
|
||||
void TIM4_IRQHandler(void)
|
||||
{
|
||||
if(TIM4->SR&0X0001) //Overflow interrupt //溢出中断
|
||||
{
|
||||
}
|
||||
TIM4->SR&=~(1<<0); //Clear the interrupt flag bit //清除中断标志位
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: Tim9 interrupt service function
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:TIM9中断服务函数
|
||||
入口参数:无
|
||||
返 回 值:无
|
||||
**************************************************************************/
|
||||
void TIM5_IRQHandler(void)
|
||||
{
|
||||
if(TIM5->SR&0X0001) //Overflow interrupt //溢出中断
|
||||
{
|
||||
}
|
||||
TIM5->SR&=~(1<<0); //Clear the interrupt flag bit //清除中断标志位
|
||||
}
|
||||
|
||||
void TIM8_BRK_TIM12_IRQHandler(void)
|
||||
{
|
||||
if(TIM12->SR&0X0001) //Overflow interrupt //溢出中断
|
||||
{
|
||||
}
|
||||
TIM12->SR&=~(1<<0); //Clear the interrupt flag bit //清除中断标志位
|
||||
|
||||
}
|
||||
24
HARDWARE/encoder.h
Normal file
24
HARDWARE/encoder.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef __ENCODER_H
|
||||
#define __ENCODER_H
|
||||
#include <sys.h>
|
||||
#include "system.h"
|
||||
|
||||
// No larger than 65535, because the timer of STM32F103 is 16 bit
|
||||
//不可大于65535,因为STM32F103的定时器是16位的
|
||||
#define ENCODER_TIM_PERIOD (u16)(65535)
|
||||
|
||||
void Encoder_Init_TIM2(void);
|
||||
void Encoder_Init_TIM3(void);
|
||||
void Encoder_Init_TIM4(void);
|
||||
void Encoder_Init_TIM5(void);
|
||||
|
||||
|
||||
int Read_Encoder(u8 TIMX);
|
||||
|
||||
void TIM2_IRQHandler(void);
|
||||
void TIM3_IRQHandler(void);
|
||||
void TIM4_IRQHandler(void);
|
||||
void TIM5_IRQHandler(void);
|
||||
void TIM8_BRK_TIM12_IRQHandler(void);
|
||||
|
||||
#endif
|
||||
29
HARDWARE/exti.c
Normal file
29
HARDWARE/exti.c
Normal file
@@ -0,0 +1,29 @@
|
||||
#include "exti.h"
|
||||
/**************************************************************************
|
||||
作者:平衡小车之家
|
||||
我的淘宝小店:http://shop114407458.taobao.com/
|
||||
**************************************************************************/
|
||||
/**************************************************************************
|
||||
函数功能:外部中断初始化
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void EXTI1_Init(void)
|
||||
{
|
||||
// RCC->APB2ENR|=1<<3; //使能PORTB时钟
|
||||
// GPIOB->CRH&=0X0FFFFFFF;
|
||||
// GPIOB->CRH|=0X80000000;//PB5上拉输入
|
||||
// GPIOB->ODR|=1<<15; //PB5上拉
|
||||
// Ex_NVIC_Config(GPIO_B,15,FTIR); //下降沿触发
|
||||
// MY_NVIC_Init(2,1,EXTI15_10_IRQn,2); //抢占2,子优先级1,组2
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
35
HARDWARE/exti.h
Normal file
35
HARDWARE/exti.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef __EXTI_H
|
||||
#define __EXIT_H
|
||||
#include "sys.h"
|
||||
/**************************************************************************
|
||||
作者:平衡小车之家
|
||||
我的淘宝小店:http://shop114407458.taobao.com/
|
||||
**************************************************************************/
|
||||
#define INT PBin(15) //PB5连接到MPU6050的中断引脚
|
||||
void EXTI_Init(void); //外部中断初始化
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
185
HARDWARE/key.c
Normal file
185
HARDWARE/key.c
Normal file
@@ -0,0 +1,185 @@
|
||||
#include "key.h"
|
||||
|
||||
/**************************************************************************
|
||||
Function: Key initialization
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:按键初始化
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void KEY_Init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOB时钟
|
||||
GPIO_InitStructure.GPIO_Pin = KEY_PIN; //KEY对应引脚
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
|
||||
GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOB14
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Buttons to scan
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:按键扫描
|
||||
入口参数:无
|
||||
返回 值:按键状态 0:无动作 1:单击
|
||||
**************************************************************************/
|
||||
u8 click(void)
|
||||
{
|
||||
//Press the release sign
|
||||
//按键按松开标志
|
||||
static u8 flag_key=1;
|
||||
|
||||
if(flag_key&&KEY==0)
|
||||
{
|
||||
flag_key=0; //The key is pressed //按键按下
|
||||
return 1;
|
||||
}
|
||||
else if(1==KEY)
|
||||
flag_key=1;
|
||||
return 0; //No key is pressed //无按键按下
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Delay function
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:延迟函数
|
||||
入口参数:无
|
||||
返 回 值:无
|
||||
**************************************************************************/
|
||||
void Delay_ms(void)
|
||||
{
|
||||
int ii,i;
|
||||
for(ii=0;ii<50;ii++)
|
||||
{
|
||||
for(i=0;i<50;i++);
|
||||
}
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Buttons to scan
|
||||
Input : Double click wait time
|
||||
Output : Button status: 0- no action, 1- click, 2- double click
|
||||
函数功能:按键扫描
|
||||
入口参数:双击等待时间
|
||||
返回 值:按键状态: 0-无动作, 1-单击, 2-双击
|
||||
**************************************************************************/
|
||||
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++;
|
||||
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; //Double click //双击
|
||||
}
|
||||
}
|
||||
if(1==KEY) flag_key=0,count_key=0;
|
||||
|
||||
if(1==double_key)
|
||||
{
|
||||
count_single++;
|
||||
if(count_single>time&&Forever_count<time)
|
||||
{
|
||||
double_key=0;
|
||||
count_single=0;
|
||||
return 1; //Click //单击
|
||||
}
|
||||
if(Forever_count>time)
|
||||
{
|
||||
double_key=0;
|
||||
count_single=0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Button scan.Because static variables are used, a function with a different name needs to be defined when the keystroke scan function is used multiple times
|
||||
Input : none
|
||||
Output : Button status: 0- no action, 1- click, 2- double click
|
||||
函数功能:按键扫描。因为使用到了静态变量,当多处需要使用按键扫描函数时,需要再定义一个不同名函数
|
||||
入口参数:无
|
||||
返 回 值:按键状态: 0-无动作, 1-单击, 2-双击
|
||||
**************************************************************************/
|
||||
u8 click_N_Double_MPU6050 (u8 time)
|
||||
{
|
||||
static u8 flag_key,count_key,double_key;
|
||||
static u16 count_single,Forever_count;
|
||||
|
||||
if(KEY==0) Forever_count++;
|
||||
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; //Double click //双击
|
||||
}
|
||||
}
|
||||
if(1==KEY) flag_key=0,count_key=0;
|
||||
|
||||
if(1==double_key)
|
||||
{
|
||||
count_single++;
|
||||
if(count_single>time&&Forever_count<time)
|
||||
{
|
||||
double_key=0;
|
||||
count_single=0;
|
||||
return 1; //Click //单击
|
||||
}
|
||||
if(Forever_count>time)
|
||||
{
|
||||
double_key=0;
|
||||
count_single=0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Long according to the test
|
||||
Input : none
|
||||
Output : Key state 0: no action 1: long press 3s
|
||||
函数功能:长按检测
|
||||
入口参数:无
|
||||
返回 值:按键状态 0:无动作 1:长按3s
|
||||
**************************************************************************/
|
||||
u8 Long_Press(void)
|
||||
{
|
||||
static u16 Long_Press_count,Long_Press;
|
||||
|
||||
if(Long_Press==0&&KEY==0) Long_Press_count++;
|
||||
else Long_Press_count=0;
|
||||
|
||||
if(Long_Press_count>15) //3 seconds //3秒
|
||||
{
|
||||
Long_Press=1;
|
||||
Long_Press_count=0;
|
||||
return 1;
|
||||
}
|
||||
if(Long_Press==1) //Long press position 1 //长按标志位置1
|
||||
{
|
||||
Long_Press=0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
19
HARDWARE/key.h
Normal file
19
HARDWARE/key.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef __KEY_H
|
||||
#define __KEY_H
|
||||
#include "sys.h"
|
||||
#include "system.h"
|
||||
|
||||
void KEY_Init(void);
|
||||
u8 click(void);
|
||||
void Delay_ms(void);
|
||||
u8 click_N_Double (u8 time);
|
||||
u8 click_N_Double_MPU6050 (u8 time);
|
||||
u8 Long_Press(void);
|
||||
|
||||
/*--------KEY control pin--------*/
|
||||
#define KEY_PORT GPIOE
|
||||
#define KEY_PIN GPIO_Pin_0
|
||||
#define KEY PEin(0)
|
||||
/*----------------------------------*/
|
||||
|
||||
#endif
|
||||
222
HARDWARE/motor.c
Normal file
222
HARDWARE/motor.c
Normal file
@@ -0,0 +1,222 @@
|
||||
#include "motor.h"
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
Function: Enable switch pin initialization
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:使能开关引脚初始化
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void Enable_Pin(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);//使能GPIOB时钟
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //KEY对应引脚
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
|
||||
GPIO_Init(GPIOD, &GPIO_InitStructure);//初始化GPIOB14
|
||||
}
|
||||
|
||||
void TIM1_PWM_Init(u16 arr,u16 psc)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||
TIM_OCInitTypeDef TIM_OCInitStructure;
|
||||
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); //TIM8时钟使能
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); //使能PORTC时钟
|
||||
|
||||
GPIO_PinAFConfig(GPIOE,GPIO_PinSource9,GPIO_AF_TIM1);
|
||||
GPIO_PinAFConfig(GPIOE,GPIO_PinSource11,GPIO_AF_TIM1);
|
||||
GPIO_PinAFConfig(GPIOE,GPIO_PinSource13,GPIO_AF_TIM1);
|
||||
GPIO_PinAFConfig(GPIOE,GPIO_PinSource14,GPIO_AF_TIM1);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_11|GPIO_Pin_13|GPIO_Pin_14; //GPIO
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
|
||||
GPIO_Init(GPIOE,&GPIO_InitStructure); //初始化PC口
|
||||
|
||||
//Sets the value of the auto-reload register cycle for the next update event load activity
|
||||
//设置在下一个更新事件装入活动的自动重装载寄存器周期的值
|
||||
TIM_TimeBaseStructure.TIM_Period = arr;
|
||||
//Sets the pre-divider value used as the TIMX clock frequency divisor
|
||||
//设置用来作为TIMx时钟频率除数的预分频值
|
||||
TIM_TimeBaseStructure.TIM_Prescaler =psc;
|
||||
//Set the clock split :TDTS = Tck_tim
|
||||
//设置时钟分割:TDTS = Tck_tim
|
||||
TIM_TimeBaseStructure.TIM_ClockDivision = 1;
|
||||
//Up counting mode
|
||||
//向上计数模式
|
||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||
//Initializes the timebase unit for TIMX based on the parameter specified in TIM_TIMEBASEINITSTRUCT
|
||||
//根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
|
||||
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
|
||||
|
||||
//Select Timer mode :TIM Pulse Width Modulation mode 1
|
||||
//选择定时器模式:TIM脉冲宽度调制模式1
|
||||
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
|
||||
//Compare output enablement
|
||||
//比较输出使能
|
||||
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
|
||||
//Output polarity :TIM output polarity is higher
|
||||
//输出极性:TIM输出比较极性高
|
||||
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
|
||||
//Initialize the peripheral TIMX based on the parameter specified in TIM_OCINITSTRUCT
|
||||
//根据TIM_OCInitStruct中指定的参数初始化外设TIMx
|
||||
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
|
||||
TIM_OC2Init(TIM1, &TIM_OCInitStructure);
|
||||
TIM_OC3Init(TIM1, &TIM_OCInitStructure);
|
||||
TIM_OC4Init(TIM1, &TIM_OCInitStructure);
|
||||
|
||||
// Advanced timer output must be enabled
|
||||
//高级定时器输出必须使能这句
|
||||
TIM_CtrlPWMOutputs(TIM1,ENABLE);
|
||||
|
||||
//CH1 is pre-loaded and enabled
|
||||
//CH1预装载使能
|
||||
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
|
||||
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
|
||||
TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
|
||||
TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);
|
||||
|
||||
// Enable the TIMX preloaded register on the ARR
|
||||
//使能TIMx在ARR上的预装载寄存器
|
||||
TIM_ARRPreloadConfig(TIM1, ENABLE);
|
||||
|
||||
//Enable TIM8
|
||||
//使能TIM8
|
||||
TIM_Cmd(TIM1, ENABLE);
|
||||
}
|
||||
|
||||
void TIM9_PWM_Init(u16 arr,u16 psc)
|
||||
{
|
||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
TIM_OCInitTypeDef TIM_OCInitStructure;
|
||||
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9,ENABLE);/*使能定时器11时钟*/
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);/*使能GPIOF时钟*/
|
||||
|
||||
GPIO_PinAFConfig(GPIOE,GPIO_PinSource5,GPIO_AF_TIM9);/*复用*/
|
||||
GPIO_PinAFConfig(GPIOE,GPIO_PinSource6,GPIO_AF_TIM9);/*复用*/
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6; //GPIOF9
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
|
||||
GPIO_Init(GPIOE,&GPIO_InitStructure); //初始化PF9
|
||||
|
||||
TIM_TimeBaseInitStructure.TIM_Period = arr;/*自动重装载*/
|
||||
TIM_TimeBaseInitStructure.TIM_Prescaler = psc;/*预分频*/
|
||||
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;/*时钟分频*/
|
||||
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;/*向上计数*/
|
||||
TIM_TimeBaseInit(TIM9,&TIM_TimeBaseInitStructure);/*初始化*/
|
||||
|
||||
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;/*PWM模式*/
|
||||
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;/*输出*/
|
||||
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;/*比较极性高*/
|
||||
TIM_OC1Init(TIM9,&TIM_OCInitStructure);
|
||||
TIM_OC2Init(TIM9,&TIM_OCInitStructure);
|
||||
|
||||
TIM_OC1PreloadConfig(TIM9,TIM_OCPreload_Enable);/*输出比较预装载使能*/
|
||||
TIM_OC2PreloadConfig(TIM9,TIM_OCPreload_Enable);/*输出比较预装载使能*/
|
||||
|
||||
TIM_ARRPreloadConfig(TIM9,ENABLE);/*自动重载预装载使能*/
|
||||
|
||||
TIM_Cmd(TIM9,ENABLE);/*计数使能*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
void TIM10_PWM_Init(u16 arr,u16 psc)
|
||||
{
|
||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
TIM_OCInitTypeDef TIM_OCInitStructure;
|
||||
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);/*使能GPIOF时钟*/
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10,ENABLE);/*使能定时器11时钟*/
|
||||
|
||||
GPIO_PinAFConfig(GPIOB,GPIO_PinSource8,GPIO_AF_TIM10);/*复用*/
|
||||
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;/*复用*/
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;/*推挽输出*/
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;/*PF7*/
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;/*上拉*/
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;/**/
|
||||
GPIO_Init(GPIOB,&GPIO_InitStructure);/*初始化IO*/
|
||||
|
||||
TIM_TimeBaseInitStructure.TIM_Period = arr;/*自动重装载*/
|
||||
TIM_TimeBaseInitStructure.TIM_Prescaler = psc;/*预分频*/
|
||||
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;/*时钟分频*/
|
||||
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;/*向上计数*/
|
||||
TIM_TimeBaseInit(TIM10,&TIM_TimeBaseInitStructure);/*初始化*/
|
||||
|
||||
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;/*PWM模式*/
|
||||
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;/*输出*/
|
||||
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;/*比较极性高*/
|
||||
TIM_OC1Init(TIM10,&TIM_OCInitStructure);
|
||||
|
||||
TIM_OC1PreloadConfig(TIM10,TIM_OCPreload_Enable);/*输出比较预装载使能*/
|
||||
|
||||
//TIM_CtrlPWMOutputs(TIM10,ENABLE);
|
||||
|
||||
TIM_ARRPreloadConfig(TIM10,ENABLE);/*自动重载预装载使能*/
|
||||
|
||||
TIM_Cmd(TIM10,ENABLE);/*计数使能*/
|
||||
|
||||
}
|
||||
|
||||
void TIM11_PWM_Init(u16 arr,u16 psc)
|
||||
{
|
||||
|
||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
TIM_OCInitTypeDef TIM_OCInitStructure;
|
||||
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);/*使能GPIOF时钟*/
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11,ENABLE);/*使能定时器11时钟*/
|
||||
|
||||
GPIO_PinAFConfig(GPIOB,GPIO_PinSource9,GPIO_AF_TIM11);/*复用*/
|
||||
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;/*复用*/
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;/*推挽输出*/
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;/*PF7*/
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;/*上拉*/
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;/**/
|
||||
GPIO_Init(GPIOB,&GPIO_InitStructure);/*初始化IO*/
|
||||
|
||||
TIM_TimeBaseInitStructure.TIM_Period = arr;/*自动重装载*/
|
||||
TIM_TimeBaseInitStructure.TIM_Prescaler = psc;/*预分频*/
|
||||
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;/*时钟分频*/
|
||||
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;/*向上计数*/
|
||||
TIM_TimeBaseInit(TIM11,&TIM_TimeBaseInitStructure);/*初始化*/
|
||||
|
||||
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;/*PWM模式*/
|
||||
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;/*输出*/
|
||||
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;/*比较极性高*/
|
||||
TIM_OC1Init(TIM11,&TIM_OCInitStructure);
|
||||
|
||||
TIM_OC1PreloadConfig(TIM11,TIM_OCPreload_Enable);/*输出比较预装载使能*/
|
||||
|
||||
TIM_CtrlPWMOutputs(TIM11,ENABLE);
|
||||
|
||||
TIM_ARRPreloadConfig(TIM11,ENABLE);/*自动重载预装载使能*/
|
||||
|
||||
TIM_Cmd(TIM11,ENABLE);/*计数使能*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
63
HARDWARE/motor.h
Normal file
63
HARDWARE/motor.h
Normal file
@@ -0,0 +1,63 @@
|
||||
|
||||
#ifndef __MOTOR_H
|
||||
#define __MOTOR_H
|
||||
|
||||
#include "system.h"
|
||||
|
||||
/*--------Motor_A control pins--------*/
|
||||
#define PWM_PORTA1 GPIOB //PWMA
|
||||
#define PWM_PIN_A1 GPIO_Pin_8 //PWMA
|
||||
#define PWMA1 TIM10->CCR1 //PWMA
|
||||
|
||||
#define PWM_PORTA2 GPIOB //PWMA
|
||||
#define PWM_PIN_A2 GPIO_Pin_9 //PWMA
|
||||
#define PWMA2 TIM11->CCR1 //PWMA
|
||||
/*------------------------------------*/
|
||||
|
||||
/*--------Motor_B control pins--------*/
|
||||
#define PWM_PORTB1 GPIOE //PWMB
|
||||
#define PWM_PIN_B1 GPIO_Pin_5 //PWMB
|
||||
#define PWMB1 TIM9->CCR1 //PWMB
|
||||
|
||||
#define PWM_PORTB2 GPIOE //PWMB
|
||||
#define PWM_PIN_B2 GPIO_Pin_6 //PWMB
|
||||
#define PWMB2 TIM9->CCR2 //PWMB
|
||||
|
||||
/*------------------------------------*/
|
||||
|
||||
/*--------Motor_C control pins--------*/
|
||||
#define PWM_PORTC1 GPIOE //PWMC
|
||||
#define PWM_PIN_C1 GPIO_Pin_11 //PWMC
|
||||
#define PWMC1 TIM1->CCR2 //PWMC
|
||||
|
||||
#define PWM_PORTC2 GPIOE //PWMC
|
||||
#define PWM_PIN_C2 GPIO_Pin_9 //PWMC
|
||||
#define PWMC2 TIM1->CCR1 //PWMC
|
||||
|
||||
/*------------------------------------*/
|
||||
|
||||
/*--------Motor_D control pins--------*/
|
||||
#define PWM_PORTD1 GPIOE //PWMD
|
||||
#define PWM_PIN_D1 GPIO_Pin_14 //PWMD
|
||||
#define PWMD1 TIM1->CCR4 //PWMD
|
||||
|
||||
#define PWM_PORTD2 GPIOE //PWMD
|
||||
#define PWM_PIN_D2 GPIO_Pin_13 //PWMD
|
||||
#define PWMD2 TIM1->CCR3 //PWMD
|
||||
|
||||
/*------------------------------------*/
|
||||
#define EN PDin(3)
|
||||
|
||||
#define Servo_PWM TIM12->CCR2
|
||||
#define SERVO_INIT 1600 //Servo zero point //¶æ»úÁãµã
|
||||
|
||||
void Enable_Pin(void);
|
||||
void Servo_PWM_Init(u16 arr,u16 psc);
|
||||
void TIM1_PWM_Init(u16 arr,u16 psc);
|
||||
void TIM9_PWM_Init(u16 arr,u16 psc);
|
||||
void TIM10_PWM_Init(u16 arr,u16 psc);
|
||||
void TIM11_PWM_Init(u16 arr,u16 psc);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
325
HARDWARE/oled.c
Normal file
325
HARDWARE/oled.c
Normal file
@@ -0,0 +1,325 @@
|
||||
#include "oled.h"
|
||||
#include "stdlib.h"
|
||||
#include "oledfont.h"
|
||||
#include "delay.h"
|
||||
|
||||
u8 OLED_GRAM[128][8];
|
||||
/**************************************************************************
|
||||
Function: Refresh the OLED screen
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:刷新OLED屏幕
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void OLED_Refresh_Gram(void)
|
||||
{
|
||||
u8 i,n;
|
||||
for(i=0;i<8;i++)
|
||||
{
|
||||
OLED_WR_Byte (0xb0+i,OLED_CMD); //Set page address (0~7) //设置页地址(0~7)
|
||||
OLED_WR_Byte (0x00,OLED_CMD); //Set the display location - column low address //设置显示位置—列低地址
|
||||
OLED_WR_Byte (0x10,OLED_CMD); //Set the display location - column height address //设置显示位置—列高地址
|
||||
for(n=0;n<128;n++)OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA);
|
||||
}
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Refresh the OLED screen
|
||||
Input : Dat: data/command to write, CMD: data/command flag 0, represents the command;1, represents data
|
||||
Output : none
|
||||
函数功能:向OLED写入一个字节
|
||||
入口参数:dat:要写入的数据/命令,cmd:数据/命令标志 0,表示命令;1,表示数据
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void OLED_WR_Byte(u8 dat,u8 cmd)
|
||||
{
|
||||
u8 i;
|
||||
if(cmd)
|
||||
OLED_RS_Set();
|
||||
else
|
||||
OLED_RS_Clr();
|
||||
for(i=0;i<8;i++)
|
||||
{
|
||||
OLED_SCLK_Clr();
|
||||
if(dat&0x80)
|
||||
OLED_SDIN_Set();
|
||||
else
|
||||
OLED_SDIN_Clr();
|
||||
OLED_SCLK_Set();
|
||||
dat<<=1;
|
||||
}
|
||||
OLED_RS_Set();
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Turn on the OLED display
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:开启OLED显示
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void OLED_Display_On(void)
|
||||
{
|
||||
OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC command //SET DCDC命令
|
||||
OLED_WR_Byte(0X14,OLED_CMD); //DCDC ON
|
||||
OLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Turn off the OLED display
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:关闭OLED显示
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void OLED_Display_Off(void)
|
||||
{
|
||||
OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC command //SET DCDC命令
|
||||
OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFF
|
||||
OLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Screen clear function, clear the screen, the entire screen is black, and did not light up the same
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:清屏函数,清完屏,整个屏幕是黑色的,和没点亮一样
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void OLED_Clear(void)
|
||||
{
|
||||
u8 i,n;
|
||||
for(i=0;i<8;i++)for(n=0;n<128;n++)OLED_GRAM[n][i]=0X00;
|
||||
OLED_Refresh_Gram(); //Update the display //更新显示
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Draw point
|
||||
Input : x,y: starting coordinate;T :1, fill,0, empty
|
||||
Output : none
|
||||
函数功能:画点
|
||||
入口参数:x,y :起点坐标; t:1,填充,0,清空
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void OLED_DrawPoint(u8 x,u8 y,u8 t)
|
||||
{
|
||||
u8 pos,bx,temp=0;
|
||||
if(x>127||y>63)return;//超出范围了.
|
||||
pos=7-y/8;
|
||||
bx=y%8;
|
||||
temp=1<<(7-bx);
|
||||
if(t)OLED_GRAM[x][pos]|=temp;
|
||||
else OLED_GRAM[x][pos]&=~temp;
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Displays a character, including partial characters, at the specified position
|
||||
Input : x,y: starting coordinate;Len: The number of digits;Size: font size;Mode :0, anti-white display,1, normal display
|
||||
Output : none
|
||||
函数功能:在指定位置显示一个字符,包括部分字符
|
||||
入口参数:x,y :起点坐标; len :数字的位数; size:字体大小; mode:0,反白显示,1,正常显示
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode)
|
||||
{
|
||||
u8 temp,t,t1;
|
||||
u8 y0=y;
|
||||
chr=chr-' '; //Get the offset value //得到偏移后的值
|
||||
for(t=0;t<size;t++)
|
||||
{
|
||||
if(size==12)temp=oled_asc2_1206[chr][t]; //Invoke 1206 font //调用1206字体
|
||||
else temp=oled_asc2_1608[chr][t]; //Invoke the 1608 font //调用1608字体
|
||||
for(t1=0;t1<8;t1++)
|
||||
{
|
||||
if(temp&0x80)OLED_DrawPoint(x,y,mode);
|
||||
else OLED_DrawPoint(x,y,!mode);
|
||||
temp<<=1;
|
||||
y++;
|
||||
if((y-y0)==size)
|
||||
{
|
||||
y=y0;
|
||||
x++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Find m to the NTH power
|
||||
Input : m: base number, n: power number
|
||||
Output : none
|
||||
函数功能:求m的n次方的函数
|
||||
入口参数:m:底数,n:次方数
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
u32 oled_pow(u8 m,u8 n)
|
||||
{
|
||||
u32 result=1;
|
||||
while(n--)result*=m;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: Displays 2 numbers
|
||||
Input : x,y: starting coordinate;Len: The number of digits;Size: font size;Mode: mode, 0, fill mode, 1, overlay mode;Num: value (0 ~ 4294967295);
|
||||
Output : none
|
||||
函数功能:显示2个数字
|
||||
入口参数:x,y :起点坐标; len :数字的位数; size:字体大小; mode:模式, 0,填充模式, 1,叠加模式; num:数值(0~4294967295);
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void OLED_ShowNumber(u8 x,u8 y,u32 num,u8 len,u8 size)
|
||||
{
|
||||
u8 t,temp;
|
||||
u8 enshow=0;
|
||||
for(t=0;t<len;t++)
|
||||
{
|
||||
temp=(num/oled_pow(10,len-t-1))%10;
|
||||
if(enshow==0&&t<(len-1))
|
||||
{
|
||||
if(temp==0)
|
||||
{
|
||||
OLED_ShowChar(x+(size/2)*t,y,' ',size,1);
|
||||
continue;
|
||||
}else enshow=1;
|
||||
|
||||
}
|
||||
OLED_ShowChar(x+(size/2)*t,y,temp+'0',size,1);
|
||||
}
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Display string
|
||||
Input : x,y: starting coordinate;*p: starting address of the string
|
||||
Output : none
|
||||
函数功能:显示字符串
|
||||
入口参数:x,y :起点坐标; *p:字符串起始地址
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void OLED_ShowString(u8 x,u8 y,const u8 *p)
|
||||
{
|
||||
#define MAX_CHAR_POSX 122
|
||||
#define MAX_CHAR_POSY 58
|
||||
while(*p!='\0')
|
||||
{
|
||||
if(x>MAX_CHAR_POSX){x=0;y+=16;}
|
||||
if(y>MAX_CHAR_POSY){y=x=0;OLED_Clear();}
|
||||
OLED_ShowChar(x,y,*p,12,1);
|
||||
x+=8;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Initialize the OLED
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:初始化OLED
|
||||
入口参数: 无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void OLED_Init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
//Enable pB port clock
|
||||
//使能PB端口时钟
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD , ENABLE); //使能GPIOC
|
||||
|
||||
//Port configuration
|
||||
//端口配置
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //输出
|
||||
GPIO_InitStructure.GPIO_OType =GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_Speed =GPIO_Speed_2MHz; //2M
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//根据设定参数初始化GPIO
|
||||
GPIO_Init(GPIOD, &GPIO_InitStructure);
|
||||
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR , ENABLE); //PWR使能
|
||||
//Allows you to modify RTC and backup registers
|
||||
//允许修改RTC和后备寄存器
|
||||
PWR_BackupAccessCmd(ENABLE);
|
||||
//Turn off the external low speed external clock signal function, PC13, PC14, PC15 can be used as normal IO
|
||||
//关闭外部低速外部时钟信号功能 后,PC13 PC14 PC15 才可以当普通IO用
|
||||
RCC_LSEConfig(RCC_LSE_OFF);
|
||||
//Do not modify the backup register
|
||||
//禁止修改后备寄存器
|
||||
PWR_BackupAccessCmd(DISABLE);
|
||||
|
||||
OLED_RST_Clr();
|
||||
delay_ms(100);
|
||||
OLED_RST_Set();
|
||||
|
||||
OLED_WR_Byte(0xAE,OLED_CMD); //Close display //关闭显示
|
||||
OLED_WR_Byte(0xD5,OLED_CMD); //The frequency frequency factor, the frequency of the shock //设置时钟分频因子,震荡频率
|
||||
OLED_WR_Byte(80,OLED_CMD); //[3:0], the frequency dividing factor;[7:4], oscillation frequency //[3:0],分频因子;[7:4],震荡频率
|
||||
OLED_WR_Byte(0xA8,OLED_CMD); //Set the number of driver paths //设置驱动路数
|
||||
OLED_WR_Byte(0X3F,OLED_CMD); //Default 0x3f(1/64) //默认0X3F(1/64)
|
||||
OLED_WR_Byte(0xD3,OLED_CMD); //Setting display deviation //设置显示偏移
|
||||
OLED_WR_Byte(0X00,OLED_CMD); //Default is 0//默认为0
|
||||
|
||||
OLED_WR_Byte(0x40,OLED_CMD); //Sets the number of rows to display starting line [5:0] //设置显示开始行 [5:0],行数
|
||||
|
||||
OLED_WR_Byte(0x8D,OLED_CMD); //Charge pump setup //电荷泵设置
|
||||
OLED_WR_Byte(0x14,OLED_CMD); //Bit2, on/off //bit2,开启/关闭
|
||||
OLED_WR_Byte(0x20,OLED_CMD); //Set up the memory address mode //设置内存地址模式
|
||||
OLED_WR_Byte(0x02,OLED_CMD); //[1:0],00, column address mode;01, line address mode;10. Page address mode;The default 10; //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;
|
||||
OLED_WR_Byte(0xA1,OLED_CMD); //Segment redefine setting,bit0:0,0- >;0;1, 0 - & gt;127; //段重定义设置,bit0:0,0->0;1,0->127;
|
||||
OLED_WR_Byte(0xC0,OLED_CMD); //Set the COM scan direction;Bit3:0, normal mode;1, Re-define schema COM[n-1]- >;COM0;N: Number of driving paths//设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数
|
||||
OLED_WR_Byte(0xDA,OLED_CMD); //Set the COM hardware pin configuration //设置COM硬件引脚配置
|
||||
OLED_WR_Byte(0x12,OLED_CMD); //[5:4]configuration //[5:4]配置
|
||||
|
||||
OLED_WR_Byte(0x81,OLED_CMD); //Contrast Settings //对比度设置
|
||||
OLED_WR_Byte(0xEF,OLED_CMD); //1~ 255; Default 0x7f (brightness Settings, the bigger the brighter) //1~255;默认0X7F (亮度设置,越大越亮)
|
||||
OLED_WR_Byte(0xD9,OLED_CMD); //Set the pre-charging cycle //设置预充电周期
|
||||
OLED_WR_Byte(0xf1,OLED_CMD); //[3:0],PHASE 1;[7:4],PHASE 2;
|
||||
OLED_WR_Byte(0xDB,OLED_CMD); //Setting vcomh voltage multiplier//设置VCOMH 电压倍率
|
||||
OLED_WR_Byte(0x30,OLED_CMD); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;
|
||||
|
||||
OLED_WR_Byte(0xA4,OLED_CMD); //Global display; Bit0:1, open; 0, close; (white screen/black screen)//全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)
|
||||
OLED_WR_Byte(0xA6,OLED_CMD); //Settings display mode; Bit0:1, anti-phase display; 0, normal display//设置显示方式;bit0:1,反相显示;0,正常显示
|
||||
OLED_WR_Byte(0xAF,OLED_CMD); //Open display //开启显示
|
||||
OLED_Clear();
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: Display character
|
||||
Input : x: indicates the horizontal coordinates displayed; Y: the vertical coordinates that show the display;
|
||||
no: the line number in the array of the Chinese character (module) in the hzk-and "array", which is determined by the line number to determine the characters shown in the array,
|
||||
The value of the width of the font here must be consistent with the size of the dot matrix value of the use of the word mold.
|
||||
font_height: the font is high for the use of the word mold, because my screen pixels are 32hours, 128----0~ 7, and four bits per page
|
||||
Output : none
|
||||
Note: this method is used to show that the Chinese character must satisfy the size of the word that the word model generates the software to generate the same size as the dot matrix
|
||||
函数功能:显示汉字
|
||||
入口参数: x:表示显示的水平坐标; y: 表示显示的垂直坐标;
|
||||
no: 表示要显示的汉字(模组)在hzk[][]数组中的行号,通过行号来确定在数组中要显示的汉字,
|
||||
这里字体的宽font_width的值必须与用字模制作软件生成字模时的点阵值大小一致;
|
||||
font_height:为用字模制作软件生成字模时字体的高,由于我的屏像素为32*128-----0~7共8页,每页4个位
|
||||
返回 值:无
|
||||
注意:用这种方法来显示汉字一定要满足用字模生成软件生成的字宽与点阵大小相同才行,否者容易乱码
|
||||
**************************************************************************/
|
||||
void OLED_ShowCHinese(u8 x,u8 y,u8 no,u8 font_width,u8 font_height)
|
||||
{
|
||||
u8 t, i;
|
||||
for(i=0;i<(font_height/8);i++) //The maximum height of font_height is 32. this screen is only 8 pages (line), four digits per page
|
||||
//font_height最大值为32,这张屏只有8个页(行),每页4个位
|
||||
{
|
||||
OLED_Set_Pos(x,y+i);
|
||||
for(t=0;t<font_width;t++) //The maximum value of font_width is 128. the screen is only that large
|
||||
//font_width最大值为128,屏幕只有这么大
|
||||
{
|
||||
OLED_WR_Byte(Hzk16[(font_height/8)*no+i][t],OLED_DATA);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Set the coordinates (position) displayed on the screen.
|
||||
Input : x, y: starting point coordinates
|
||||
Output : none
|
||||
函数功能:设置汉字在屏幕上显示的坐标(位置)
|
||||
入口参数: x,y :起点坐标
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void OLED_Set_Pos(unsigned char x, unsigned char y)
|
||||
{
|
||||
OLED_WR_Byte(0xb0+y,OLED_CMD);
|
||||
OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
|
||||
OLED_WR_Byte((x&0x0f),OLED_CMD);
|
||||
}
|
||||
|
||||
|
||||
41
HARDWARE/oled.h
Normal file
41
HARDWARE/oled.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef __OLED_H
|
||||
#define __OLED_H
|
||||
#include "sys.h"
|
||||
#include "system.h"
|
||||
|
||||
//Oled port macro definition
|
||||
//OLED端口宏定义
|
||||
#define OLED_RST_Clr() PDout(12)=0 //RST
|
||||
#define OLED_RST_Set() PDout(12)=1 //RST
|
||||
|
||||
#define OLED_RS_Clr() PDout(11)=0 //DC
|
||||
#define OLED_RS_Set() PDout(11)=1 //DC
|
||||
|
||||
#define OLED_SCLK_Clr() PDout(14)=0 //SCL
|
||||
#define OLED_SCLK_Set() PDout(14)=1 //SCL
|
||||
|
||||
#define OLED_SDIN_Clr() PDout(13)=0 //SDA
|
||||
#define OLED_SDIN_Set() PDout(13)=1 //SDA
|
||||
#define OLED_CMD 0 //Command //写命令
|
||||
#define OLED_DATA 1 //Data //写数据
|
||||
|
||||
//Oled control function
|
||||
//OLED控制用函数
|
||||
void OLED_WR_Byte(u8 dat,u8 cmd);
|
||||
void OLED_Display_On(void);
|
||||
void OLED_Display_Off(void);
|
||||
void OLED_Refresh_Gram(void);
|
||||
void OLED_Init(void);
|
||||
void OLED_Clear(void);
|
||||
void OLED_DrawPoint(u8 x,u8 y,u8 t);
|
||||
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode);
|
||||
void OLED_ShowNumber(u8 x,u8 y,u32 num,u8 len,u8 size);
|
||||
void OLED_ShowString(u8 x,u8 y,const u8 *p);
|
||||
|
||||
#define CNSizeWidth 16
|
||||
#define CNSizeHeight 16
|
||||
//extern char Hzk16[][16];
|
||||
void OLED_ShowCHinese(u8 x,u8 y,u8 no,u8 font_width,u8 font_height);
|
||||
void OLED_Set_Pos(unsigned char x, unsigned char y);
|
||||
#endif
|
||||
|
||||
398
HARDWARE/oledfont.h
Normal file
398
HARDWARE/oledfont.h
Normal file
@@ -0,0 +1,398 @@
|
||||
#ifndef __OLEDFONT_H
|
||||
#define __OLEDFONT_H
|
||||
|
||||
//Common ASCII tables
|
||||
//Offset
|
||||
//Ascii character set
|
||||
//Offset
|
||||
//Size: 1
|
||||
//常用ASCII表
|
||||
//偏移量32
|
||||
//ASCII字符集
|
||||
//偏移量32
|
||||
//大小:12*6
|
||||
const unsigned char oled_asc2_1206[95][12]={
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
|
||||
{0x00,0x00,0x00,0x00,0x3F,0x40,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
|
||||
{0x00,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x40,0x00,0x00,0x00},/*""",2*/
|
||||
{0x09,0x00,0x0B,0xC0,0x3D,0x00,0x0B,0xC0,0x3D,0x00,0x09,0x00},/*"#",3*/
|
||||
{0x18,0xC0,0x24,0x40,0x7F,0xE0,0x22,0x40,0x31,0x80,0x00,0x00},/*"$",4*/
|
||||
{0x18,0x00,0x24,0xC0,0x1B,0x00,0x0D,0x80,0x32,0x40,0x01,0x80},/*"%",5*/
|
||||
{0x03,0x80,0x1C,0x40,0x27,0x40,0x1C,0x80,0x07,0x40,0x00,0x40},/*"&",6*/
|
||||
{0x10,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x20,0x40,0x40,0x20},/*"(",8*/
|
||||
{0x00,0x00,0x40,0x20,0x20,0x40,0x1F,0x80,0x00,0x00,0x00,0x00},/*")",9*/
|
||||
{0x09,0x00,0x06,0x00,0x1F,0x80,0x06,0x00,0x09,0x00,0x00,0x00},/*"*",10*/
|
||||
{0x04,0x00,0x04,0x00,0x3F,0x80,0x04,0x00,0x04,0x00,0x00,0x00},/*"+",11*/
|
||||
{0x00,0x10,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/
|
||||
{0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00},/*"-",13*/
|
||||
{0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/
|
||||
{0x00,0x20,0x01,0xC0,0x06,0x00,0x38,0x00,0x40,0x00,0x00,0x00},/*"/",15*/
|
||||
{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"0",16*/
|
||||
{0x00,0x00,0x10,0x40,0x3F,0xC0,0x00,0x40,0x00,0x00,0x00,0x00},/*"1",17*/
|
||||
{0x18,0xC0,0x21,0x40,0x22,0x40,0x24,0x40,0x18,0x40,0x00,0x00},/*"2",18*/
|
||||
{0x10,0x80,0x20,0x40,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"3",19*/
|
||||
{0x02,0x00,0x0D,0x00,0x11,0x00,0x3F,0xC0,0x01,0x40,0x00,0x00},/*"4",20*/
|
||||
{0x3C,0x80,0x24,0x40,0x24,0x40,0x24,0x40,0x23,0x80,0x00,0x00},/*"5",21*/
|
||||
{0x1F,0x80,0x24,0x40,0x24,0x40,0x34,0x40,0x03,0x80,0x00,0x00},/*"6",22*/
|
||||
{0x30,0x00,0x20,0x00,0x27,0xC0,0x38,0x00,0x20,0x00,0x00,0x00},/*"7",23*/
|
||||
{0x1B,0x80,0x24,0x40,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"8",24*/
|
||||
{0x1C,0x00,0x22,0xC0,0x22,0x40,0x22,0x40,0x1F,0x80,0x00,0x00},/*"9",25*/
|
||||
{0x00,0x00,0x00,0x00,0x08,0x40,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/
|
||||
{0x00,0x00,0x00,0x00,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/
|
||||
{0x00,0x00,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0x40,0x40},/*"<",28*/
|
||||
{0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x00,0x00},/*"=",29*/
|
||||
{0x00,0x00,0x40,0x40,0x20,0x80,0x11,0x00,0x0A,0x00,0x04,0x00},/*">",30*/
|
||||
{0x18,0x00,0x20,0x00,0x23,0x40,0x24,0x00,0x18,0x00,0x00,0x00},/*"?",31*/
|
||||
{0x1F,0x80,0x20,0x40,0x27,0x40,0x29,0x40,0x1F,0x40,0x00,0x00},/*"@",32*/
|
||||
{0x00,0x40,0x07,0xC0,0x39,0x00,0x0F,0x00,0x01,0xC0,0x00,0x40},/*"A",33*/
|
||||
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"B",34*/
|
||||
{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x30,0x80,0x00,0x00},/*"C",35*/
|
||||
{0x20,0x40,0x3F,0xC0,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"D",36*/
|
||||
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x2E,0x40,0x30,0xC0,0x00,0x00},/*"E",37*/
|
||||
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x2E,0x00,0x30,0x00,0x00,0x00},/*"F",38*/
|
||||
{0x0F,0x00,0x10,0x80,0x20,0x40,0x22,0x40,0x33,0x80,0x02,0x00},/*"G",39*/
|
||||
{0x20,0x40,0x3F,0xC0,0x04,0x00,0x04,0x00,0x3F,0xC0,0x20,0x40},/*"H",40*/
|
||||
{0x20,0x40,0x20,0x40,0x3F,0xC0,0x20,0x40,0x20,0x40,0x00,0x00},/*"I",41*/
|
||||
{0x00,0x60,0x20,0x20,0x20,0x20,0x3F,0xC0,0x20,0x00,0x20,0x00},/*"J",42*/
|
||||
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x0B,0x00,0x30,0xC0,0x20,0x40},/*"K",43*/
|
||||
{0x20,0x40,0x3F,0xC0,0x20,0x40,0x00,0x40,0x00,0x40,0x00,0xC0},/*"L",44*/
|
||||
{0x3F,0xC0,0x3C,0x00,0x03,0xC0,0x3C,0x00,0x3F,0xC0,0x00,0x00},/*"M",45*/
|
||||
{0x20,0x40,0x3F,0xC0,0x0C,0x40,0x23,0x00,0x3F,0xC0,0x20,0x00},/*"N",46*/
|
||||
{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"O",47*/
|
||||
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x24,0x00,0x18,0x00,0x00,0x00},/*"P",48*/
|
||||
{0x1F,0x80,0x21,0x40,0x21,0x40,0x20,0xE0,0x1F,0xA0,0x00,0x00},/*"Q",49*/
|
||||
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x26,0x00,0x19,0xC0,0x00,0x40},/*"R",50*/
|
||||
{0x18,0xC0,0x24,0x40,0x24,0x40,0x22,0x40,0x31,0x80,0x00,0x00},/*"S",51*/
|
||||
{0x30,0x00,0x20,0x40,0x3F,0xC0,0x20,0x40,0x30,0x00,0x00,0x00},/*"T",52*/
|
||||
{0x20,0x00,0x3F,0x80,0x00,0x40,0x00,0x40,0x3F,0x80,0x20,0x00},/*"U",53*/
|
||||
{0x20,0x00,0x3E,0x00,0x01,0xC0,0x07,0x00,0x38,0x00,0x20,0x00},/*"V",54*/
|
||||
{0x38,0x00,0x07,0xC0,0x3C,0x00,0x07,0xC0,0x38,0x00,0x00,0x00},/*"W",55*/
|
||||
{0x20,0x40,0x39,0xC0,0x06,0x00,0x39,0xC0,0x20,0x40,0x00,0x00},/*"X",56*/
|
||||
{0x20,0x00,0x38,0x40,0x07,0xC0,0x38,0x40,0x20,0x00,0x00,0x00},/*"Y",57*/
|
||||
{0x30,0x40,0x21,0xC0,0x26,0x40,0x38,0x40,0x20,0xC0,0x00,0x00},/*"Z",58*/
|
||||
{0x00,0x00,0x00,0x00,0x7F,0xE0,0x40,0x20,0x40,0x20,0x00,0x00},/*"[",59*/
|
||||
{0x00,0x00,0x70,0x00,0x0C,0x00,0x03,0x80,0x00,0x40,0x00,0x00},/*"\",60*/
|
||||
{0x00,0x00,0x40,0x20,0x40,0x20,0x7F,0xE0,0x00,0x00,0x00,0x00},/*"]",61*/
|
||||
{0x00,0x00,0x20,0x00,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x00},/*"^",62*/
|
||||
{0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10},/*"_",63*/
|
||||
{0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
|
||||
{0x00,0x00,0x02,0x80,0x05,0x40,0x05,0x40,0x03,0xC0,0x00,0x40},/*"a",65*/
|
||||
{0x20,0x00,0x3F,0xC0,0x04,0x40,0x04,0x40,0x03,0x80,0x00,0x00},/*"b",66*/
|
||||
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x40,0x06,0x40,0x00,0x00},/*"c",67*/
|
||||
{0x00,0x00,0x03,0x80,0x04,0x40,0x24,0x40,0x3F,0xC0,0x00,0x40},/*"d",68*/
|
||||
{0x00,0x00,0x03,0x80,0x05,0x40,0x05,0x40,0x03,0x40,0x00,0x00},/*"e",69*/
|
||||
{0x00,0x00,0x04,0x40,0x1F,0xC0,0x24,0x40,0x24,0x40,0x20,0x00},/*"f",70*/
|
||||
{0x00,0x00,0x02,0xE0,0x05,0x50,0x05,0x50,0x06,0x50,0x04,0x20},/*"g",71*/
|
||||
{0x20,0x40,0x3F,0xC0,0x04,0x40,0x04,0x00,0x03,0xC0,0x00,0x40},/*"h",72*/
|
||||
{0x00,0x00,0x04,0x40,0x27,0xC0,0x00,0x40,0x00,0x00,0x00,0x00},/*"i",73*/
|
||||
{0x00,0x10,0x00,0x10,0x04,0x10,0x27,0xE0,0x00,0x00,0x00,0x00},/*"j",74*/
|
||||
{0x20,0x40,0x3F,0xC0,0x01,0x40,0x07,0x00,0x04,0xC0,0x04,0x40},/*"k",75*/
|
||||
{0x20,0x40,0x20,0x40,0x3F,0xC0,0x00,0x40,0x00,0x40,0x00,0x00},/*"l",76*/
|
||||
{0x07,0xC0,0x04,0x00,0x07,0xC0,0x04,0x00,0x03,0xC0,0x00,0x00},/*"m",77*/
|
||||
{0x04,0x40,0x07,0xC0,0x04,0x40,0x04,0x00,0x03,0xC0,0x00,0x40},/*"n",78*/
|
||||
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x40,0x03,0x80,0x00,0x00},/*"o",79*/
|
||||
{0x04,0x10,0x07,0xF0,0x04,0x50,0x04,0x40,0x03,0x80,0x00,0x00},/*"p",80*/
|
||||
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x50,0x07,0xF0,0x00,0x10},/*"q",81*/
|
||||
{0x04,0x40,0x07,0xC0,0x02,0x40,0x04,0x00,0x04,0x00,0x00,0x00},/*"r",82*/
|
||||
{0x00,0x00,0x06,0x40,0x05,0x40,0x05,0x40,0x04,0xC0,0x00,0x00},/*"s",83*/
|
||||
{0x00,0x00,0x04,0x00,0x1F,0x80,0x04,0x40,0x00,0x40,0x00,0x00},/*"t",84*/
|
||||
{0x04,0x00,0x07,0x80,0x00,0x40,0x04,0x40,0x07,0xC0,0x00,0x40},/*"u",85*/
|
||||
{0x04,0x00,0x07,0x00,0x04,0xC0,0x01,0x80,0x06,0x00,0x04,0x00},/*"v",86*/
|
||||
{0x06,0x00,0x01,0xC0,0x07,0x00,0x01,0xC0,0x06,0x00,0x00,0x00},/*"w",87*/
|
||||
{0x04,0x40,0x06,0xC0,0x01,0x00,0x06,0xC0,0x04,0x40,0x00,0x00},/*"x",88*/
|
||||
{0x04,0x10,0x07,0x10,0x04,0xE0,0x01,0x80,0x06,0x00,0x04,0x00},/*"y",89*/
|
||||
{0x00,0x00,0x04,0x40,0x05,0xC0,0x06,0x40,0x04,0x40,0x00,0x00},/*"z",90*/
|
||||
{0x00,0x00,0x00,0x00,0x04,0x00,0x7B,0xE0,0x40,0x20,0x00,0x00},/*"{",91*/
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xF0,0x00,0x00,0x00,0x00},/*"|",92*/
|
||||
{0x00,0x00,0x40,0x20,0x7B,0xE0,0x04,0x00,0x00,0x00,0x00,0x00},/*"}",93*/
|
||||
{0x40,0x00,0x80,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0x40,0x00},/*"~",94*/
|
||||
};
|
||||
const unsigned char oled_asc2_1608[95][16]={
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xCC,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
|
||||
{0x00,0x00,0x08,0x00,0x30,0x00,0x60,0x00,0x08,0x00,0x30,0x00,0x60,0x00,0x00,0x00},/*""",2*/
|
||||
{0x02,0x20,0x03,0xFC,0x1E,0x20,0x02,0x20,0x03,0xFC,0x1E,0x20,0x02,0x20,0x00,0x00},/*"#",3*/
|
||||
{0x00,0x00,0x0E,0x18,0x11,0x04,0x3F,0xFF,0x10,0x84,0x0C,0x78,0x00,0x00,0x00,0x00},/*"$",4*/
|
||||
{0x0F,0x00,0x10,0x84,0x0F,0x38,0x00,0xC0,0x07,0x78,0x18,0x84,0x00,0x78,0x00,0x00},/*"%",5*/
|
||||
{0x00,0x78,0x0F,0x84,0x10,0xC4,0x11,0x24,0x0E,0x98,0x00,0xE4,0x00,0x84,0x00,0x08},/*"&",6*/
|
||||
{0x08,0x00,0x68,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x18,0x18,0x20,0x04,0x40,0x02,0x00,0x00},/*"(",8*/
|
||||
{0x00,0x00,0x40,0x02,0x20,0x04,0x18,0x18,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00},/*")",9*/
|
||||
{0x02,0x40,0x02,0x40,0x01,0x80,0x0F,0xF0,0x01,0x80,0x02,0x40,0x02,0x40,0x00,0x00},/*"*",10*/
|
||||
{0x00,0x80,0x00,0x80,0x00,0x80,0x0F,0xF8,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x00},/*"+",11*/
|
||||
{0x00,0x01,0x00,0x0D,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/
|
||||
{0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80},/*"-",13*/
|
||||
{0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/
|
||||
{0x00,0x00,0x00,0x06,0x00,0x18,0x00,0x60,0x01,0x80,0x06,0x00,0x18,0x00,0x20,0x00},/*"/",15*/
|
||||
{0x00,0x00,0x07,0xF0,0x08,0x08,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"0",16*/
|
||||
{0x00,0x00,0x08,0x04,0x08,0x04,0x1F,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"1",17*/
|
||||
{0x00,0x00,0x0E,0x0C,0x10,0x14,0x10,0x24,0x10,0x44,0x11,0x84,0x0E,0x0C,0x00,0x00},/*"2",18*/
|
||||
{0x00,0x00,0x0C,0x18,0x10,0x04,0x11,0x04,0x11,0x04,0x12,0x88,0x0C,0x70,0x00,0x00},/*"3",19*/
|
||||
{0x00,0x00,0x00,0xE0,0x03,0x20,0x04,0x24,0x08,0x24,0x1F,0xFC,0x00,0x24,0x00,0x00},/*"4",20*/
|
||||
{0x00,0x00,0x1F,0x98,0x10,0x84,0x11,0x04,0x11,0x04,0x10,0x88,0x10,0x70,0x00,0x00},/*"5",21*/
|
||||
{0x00,0x00,0x07,0xF0,0x08,0x88,0x11,0x04,0x11,0x04,0x18,0x88,0x00,0x70,0x00,0x00},/*"6",22*/
|
||||
{0x00,0x00,0x1C,0x00,0x10,0x00,0x10,0xFC,0x13,0x00,0x1C,0x00,0x10,0x00,0x00,0x00},/*"7",23*/
|
||||
{0x00,0x00,0x0E,0x38,0x11,0x44,0x10,0x84,0x10,0x84,0x11,0x44,0x0E,0x38,0x00,0x00},/*"8",24*/
|
||||
{0x00,0x00,0x07,0x00,0x08,0x8C,0x10,0x44,0x10,0x44,0x08,0x88,0x07,0xF0,0x00,0x00},/*"9",25*/
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x03,0x0C,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/
|
||||
{0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/
|
||||
{0x00,0x00,0x00,0x80,0x01,0x40,0x02,0x20,0x04,0x10,0x08,0x08,0x10,0x04,0x00,0x00},/*"<",28*/
|
||||
{0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x00,0x00},/*"=",29*/
|
||||
{0x00,0x00,0x10,0x04,0x08,0x08,0x04,0x10,0x02,0x20,0x01,0x40,0x00,0x80,0x00,0x00},/*">",30*/
|
||||
{0x00,0x00,0x0E,0x00,0x12,0x00,0x10,0x0C,0x10,0x6C,0x10,0x80,0x0F,0x00,0x00,0x00},/*"?",31*/
|
||||
{0x03,0xE0,0x0C,0x18,0x13,0xE4,0x14,0x24,0x17,0xC4,0x08,0x28,0x07,0xD0,0x00,0x00},/*"@",32*/
|
||||
{0x00,0x04,0x00,0x3C,0x03,0xC4,0x1C,0x40,0x07,0x40,0x00,0xE4,0x00,0x1C,0x00,0x04},/*"A",33*/
|
||||
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x04,0x11,0x04,0x0E,0x88,0x00,0x70,0x00,0x00},/*"B",34*/
|
||||
{0x03,0xE0,0x0C,0x18,0x10,0x04,0x10,0x04,0x10,0x04,0x10,0x08,0x1C,0x10,0x00,0x00},/*"C",35*/
|
||||
{0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"D",36*/
|
||||
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x04,0x17,0xC4,0x10,0x04,0x08,0x18,0x00,0x00},/*"E",37*/
|
||||
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x00,0x17,0xC0,0x10,0x00,0x08,0x00,0x00,0x00},/*"F",38*/
|
||||
{0x03,0xE0,0x0C,0x18,0x10,0x04,0x10,0x04,0x10,0x44,0x1C,0x78,0x00,0x40,0x00,0x00},/*"G",39*/
|
||||
{0x10,0x04,0x1F,0xFC,0x10,0x84,0x00,0x80,0x00,0x80,0x10,0x84,0x1F,0xFC,0x10,0x04},/*"H",40*/
|
||||
{0x00,0x00,0x10,0x04,0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x04,0x00,0x00,0x00,0x00},/*"I",41*/
|
||||
{0x00,0x03,0x00,0x01,0x10,0x01,0x10,0x01,0x1F,0xFE,0x10,0x00,0x10,0x00,0x00,0x00},/*"J",42*/
|
||||
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x03,0x80,0x14,0x64,0x18,0x1C,0x10,0x04,0x00,0x00},/*"K",43*/
|
||||
{0x10,0x04,0x1F,0xFC,0x10,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x0C,0x00,0x00},/*"L",44*/
|
||||
{0x10,0x04,0x1F,0xFC,0x1F,0x00,0x00,0xFC,0x1F,0x00,0x1F,0xFC,0x10,0x04,0x00,0x00},/*"M",45*/
|
||||
{0x10,0x04,0x1F,0xFC,0x0C,0x04,0x03,0x00,0x00,0xE0,0x10,0x18,0x1F,0xFC,0x10,0x00},/*"N",46*/
|
||||
{0x07,0xF0,0x08,0x08,0x10,0x04,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"O",47*/
|
||||
{0x10,0x04,0x1F,0xFC,0x10,0x84,0x10,0x80,0x10,0x80,0x10,0x80,0x0F,0x00,0x00,0x00},/*"P",48*/
|
||||
{0x07,0xF0,0x08,0x18,0x10,0x24,0x10,0x24,0x10,0x1C,0x08,0x0A,0x07,0xF2,0x00,0x00},/*"Q",49*/
|
||||
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x00,0x11,0xC0,0x11,0x30,0x0E,0x0C,0x00,0x04},/*"R",50*/
|
||||
{0x00,0x00,0x0E,0x1C,0x11,0x04,0x10,0x84,0x10,0x84,0x10,0x44,0x1C,0x38,0x00,0x00},/*"S",51*/
|
||||
{0x18,0x00,0x10,0x00,0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x00,0x18,0x00,0x00,0x00},/*"T",52*/
|
||||
{0x10,0x00,0x1F,0xF8,0x10,0x04,0x00,0x04,0x00,0x04,0x10,0x04,0x1F,0xF8,0x10,0x00},/*"U",53*/
|
||||
{0x10,0x00,0x1E,0x00,0x11,0xE0,0x00,0x1C,0x00,0x70,0x13,0x80,0x1C,0x00,0x10,0x00},/*"V",54*/
|
||||
{0x1F,0xC0,0x10,0x3C,0x00,0xE0,0x1F,0x00,0x00,0xE0,0x10,0x3C,0x1F,0xC0,0x00,0x00},/*"W",55*/
|
||||
{0x10,0x04,0x18,0x0C,0x16,0x34,0x01,0xC0,0x01,0xC0,0x16,0x34,0x18,0x0C,0x10,0x04},/*"X",56*/
|
||||
{0x10,0x00,0x1C,0x00,0x13,0x04,0x00,0xFC,0x13,0x04,0x1C,0x00,0x10,0x00,0x00,0x00},/*"Y",57*/
|
||||
{0x08,0x04,0x10,0x1C,0x10,0x64,0x10,0x84,0x13,0x04,0x1C,0x04,0x10,0x18,0x00,0x00},/*"Z",58*/
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xFE,0x40,0x02,0x40,0x02,0x40,0x02,0x00,0x00},/*"[",59*/
|
||||
{0x00,0x00,0x30,0x00,0x0C,0x00,0x03,0x80,0x00,0x60,0x00,0x1C,0x00,0x03,0x00,0x00},/*"\",60*/
|
||||
{0x00,0x00,0x40,0x02,0x40,0x02,0x40,0x02,0x7F,0xFE,0x00,0x00,0x00,0x00,0x00,0x00},/*"]",61*/
|
||||
{0x00,0x00,0x00,0x00,0x20,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x00,0x00},/*"^",62*/
|
||||
{0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01},/*"_",63*/
|
||||
{0x00,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
|
||||
{0x00,0x00,0x00,0x98,0x01,0x24,0x01,0x44,0x01,0x44,0x01,0x44,0x00,0xFC,0x00,0x04},/*"a",65*/
|
||||
{0x10,0x00,0x1F,0xFC,0x00,0x88,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x70,0x00,0x00},/*"b",66*/
|
||||
{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x00},/*"c",67*/
|
||||
{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x11,0x08,0x1F,0xFC,0x00,0x04},/*"d",68*/
|
||||
{0x00,0x00,0x00,0xF8,0x01,0x44,0x01,0x44,0x01,0x44,0x01,0x44,0x00,0xC8,0x00,0x00},/*"e",69*/
|
||||
{0x00,0x00,0x01,0x04,0x01,0x04,0x0F,0xFC,0x11,0x04,0x11,0x04,0x11,0x00,0x18,0x00},/*"f",70*/
|
||||
{0x00,0x00,0x00,0xD6,0x01,0x29,0x01,0x29,0x01,0x29,0x01,0xC9,0x01,0x06,0x00,0x00},/*"g",71*/
|
||||
{0x10,0x04,0x1F,0xFC,0x00,0x84,0x01,0x00,0x01,0x00,0x01,0x04,0x00,0xFC,0x00,0x04},/*"h",72*/
|
||||
{0x00,0x00,0x01,0x04,0x19,0x04,0x19,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"i",73*/
|
||||
{0x00,0x00,0x00,0x03,0x00,0x01,0x01,0x01,0x19,0x01,0x19,0xFE,0x00,0x00,0x00,0x00},/*"j",74*/
|
||||
{0x10,0x04,0x1F,0xFC,0x00,0x24,0x00,0x40,0x01,0xB4,0x01,0x0C,0x01,0x04,0x00,0x00},/*"k",75*/
|
||||
{0x00,0x00,0x10,0x04,0x10,0x04,0x1F,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"l",76*/
|
||||
{0x01,0x04,0x01,0xFC,0x01,0x04,0x01,0x00,0x01,0xFC,0x01,0x04,0x01,0x00,0x00,0xFC},/*"m",77*/
|
||||
{0x01,0x04,0x01,0xFC,0x00,0x84,0x01,0x00,0x01,0x00,0x01,0x04,0x00,0xFC,0x00,0x04},/*"n",78*/
|
||||
{0x00,0x00,0x00,0xF8,0x01,0x04,0x01,0x04,0x01,0x04,0x01,0x04,0x00,0xF8,0x00,0x00},/*"o",79*/
|
||||
{0x01,0x01,0x01,0xFF,0x00,0x85,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x70,0x00,0x00},/*"p",80*/
|
||||
{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x01,0x05,0x01,0xFF,0x00,0x01},/*"q",81*/
|
||||
{0x01,0x04,0x01,0x04,0x01,0xFC,0x00,0x84,0x01,0x04,0x01,0x00,0x01,0x80,0x00,0x00},/*"r",82*/
|
||||
{0x00,0x00,0x00,0xCC,0x01,0x24,0x01,0x24,0x01,0x24,0x01,0x24,0x01,0x98,0x00,0x00},/*"s",83*/
|
||||
{0x00,0x00,0x01,0x00,0x01,0x00,0x07,0xF8,0x01,0x04,0x01,0x04,0x00,0x00,0x00,0x00},/*"t",84*/
|
||||
{0x01,0x00,0x01,0xF8,0x00,0x04,0x00,0x04,0x00,0x04,0x01,0x08,0x01,0xFC,0x00,0x04},/*"u",85*/
|
||||
{0x01,0x00,0x01,0x80,0x01,0x70,0x00,0x0C,0x00,0x10,0x01,0x60,0x01,0x80,0x01,0x00},/*"v",86*/
|
||||
{0x01,0xF0,0x01,0x0C,0x00,0x30,0x01,0xC0,0x00,0x30,0x01,0x0C,0x01,0xF0,0x01,0x00},/*"w",87*/
|
||||
{0x00,0x00,0x01,0x04,0x01,0x8C,0x00,0x74,0x01,0x70,0x01,0x8C,0x01,0x04,0x00,0x00},/*"x",88*/
|
||||
{0x01,0x01,0x01,0x81,0x01,0x71,0x00,0x0E,0x00,0x18,0x01,0x60,0x01,0x80,0x01,0x00},/*"y",89*/
|
||||
{0x00,0x00,0x01,0x84,0x01,0x0C,0x01,0x34,0x01,0x44,0x01,0x84,0x01,0x0C,0x00,0x00},/*"z",90*/
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x3E,0xFC,0x40,0x02,0x40,0x02},/*"{",91*/
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},/*"|",92*/
|
||||
{0x00,0x00,0x40,0x02,0x40,0x02,0x3E,0xFC,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"}",93*/
|
||||
{0x00,0x00,0x60,0x00,0x80,0x00,0x80,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x20,0x00},/*"~",94*/
|
||||
};
|
||||
|
||||
const unsigned char Hzk16[164][16]=
|
||||
{
|
||||
//按下用户按键确认开始自检无操作秒后退出正在自检,秒后完成轴角速度自检完成错误代码
|
||||
|
||||
//16*16
|
||||
{0x40,0x42,0x81,0xFE,0x00,0x00,0x01,0x21,0xD2,0x14,0x08,0x14,0xE2,0x01,0x00,0x00},
|
||||
{0x08,0x08,0x08,0xFF,0x09,0x04,0x19,0x11,0x11,0x97,0x71,0x11,0x11,0x15,0x19,0x00},/*"按",0*/
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00},
|
||||
{0x40,0x40,0x40,0x40,0x40,0x40,0x7F,0x40,0x40,0x42,0x41,0x40,0x40,0x40,0x40,0x00},/*"下",1*/
|
||||
{0x01,0x06,0xF8,0x40,0x40,0x40,0x40,0xFE,0x40,0x40,0x42,0x41,0xFE,0x00,0x00,0x00},
|
||||
{0x00,0x00,0x7F,0x44,0x44,0x44,0x44,0x7F,0x44,0x44,0x44,0x44,0x7F,0x00,0x00,0x00},/*"用",2*/
|
||||
{0x00,0x01,0x06,0xF8,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0x00,0x00,0x00},
|
||||
{0x00,0x00,0x00,0x1F,0x10,0x10,0x90,0x70,0x10,0x10,0x10,0x10,0x1F,0x00,0x00,0x00},/*"户",3*/
|
||||
{0x40,0x42,0x81,0xFE,0x00,0x00,0x01,0x21,0xD2,0x14,0x08,0x14,0xE2,0x01,0x00,0x00},
|
||||
{0x08,0x08,0x08,0xFF,0x09,0x04,0x19,0x11,0x11,0x97,0x71,0x11,0x11,0x15,0x19,0x00},/*"按",4*/
|
||||
{0x80,0x80,0xFE,0x84,0x8A,0x64,0x18,0xE4,0x22,0xA2,0xA2,0xFA,0xA2,0xA2,0x22,0x00},
|
||||
{0x02,0x0C,0xF7,0x24,0x24,0x01,0x27,0x39,0x08,0x2A,0x2A,0xFF,0x2A,0x3E,0x08,0x00},/*"键",5*/
|
||||
{0x40,0x80,0xFE,0x08,0x08,0xFC,0x01,0x06,0xF8,0x90,0x90,0xFC,0x92,0x91,0xFE,0x00},
|
||||
{0x20,0x21,0x27,0x3A,0x22,0x23,0x04,0x08,0x17,0xE4,0x24,0x27,0x2C,0x34,0x07,0x00},/*"确",6*/
|
||||
{0x00,0x00,0x00,0xFC,0x09,0x12,0x04,0x18,0xE0,0x00,0xE0,0x18,0x04,0x02,0x01,0x00},
|
||||
{0x02,0x02,0x42,0x33,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},/*"认",7*/
|
||||
{0x00,0x01,0x02,0x0C,0xF0,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00},
|
||||
{0x01,0x41,0x41,0x41,0x7F,0x41,0x41,0x41,0x41,0x41,0x7F,0x41,0x41,0x41,0x01,0x00},/*"开",8*/
|
||||
{0x02,0x44,0xA8,0x10,0x68,0x84,0x00,0x00,0x7F,0x42,0x42,0x42,0x42,0x7F,0x00,0x00},
|
||||
{0x08,0x08,0x0F,0xF8,0x08,0x0F,0x00,0x02,0x07,0x1A,0xE2,0x02,0x0A,0x06,0x03,0x00},/*"始",9*/
|
||||
{0x00,0x00,0x00,0xFF,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xFF,0x00,0x00,0x00,0x00},
|
||||
{0x00,0x00,0x00,0x1F,0x11,0x31,0x51,0x91,0x11,0x11,0x11,0x1F,0x00,0x00,0x00,0x00},/*"自",10*/
|
||||
{0x20,0xC0,0x00,0xFF,0x00,0x82,0x22,0x1A,0x82,0x72,0x06,0x1A,0xE2,0x02,0x02,0x00},
|
||||
{0x08,0x08,0x0B,0xFF,0x09,0x0A,0x04,0x0A,0x32,0xC2,0x32,0x0A,0x04,0x02,0x02,0x00},/*"检",11*/
|
||||
|
||||
{0x01,0x02,0x04,0x08,0x30,0xC0,0x00,0x00,0xFC,0x02,0x02,0x02,0x02,0x0E,0x00,0x00},
|
||||
{0x00,0x02,0x42,0x42,0x42,0x43,0x7E,0x42,0x43,0x42,0x42,0x42,0x02,0x02,0x00,0x00},/*"无",12*/
|
||||
{0x42,0x41,0xFE,0x82,0x22,0xA4,0xA8,0xB0,0xA0,0x7F,0xB0,0xA8,0xA4,0xA2,0x22,0x00},
|
||||
{0x08,0x08,0xFF,0x08,0x09,0x07,0xF4,0x94,0x97,0x90,0x97,0x94,0xF4,0x07,0x00,0x00},/*"操",13*/
|
||||
{0x80,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0xFF,0x10,0x10,0x10,0x10,0x10,0x00,0x00},
|
||||
{0x00,0x01,0x06,0x1F,0xE0,0x02,0x0C,0xF0,0x1F,0x11,0x11,0x11,0x11,0x10,0x10,0x00},/*"作",14*/
|
||||
{0x10,0x60,0x80,0xFF,0x80,0x60,0x81,0x01,0x02,0x02,0xE4,0x08,0x30,0xC0,0x00,0x00},
|
||||
{0x24,0x24,0x25,0x7F,0xC4,0x44,0x00,0x03,0x1C,0x00,0xFF,0x00,0x10,0x08,0x06,0x00},/*"秒",15*/
|
||||
{0x02,0x04,0x18,0xE0,0x00,0x7F,0x42,0x42,0x42,0x42,0x42,0x42,0x7F,0x00,0x00,0x00},
|
||||
{0x00,0x00,0x00,0x3F,0x24,0x24,0x24,0x24,0x44,0x44,0x44,0xC4,0x44,0x04,0x04,0x00},/*"后",16*/
|
||||
{0x00,0x02,0x04,0xF8,0x04,0x02,0xFA,0x12,0x22,0x02,0x82,0x42,0xA2,0x1A,0x02,0x00},
|
||||
{0x02,0x02,0x42,0x33,0x00,0x00,0xFF,0x92,0x92,0x93,0x92,0x92,0xFE,0x01,0x00,0x00},/*"退",17*/
|
||||
{0x00,0x3E,0x02,0x02,0x02,0x02,0x02,0xFE,0x02,0x02,0x02,0x02,0x02,0x3F,0x00,0x00},
|
||||
{0x00,0x00,0x3E,0x02,0x02,0x02,0x02,0xFF,0x02,0x02,0x02,0x02,0x3F,0x00,0x00,0x00},/*"出",18*/
|
||||
|
||||
{0x02,0x02,0x02,0xFE,0x02,0x02,0x02,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00},
|
||||
{0x00,0x40,0x40,0x43,0x40,0x40,0x40,0x7F,0x41,0x41,0x41,0x41,0x41,0x40,0x00,0x00},/*"正",19*/
|
||||
{0x40,0x80,0x00,0xFF,0x02,0x82,0x82,0x82,0x82,0xFE,0x82,0x82,0x82,0x82,0x02,0x00},
|
||||
{0x10,0x10,0x11,0x13,0x1C,0x30,0xD0,0x10,0x10,0x17,0x10,0x10,0x10,0x10,0x10,0x00},/*"在",20*/
|
||||
{0x00,0x00,0x00,0xFF,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xFF,0x00,0x00,0x00,0x00},
|
||||
{0x00,0x00,0x00,0x1F,0x11,0x31,0x51,0x91,0x11,0x11,0x11,0x1F,0x00,0x00,0x00,0x00},/*"自",21*/
|
||||
{0x20,0xC0,0x00,0xFF,0x00,0x82,0x22,0x1A,0x82,0x72,0x06,0x1A,0xE2,0x02,0x02,0x00},
|
||||
{0x08,0x08,0x0B,0xFF,0x09,0x0A,0x04,0x0A,0x32,0xC2,0x32,0x0A,0x04,0x02,0x02,0x00},/*"检",22*/
|
||||
{0x00,0x00,0x1A,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",23*/
|
||||
{0x10,0x60,0x80,0xFF,0x80,0x60,0x81,0x01,0x02,0x02,0xE4,0x08,0x30,0xC0,0x00,0x00},
|
||||
{0x24,0x24,0x25,0x7F,0xC4,0x44,0x00,0x03,0x1C,0x00,0xFF,0x00,0x10,0x08,0x06,0x00},/*"秒",24*/
|
||||
{0x02,0x04,0x18,0xE0,0x00,0x7F,0x42,0x42,0x42,0x42,0x42,0x42,0x7F,0x00,0x00,0x00},
|
||||
{0x00,0x00,0x00,0x3F,0x24,0x24,0x24,0x24,0x44,0x44,0x44,0xC4,0x44,0x04,0x04,0x00},/*"后",25*/
|
||||
{0x00,0x81,0x81,0x82,0x8C,0xF0,0x80,0x80,0x80,0xFE,0x81,0x81,0x81,0x8F,0x00,0x00},
|
||||
{0x08,0x30,0x20,0x24,0x24,0x24,0xA4,0x64,0x24,0x24,0x24,0x24,0x20,0x28,0x30,0x00},/*"完",26*/
|
||||
{0x01,0x06,0xF8,0x00,0x08,0x04,0xF8,0x01,0x02,0x84,0x68,0x18,0x64,0x82,0x1F,0x00},
|
||||
{0x00,0x00,0x1F,0x11,0x11,0x11,0x11,0x10,0x10,0xFF,0x10,0x90,0x50,0x13,0x10,0x00},/*"成",27*/
|
||||
|
||||
{0x10,0x18,0x10,0xFF,0x20,0x20,0x00,0xFF,0x42,0x42,0xFE,0x42,0x42,0xFF,0x00,0x00},
|
||||
{0x13,0x1D,0xF1,0x17,0x11,0x11,0x00,0x0F,0x08,0x08,0xFF,0x08,0x08,0x0F,0x00,0x00},/*"轴",28*/
|
||||
{0x01,0x06,0xF8,0x90,0x90,0x90,0x90,0xFE,0x90,0x90,0x92,0x91,0xFE,0x00,0x00,0x00},
|
||||
{0x04,0x08,0x17,0x24,0xE4,0x24,0x24,0x27,0x24,0x2C,0x34,0x04,0x07,0x00,0x00,0x00},/*"角",29*/
|
||||
{0x00,0x02,0x04,0xF8,0x04,0x12,0x22,0x42,0x82,0xFA,0x82,0x42,0x22,0x12,0x02,0x00},
|
||||
{0x02,0x02,0x42,0x33,0x00,0x20,0x2F,0x29,0x29,0xFF,0x29,0x29,0x2F,0x20,0x00,0x00},/*"速",30*/
|
||||
{0x02,0x0C,0xF1,0x01,0x21,0x32,0xAA,0xA4,0xA4,0xA4,0xAA,0x32,0x01,0x01,0x01,0x00},
|
||||
{0x00,0x00,0x3F,0x24,0x24,0x24,0x3F,0xA4,0x64,0x24,0x3F,0x24,0x24,0x24,0x20,0x00},/*"度",31*/
|
||||
|
||||
{0x00,0x00,0x00,0xFF,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xFF,0x00,0x00,0x00,0x00},
|
||||
{0x00,0x00,0x00,0x1F,0x11,0x31,0x51,0x91,0x11,0x11,0x11,0x1F,0x00,0x00,0x00,0x00},/*"自",32*/
|
||||
{0x20,0xC0,0x00,0xFF,0x00,0x82,0x22,0x1A,0x82,0x72,0x06,0x1A,0xE2,0x02,0x02,0x00},
|
||||
{0x08,0x08,0x0B,0xFF,0x09,0x0A,0x04,0x0A,0x32,0xC2,0x32,0x0A,0x04,0x02,0x02,0x00},/*"检",33*/
|
||||
{0x00,0x81,0x81,0x82,0x8C,0xF0,0x80,0x80,0x80,0xFE,0x81,0x81,0x81,0x8F,0x00,0x00},
|
||||
{0x08,0x30,0x20,0x24,0x24,0x24,0xA4,0x64,0x24,0x24,0x24,0x24,0x20,0x28,0x30,0x00},/*"完",34*/
|
||||
{0x01,0x06,0xF8,0x00,0x08,0x04,0xF8,0x01,0x02,0x84,0x68,0x18,0x64,0x82,0x1F,0x00},
|
||||
{0x00,0x00,0x1F,0x11,0x11,0x11,0x11,0x10,0x10,0xFF,0x10,0x90,0x50,0x13,0x10,0x00},/*"成",35*/
|
||||
|
||||
{0x80,0x80,0xFE,0x84,0x88,0x00,0xFF,0x92,0x92,0x92,0x92,0x92,0xFF,0x00,0x00,0x00},
|
||||
{0x02,0x0C,0xF7,0x24,0x26,0x12,0x12,0xFE,0x12,0x12,0x12,0xFE,0x12,0x12,0x02,0x00},/*"错",36*/
|
||||
{0x00,0x00,0xFE,0x04,0x29,0x21,0x22,0x24,0x28,0xF0,0x28,0x24,0x22,0x21,0x21,0x00},
|
||||
{0x02,0x42,0x33,0x00,0x00,0x01,0x79,0x49,0x49,0x49,0x49,0x49,0x79,0x01,0x00,0x00},/*"误",37*/
|
||||
{0x80,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0xC0,0x30,0x08,0x04,0x02,0x1F,0x00},
|
||||
{0x00,0x01,0x06,0x1F,0xE0,0x04,0x04,0x04,0xFE,0x05,0x08,0x88,0x68,0x08,0x08,0x00},/*"代",38*/
|
||||
{0x40,0x80,0xFE,0x08,0x08,0xFC,0x00,0x10,0x10,0x10,0x10,0x12,0x11,0x02,0xFC,0x00},
|
||||
{0x20,0x21,0x27,0x3A,0x22,0x23,0x00,0x40,0x4F,0x41,0x41,0x41,0x7F,0x01,0x01,0x00},/*"码",39*/
|
||||
|
||||
{0x00,0x00,0xF8,0x10,0x10,0x10,0x10,0xFE,0x11,0x11,0x11,0x11,0xF9,0x01,0x0F,0x00},
|
||||
{0x00,0x00,0x1F,0x11,0x11,0x11,0x11,0xFF,0x11,0x11,0x11,0x11,0x1F,0x00,0x00,0x00},/*"电",40*/
|
||||
{0x01,0x06,0xF8,0x02,0x02,0x02,0x02,0x02,0xFE,0x02,0x02,0x22,0x1A,0x02,0x02,0x00},
|
||||
{0x00,0x00,0x7F,0x40,0x41,0x41,0x41,0x41,0x5F,0x41,0x41,0x41,0x41,0x41,0x40,0x00},/*"压",41*/
|
||||
{0x00,0x02,0x04,0xF8,0x04,0x02,0x02,0x82,0x02,0x12,0x0A,0xF2,0x02,0x02,0x02,0x00},
|
||||
{0x02,0x02,0x42,0x33,0x00,0x10,0x12,0x11,0x10,0x10,0x10,0xFF,0x10,0x10,0x10,0x00},/*"过",42*/
|
||||
{0x80,0x00,0x00,0xFF,0x00,0x00,0xFF,0x02,0x04,0x00,0x82,0x71,0x0C,0x02,0x1F,0x00},
|
||||
{0x00,0x01,0x06,0x1F,0xE0,0x00,0x3F,0x21,0x21,0x21,0x7F,0x41,0xC1,0x41,0x01,0x00},/*"低",43*/
|
||||
|
||||
{0x00,0x00,0xFF,0x00,0x01,0x81,0xA2,0x94,0x88,0xF4,0x82,0x82,0x81,0x81,0x01,0x00},
|
||||
{0x01,0x06,0x1F,0xE0,0x20,0x27,0x24,0x24,0x24,0xFF,0x24,0x24,0x24,0x27,0x20,0x00},/*"使",44*/
|
||||
{0x00,0xFF,0x48,0x48,0x4A,0x49,0xFE,0x00,0x00,0x7E,0x11,0x11,0x21,0x41,0x07,0x00},
|
||||
{0x10,0x33,0x52,0x92,0x12,0x52,0x33,0x18,0x00,0xFE,0x11,0x11,0x21,0x41,0x07,0x00},/*"能",45*/
|
||||
{0x00,0x01,0x02,0x0C,0xF0,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00},
|
||||
{0x01,0x41,0x41,0x41,0x7F,0x41,0x41,0x41,0x41,0x41,0x7F,0x41,0x41,0x41,0x01,0x00},/*"开",46*/
|
||||
{0x81,0x81,0x82,0x82,0x84,0x88,0xB0,0xC0,0xB0,0x88,0x84,0x82,0x82,0x81,0x81,0x00},
|
||||
{0x00,0x00,0x08,0x88,0x68,0x08,0x08,0x0F,0x08,0x08,0x28,0xC8,0x08,0x00,0x00,0x00},/*"关",47*/
|
||||
{0x81,0x81,0x82,0x82,0x84,0x88,0xB0,0xC0,0xB0,0x88,0x84,0x82,0x82,0x81,0x81,0x00},
|
||||
{0x00,0x00,0x08,0x88,0x68,0x08,0x08,0x0F,0x08,0x08,0x28,0xC8,0x08,0x00,0x00,0x00},/*"关",48*/
|
||||
{0x00,0xFF,0x00,0x10,0x20,0x40,0x88,0x04,0xF8,0x00,0x00,0x02,0x01,0xFE,0x00,0x00},
|
||||
{0x00,0x1F,0x80,0x44,0x04,0x44,0x44,0x45,0x5F,0x44,0x44,0x44,0x40,0x7F,0x00,0x00},/*"闭",49*/
|
||||
|
||||
{0x10,0x18,0x12,0x21,0x22,0xFC,0x00,0xFE,0x0A,0x12,0x62,0x82,0x62,0x1A,0x02,0x00},
|
||||
{0x40,0x5F,0x41,0x41,0x7F,0x01,0x00,0x7F,0x40,0x48,0x46,0x41,0x46,0x58,0x40,0x00},/*"驱",49*/
|
||||
{0x08,0x3C,0xC8,0x08,0x28,0x1D,0x02,0x0C,0x70,0x80,0x02,0x01,0x02,0xFC,0x00,0x00},
|
||||
{0x02,0x22,0x23,0x22,0x22,0x22,0x02,0x08,0x08,0xFF,0x08,0x08,0x08,0x0F,0x00,0x00},/*"动",50*/
|
||||
{0x44,0xE6,0x44,0x48,0x48,0x48,0x02,0x02,0x04,0xC8,0x30,0x28,0x44,0x82,0x1F,0x00},
|
||||
{0x04,0x0C,0x35,0xC6,0x04,0x18,0x01,0x09,0x09,0xFF,0x09,0x92,0x52,0x12,0x02,0x00},/*"线",51*/
|
||||
{0x02,0x0C,0xF1,0x01,0x02,0x02,0xC4,0x28,0x10,0x28,0x44,0x82,0x02,0x01,0x01,0x00},
|
||||
{0x00,0x00,0x3F,0x24,0x24,0x27,0x24,0x24,0x44,0x44,0x44,0xC5,0x46,0x00,0x00,0x00},/*"反",52*/
|
||||
{0x20,0x22,0x41,0xFE,0x80,0x41,0x41,0x52,0x6A,0xC4,0x44,0x4A,0x72,0x41,0x40,0x00},
|
||||
{0x08,0x08,0x08,0xFF,0x08,0x0A,0x22,0x2A,0xA6,0x63,0x22,0x26,0x2A,0x22,0x02,0x00},/*"接",53*/
|
||||
|
||||
{0x10,0x18,0x12,0x21,0x22,0xFC,0x00,0xFE,0x0A,0x12,0x62,0x82,0x62,0x1A,0x02,0x00},
|
||||
{0x40,0x5F,0x41,0x41,0x7F,0x01,0x00,0x7F,0x40,0x48,0x46,0x41,0x46,0x58,0x40,0x00},/*"驱",54*/
|
||||
{0x08,0x3C,0xC8,0x08,0x28,0x1D,0x02,0x0C,0x70,0x80,0x02,0x01,0x02,0xFC,0x00,0x00},
|
||||
{0x02,0x22,0x23,0x22,0x22,0x22,0x02,0x08,0x08,0xFF,0x08,0x08,0x08,0x0F,0x00,0x00},/*"动",55*/
|
||||
{0x20,0x22,0x41,0xFE,0x80,0x00,0x01,0xF1,0x02,0x0C,0xF0,0x08,0x04,0xF3,0x00,0x00},
|
||||
{0x08,0x08,0x08,0xFF,0x08,0x09,0x00,0x03,0x7A,0x4A,0x4A,0x4A,0x7A,0x03,0x00,0x00},/*"损",56*/
|
||||
{0x10,0x18,0x10,0xE0,0x20,0x28,0x10,0x20,0x40,0x80,0xFF,0x00,0x00,0xC0,0x30,0x00},
|
||||
{0x04,0x04,0x04,0xFF,0x04,0x04,0x20,0x20,0x20,0x21,0x27,0x38,0x21,0x20,0x20,0x00},/*"坏",57*/
|
||||
|
||||
{0x44,0xE6,0x44,0x48,0x4A,0x1C,0xE0,0xFF,0x90,0xFE,0x90,0xFC,0x91,0xFF,0x00,0x00},
|
||||
{0x04,0x0C,0x35,0xC6,0x0C,0x00,0x3F,0x24,0xA4,0x64,0x24,0x24,0x24,0x3C,0x00,0x00},/*"编",58*/
|
||||
{0x40,0x80,0xFE,0x08,0x08,0xFC,0x00,0x10,0x10,0x10,0x10,0x12,0x11,0x02,0xFC,0x00},
|
||||
{0x20,0x21,0x27,0x3A,0x22,0x23,0x00,0x40,0x4F,0x41,0x41,0x41,0x7F,0x01,0x01,0x00},/*"码",59*/
|
||||
{0x10,0x10,0x2F,0x29,0x49,0x49,0x8F,0x00,0x80,0x4F,0x49,0x29,0x29,0x1F,0x10,0x00},
|
||||
{0x01,0x01,0x79,0x49,0x49,0x49,0x79,0x07,0x01,0x79,0x4D,0x4B,0x49,0x79,0x01,0x00},/*"器",60*/
|
||||
{0x20,0x22,0x41,0xFE,0x80,0x00,0x01,0xF1,0x02,0x0C,0xF0,0x08,0x04,0xF3,0x00,0x00},
|
||||
{0x08,0x08,0x08,0xFF,0x08,0x09,0x00,0x03,0x7A,0x4A,0x4A,0x4A,0x7A,0x03,0x00,0x00},/*"损",61*/
|
||||
{0x10,0x18,0x10,0xE0,0x20,0x28,0x10,0x20,0x40,0x80,0xFF,0x00,0x00,0xC0,0x30,0x00},
|
||||
{0x04,0x04,0x04,0xFF,0x04,0x04,0x20,0x20,0x20,0x21,0x27,0x38,0x21,0x20,0x20,0x00},/*"坏",62*/
|
||||
|
||||
{0x00,0x00,0xF8,0x10,0x10,0x10,0x10,0xFE,0x11,0x11,0x11,0x11,0xF9,0x01,0x0F,0x00},
|
||||
{0x00,0x00,0x1F,0x11,0x11,0x11,0x11,0xFF,0x11,0x11,0x11,0x11,0x1F,0x00,0x00,0x00},/*"电",63*/
|
||||
{0x20,0x20,0x7E,0x82,0x0C,0xF0,0x04,0xC8,0x92,0x81,0xFE,0x80,0x90,0xC8,0x04,0x00},
|
||||
{0x08,0x06,0x40,0x31,0x00,0x7F,0x40,0x4F,0x4A,0x5A,0x6A,0x4A,0x4A,0x4F,0x40,0x00},/*"源",64*/
|
||||
{0x08,0x10,0x20,0x40,0x80,0x00,0x00,0xFF,0x00,0x00,0x00,0x80,0x40,0x30,0x00,0x00},
|
||||
{0x00,0x40,0x40,0x40,0x40,0x41,0x42,0x4F,0x70,0x42,0x41,0x40,0x40,0x40,0x00,0x00},/*"不",65*/
|
||||
{0x10,0x60,0x80,0xFF,0x00,0xC1,0x06,0x20,0x26,0x31,0x2D,0x21,0x23,0xE8,0x06,0x00},
|
||||
{0x24,0x24,0x25,0x7F,0xC5,0x44,0x10,0x29,0x49,0xC9,0x49,0x59,0x69,0x0F,0x00,0x00},/*"稳",66*/
|
||||
{0x01,0x02,0x04,0x78,0x04,0x02,0x02,0xFE,0x22,0x22,0x22,0x22,0x22,0x02,0x02,0x00},
|
||||
{0x08,0x30,0x22,0x22,0x22,0x22,0xA2,0x63,0x22,0x22,0x22,0x22,0x22,0x28,0x30,0x00},/*"定",67*/
|
||||
|
||||
{0x20,0x20,0x7E,0x80,0x02,0x7E,0x42,0x42,0x7E,0x42,0x7E,0x42,0x42,0x7E,0x02,0x00},
|
||||
{0x08,0x06,0x40,0x31,0x00,0x00,0x7F,0x49,0x49,0x49,0x49,0x49,0x7F,0x00,0x00,0x00},/*"温",68*/
|
||||
{0x02,0x0C,0xF1,0x01,0x21,0x32,0xAA,0xA4,0xA4,0xA4,0xAA,0x32,0x01,0x01,0x01,0x00},
|
||||
{0x00,0x00,0x3F,0x24,0x24,0x24,0x3F,0xA4,0x64,0x24,0x3F,0x24,0x24,0x24,0x20,0x00},/*"度",69*/
|
||||
{0x00,0x02,0x04,0xF8,0x04,0x02,0x02,0x82,0x02,0x12,0x0A,0xF2,0x02,0x02,0x02,0x00},
|
||||
{0x02,0x02,0x42,0x33,0x00,0x10,0x12,0x11,0x10,0x10,0x10,0xFF,0x10,0x10,0x10,0x00},/*"过",70*/
|
||||
{0x00,0x7F,0x40,0x40,0x5E,0x52,0x52,0x52,0x52,0x52,0x5E,0x40,0x41,0x7F,0x00,0x00},
|
||||
{0x20,0x20,0x20,0x20,0x2F,0x29,0xA9,0x69,0x29,0x29,0x2F,0x20,0x20,0x20,0x20,0x00},/*"高",71*/
|
||||
|
||||
{0x00,0x00,0xF8,0x10,0x10,0x10,0x10,0xFE,0x11,0x11,0x11,0x11,0xF9,0x01,0x0F,0x00},
|
||||
{0x00,0x00,0x1F,0x11,0x11,0x11,0x11,0xFF,0x11,0x11,0x11,0x11,0x1F,0x00,0x00,0x00},/*"电",72*/
|
||||
{0x20,0xC0,0x00,0xFF,0x00,0xC1,0x06,0xF8,0x00,0x00,0x00,0xFC,0x02,0x02,0x1E,0x00},
|
||||
{0x08,0x08,0x0B,0xFF,0x09,0x08,0x00,0x7F,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,0x00},/*"机",73*/
|
||||
{0x44,0xE6,0x44,0x48,0x48,0x48,0x02,0x02,0x04,0xC8,0x30,0x28,0x44,0x82,0x1F,0x00},
|
||||
{0x04,0x0C,0x35,0xC6,0x04,0x18,0x01,0x09,0x09,0xFF,0x09,0x92,0x52,0x12,0x02,0x00},/*"线",74*/
|
||||
{0x20,0x22,0x41,0xFE,0x80,0x41,0x41,0x52,0x6A,0xC4,0x44,0x4A,0x72,0x41,0x40,0x00},
|
||||
{0x08,0x08,0x08,0xFF,0x08,0x0A,0x22,0x2A,0xA6,0x63,0x22,0x26,0x2A,0x22,0x02,0x00},/*"接",75*/
|
||||
{0x80,0x80,0xFE,0x84,0x88,0x00,0xFF,0x92,0x92,0x92,0x92,0x92,0xFF,0x00,0x00,0x00},
|
||||
{0x02,0x0C,0xF7,0x24,0x26,0x12,0x12,0xFE,0x12,0x12,0x12,0xFE,0x12,0x12,0x02,0x00},/*"错",76*/
|
||||
|
||||
{0x10,0x20,0xC0,0x00,0x00,0x02,0x01,0xFE,0x00,0x00,0x00,0x00,0x00,0x80,0x70,0x00},
|
||||
{0x00,0x00,0x00,0x07,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x04,0x02,0x01,0x00,0x00},/*"小",77*/
|
||||
{0x10,0x10,0x90,0x90,0x90,0x90,0x90,0xFF,0x90,0x90,0x90,0x90,0x90,0x10,0x10,0x00},
|
||||
{0x00,0x10,0x11,0x12,0x14,0x18,0xF0,0x17,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00},/*"车",78*/
|
||||
{0x02,0x02,0x02,0xFE,0x02,0x02,0x02,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00},
|
||||
{0x00,0x40,0x40,0x43,0x40,0x40,0x40,0x7F,0x41,0x41,0x41,0x41,0x41,0x40,0x00,0x00},/*"正",79*/
|
||||
{0x00,0x00,0x7C,0x40,0x40,0x40,0x40,0xFF,0x40,0x40,0x48,0x44,0x78,0x00,0x00,0x00},
|
||||
{0x04,0x18,0x10,0x57,0x35,0x15,0x15,0xF5,0x15,0x15,0x35,0x57,0x10,0x14,0x18,0x00},/*"常",80*/
|
||||
|
||||
|
||||
//16*16
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
424
HARDWARE/pstwo.c
Normal file
424
HARDWARE/pstwo.c
Normal file
@@ -0,0 +1,424 @@
|
||||
#include "pstwo.h"
|
||||
#define DELAY_TIME delay_us(5);
|
||||
|
||||
//Button value reading, zero time storage
|
||||
//按键值读取,零时存储
|
||||
u16 Handkey;
|
||||
//Start the order. Request data
|
||||
//开始命令。请求数据
|
||||
u8 Comd[2]={0x01,0x42};
|
||||
//Data store array
|
||||
//数据存储数组
|
||||
u8 Data[9]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
|
||||
u16 MASK[]={
|
||||
PSB_SELECT,
|
||||
PSB_L3,
|
||||
PSB_R3 ,
|
||||
PSB_START,
|
||||
PSB_PAD_UP,
|
||||
PSB_PAD_RIGHT,
|
||||
PSB_PAD_DOWN,
|
||||
PSB_PAD_LEFT,
|
||||
PSB_L2,
|
||||
PSB_R2,
|
||||
PSB_L1,
|
||||
PSB_R1 ,
|
||||
PSB_GREEN,
|
||||
PSB_RED,
|
||||
PSB_BLUE,
|
||||
PSB_PINK
|
||||
}; //Key value and key name //按键值与按键名
|
||||
/**************************************************************************
|
||||
Function: Ps2 handle task
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:PS2手柄任务
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void pstwo_task(void *pvParameters)
|
||||
{
|
||||
u32 lastWakeTime = getSysTickCnt();
|
||||
while(1)
|
||||
{
|
||||
//The task is run at 100hz
|
||||
//此任务以100Hz的频率运行
|
||||
vTaskDelayUntil(&lastWakeTime, F2T(RATE_100_HZ));
|
||||
//Read the ps2 data
|
||||
//读取PS2的数据
|
||||
PS2_Read();
|
||||
}
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Ps2 handle initializer
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:PS2手柄初始化
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void PS2_Init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
//Enable the ability port clock
|
||||
//使能端口时钟
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; //端口配置
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; //普通输入模式
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100M
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉
|
||||
GPIO_Init(GPIOE, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_10|GPIO_Pin_12;
|
||||
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
|
||||
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
|
||||
GPIO_Init(GPIOE, &GPIO_InitStructure);
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Read the control of the ps2 handle
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:读取PS2手柄的控制量
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void PS2_Read(void)
|
||||
{
|
||||
static int Strat;
|
||||
|
||||
//Reading key
|
||||
//读取按键键值
|
||||
PS2_KEY=PS2_DataKey();
|
||||
//Read the analog of the remote sensing x axis on the left
|
||||
//读取左边遥感X轴方向的模拟量
|
||||
PS2_LX=PS2_AnologData(PSS_LX);
|
||||
//Read the analog of the directional direction of remote sensing on the left
|
||||
//读取左边遥感Y轴方向的模拟量
|
||||
PS2_LY=PS2_AnologData(PSS_LY);
|
||||
//Read the analog of the remote sensing x axis
|
||||
//读取右边遥感X轴方向的模拟量
|
||||
PS2_RX=PS2_AnologData(PSS_RX);
|
||||
//Read the analog of the directional direction of the remote sensing y axis
|
||||
//读取右边遥感Y轴方向的模拟量
|
||||
PS2_RY=PS2_AnologData(PSS_RY);
|
||||
|
||||
if(PS2_KEY==4&&PS2_ON_Flag==0)
|
||||
//The start button on the // handle is pressed
|
||||
//手柄上的Start按键被按下
|
||||
Strat=1;
|
||||
|
||||
if(Strat&&(PS2_LY<118)&&PS2_ON_Flag==0&&Deviation_Count>=CONTROL_DELAY)
|
||||
//When the button is pressed, you need to push the right side forward to the formal ps2 control car
|
||||
//Start按键被按下后,需要推下右边前进杆,才可以正式PS2控制小车
|
||||
PS2_ON_Flag=1,Remote_ON_Flag=0,APP_ON_Flag=0,CAN_ON_Flag=0,Usart1_ON_Flag=0,Usart5_ON_Flag=0;
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Send commands to the handle
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:向手柄发送命令
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void PS2_Cmd(u8 CMD)
|
||||
{
|
||||
volatile u16 ref=0x01;
|
||||
Data[1] = 0;
|
||||
for(ref=0x01;ref<0x0100;ref<<=1)
|
||||
{
|
||||
if(ref&CMD)
|
||||
{
|
||||
DO_H; //Output a control bit //输出一位控制位
|
||||
}
|
||||
else DO_L;
|
||||
|
||||
CLK_H; //Clock lift //时钟拉高
|
||||
DELAY_TIME;
|
||||
CLK_L;
|
||||
DELAY_TIME;
|
||||
CLK_H;
|
||||
if(DI)
|
||||
Data[1] = ref|Data[1];
|
||||
}
|
||||
delay_us(16);
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Whether it is a red light mode, 0x41= analog green light, 0x73= analog red light
|
||||
Input : none
|
||||
Output : 0: red light mode, other: other modes
|
||||
函数功能:判断是否为红灯模式,0x41=模拟绿灯,0x73=模拟红灯
|
||||
入口参数:无
|
||||
返回 值:0:红灯模式,其他:其他模式
|
||||
**************************************************************************/
|
||||
u8 PS2_RedLight(void)
|
||||
{
|
||||
CS_L;
|
||||
PS2_Cmd(Comd[0]); //Start orders //开始命令
|
||||
PS2_Cmd(Comd[1]); //Request data //请求数据
|
||||
CS_H;
|
||||
if( Data[1] == 0X73) return 0 ;
|
||||
else return 1;
|
||||
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Read the handle data
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:读取手柄数据
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void PS2_ReadData(void)
|
||||
{
|
||||
volatile u8 byte=0;
|
||||
volatile u16 ref=0x01;
|
||||
CS_L;
|
||||
PS2_Cmd(Comd[0]); //Start orders //开始命令
|
||||
PS2_Cmd(Comd[1]); //Request data //请求数据
|
||||
for(byte=2;byte<9;byte++) //Start receiving data //开始接受数据
|
||||
{
|
||||
for(ref=0x01;ref<0x100;ref<<=1)
|
||||
{
|
||||
CLK_H;
|
||||
DELAY_TIME;
|
||||
CLK_L;
|
||||
DELAY_TIME;
|
||||
CLK_H;
|
||||
if(DI)
|
||||
Data[byte] = ref|Data[byte];
|
||||
}
|
||||
delay_us(16);
|
||||
}
|
||||
CS_H;
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Handle the data of the read 2 and handle only the key parts
|
||||
Input : none
|
||||
Output : 0: only one button presses the next time; No press
|
||||
函数功能:对读出来的PS2的数据进行处理,只处理按键部分
|
||||
入口参数:无
|
||||
返回 值:0: 只有一个按键按下时按下; 1: 未按下
|
||||
**************************************************************************/
|
||||
u8 PS2_DataKey()
|
||||
{
|
||||
u8 index;
|
||||
|
||||
PS2_ClearData();
|
||||
PS2_ReadData();
|
||||
|
||||
Handkey=(Data[4]<<8)|Data[3]; //This is 16 buttons, pressed down to 0, and not pressed for 1 //这是16个按键,按下为0,未按下为1
|
||||
for(index=0;index<16;index++)
|
||||
{
|
||||
if((Handkey&(1<<(MASK[index]-1)))==0)
|
||||
return index+1;
|
||||
}
|
||||
return 0; //No buttons //没有任何按键按下
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Get a simulation of a rocker
|
||||
Input : Rocker
|
||||
Output : Simulation of rocker, range 0~ 256
|
||||
函数功能:得到一个摇杆的模拟量
|
||||
入口参数:摇杆
|
||||
返回 值:摇杆的模拟量, 范围0~256
|
||||
**************************************************************************/
|
||||
u8 PS2_AnologData(u8 button)
|
||||
{
|
||||
return Data[button];
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Clear data buffer
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:清除数据缓冲区
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void PS2_ClearData()
|
||||
{
|
||||
u8 a;
|
||||
for(a=0;a<9;a++)
|
||||
Data[a]=0x00;
|
||||
}
|
||||
/******************************************************
|
||||
Function: Handle vibration function
|
||||
Input : motor1: the right small vibrator, 0x00, other
|
||||
motor2: the left big shock motor 0x40~ 0xff motor is open, and the value is greater
|
||||
Output : none
|
||||
函数功能:手柄震动函数
|
||||
入口参数:motor1:右侧小震动电机 0x00关,其他开
|
||||
motor2:左侧大震动电机 0x40~0xFF 电机开,值越大 震动越大
|
||||
返回 值:无
|
||||
******************************************************/
|
||||
void PS2_Vibration(u8 motor1, u8 motor2)
|
||||
{
|
||||
CS_L;
|
||||
delay_us(16);
|
||||
PS2_Cmd(0x01); //Start order //开始命令
|
||||
PS2_Cmd(0x42); //Request data //请求数据
|
||||
PS2_Cmd(0X00);
|
||||
PS2_Cmd(motor1);
|
||||
PS2_Cmd(motor2);
|
||||
PS2_Cmd(0X00);
|
||||
PS2_Cmd(0X00);
|
||||
PS2_Cmd(0X00);
|
||||
PS2_Cmd(0X00);
|
||||
CS_H;
|
||||
delay_us(16);
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Short press
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:短按
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void PS2_ShortPoll(void)
|
||||
{
|
||||
CS_L;
|
||||
delay_us(16);
|
||||
PS2_Cmd(0x01);
|
||||
PS2_Cmd(0x42);
|
||||
PS2_Cmd(0X00);
|
||||
PS2_Cmd(0x00);
|
||||
PS2_Cmd(0x00);
|
||||
CS_H;
|
||||
delay_us(16);
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Enter configuration
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:进入配置
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void PS2_EnterConfing(void)
|
||||
{
|
||||
CS_L;
|
||||
delay_us(16);
|
||||
PS2_Cmd(0x01);
|
||||
PS2_Cmd(0x43);
|
||||
PS2_Cmd(0X00);
|
||||
PS2_Cmd(0x01);
|
||||
PS2_Cmd(0x00);
|
||||
PS2_Cmd(0X00);
|
||||
PS2_Cmd(0X00);
|
||||
PS2_Cmd(0X00);
|
||||
PS2_Cmd(0X00);
|
||||
CS_H;
|
||||
delay_us(16);
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Send mode Settings
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:发送模式设置
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void PS2_TurnOnAnalogMode(void)
|
||||
{
|
||||
CS_L;
|
||||
PS2_Cmd(0x01);
|
||||
PS2_Cmd(0x44);
|
||||
PS2_Cmd(0X00);
|
||||
PS2_Cmd(0x01); //analog=0x01;digital=0x00 Software Settings send mode 软件设置发送模式
|
||||
PS2_Cmd(0x03); //0x03 lock storage setup, which cannot be set by the key "mode" set mode. //0x03锁存设置,即不可通过按键“MODE”设置模式。
|
||||
//0xee non-locking software Settings can be set by the key "mode" set mode.//0xEE不锁存软件设置,可通过按键“MODE”设置模式。
|
||||
PS2_Cmd(0X00);
|
||||
PS2_Cmd(0X00);
|
||||
PS2_Cmd(0X00);
|
||||
PS2_Cmd(0X00);
|
||||
CS_H;
|
||||
delay_us(16);
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Vibration setting
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:振动设置
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void PS2_VibrationMode(void)
|
||||
{
|
||||
CS_L;
|
||||
delay_us(16);
|
||||
PS2_Cmd(0x01);
|
||||
PS2_Cmd(0x4D);
|
||||
PS2_Cmd(0X00);
|
||||
PS2_Cmd(0x00);
|
||||
PS2_Cmd(0X01);
|
||||
CS_H;
|
||||
delay_us(16);
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Complete and save the configuration
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:完成并保存配置
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void PS2_ExitConfing(void)
|
||||
{
|
||||
CS_L;
|
||||
delay_us(16);
|
||||
PS2_Cmd(0x01);
|
||||
PS2_Cmd(0x43);
|
||||
PS2_Cmd(0X00);
|
||||
PS2_Cmd(0x00);
|
||||
PS2_Cmd(0x5A);
|
||||
PS2_Cmd(0x5A);
|
||||
PS2_Cmd(0x5A);
|
||||
PS2_Cmd(0x5A);
|
||||
PS2_Cmd(0x5A);
|
||||
CS_H;
|
||||
delay_us(16);
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Handle configuration initialization
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:手柄配置初始化
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void PS2_SetInit(void)
|
||||
{
|
||||
PS2_ShortPoll();
|
||||
PS2_ShortPoll();
|
||||
PS2_ShortPoll();
|
||||
PS2_EnterConfing(); //Enter configuration mode //进入配置模式
|
||||
PS2_TurnOnAnalogMode(); //The "traffic light" configuration mode and select whether to save //“红绿灯”配置模式,并选择是否保存
|
||||
//PS2_VibrationMode(); //Open vibration mode //开启震动模式
|
||||
PS2_ExitConfing(); //Complete and save the configuration //完成并保存配置
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Read the handle information
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:读取手柄信息
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void PS2_Receive (void)
|
||||
{
|
||||
if(PS2_ON_Flag)
|
||||
{
|
||||
PS2_LX=PS2_AnologData(PSS_LX);
|
||||
PS2_LY=PS2_AnologData(PSS_LY);
|
||||
PS2_RX=PS2_AnologData(PSS_RX);
|
||||
PS2_RY=PS2_AnologData(PSS_RY);
|
||||
}
|
||||
PS2_KEY=PS2_DataKey();
|
||||
}
|
||||
|
||||
|
||||
75
HARDWARE/pstwo.h
Normal file
75
HARDWARE/pstwo.h
Normal file
@@ -0,0 +1,75 @@
|
||||
#ifndef __PSTWO_H
|
||||
#define __PSTWO_H
|
||||
#include "delay.h"
|
||||
#include "sys.h"
|
||||
#include "system.h"
|
||||
|
||||
#define PS2_TASK_PRIO 4 //Task priority //任务优先级
|
||||
#define PS2_STK_SIZE 256 //Task stack size //任务堆栈大小
|
||||
|
||||
|
||||
#define DI PEin(15) //Input pin //输入引脚
|
||||
|
||||
#define DO_H PEout(12)=1 //Command height //命令位高
|
||||
#define DO_L PEout(12)=0 //Command low //命令位低
|
||||
|
||||
#define CS_H PEout(10)=1 //Cs pull up //CS拉高
|
||||
#define CS_L PEout(10)=0 //Cs drawdown //CS拉低
|
||||
|
||||
#define CLK_H PEout(8)=1 //Clock lift //时钟拉高
|
||||
#define CLK_L PEout(8)=0 //Clock down //时钟拉低
|
||||
|
||||
//These are our button constants
|
||||
#define PSB_SELECT 1
|
||||
#define PSB_L3 2
|
||||
#define PSB_R3 3
|
||||
#define PSB_START 4
|
||||
#define PSB_PAD_UP 5
|
||||
#define PSB_PAD_RIGHT 6
|
||||
#define PSB_PAD_DOWN 7
|
||||
#define PSB_PAD_LEFT 8
|
||||
#define PSB_L2 9
|
||||
#define PSB_R2 10
|
||||
#define PSB_L1 11
|
||||
#define PSB_R1 12
|
||||
#define PSB_GREEN 13
|
||||
#define PSB_RED 14
|
||||
#define PSB_BLUE 15
|
||||
#define PSB_PINK 16
|
||||
|
||||
#define PSB_TRIANGLE 13
|
||||
#define PSB_CIRCLE 14
|
||||
#define PSB_CROSS 15
|
||||
#define PSB_SQUARE 16
|
||||
|
||||
#define PSS_RX 5 //Right rocker x shaft data //右摇杆X轴数据
|
||||
#define PSS_RY 6 //The left rocker y axis data //左摇杆Y轴数据
|
||||
#define PSS_LX 7 //Right rocker x axis data //右摇杆X轴数据
|
||||
#define PSS_LY 8 //The left rocker y axis data //左摇杆Y轴数据
|
||||
|
||||
extern u8 Data[9];
|
||||
extern u16 MASK[16];
|
||||
extern u16 Handkey;
|
||||
void PS2_Read(void);
|
||||
void PS2_Init(void);
|
||||
u8 PS2_RedLight(void);
|
||||
void PS2_ReadData(void);
|
||||
void PS2_Cmd(u8 CMD);
|
||||
u8 PS2_DataKey(void);
|
||||
u8 PS2_AnologData(u8 button);
|
||||
void PS2_ClearData(void);
|
||||
void PS2_Vibration(u8 motor1, u8 motor2);
|
||||
|
||||
void PS2_EnterConfing(void);
|
||||
void PS2_TurnOnAnalogMode(void);
|
||||
void PS2_VibrationMode(void);
|
||||
void PS2_ExitConfing(void);
|
||||
void PS2_SetInit(void);
|
||||
void PS2_Receive (void);
|
||||
void pstwo_task(void *pvParameters);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
220
HARDWARE/stmflash.c
Normal file
220
HARDWARE/stmflash.c
Normal file
@@ -0,0 +1,220 @@
|
||||
#include "stmflash.h"
|
||||
#include "delay.h"
|
||||
#include "stmflash.h"
|
||||
#define FLASH_SAVE_ADDR 0X0800E000 //设置FLASH 保存地址(必须为偶数,且其值要大于本代码所占用FLASH的大小+0X08000000)
|
||||
//解锁STM32的FLASH
|
||||
void STMFLASH_Unlock(void)
|
||||
{
|
||||
FLASH->KEYR=FLASH_KEY1;//写入解锁序列.
|
||||
FLASH->KEYR=FLASH_KEY2;
|
||||
}
|
||||
//flash上锁
|
||||
void STMFLASH_Lock(void)
|
||||
{
|
||||
FLASH->CR|=1<<7;//上锁
|
||||
}
|
||||
//得到FLASH状态
|
||||
u8 STMFLASH_GetStatus(void)
|
||||
{
|
||||
u32 res;
|
||||
res=FLASH->SR;
|
||||
if(res&(1<<0))return 1; //忙
|
||||
else if(res&(1<<2))return 2; //编程错误
|
||||
else if(res&(1<<4))return 3; //写保护错误
|
||||
return 0; //操作完成
|
||||
}
|
||||
//等待操作完成
|
||||
//time:要延时的长短
|
||||
//返回值:状态.
|
||||
u8 STMFLASH_WaitDone(u16 time)
|
||||
{
|
||||
u8 res;
|
||||
do
|
||||
{
|
||||
res=STMFLASH_GetStatus();
|
||||
if(res!=1)break;//非忙,无需等待了,直接退出.
|
||||
delay_us(1);
|
||||
time--;
|
||||
}while(time);
|
||||
if(time==0)res=0xff;//TIMEOUT
|
||||
return res;
|
||||
}
|
||||
//擦除页
|
||||
//paddr:页地址
|
||||
//返回值:执行情况
|
||||
u8 STMFLASH_ErasePage(u32 paddr)
|
||||
{
|
||||
u8 res=0;
|
||||
res=STMFLASH_WaitDone(0X5FFF);//等待上次操作结束,>20ms
|
||||
if(res==0)
|
||||
{
|
||||
FLASH->CR|=1<<1;//页擦除
|
||||
FLASH->AR=paddr;//设置页地址
|
||||
FLASH->CR|=1<<6;//开始擦除
|
||||
res=STMFLASH_WaitDone(0X5FFF);//等待操作结束,>20ms
|
||||
if(res!=1)//非忙
|
||||
{
|
||||
FLASH->CR&=~(1<<1);//清除页擦除标志.
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
//在FLASH指定地址写入半字
|
||||
//faddr:指定地址(此地址必须为2的倍数!!)
|
||||
//dat:要写入的数据
|
||||
//返回值:写入的情况
|
||||
u8 STMFLASH_WriteHalfWord(u32 faddr, u16 dat)
|
||||
{
|
||||
u8 res;
|
||||
res=STMFLASH_WaitDone(0XFF);
|
||||
if(res==0)//OK
|
||||
{
|
||||
FLASH->CR|=1<<0;//编程使能
|
||||
*(vu16*)faddr=dat;//写入数据
|
||||
res=STMFLASH_WaitDone(0XFF);//等待操作完成
|
||||
if(res!=1)//操作成功
|
||||
{
|
||||
FLASH->CR&=~(1<<0);//清除PG位.
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
//读取指定地址的半字(16位数据)
|
||||
//faddr:读地址
|
||||
//返回值:对应数据.
|
||||
u16 STMFLASH_ReadHalfWord(u32 faddr)
|
||||
{
|
||||
return *(vu16*)faddr;
|
||||
}
|
||||
#if STM32_FLASH_WREN //如果使能了写
|
||||
//不检查的写入
|
||||
//WriteAddr:起始地址
|
||||
//pBuffer:数据指针
|
||||
//NumToWrite:半字(16位)数
|
||||
void STMFLASH_Write_NoCheck(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)
|
||||
{
|
||||
u16 i;
|
||||
for(i=0;i<NumToWrite;i++)
|
||||
{
|
||||
STMFLASH_WriteHalfWord(WriteAddr,pBuffer[i]);
|
||||
WriteAddr+=2;//地址增加2.
|
||||
}
|
||||
}
|
||||
//从指定地址开始写入指定长度的数据
|
||||
//WriteAddr:起始地址(此地址必须为2的倍数!!)
|
||||
//pBuffer:数据指针
|
||||
//NumToWrite:半字(16位)数(就是要写入的16位数据的个数.)
|
||||
#if STM32_FLASH_SIZE<256
|
||||
#define STM_SECTOR_SIZE 1024 //字节
|
||||
#else
|
||||
#define STM_SECTOR_SIZE 2048
|
||||
#endif
|
||||
u16 STMFLASH_BUF[STM_SECTOR_SIZE/2];//最多是2K字节
|
||||
void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)
|
||||
{
|
||||
u32 secpos; //扇区地址
|
||||
u16 secoff; //扇区内偏移地址(16位字计算)
|
||||
u16 secremain; //扇区内剩余地址(16位字计算)
|
||||
u16 i;
|
||||
u32 offaddr; //去掉0X08000000后的地址
|
||||
if(WriteAddr<STM32_FLASH_BASE||(WriteAddr>=(STM32_FLASH_BASE+1024*STM32_FLASH_SIZE)))return;//非法地址
|
||||
STMFLASH_Unlock(); //解锁
|
||||
offaddr=WriteAddr-STM32_FLASH_BASE; //实际偏移地址.
|
||||
secpos=offaddr/STM_SECTOR_SIZE; //扇区地址 0~127 for STM32F103RBT6
|
||||
secoff=(offaddr%STM_SECTOR_SIZE)/2; //在扇区内的偏移(2个字节为基本单位.)
|
||||
secremain=STM_SECTOR_SIZE/2-secoff; //扇区剩余空间大小
|
||||
if(NumToWrite<=secremain)secremain=NumToWrite;//不大于该扇区范围
|
||||
while(1)
|
||||
{
|
||||
STMFLASH_Read(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//读出整个扇区的内容
|
||||
for(i=0;i<secremain;i++)//校验数据
|
||||
{
|
||||
if(STMFLASH_BUF[secoff+i]!=0XFFFF)break;//需要擦除
|
||||
}
|
||||
if(i<secremain)//需要擦除
|
||||
{
|
||||
STMFLASH_ErasePage(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE);//擦除这个扇区
|
||||
for(i=0;i<secremain;i++)//复制
|
||||
{
|
||||
STMFLASH_BUF[i+secoff]=pBuffer[i];
|
||||
}
|
||||
STMFLASH_Write_NoCheck(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//写入整个扇区
|
||||
}else STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);//写已经擦除了的,直接写入扇区剩余区间.
|
||||
if(NumToWrite==secremain)break;//写入结束了
|
||||
else//写入未结束
|
||||
{
|
||||
secpos++; //扇区地址增1
|
||||
secoff=0; //偏移位置为0
|
||||
pBuffer+=secremain; //指针偏移
|
||||
WriteAddr+=secremain*2; //写地址偏移(16位数据地址,需要*2)
|
||||
NumToWrite-=secremain; //字节(16位)数递减
|
||||
if(NumToWrite>(STM_SECTOR_SIZE/2))secremain=STM_SECTOR_SIZE/2;//下一个扇区还是写不完
|
||||
else secremain=NumToWrite;//下一个扇区可以写完了
|
||||
}
|
||||
};
|
||||
STMFLASH_Lock();//上锁
|
||||
}
|
||||
#endif
|
||||
//从指定地址开始读出指定长度的数据
|
||||
//ReadAddr:起始地址
|
||||
//pBuffer:数据指针
|
||||
//NumToWrite:半字(16位)数
|
||||
void STMFLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead)
|
||||
{
|
||||
u16 i;
|
||||
for(i=0;i<NumToRead;i++)
|
||||
{
|
||||
pBuffer[i]=STMFLASH_ReadHalfWord(ReadAddr);//读取2个字节.
|
||||
ReadAddr+=2;//偏移2个字节.
|
||||
}
|
||||
}
|
||||
|
||||
//WriteAddr:起始地址
|
||||
//WriteData:要写入的数据
|
||||
void Test_Write(u32 WriteAddr,u16 WriteData)
|
||||
{
|
||||
STMFLASH_Write(WriteAddr,&WriteData,1);//写入一个字
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
函数功能:从Flash读取指定数据
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void Flash_Read(void)
|
||||
{
|
||||
STMFLASH_Read(FLASH_SAVE_ADDR,(u16*)PID_Parameter,10);
|
||||
if(PID_Parameter[0]==65535&&PID_Parameter[1]==65535&&PID_Parameter[2]==65535&&PID_Parameter[3]==65535&&PID_Parameter[4]==65535&&PID_Parameter[5]==65535&&PID_Parameter[6]==65535)
|
||||
{
|
||||
RC_Velocity=30;
|
||||
Velocity_KP=12;
|
||||
Velocity_KI=12;
|
||||
}
|
||||
else
|
||||
{
|
||||
RC_Velocity=PID_Parameter[0];//从Flash里面读取数据
|
||||
Velocity_KP=PID_Parameter[1];
|
||||
Velocity_KI=PID_Parameter[2];
|
||||
}
|
||||
}
|
||||
/**************************************************************************
|
||||
函数功能:向Flash写入指定数据
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void Flash_Write(void)
|
||||
{
|
||||
Flash_Parameter[0]=RC_Velocity; //写入数据
|
||||
Flash_Parameter[1]=Velocity_KP; //
|
||||
Flash_Parameter[2]=Velocity_KI; //
|
||||
STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)Flash_Parameter,10);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
52
HARDWARE/stmflash.h
Normal file
52
HARDWARE/stmflash.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef __STMFLASH_H__
|
||||
#define __STMFLASH_H__
|
||||
#include "sys.h"
|
||||
#include "system.h"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//用户根据自己的需要设置
|
||||
#define STM32_FLASH_SIZE 64 //所选STM32的FLASH容量大小(单位为K)
|
||||
#define STM32_FLASH_WREN 1 //使能FLASH写入(0,不是能;1,使能)
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//FLASH起始地址
|
||||
#define STM32_FLASH_BASE 0x08000000 //STM32 FLASH的起始地址
|
||||
//FLASH解锁键值
|
||||
#define FLASH_KEY1 0X45670123
|
||||
#define FLASH_KEY2 0XCDEF89AB
|
||||
void STMFLASH_Unlock(void); //FLASH解锁
|
||||
void STMFLASH_Lock(void); //FLASH上锁
|
||||
u8 STMFLASH_GetStatus(void); //获得状态
|
||||
u8 STMFLASH_WaitDone(u16 time); //等待操作结束
|
||||
u8 STMFLASH_ErasePage(u32 paddr); //擦除页
|
||||
u8 STMFLASH_WriteHalfWord(u32 faddr, u16 dat); //写入半字
|
||||
u16 STMFLASH_ReadHalfWord(u32 faddr); //读出半字
|
||||
void STMFLASH_WriteLenByte(u32 WriteAddr,u32 DataToWrite,u16 Len); //指定地址开始写入指定长度的数据
|
||||
u32 STMFLASH_ReadLenByte(u32 ReadAddr,u16 Len); //指定地址开始读取指定长度数据
|
||||
void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite); //从指定地址开始写入指定长度的数据
|
||||
void STMFLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead); //从指定地址开始读出指定长度的数据
|
||||
|
||||
//测试写入
|
||||
void Test_Write(u32 WriteAddr,u16 WriteData);
|
||||
|
||||
void Flash_Read(void);
|
||||
void Flash_Write(void);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
474
HARDWARE/timer.c
Normal file
474
HARDWARE/timer.c
Normal file
@@ -0,0 +1,474 @@
|
||||
#include "timer.h"
|
||||
|
||||
//Input the capture flag for channel 1,
|
||||
//the capture flag for the higher bits, and the overflow flag for the lower 6 bits
|
||||
//通道1输入捕获标志,高两位做捕获标志,低6位做溢出标志
|
||||
u8 TIM8CH1_CAPTURE_STA = 0;
|
||||
u16 TIM8CH1_CAPTURE_UPVAL;
|
||||
u16 TIM8CH1_CAPTURE_DOWNVAL;
|
||||
|
||||
//Input the capture flag for channel 2,
|
||||
//the capture flag for the higher bits, and the overflow flag for the lower 6 bits
|
||||
//通道2输入捕获标志,高两位做捕获标志,低6位做溢出标志
|
||||
u8 TIM8CH2_CAPTURE_STA = 0;
|
||||
u16 TIM8CH2_CAPTURE_UPVAL;
|
||||
u16 TIM8CH2_CAPTURE_DOWNVAL;
|
||||
|
||||
//Input the capture flag for channel 3,
|
||||
//the capture flag for the higher bits, and the overflow flag for the lower 6 bits
|
||||
//通道3输入捕获标志,高两位做捕获标志,低6位做溢出标志
|
||||
u8 TIM8CH3_CAPTURE_STA = 0;
|
||||
u16 TIM8CH3_CAPTURE_UPVAL;
|
||||
u16 TIM8CH3_CAPTURE_DOWNVAL;
|
||||
|
||||
//Input the capture flag for channel 4,
|
||||
//the capture flag for the higher bits, and the overflow flag for the lower 6 bits
|
||||
//通道4输入捕获标志,高两位做捕获标志,低6位做溢出标志
|
||||
u8 TIM8CH4_CAPTURE_STA = 0;
|
||||
u16 TIM8CH4_CAPTURE_UPVAL;
|
||||
u16 TIM8CH4_CAPTURE_DOWNVAL;
|
||||
|
||||
u32 TIM8_T1;
|
||||
u32 TIM8_T2;
|
||||
u32 TIM8_T3;
|
||||
u32 TIM8_T4;
|
||||
|
||||
//Variables related to remote control acquisition of model aircraft
|
||||
//航模遥控采集相关变量
|
||||
int Remoter_Ch1=1500,Remoter_Ch2=1500,Remoter_Ch3=1500,Remoter_Ch4=1500;
|
||||
//Model aircraft remote control receiver variable
|
||||
//航模遥控接收变量
|
||||
int L_Remoter_Ch1=1500,L_Remoter_Ch2=1500,L_Remoter_Ch3=1500,L_Remoter_Ch4=1500;
|
||||
|
||||
/**************************************************************************
|
||||
Function: Model aircraft remote control initialization function, timer 1 input capture initialization
|
||||
Input : arr: Automatic reload value, psc: clock preset frequency
|
||||
Output : none
|
||||
函数功能:航模遥控初始化函数,定时器1输入捕获初始化
|
||||
入口参数:arr:自动重装值,psc:时钟预分频数
|
||||
返 回 值:无
|
||||
**************************************************************************/
|
||||
void TIM8_Cap_Init(u16 arr, u16 psc)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
TIM_ICInitTypeDef TIM_ICInitStructure;
|
||||
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE); //TIM1时钟使能
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //使能PORTE时钟
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9; //GPIOC
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉
|
||||
GPIO_Init(GPIOC,&GPIO_InitStructure);
|
||||
|
||||
GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_TIM8);
|
||||
GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_TIM8);
|
||||
GPIO_PinAFConfig(GPIOC,GPIO_PinSource8,GPIO_AF_TIM8);
|
||||
GPIO_PinAFConfig(GPIOC,GPIO_PinSource9,GPIO_AF_TIM8);
|
||||
|
||||
/*** Initialize timer 1 || 初始化定时器1 ***/
|
||||
//Set the counter to automatically reload //设定计数器自动重装值
|
||||
TIM_TimeBaseStructure.TIM_Period = arr;
|
||||
//Pre-divider //预分频器
|
||||
TIM_TimeBaseStructure.TIM_Prescaler = psc;
|
||||
//Set the clock split: TDTS = Tck_tim //设置时钟分割:TDTS = Tck_tim
|
||||
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
|
||||
//TIM up count mode //TIM向上计数模式
|
||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||
//Initializes the timebase unit for TIMX based on the parameter specified in TIM_TimeBaseInitStruct
|
||||
//根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
|
||||
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
|
||||
|
||||
/*** 初始化TIM1输入捕获参数,通道1 || Initialize TIM1 for the capture parameter, channel 1 ***/
|
||||
//Select input //选择输入端
|
||||
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
|
||||
//Rising edge capture //上升沿捕获
|
||||
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
|
||||
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
|
||||
//Configure input frequency division, regardless of frequency //配置输入分频,不分频
|
||||
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
|
||||
//IC1F=0000 Configure input filter //配置输入滤波器
|
||||
TIM_ICInitStructure.TIM_ICFilter = 0x0F;
|
||||
TIM_ICInit(TIM8, &TIM_ICInitStructure);
|
||||
|
||||
/*** 初始化TIM1输入捕获参数,通道2 || Initialize TIM1 for the capture parameter, channel 2 ***/
|
||||
//CC1S=01 Select input //选择输入端
|
||||
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
|
||||
//Rising edge capture //上升沿捕获
|
||||
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
|
||||
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
|
||||
//Configure input frequency division, regardless of frequency //配置输入分频,不分频
|
||||
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
|
||||
TIM_ICInitStructure.TIM_ICFilter = 0x00; //IC1F=0000 配置输入滤波器
|
||||
TIM_ICInit(TIM8, &TIM_ICInitStructure);
|
||||
|
||||
/*** 初始化TIM1输入捕获参数,通道3 || Initialize TIM1 for the capture parameter, channel 3 ***/
|
||||
//Select input //选择输入端
|
||||
TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
|
||||
//Rising edge capture //上升沿捕获
|
||||
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
|
||||
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
|
||||
//Configure input frequency division, regardless of frequency //配置输入分频,不分频
|
||||
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
|
||||
//IC1F=0000 Configure input filter //配置输入滤波器,不滤波
|
||||
TIM_ICInitStructure.TIM_ICFilter = 0x00;
|
||||
TIM_ICInit(TIM8, &TIM_ICInitStructure);
|
||||
|
||||
/*** 初始化TIM1输入捕获参数,通道4 || Initialize TIM1 for the capture parameter, channel 4 ***/
|
||||
//Select input //选择输入端
|
||||
TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;
|
||||
//Rising edge capture //上升沿捕获
|
||||
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
|
||||
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
|
||||
//Configure input frequency division, regardless of frequency //配置输入分频,不分频
|
||||
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
|
||||
//IC1F=0000 Configure input filter //配置输入滤波器,不滤波
|
||||
TIM_ICInitStructure.TIM_ICFilter = 0x00;
|
||||
TIM_ICInit(TIM8, &TIM_ICInitStructure);
|
||||
|
||||
/*** interrupt packet initialization || 中断分组初始化 ***/
|
||||
//TIM1 interrupts //TIM1中断
|
||||
NVIC_InitStructure.NVIC_IRQChannel = TIM8_CC_IRQn;
|
||||
//Preempt priority 0 //先占优先级0级
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
|
||||
//Level 0 from priority //从优先级0级
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
|
||||
//IRQ channels are enabled //IRQ通道被使能
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
//Initializes the peripheral NVIC register according to the parameters specified in NVIC_InitStruct
|
||||
//根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
|
||||
//Allow CC1IE,CC2IE,CC3IE,CC4IE to catch interrupts, not allowed update_interrupts
|
||||
//不允许更新中断,允许CC1IE,CC2IE,CC3IE,CC4IE捕获中断
|
||||
TIM_ITConfig(TIM8, TIM_IT_CC1|TIM_IT_CC2|TIM_IT_CC3|TIM_IT_CC4, ENABLE);
|
||||
//Advanced timer output must be enabled //高级定时器输出必须使能这句
|
||||
TIM_CtrlPWMOutputs(TIM8,ENABLE);
|
||||
//Enable timer //使能定时器
|
||||
TIM_Cmd(TIM8, ENABLE);
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Model aircraft remote control receiving interrupt, namely timer 8 input capture interrupt
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:航模遥控接收中断,即定时器8输入捕获中断
|
||||
入口参数:无
|
||||
返 回 值:无
|
||||
**************************************************************************/
|
||||
void TIM8_CC_IRQHandler(void)
|
||||
{
|
||||
//连接航模遥遥控器后,需要推下前进杆,才可以正式航模控制小车
|
||||
//After connecting the remote controller of the model aircraft,
|
||||
//you need to push down the forward lever to officially control the car of the model aircraft
|
||||
if(Remoter_Ch2>1600&&Remote_ON_Flag==0&&Deviation_Count>=CONTROL_DELAY)
|
||||
{
|
||||
//Model aircraft remote control mark position 1, other marks position 0
|
||||
//航模遥控标志位置1,其它标志位置0
|
||||
Remote_ON_Flag=1;
|
||||
APP_ON_Flag=0;
|
||||
PS2_ON_Flag=0;
|
||||
CAN_ON_Flag=0;
|
||||
//Usart_ON_Flag=0;
|
||||
Usart1_ON_Flag=0;
|
||||
Usart5_ON_Flag=0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// //Channel 1 //通道一
|
||||
if ((TIM8CH1_CAPTURE_STA & 0X80) == 0)
|
||||
{
|
||||
if (TIM_GetITStatus(TIM8, TIM_IT_CC1) != RESET) //A capture event occurred on channel 1 //通道1发生捕获事件
|
||||
{
|
||||
TIM_ClearITPendingBit(TIM8, TIM_IT_CC1); //Clear the interrupt flag bit //清除中断标志位
|
||||
if (TIM8CH1_CAPTURE_STA & 0X40) //A falling edge is caught //捕获到一个下降沿
|
||||
{
|
||||
TIM8CH1_CAPTURE_DOWNVAL = TIM_GetCapture1(TIM8); //Record the timer value at this point //记录下此时的定时器计数值
|
||||
if (TIM8CH1_CAPTURE_DOWNVAL < TIM8CH1_CAPTURE_UPVAL)
|
||||
{
|
||||
TIM8_T1 = 9999;
|
||||
}
|
||||
else
|
||||
TIM8_T1 = 0;
|
||||
Remoter_Ch1 = TIM8CH1_CAPTURE_DOWNVAL - TIM8CH1_CAPTURE_UPVAL + TIM8_T1; //Time to get the total high level //得到总的高电平的时间
|
||||
if(abs(Remoter_Ch1-L_Remoter_Ch1)>500) Remoter_Ch1=L_Remoter_Ch1; //Filter //滤波
|
||||
L_Remoter_Ch1=Remoter_Ch1;
|
||||
|
||||
TIM8CH1_CAPTURE_STA = 0; //Capture flag bit to zero //捕获标志位清零
|
||||
TIM_OC1PolarityConfig(TIM8, TIM_ICPolarity_Rising); //Set to rising edge capture //设置为上升沿捕获
|
||||
}
|
||||
else
|
||||
{
|
||||
//When the capture time occurs but not the falling edge, the first time the rising edge is captured, record the timer value at this time
|
||||
//发生捕获时间但不是下降沿,第一次捕获到上升沿,记录此时的定时器计数值
|
||||
TIM8CH1_CAPTURE_UPVAL = TIM_GetCapture1(TIM8); //Obtain rising edge data //获取上升沿数据
|
||||
TIM8CH1_CAPTURE_STA |= 0X40; //The flag has been caught on the rising edge //标记已捕获到上升沿
|
||||
TIM_OC1PolarityConfig(TIM8, TIM_ICPolarity_Falling); //Set to Falling Edge Capture //设置为下降沿捕获
|
||||
}
|
||||
}
|
||||
}
|
||||
//Channel 2 //通道二
|
||||
if ((TIM8CH2_CAPTURE_STA & 0X80) == 0)
|
||||
{
|
||||
if (TIM_GetITStatus(TIM8, TIM_IT_CC2) != RESET) //A capture event occurred on channel 2 //通道2发生捕获事件
|
||||
{
|
||||
TIM_ClearITPendingBit(TIM8, TIM_IT_CC2); //Clear the interrupt flag bit //清除中断标志位
|
||||
if (TIM8CH2_CAPTURE_STA & 0X40) //A falling edge is caught //捕获到一个下降沿
|
||||
{
|
||||
TIM8CH2_CAPTURE_DOWNVAL = TIM_GetCapture2(TIM8); //Record the timer value at this point //记录下此时的定时器计数值
|
||||
if (TIM8CH2_CAPTURE_DOWNVAL < TIM8CH2_CAPTURE_UPVAL)
|
||||
{
|
||||
TIM8_T2 = 9999;
|
||||
}
|
||||
else
|
||||
TIM8_T2 = 0;
|
||||
Remoter_Ch2 = TIM8CH2_CAPTURE_DOWNVAL - TIM8CH2_CAPTURE_UPVAL + TIM8_T2; //Time to get the total high level //得到总的高电平的时间
|
||||
if(abs(Remoter_Ch2-L_Remoter_Ch2)>500)Remoter_Ch2=L_Remoter_Ch2; //Filter //滤波
|
||||
L_Remoter_Ch2=Remoter_Ch2;
|
||||
|
||||
TIM8CH2_CAPTURE_STA = 0; //Capture flag bit to zero //捕获标志位清零
|
||||
TIM_OC2PolarityConfig(TIM8, TIM_ICPolarity_Rising); //Set to rising edge capture //设置为上升沿捕获
|
||||
}
|
||||
else
|
||||
{
|
||||
//When the capture time occurs but not the falling edge, the first time the rising edge is captured, record the timer value at this time
|
||||
//发生捕获时间但不是下降沿,第一次捕获到上升沿,记录此时的定时器计数值
|
||||
TIM8CH2_CAPTURE_UPVAL = TIM_GetCapture2(TIM8); //Obtain rising edge data //获取上升沿数据
|
||||
TIM8CH2_CAPTURE_STA |= 0X40; //The flag has been caught on the rising edge //标记已捕获到上升沿
|
||||
TIM_OC2PolarityConfig(TIM8, TIM_ICPolarity_Falling); //Set to Falling Edge Capture //设置为下降沿捕获
|
||||
}
|
||||
}
|
||||
}
|
||||
//Channel 3 //通道三
|
||||
if ((TIM8CH3_CAPTURE_STA & 0X80) == 0)
|
||||
{
|
||||
if (TIM_GetITStatus(TIM8, TIM_IT_CC3) != RESET) //A capture event occurred on channel 3 //通道3发生捕获事件
|
||||
{
|
||||
TIM_ClearITPendingBit(TIM8, TIM_IT_CC3); //Clear the interrupt flag bit //清除中断标志位
|
||||
if (TIM8CH3_CAPTURE_STA & 0X40) //A falling edge is caught //捕获到一个下降沿
|
||||
{
|
||||
TIM8CH3_CAPTURE_DOWNVAL = TIM_GetCapture3(TIM8); //Record the timer value at this point //记录下此时的定时器计数值
|
||||
if (TIM8CH3_CAPTURE_DOWNVAL < TIM8CH3_CAPTURE_UPVAL)
|
||||
{
|
||||
TIM8_T3 = 9999;
|
||||
}
|
||||
else
|
||||
TIM8_T3 = 0;
|
||||
Remoter_Ch3 = TIM8CH3_CAPTURE_DOWNVAL - TIM8CH3_CAPTURE_UPVAL + TIM8_T3; //Time to get the total high level //得到总的高电平的时间
|
||||
if(abs(Remoter_Ch3-L_Remoter_Ch3)>500)Remoter_Ch3=L_Remoter_Ch3; //Filter //滤波
|
||||
L_Remoter_Ch3=Remoter_Ch3;
|
||||
TIM8CH3_CAPTURE_STA = 0; //Capture flag bit to zero //捕获标志位清零
|
||||
TIM_OC3PolarityConfig(TIM8, TIM_ICPolarity_Rising); //Set to rising edge capture //设置为上升沿捕获
|
||||
}
|
||||
else
|
||||
{
|
||||
//When the capture time occurs but not the falling edge, the first time the rising edge is captured, record the timer value at this time
|
||||
//发生捕获时间但不是下降沿,第一次捕获到上升沿,记录此时的定时器计数值
|
||||
TIM8CH3_CAPTURE_UPVAL = TIM_GetCapture3(TIM8); //Obtain rising edge data //获取上升沿数据
|
||||
TIM8CH3_CAPTURE_STA |= 0X40; //The flag has been caught on the rising edge //标记已捕获到上升沿
|
||||
TIM_OC3PolarityConfig(TIM8, TIM_ICPolarity_Falling); //Set to Falling Edge Capture //设置为下降沿捕获
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
|
||||
//Channel 4 //通道四
|
||||
if ((TIM8CH4_CAPTURE_STA & 0X80) == 0)
|
||||
{
|
||||
if (TIM_GetITStatus(TIM8, TIM_IT_CC4) != RESET) //A capture event occurred on channel 4 //通道4发生捕获事件
|
||||
{
|
||||
TIM_ClearITPendingBit(TIM8, TIM_IT_CC4); //Clear the interrupt flag bit //清除中断标志位
|
||||
if (TIM8CH4_CAPTURE_STA & 0X40) //A falling edge is caught //捕获到一个下降沿
|
||||
{
|
||||
TIM8CH4_CAPTURE_DOWNVAL = TIM_GetCapture4(TIM8); //Record the timer value at this point //记录下此时的定时器计数值
|
||||
if (TIM8CH4_CAPTURE_DOWNVAL < TIM8CH4_CAPTURE_UPVAL)
|
||||
{
|
||||
TIM8_T4 = 9999;
|
||||
}
|
||||
else
|
||||
TIM8_T4 = 0;
|
||||
Remoter_Ch4 = TIM8CH4_CAPTURE_DOWNVAL - TIM8CH4_CAPTURE_UPVAL + TIM8_T4; //Time to get the total high level //得到总的高电平的时间
|
||||
if(abs(Remoter_Ch4-L_Remoter_Ch4)>500)Remoter_Ch4=L_Remoter_Ch4; //Filter //滤波
|
||||
L_Remoter_Ch4=Remoter_Ch4;
|
||||
TIM8CH4_CAPTURE_STA = 0; //Capture flag bit to zero //捕获标志位清零
|
||||
TIM_OC4PolarityConfig(TIM8, TIM_ICPolarity_Rising); //Set to rising edge capture //设置为上升沿捕获
|
||||
}
|
||||
else
|
||||
{
|
||||
//When the capture time occurs but not the falling edge, the first time the rising edge is captured, record the timer value at this time
|
||||
//发生捕获时间但不是下降沿,第一次捕获到上升沿,记录此时的定时器计数值
|
||||
TIM8CH4_CAPTURE_UPVAL = TIM_GetCapture4(TIM8); //Obtain rising edge data //获取上升沿数据
|
||||
TIM8CH4_CAPTURE_STA |= 0X40; //The flag has been caught on the rising edge //标记已捕获到上升沿
|
||||
TIM_OC4PolarityConfig(TIM8, TIM_ICPolarity_Falling); //Set to Falling Edge Capture //设置为下降沿捕获
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: TIM1 Update Interrupt
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:定时器8更新中断
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void TIM8_UP_TIM13_IRQHandler(void)
|
||||
{
|
||||
//Clear the interrupt flag bit
|
||||
//清除中断标志位
|
||||
TIM8->SR&=~(1<<0);
|
||||
}
|
||||
|
||||
void TIM8_SERVO_Init(u16 arr,u16 psc)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure; //IO
|
||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //定时器
|
||||
TIM_OCInitTypeDef TIM_OCInitStructure; //PWM输出
|
||||
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE); //TIM1时钟使能
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //使能PORTE时钟
|
||||
|
||||
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
|
||||
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
|
||||
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
|
||||
GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||||
|
||||
GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_TIM8);
|
||||
GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_TIM8);
|
||||
GPIO_PinAFConfig(GPIOC,GPIO_PinSource8,GPIO_AF_TIM8);
|
||||
GPIO_PinAFConfig(GPIOC,GPIO_PinSource9,GPIO_AF_TIM8);
|
||||
|
||||
|
||||
/*** Initialize timer 1 || 初始化定时器1 ***/
|
||||
//Set the counter to automatically reload //设定计数器自动重装值
|
||||
TIM_TimeBaseStructure.TIM_Period = arr;
|
||||
//Pre-divider //预分频器
|
||||
TIM_TimeBaseStructure.TIM_Prescaler = psc;
|
||||
//Set the clock split: TDTS = Tck_tim //设置时钟分割:TDTS = Tck_tim
|
||||
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
|
||||
//TIM up count mode //TIM向上计数模式
|
||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||
//Initializes the timebase unit for TIMX based on the parameter specified in TIM_TimeBaseInitStruct
|
||||
//根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
|
||||
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
|
||||
|
||||
|
||||
//-----------舵机初始化-----------//
|
||||
//Select Timer mode :TIM Pulse Width Modulation mode 1
|
||||
//选择定时器模式:TIM脉冲宽度调制模式1
|
||||
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
|
||||
//Compare output enablement
|
||||
//比较输出使能
|
||||
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
|
||||
//Set the pulse value of the capture comparison register to be loaded
|
||||
//设置待装入捕获比较寄存器的脉冲值
|
||||
TIM_OCInitStructure.TIM_Pulse = 0;
|
||||
//Output polarity :TIM output polarity is higher
|
||||
//输出极性:TIM输出比较极性高
|
||||
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
|
||||
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
|
||||
|
||||
//Initialize the peripheral TIMX based on the parameter specified in TIM_OCINITSTRUCT
|
||||
//根据TIM_OCInitStruct中指定的参数初始化外设TIMx
|
||||
TIM_OC1Init(TIM8, &TIM_OCInitStructure);
|
||||
TIM_OC2Init(TIM8, &TIM_OCInitStructure);
|
||||
TIM_OC3Init(TIM8, &TIM_OCInitStructure);
|
||||
TIM_OC4Init(TIM8, &TIM_OCInitStructure);
|
||||
//Channel preload enable
|
||||
//通道预装载使能
|
||||
TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable);
|
||||
TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable);
|
||||
TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable);
|
||||
TIM_OC4PreloadConfig(TIM8, TIM_OCPreload_Enable);
|
||||
//-----------舵机初始化-----------//
|
||||
|
||||
TIM_CtrlPWMOutputs(TIM8,ENABLE);
|
||||
//Enable timer //使能定时器
|
||||
TIM_Cmd(TIM8, ENABLE);
|
||||
|
||||
//The channel value is initialized to 1500, corresponding to the steering gear zero
|
||||
//通道值初始化为1500,舵机零点对应值
|
||||
// TIM8->CCR1=1500;
|
||||
// TIM8->CCR2=1500;
|
||||
// TIM8->CCR3=1500;
|
||||
// TIM8->CCR4=1500;
|
||||
}
|
||||
|
||||
|
||||
void TIM12_SERVO_Init(u16 arr,u16 psc)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure; //IO
|
||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //定时器
|
||||
TIM_OCInitTypeDef TIM_OCInitStructure; //PWM输出
|
||||
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM12,ENABLE); //TIM1时钟使能
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); //使能PORTE时钟
|
||||
|
||||
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14|GPIO_Pin_15;
|
||||
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
|
||||
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_TIM12);
|
||||
GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_TIM12);
|
||||
|
||||
|
||||
/*** Initialize timer 1 || 初始化定时器1 ***/
|
||||
//Set the counter to automatically reload //设定计数器自动重装值
|
||||
TIM_TimeBaseStructure.TIM_Period = arr;
|
||||
//Pre-divider //预分频器
|
||||
TIM_TimeBaseStructure.TIM_Prescaler = psc;
|
||||
//Set the clock split: TDTS = Tck_tim //设置时钟分割:TDTS = Tck_tim
|
||||
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
|
||||
//TIM up count mode //TIM向上计数模式
|
||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||
//Initializes the timebase unit for TIMX based on the parameter specified in TIM_TimeBaseInitStruct
|
||||
//根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
|
||||
TIM_TimeBaseInit(TIM12, &TIM_TimeBaseStructure);
|
||||
|
||||
|
||||
//-----------舵机初始化-----------//
|
||||
//Select Timer mode :TIM Pulse Width Modulation mode 1
|
||||
//选择定时器模式:TIM脉冲宽度调制模式1
|
||||
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
|
||||
//Compare output enablement
|
||||
//比较输出使能
|
||||
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
|
||||
//Set the pulse value of the capture comparison register to be loaded
|
||||
//设置待装入捕获比较寄存器的脉冲值
|
||||
TIM_OCInitStructure.TIM_Pulse = 0;
|
||||
//Output polarity :TIM output polarity is higher
|
||||
//输出极性:TIM输出比较极性高
|
||||
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
|
||||
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
|
||||
|
||||
//Initialize the peripheral TIMX based on the parameter specified in TIM_OCINITSTRUCT
|
||||
//根据TIM_OCInitStruct中指定的参数初始化外设TIMx
|
||||
TIM_OC1Init(TIM12, &TIM_OCInitStructure);
|
||||
TIM_OC2Init(TIM12, &TIM_OCInitStructure);
|
||||
//Channel preload enable
|
||||
//通道预装载使能
|
||||
TIM_OC1PreloadConfig(TIM12, TIM_OCPreload_Enable);
|
||||
TIM_OC2PreloadConfig(TIM12, TIM_OCPreload_Enable);
|
||||
//-----------舵机初始化-----------//
|
||||
|
||||
|
||||
TIM_CtrlPWMOutputs(TIM12,ENABLE);
|
||||
//Enable timer //使能定时器
|
||||
TIM_Cmd(TIM12, ENABLE);
|
||||
|
||||
//The channel value is initialized to 1500, corresponding to the steering gear zero
|
||||
//通道值初始化为1500,舵机零点对应值
|
||||
TIM12->CCR2=1500;
|
||||
TIM12->CCR1=1500;
|
||||
|
||||
}
|
||||
|
||||
11
HARDWARE/timer.h
Normal file
11
HARDWARE/timer.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef __TIMER_H
|
||||
#define __TIMER_H
|
||||
#include "system.h"
|
||||
void TIM8_Cap_Init(u16 arr, u16 psc);
|
||||
void TIM12_SERVO_Init(u16 arr,u16 psc);
|
||||
void TIM8_SERVO_Init(u16 arr,u16 psc);
|
||||
|
||||
extern int L_Remoter_Ch1,L_Remoter_Ch2,L_Remoter_Ch3,L_Remoter_Ch4;
|
||||
extern int Remoter_Ch1,Remoter_Ch2,Remoter_Ch3,Remoter_Ch4;
|
||||
|
||||
#endif
|
||||
936
HARDWARE/usartx.c
Normal file
936
HARDWARE/usartx.c
Normal file
@@ -0,0 +1,936 @@
|
||||
#include "usartx.h"
|
||||
SEND_DATA Send_Data;
|
||||
RECEIVE_DATA Receive_Data;
|
||||
extern int Time_count;
|
||||
|
||||
/**************************************************************************
|
||||
Function: Usartx3, Usartx1,Usartx5 and CAN send data task
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:串口3、串口1、串口5、CAN发送数据任务
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void data_task(void *pvParameters)
|
||||
{
|
||||
u32 lastWakeTime = getSysTickCnt();
|
||||
|
||||
while(1)
|
||||
{
|
||||
//The task is run at 20hz
|
||||
//此任务以20Hz的频率运行
|
||||
vTaskDelayUntil(&lastWakeTime, F2T(RATE_20_HZ));
|
||||
//Assign the data to be sent
|
||||
//对要进行发送的数据进行赋值
|
||||
data_transition();
|
||||
USART1_SEND(); //Serial port 1 sends data //串口1发送数据
|
||||
USART3_SEND(); //Serial port 3 (ROS) sends data //串口3(ROS)发送数据
|
||||
USART5_SEND(); //Serial port 5 sends data //串口5发送数据
|
||||
CAN_SEND(); //CAN send data //CAN发送数据
|
||||
}
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: The data sent by the serial port is assigned
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:串口发送的数据进行赋值
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void data_transition(void)
|
||||
{
|
||||
Send_Data.Sensor_Str.Frame_Header = FRAME_HEADER; //Frame_header //帧头
|
||||
Send_Data.Sensor_Str.Frame_Tail = FRAME_TAIL; //Frame_tail //帧尾
|
||||
|
||||
//According to different vehicle types, different kinematics algorithms were selected to carry out the forward kinematics solution,
|
||||
//and the three-axis velocity was obtained from each wheel velocity
|
||||
//根据不同车型选择不同运动学算法进行运动学正解,从各车轮速度求出三轴速度
|
||||
switch(Car_Mode)
|
||||
{
|
||||
case Mec_Car:
|
||||
Send_Data.Sensor_Str.X_speed = ((MOTOR_A.Encoder+MOTOR_B.Encoder+MOTOR_C.Encoder+MOTOR_D.Encoder)/4)*1000;
|
||||
Send_Data.Sensor_Str.Y_speed = ((MOTOR_A.Encoder-MOTOR_B.Encoder+MOTOR_C.Encoder-MOTOR_D.Encoder)/4)*1000;
|
||||
Send_Data.Sensor_Str.Z_speed = ((-MOTOR_A.Encoder-MOTOR_B.Encoder+MOTOR_C.Encoder+MOTOR_D.Encoder)/4/(Axle_spacing+Wheel_spacing))*1000;
|
||||
break;
|
||||
|
||||
case Omni_Car:
|
||||
Send_Data.Sensor_Str.X_speed = ((MOTOR_C.Encoder-MOTOR_B.Encoder)/2/X_PARAMETER)*1000;
|
||||
Send_Data.Sensor_Str.Y_speed = ((MOTOR_A.Encoder*2-MOTOR_B.Encoder-MOTOR_C.Encoder)/3)*1000;
|
||||
Send_Data.Sensor_Str.Z_speed = ((MOTOR_A.Encoder+MOTOR_B.Encoder+MOTOR_C.Encoder)/3/Omni_turn_radiaus)*1000;
|
||||
break;
|
||||
|
||||
case Akm_Car:
|
||||
Send_Data.Sensor_Str.X_speed = ((MOTOR_A.Encoder+MOTOR_B.Encoder)/2)*1000;
|
||||
Send_Data.Sensor_Str.Y_speed = 0;
|
||||
Send_Data.Sensor_Str.Z_speed = ((MOTOR_B.Encoder-MOTOR_A.Encoder)/Wheel_spacing)*1000;
|
||||
break;
|
||||
|
||||
case Diff_Car:
|
||||
Send_Data.Sensor_Str.X_speed = ((MOTOR_A.Encoder+MOTOR_B.Encoder)/2)*1000;
|
||||
Send_Data.Sensor_Str.Y_speed = 0;
|
||||
Send_Data.Sensor_Str.Z_speed = ((MOTOR_B.Encoder-MOTOR_A.Encoder)/Wheel_spacing)*1000;
|
||||
break;
|
||||
|
||||
case FourWheel_Car:
|
||||
Send_Data.Sensor_Str.X_speed = ((MOTOR_A.Encoder+MOTOR_B.Encoder+MOTOR_C.Encoder+MOTOR_D.Encoder)/4)*1000;
|
||||
Send_Data.Sensor_Str.Y_speed = 0;
|
||||
Send_Data.Sensor_Str.Z_speed = ((-MOTOR_B.Encoder-MOTOR_A.Encoder+MOTOR_C.Encoder+MOTOR_D.Encoder)/2/(Axle_spacing+Wheel_spacing))*1000;
|
||||
break;
|
||||
|
||||
case Tank_Car:
|
||||
Send_Data.Sensor_Str.X_speed = ((MOTOR_A.Encoder+MOTOR_B.Encoder)/2)*1000;
|
||||
Send_Data.Sensor_Str.Y_speed = 0;
|
||||
Send_Data.Sensor_Str.Z_speed = ((MOTOR_B.Encoder-MOTOR_A.Encoder)/(Wheel_spacing)*1000);
|
||||
break;
|
||||
}
|
||||
|
||||
//The acceleration of the triaxial acceleration //加速度计三轴加速度
|
||||
Send_Data.Sensor_Str.Accelerometer.X_data= accel[1]; //The accelerometer Y-axis is converted to the ros coordinate X axis //加速度计Y轴转换到ROS坐标X轴
|
||||
Send_Data.Sensor_Str.Accelerometer.Y_data=-accel[0]; //The accelerometer X-axis is converted to the ros coordinate y axis //加速度计X轴转换到ROS坐标Y轴
|
||||
Send_Data.Sensor_Str.Accelerometer.Z_data= accel[2]; //The accelerometer Z-axis is converted to the ros coordinate Z axis //加速度计Z轴转换到ROS坐标Z轴
|
||||
|
||||
//The Angle velocity of the triaxial velocity //角速度计三轴角速度
|
||||
Send_Data.Sensor_Str.Gyroscope.X_data= gyro[1]; //The Y-axis is converted to the ros coordinate X axis //角速度计Y轴转换到ROS坐标X轴
|
||||
Send_Data.Sensor_Str.Gyroscope.Y_data=-gyro[0]; //The X-axis is converted to the ros coordinate y axis //角速度计X轴转换到ROS坐标Y轴
|
||||
if(Flag_Stop==0)
|
||||
//If the motor control bit makes energy state, the z-axis velocity is sent normall
|
||||
//如果电机控制位使能状态,那么正常发送Z轴角速度
|
||||
Send_Data.Sensor_Str.Gyroscope.Z_data=gyro[2];
|
||||
else
|
||||
//If the robot is static (motor control dislocation), the z-axis is 0
|
||||
//如果机器人是静止的(电机控制位失能),那么发送的Z轴角速度为0
|
||||
Send_Data.Sensor_Str.Gyroscope.Z_data=0;
|
||||
|
||||
//Battery voltage (this is a thousand times larger floating point number, which will be reduced by a thousand times as well as receiving the data).
|
||||
//电池电压(这里将浮点数放大一千倍传输,相应的在接收端在接收到数据后也会缩小一千倍)
|
||||
Send_Data.Sensor_Str.Power_Voltage = Voltage*1000;
|
||||
|
||||
Send_Data.buffer[0]=Send_Data.Sensor_Str.Frame_Header; //Frame_heade //帧头
|
||||
Send_Data.buffer[1]=Flag_Stop; //Car software loss marker //小车软件失能标志位
|
||||
|
||||
//The three-axis speed of / / car is split into two eight digit Numbers
|
||||
//小车三轴速度,各轴都拆分为两个8位数据再发送
|
||||
Send_Data.buffer[2]=Send_Data.Sensor_Str.X_speed >>8;
|
||||
Send_Data.buffer[3]=Send_Data.Sensor_Str.X_speed ;
|
||||
Send_Data.buffer[4]=Send_Data.Sensor_Str.Y_speed>>8;
|
||||
Send_Data.buffer[5]=Send_Data.Sensor_Str.Y_speed;
|
||||
Send_Data.buffer[6]=Send_Data.Sensor_Str.Z_speed >>8;
|
||||
Send_Data.buffer[7]=Send_Data.Sensor_Str.Z_speed ;
|
||||
|
||||
//The acceleration of the triaxial axis of / / imu accelerometer is divided into two eight digit reams
|
||||
//IMU加速度计三轴加速度,各轴都拆分为两个8位数据再发送
|
||||
Send_Data.buffer[8]=Send_Data.Sensor_Str.Accelerometer.X_data>>8;
|
||||
Send_Data.buffer[9]=Send_Data.Sensor_Str.Accelerometer.X_data;
|
||||
Send_Data.buffer[10]=Send_Data.Sensor_Str.Accelerometer.Y_data>>8;
|
||||
Send_Data.buffer[11]=Send_Data.Sensor_Str.Accelerometer.Y_data;
|
||||
Send_Data.buffer[12]=Send_Data.Sensor_Str.Accelerometer.Z_data>>8;
|
||||
Send_Data.buffer[13]=Send_Data.Sensor_Str.Accelerometer.Z_data;
|
||||
|
||||
//The axis of the triaxial velocity of the / /imu is divided into two eight digits
|
||||
//IMU角速度计三轴角速度,各轴都拆分为两个8位数据再发送
|
||||
Send_Data.buffer[14]=Send_Data.Sensor_Str.Gyroscope.X_data>>8;
|
||||
Send_Data.buffer[15]=Send_Data.Sensor_Str.Gyroscope.X_data;
|
||||
Send_Data.buffer[16]=Send_Data.Sensor_Str.Gyroscope.Y_data>>8;
|
||||
Send_Data.buffer[17]=Send_Data.Sensor_Str.Gyroscope.Y_data;
|
||||
Send_Data.buffer[18]=Send_Data.Sensor_Str.Gyroscope.Z_data>>8;
|
||||
Send_Data.buffer[19]=Send_Data.Sensor_Str.Gyroscope.Z_data;
|
||||
|
||||
//Battery voltage, split into two 8 digit Numbers
|
||||
//电池电压,拆分为两个8位数据发送
|
||||
Send_Data.buffer[20]=Send_Data.Sensor_Str.Power_Voltage >>8;
|
||||
Send_Data.buffer[21]=Send_Data.Sensor_Str.Power_Voltage;
|
||||
|
||||
//Data check digit calculation, Pattern 1 is a data check
|
||||
//数据校验位计算,模式1是发送数据校验
|
||||
Send_Data.buffer[22]=Check_Sum(22,1);
|
||||
|
||||
Send_Data.buffer[23]=Send_Data.Sensor_Str.Frame_Tail; //Frame_tail //帧尾
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Serial port 1 sends data
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:串口1发送数据
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void USART1_SEND(void)
|
||||
{
|
||||
unsigned char i = 0;
|
||||
|
||||
for(i=0; i<24; i++)
|
||||
{
|
||||
usart1_send(Send_Data.buffer[i]);
|
||||
}
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Serial port 3 sends data
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:串口3发送数据
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void USART3_SEND(void)
|
||||
{
|
||||
unsigned char i = 0;
|
||||
for(i=0; i<24; i++)
|
||||
{
|
||||
usart3_send(Send_Data.buffer[i]);
|
||||
}
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Serial port 5 sends data
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:串口5发送数据
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void USART5_SEND(void)
|
||||
{
|
||||
unsigned char i = 0;
|
||||
for(i=0; i<24; i++)
|
||||
{
|
||||
usart5_send(Send_Data.buffer[i]);
|
||||
}
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: CAN sends data
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:CAN发送数据
|
||||
入口参数:无
|
||||
返 回 值:无
|
||||
**************************************************************************/
|
||||
void CAN_SEND(void)
|
||||
{
|
||||
u8 CAN_SENT[8],i;
|
||||
|
||||
for(i=0;i<8;i++)
|
||||
{
|
||||
CAN_SENT[i]=Send_Data.buffer[i];
|
||||
}
|
||||
CAN1_Send_Num(0x101,CAN_SENT);
|
||||
|
||||
for(i=0;i<8;i++)
|
||||
{
|
||||
CAN_SENT[i]=Send_Data.buffer[i+8];
|
||||
}
|
||||
CAN1_Send_Num(0x102,CAN_SENT);
|
||||
|
||||
for(i=0;i<8;i++)
|
||||
{
|
||||
CAN_SENT[i]=Send_Data.buffer[i+16];
|
||||
}
|
||||
CAN1_Send_Num(0x103,CAN_SENT);
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Serial port 1 initialization
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:串口1初始化
|
||||
入口参数:无
|
||||
返 回 值:无
|
||||
**************************************************************************/
|
||||
void uart1_init(u32 bound)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
USART_InitTypeDef USART_InitStructure;
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //Enable the gpio clock //使能GPIO时钟
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //Enable the Usart clock //使能USART时钟
|
||||
|
||||
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
|
||||
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10 ,GPIO_AF_USART1);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
|
||||
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF; //输出模式
|
||||
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP; //推挽输出
|
||||
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //高速50MHZ
|
||||
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP; //上拉
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化
|
||||
|
||||
//UsartNVIC configuration //UsartNVIC配置
|
||||
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
|
||||
//Preempt priority //抢占优先级
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;
|
||||
//Subpriority //子优先级
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||||
//Enable the IRQ channel //IRQ通道使能
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
//Initialize the VIC register with the specified parameters
|
||||
//根据指定的参数初始化VIC寄存器
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
|
||||
//USART Initialization Settings 初始化设置
|
||||
USART_InitStructure.USART_BaudRate = bound; //Port rate //串口波特率
|
||||
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //The word length is 8 bit data format //字长为8位数据格式
|
||||
USART_InitStructure.USART_StopBits = USART_StopBits_1; //A stop bit //一个停止位
|
||||
USART_InitStructure.USART_Parity = USART_Parity_No; //Prosaic parity bits //无奇偶校验位
|
||||
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //No hardware data flow control //无硬件数据流控制
|
||||
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //Sending and receiving mode //收发模式
|
||||
USART_Init(USART1, &USART_InitStructure); //Initialize serial port 1 //初始化串口1
|
||||
|
||||
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //Open the serial port to accept interrupts //开启串口接受中断
|
||||
USART_Cmd(USART1, ENABLE); //Enable serial port 1 //使能串口1
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Serial port 2 initialization
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:串口2初始化
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void uart2_init(u32 bound)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
USART_InitTypeDef USART_InitStructure;
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); //Enable the gpio clock //使能GPIO时钟
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //Enable the Usart clock //使能USART时钟
|
||||
|
||||
GPIO_PinAFConfig(GPIOD,GPIO_PinSource5,GPIO_AF_USART2);
|
||||
GPIO_PinAFConfig(GPIOD,GPIO_PinSource6 ,GPIO_AF_USART2);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6;
|
||||
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF; //输出模式
|
||||
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP; //推挽输出
|
||||
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //高速50MHZ
|
||||
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP; //上拉
|
||||
GPIO_Init(GPIOD, &GPIO_InitStructure); //初始化
|
||||
|
||||
//UsartNVIC configuration //UsartNVIC配置
|
||||
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
|
||||
//Preempt priority //抢占优先级
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;
|
||||
//Subpriority //子优先级
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||||
//Enable the IRQ channel //IRQ通道使能
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
//Initialize the VIC register with the specified parameters
|
||||
//根据指定的参数初始化VIC寄存器
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
|
||||
//USART Initialization Settings 初始化设置
|
||||
USART_InitStructure.USART_BaudRate = bound; //Port rate //串口波特率
|
||||
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //The word length is 8 bit data format //字长为8位数据格式
|
||||
USART_InitStructure.USART_StopBits = USART_StopBits_1; //A stop bit //一个停止
|
||||
USART_InitStructure.USART_Parity = USART_Parity_No; //Prosaic parity bits //无奇偶校验位
|
||||
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //No hardware data flow control //无硬件数据流控制
|
||||
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //Sending and receiving mode //收发模式
|
||||
USART_Init(USART2, &USART_InitStructure); //Initialize serial port 2 //初始化串口2
|
||||
|
||||
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //Open the serial port to accept interrupts //开启串口接受中断
|
||||
USART_Cmd(USART2, ENABLE); //Enable serial port 2 //使能串口2
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Serial port 3 initialization
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:串口3初始化
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void uart3_init(u32 bound)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
USART_InitTypeDef USART_InitStructure;
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); //Enable the gpio clock //使能GPIO时钟
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); //Enable the Usart clock //使能USART时钟
|
||||
|
||||
GPIO_PinAFConfig(GPIOD,GPIO_PinSource8,GPIO_AF_USART3);
|
||||
GPIO_PinAFConfig(GPIOD,GPIO_PinSource9,GPIO_AF_USART3);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;
|
||||
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF; //输出模式
|
||||
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP; //推挽输出
|
||||
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //高速50MHZ
|
||||
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP; //上拉
|
||||
GPIO_Init(GPIOD, &GPIO_InitStructure); //初始化
|
||||
|
||||
//UsartNVIC configuration //UsartNVIC配置
|
||||
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
|
||||
//Preempt priority //抢占优先级
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;
|
||||
//Preempt priority //抢占优先级
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||||
//Enable the IRQ channel //IRQ通道使能
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
//Initialize the VIC register with the specified parameters
|
||||
//根据指定的参数初始化VIC寄存器
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
|
||||
//USART Initialization Settings 初始化设置
|
||||
USART_InitStructure.USART_BaudRate = bound; //Port rate //串口波特率
|
||||
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //The word length is 8 bit data format //字长为8位数据格式
|
||||
USART_InitStructure.USART_StopBits = USART_StopBits_1; //A stop bit //一个停止
|
||||
USART_InitStructure.USART_Parity = USART_Parity_No; //Prosaic parity bits //无奇偶校验位
|
||||
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //No hardware data flow control //无硬件数据流控制
|
||||
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //Sending and receiving mode //收发模式
|
||||
USART_Init(USART3, &USART_InitStructure); //Initialize serial port 3 //初始化串口3
|
||||
|
||||
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); //Open the serial port to accept interrupts //开启串口接受中断
|
||||
USART_Cmd(USART3, ENABLE); //Enable serial port 3 //使能串口3
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Serial port 5 initialization
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:串口5初始化
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void uart5_init(u32 bound)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
USART_InitTypeDef USART_InitStructure;
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
|
||||
//PC12 TX
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //Enable the gpio clock //使能GPIO时钟
|
||||
//PD2 RX
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); //Enable the gpio clock //使能GPIO时钟
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE); //Enable the Usart clock //使能USART时钟
|
||||
|
||||
GPIO_PinAFConfig(GPIOC,GPIO_PinSource12,GPIO_AF_UART5);
|
||||
GPIO_PinAFConfig(GPIOD,GPIO_PinSource2 ,GPIO_AF_UART5);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
|
||||
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF; //输出模式
|
||||
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP; //推挽输出
|
||||
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //高速50MHZ
|
||||
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP; //上拉
|
||||
GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
|
||||
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF; //输出模式
|
||||
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP; //推挽输出
|
||||
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //高速50MHZ
|
||||
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP; //上拉
|
||||
GPIO_Init(GPIOD, &GPIO_InitStructure); //初始化
|
||||
|
||||
//UsartNVIC configuration //UsartNVIC配置
|
||||
NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;
|
||||
//Preempt priority //抢占优先级
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;
|
||||
//Preempt priority //抢占优先级
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||||
//Enable the IRQ channel //IRQ通道使能
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
//Initialize the VIC register with the specified parameters
|
||||
//根据指定的参数初始化VIC寄存器
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
|
||||
//USART Initialization Settings 初始化设置
|
||||
USART_InitStructure.USART_BaudRate = bound; //Port rate //串口波特率
|
||||
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //The word length is 8 bit data format //字长为8位数据格式
|
||||
USART_InitStructure.USART_StopBits = USART_StopBits_1; //A stop bit //一个停止
|
||||
USART_InitStructure.USART_Parity = USART_Parity_No; //Prosaic parity bits //无奇偶校验位
|
||||
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //No hardware data flow control //无硬件数据流控制
|
||||
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //Sending and receiving mode //收发模式
|
||||
USART_Init(UART5, &USART_InitStructure); //Initialize serial port 5 //初始化串口5
|
||||
USART_ITConfig(UART5, USART_IT_RXNE, ENABLE); //Open the serial port to accept interrupts //开启串口接受中断
|
||||
USART_Cmd(UART5, ENABLE); //Enable serial port 5 //使能串口5
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Serial port 1 receives interrupted
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:串口1接收中断
|
||||
入口参数:无
|
||||
返 回 值:无
|
||||
**************************************************************************/
|
||||
int USART1_IRQHandler(void)
|
||||
{
|
||||
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //Check if data is received //判断是否接收到数据
|
||||
{
|
||||
u8 Usart_Receive;
|
||||
static u8 Count;
|
||||
static u8 rxbuf[11];
|
||||
int check=0,error=1,i;
|
||||
|
||||
Usart_Receive = USART_ReceiveData(USART1); //Read the data //读取数据
|
||||
if(Time_count<CONTROL_DELAY)
|
||||
// Data is not processed until 10 seconds after startup
|
||||
//开机10秒前不处理数据
|
||||
return 0;
|
||||
|
||||
//Fill the array with serial data
|
||||
//串口数据填入数组
|
||||
rxbuf[Count]=Usart_Receive;
|
||||
|
||||
//Ensure that the first data in the array is FRAME_HEADER
|
||||
//确保数组第一个数据为FRAME_HEADER
|
||||
if(Usart_Receive == FRAME_HEADER||Count>0)
|
||||
Count++;
|
||||
else
|
||||
Count=0;
|
||||
|
||||
if (Count == 11) //Verify the length of the packet //验证数据包的长度
|
||||
{
|
||||
Count=0; //Prepare for the serial port data to be refill into the array //为串口数据重新填入数组做准备
|
||||
if(rxbuf[10] == FRAME_TAIL) //Verify the frame tail of the packet //验证数据包的帧尾
|
||||
{
|
||||
for(i=0; i<9; i++)
|
||||
{
|
||||
//XOR bit check, used to detect data error
|
||||
//异或位校验,用于检测数据是否出错
|
||||
check=rxbuf[i]^check;
|
||||
}
|
||||
if(check==rxbuf[9])
|
||||
//XOR bit check successful
|
||||
//异或位校验成功
|
||||
error=0;
|
||||
|
||||
if(error==0)
|
||||
{
|
||||
float Vz;
|
||||
if(Usart1_ON_Flag==0)
|
||||
{
|
||||
//Serial port 1 controls flag position 1, other flag position 0
|
||||
//串口1控制标志位置1,其它标志位置0
|
||||
//Usart_ON_Flag=1;
|
||||
Usart1_ON_Flag=1;
|
||||
APP_ON_Flag=0;
|
||||
PS2_ON_Flag=0;
|
||||
Remote_ON_Flag=0;
|
||||
CAN_ON_Flag=0;
|
||||
}
|
||||
command_lost_count=0; //CAN/串口控制命令丢失计数清零
|
||||
|
||||
//Calculate the 3-axis target velocity from the serial data, which is divided into 8-bit high and 8-bit low units mm/s
|
||||
//从串口数据求三轴目标速度,分高8位和低8位 单位mm/s
|
||||
Move_X=XYZ_Target_Speed_transition(rxbuf[3],rxbuf[4]);
|
||||
Move_Y=XYZ_Target_Speed_transition(rxbuf[5],rxbuf[6]);
|
||||
Vz =XYZ_Target_Speed_transition(rxbuf[7],rxbuf[8]);
|
||||
if(Car_Mode==Akm_Car)
|
||||
{
|
||||
Move_Z=Vz_to_Akm_Angle(Move_X, Vz);
|
||||
}
|
||||
else
|
||||
{
|
||||
Move_Z=XYZ_Target_Speed_transition(rxbuf[7],rxbuf[8]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Refresh the OLED screen
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:串口2接收中断
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
int USART2_IRQHandler(void)
|
||||
{
|
||||
int Usart_Receive;
|
||||
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //Check if data is received //判断是否接收到数据
|
||||
{
|
||||
static u8 Flag_PID,i,j,Receive[50],Last_Usart_Receive;
|
||||
static float Data;
|
||||
|
||||
Usart_Receive=USART2->DR; //Read the data //读取数据
|
||||
|
||||
if(Deviation_Count<CONTROL_DELAY)
|
||||
// Data is not processed until 10 seconds after startup
|
||||
//开机10秒前不处理数据
|
||||
return 0;
|
||||
|
||||
if(Usart_Receive==0x41&&Last_Usart_Receive==0x41&&APP_ON_Flag==0)
|
||||
//10 seconds after startup, press the forward button of APP to enter APP control mode
|
||||
//The APP controls the flag position 1 and the other flag position 0
|
||||
//开机10秒之后,按下APP的前进键进入APP控制模式
|
||||
//APP控制标志位置1,其它标志位置0
|
||||
PS2_ON_Flag=0,Remote_ON_Flag=0,APP_ON_Flag=1,CAN_ON_Flag=0,Usart1_ON_Flag=0,Usart5_ON_Flag=0;
|
||||
Last_Usart_Receive=Usart_Receive;
|
||||
|
||||
if(Usart_Receive==0x4B)
|
||||
//Enter the APP steering control interface
|
||||
//进入APP转向控制界面
|
||||
Turn_Flag=1;
|
||||
else if(Usart_Receive==0x49||Usart_Receive==0x4A)
|
||||
// Enter the APP direction control interface
|
||||
//进入APP方向控制界面
|
||||
Turn_Flag=0;
|
||||
|
||||
if(Turn_Flag==0)
|
||||
{
|
||||
//App rocker control interface command
|
||||
//APP摇杆控制界面命令
|
||||
if(Usart_Receive>=0x41&&Usart_Receive<=0x48)
|
||||
{
|
||||
Flag_Direction=Usart_Receive-0x40;
|
||||
}
|
||||
else if(Usart_Receive<=8)
|
||||
{
|
||||
Flag_Direction=Usart_Receive;
|
||||
}
|
||||
else Flag_Direction=0;
|
||||
}
|
||||
else if(Turn_Flag==1)
|
||||
{
|
||||
//APP steering control interface command
|
||||
//APP转向控制界面命令
|
||||
if (Usart_Receive==0x43) Flag_Left=0,Flag_Right=1; //Right rotation //右自转
|
||||
else if(Usart_Receive==0x47) Flag_Left=1,Flag_Right=0; //Left rotation //左自转
|
||||
else Flag_Left=0,Flag_Right=0;
|
||||
if (Usart_Receive==0x41||Usart_Receive==0x45) Flag_Direction=Usart_Receive-0x40;
|
||||
else Flag_Direction=0;
|
||||
}
|
||||
if(Usart_Receive==0x58) RC_Velocity=RC_Velocity+100; //Accelerate the keys, +100mm/s //加速按键,+100mm/s
|
||||
if(Usart_Receive==0x59) RC_Velocity=RC_Velocity-100; //Slow down buttons, -100mm/s //减速按键,-100mm/s
|
||||
|
||||
// The following is the communication with the APP debugging interface
|
||||
//以下是与APP调试界面通讯
|
||||
if(Usart_Receive==0x7B) Flag_PID=1; //The start bit of the APP parameter instruction //APP参数指令起始位
|
||||
if(Usart_Receive==0x7D) Flag_PID=2; //The APP parameter instruction stops the bit //APP参数指令停止位
|
||||
|
||||
if(Flag_PID==1) //Collect data //采集数据
|
||||
{
|
||||
Receive[i]=Usart_Receive;
|
||||
i++;
|
||||
}
|
||||
if(Flag_PID==2) //Analyze the data //分析数据
|
||||
{
|
||||
if(Receive[3]==0x50) PID_Send=1;
|
||||
else if(Receive[1]!=0x23)
|
||||
{
|
||||
for(j=i;j>=4;j--)
|
||||
{
|
||||
Data+=(Receive[j-1]-48)*pow(10,i-j);
|
||||
}
|
||||
switch(Receive[1])
|
||||
{
|
||||
case 0x30: RC_Velocity=Data;break;
|
||||
case 0x31: Velocity_KP=Data;break;
|
||||
case 0x32: Velocity_KI=Data;break;
|
||||
case 0x33: break;
|
||||
case 0x34: break;
|
||||
case 0x35: break;
|
||||
case 0x36: break;
|
||||
case 0x37: break;
|
||||
case 0x38: break;
|
||||
}
|
||||
}
|
||||
//Relevant flag position is cleared
|
||||
//相关标志位清零
|
||||
Flag_PID=0;
|
||||
i=0;
|
||||
j=0;
|
||||
Data=0;
|
||||
memset(Receive, 0, sizeof(u8)*50); //Clear the array to zero//数组清零
|
||||
}
|
||||
if(RC_Velocity<0) RC_Velocity=0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Serial port 3 receives interrupted
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:串口3接收中断
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
float test_movz = 0;
|
||||
int USART3_IRQHandler(void)
|
||||
{
|
||||
static u8 Count=0;
|
||||
u8 Usart_Receive;
|
||||
|
||||
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //Check if data is received //判断是否接收到数据
|
||||
{
|
||||
Usart_Receive = USART_ReceiveData(USART3);//Read the data //读取数据
|
||||
if(Time_count<CONTROL_DELAY)
|
||||
// Data is not processed until 10 seconds after startup
|
||||
//开机10秒前不处理数据
|
||||
return 0;
|
||||
|
||||
//Fill the array with serial data
|
||||
//串口数据填入数组
|
||||
Receive_Data.buffer[Count]=Usart_Receive;
|
||||
|
||||
// Ensure that the first data in the array is FRAME_HEADER
|
||||
//确保数组第一个数据为FRAME_HEADER
|
||||
if(Usart_Receive == FRAME_HEADER||Count>0)
|
||||
Count++;
|
||||
else
|
||||
Count=0;
|
||||
|
||||
if (Count == 11) //Verify the length of the packet //验证数据包的长度
|
||||
{
|
||||
Count=0; //Prepare for the serial port data to be refill into the array //为串口数据重新填入数组做准备
|
||||
if(Receive_Data.buffer[10] == FRAME_TAIL) //Verify the frame tail of the packet //验证数据包的帧尾
|
||||
{
|
||||
//Data exclusionary or bit check calculation, mode 0 is sent data check
|
||||
//数据异或位校验计算,模式0是发送数据校验
|
||||
if(Receive_Data.buffer[9] ==Check_Sum(9,0))
|
||||
{
|
||||
float Vz;
|
||||
//All modes flag position 0, USART3 control mode
|
||||
//所有模式标志位置0,为Usart3控制模式
|
||||
PS2_ON_Flag=0;
|
||||
Remote_ON_Flag=0;
|
||||
APP_ON_Flag=0;
|
||||
CAN_ON_Flag=0;
|
||||
Usart1_ON_Flag=0;
|
||||
Usart5_ON_Flag=0;
|
||||
command_lost_count=0; //CAN/串口控制命令丢失计数清零
|
||||
|
||||
//Calculate the target speed of three axis from serial data, unit m/s
|
||||
//从串口数据求三轴目标速度, 单位m/s
|
||||
Move_X=XYZ_Target_Speed_transition(Receive_Data.buffer[3],Receive_Data.buffer[4]);
|
||||
Move_Y=XYZ_Target_Speed_transition(Receive_Data.buffer[5],Receive_Data.buffer[6]);
|
||||
Vz =XYZ_Target_Speed_transition(Receive_Data.buffer[7],Receive_Data.buffer[8]);
|
||||
test_movz = Vz;
|
||||
if(Car_Mode==Akm_Car)
|
||||
{
|
||||
Move_Z=Vz_to_Akm_Angle(Move_X, Vz);
|
||||
}
|
||||
else
|
||||
{
|
||||
Move_Z=XYZ_Target_Speed_transition(Receive_Data.buffer[7],Receive_Data.buffer[8]);
|
||||
} }
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: Serial port 5 receives interrupted
|
||||
Input : none
|
||||
Output : none
|
||||
函数功能:串口5接收中断
|
||||
入口参数:无
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
int UART5_IRQHandler(void)
|
||||
{
|
||||
static u8 Count=0;
|
||||
u8 Usart_Receive;
|
||||
|
||||
if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET) //Check if data is received //判断是否接收到数据
|
||||
{
|
||||
Usart_Receive = USART_ReceiveData(UART5);//Read the data //读取数据
|
||||
if(Time_count<CONTROL_DELAY)
|
||||
// Data is not processed until 10 seconds after startup
|
||||
//开机10秒前不处理数据
|
||||
return 0;
|
||||
|
||||
//Fill the array with serial data
|
||||
//串口数据填入数组
|
||||
Receive_Data.buffer[Count]=Usart_Receive;
|
||||
|
||||
// Ensure that the first data in the array is FRAME_HEADER
|
||||
//确保数组第一个数据为FRAME_HEADER
|
||||
if(Usart_Receive == FRAME_HEADER||Count>0)
|
||||
Count++;
|
||||
else
|
||||
Count=0;
|
||||
|
||||
if (Count == 11) //Verify the length of the packet //验证数据包的长度
|
||||
{
|
||||
Count=0; //Prepare for the serial port data to be refill into the array //为串口数据重新填入数组做准备
|
||||
if(Receive_Data.buffer[10] == FRAME_TAIL) //Verify the frame tail of the packet //验证数据包的帧尾
|
||||
{
|
||||
//Data exclusionary or bit check calculation, mode 0 is sent data check
|
||||
//数据异或位校验计算,模式0是发送数据校验
|
||||
if(Receive_Data.buffer[9] ==Check_Sum(9,0))
|
||||
{
|
||||
float Vz;
|
||||
//All modes flag position 0, USART3 control mode
|
||||
//所有模式标志位置0,为Usart5控制模式
|
||||
PS2_ON_Flag=0;
|
||||
Remote_ON_Flag=0;
|
||||
APP_ON_Flag=0;
|
||||
CAN_ON_Flag=0;
|
||||
Usart5_ON_Flag=0;
|
||||
command_lost_count=0; //CAN/串口控制命令丢失计数清零
|
||||
|
||||
//Calculate the target speed of three axis from serial data, unit m/s
|
||||
//从串口数据求三轴目标速度, 单位m/s
|
||||
Move_X=XYZ_Target_Speed_transition(Receive_Data.buffer[3],Receive_Data.buffer[4]);
|
||||
Move_Y=XYZ_Target_Speed_transition(Receive_Data.buffer[5],Receive_Data.buffer[6]);
|
||||
Vz =XYZ_Target_Speed_transition(Receive_Data.buffer[7],Receive_Data.buffer[8]);
|
||||
if(Car_Mode==Akm_Car)
|
||||
{
|
||||
Move_Z=Vz_to_Akm_Angle(Move_X, Vz);
|
||||
}
|
||||
else
|
||||
{
|
||||
Move_Z=XYZ_Target_Speed_transition(Receive_Data.buffer[7],Receive_Data.buffer[8]);
|
||||
} }
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: After the top 8 and low 8 figures are integrated into a short type data, the unit reduction is converted
|
||||
Input : 8 bits high, 8 bits low
|
||||
Output : The target velocity of the robot on the X/Y/Z axis
|
||||
函数功能:将上位机发过来目标前进速度Vx、目标角速度Vz,转换为阿克曼小车的右前轮转角
|
||||
入口参数:目标前进速度Vx、目标角速度Vz,单位:m/s,rad/s
|
||||
返回 值:阿克曼小车的右前轮转角,单位:rad
|
||||
**************************************************************************/
|
||||
|
||||
float test_z=0;
|
||||
float Vz_to_Akm_Angle(float Vx, float Vz)
|
||||
{
|
||||
float R, AngleR, Min_Turn_Radius;
|
||||
//float AngleL;
|
||||
|
||||
//Ackermann car needs to set minimum turning radius
|
||||
//If the target speed requires a turn radius less than the minimum turn radius,
|
||||
//This will greatly improve the friction force of the car, which will seriously affect the control effect
|
||||
//阿克曼小车需要设置最小转弯半径
|
||||
//如果目标速度要求的转弯半径小于最小转弯半径,
|
||||
//会导致小车运动摩擦力大大提高,严重影响控制效果
|
||||
Min_Turn_Radius=MINI_AKM_MIN_TURN_RADIUS;
|
||||
|
||||
if(Vz!=0 && Vx!=0)
|
||||
{
|
||||
//If the target speed requires a turn radius less than the minimum turn radius
|
||||
//如果目标速度要求的转弯半径小于最小转弯半径
|
||||
// if(float_abs(Vx/Vz)<=Min_Turn_Radius)
|
||||
// {
|
||||
// //Reduce the target angular velocity and increase the turning radius to the minimum turning radius in conjunction with the forward speed
|
||||
// //降低目标角速度,配合前进速度,提高转弯半径到最小转弯半径
|
||||
// if(Vz>0)
|
||||
// Vz= float_abs(Vx)/(Min_Turn_Radius);
|
||||
// else
|
||||
// Vz=-float_abs(Vx)/(Min_Turn_Radius);
|
||||
// }
|
||||
//R=Vx/Vz;
|
||||
R=Vx/Vz;
|
||||
//AngleL=atan(Axle_spacing/(R+0.5*Wheel_spacing));
|
||||
AngleR=atan(Axle_spacing/(R+0.05*Wheel_spacing));//2025.7.20edit
|
||||
}
|
||||
else
|
||||
{
|
||||
AngleR=0;
|
||||
}
|
||||
test_z = AngleR;//test
|
||||
return AngleR;
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: After the top 8 and low 8 figures are integrated into a short type data, the unit reduction is converted
|
||||
Input : 8 bits high, 8 bits low
|
||||
Output : The target velocity of the robot on the X/Y/Z axis
|
||||
函数功能:将上位机发过来的高8位和低8位数据整合成一个short型数据后,再做单位还原换算
|
||||
入口参数:高8位,低8位
|
||||
返回 值:机器人X/Y/Z轴的目标速度
|
||||
**************************************************************************/
|
||||
float XYZ_Target_Speed_transition(u8 High,u8 Low)
|
||||
{
|
||||
//Data conversion intermediate variable
|
||||
//数据转换的中间变量
|
||||
short transition;
|
||||
|
||||
//将高8位和低8位整合成一个16位的short型数据
|
||||
//The high 8 and low 8 bits are integrated into a 16-bit short data
|
||||
transition=((High<<8)+Low);
|
||||
return
|
||||
transition/1000+(transition%1000)*0.001; //Unit conversion, mm/s->m/s //单位转换, mm/s->m/s
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Serial port 1 sends data
|
||||
Input : The data to send
|
||||
Output : none
|
||||
函数功能:串口1发送数据
|
||||
入口参数:要发送的数据
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void usart1_send(u8 data)
|
||||
{
|
||||
USART1->DR = data;
|
||||
while((USART1->SR&0x40)==0);
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Serial port 2 sends data
|
||||
Input : The data to send
|
||||
Output : none
|
||||
函数功能:串口2发送数据
|
||||
入口参数:要发送的数据
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void usart2_send(u8 data)
|
||||
{
|
||||
USART2->DR = data;
|
||||
while((USART2->SR&0x40)==0);
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Serial port 3 sends data
|
||||
Input : The data to send
|
||||
Output : none
|
||||
函数功能:串口3发送数据
|
||||
入口参数:要发送的数据
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void usart3_send(u8 data)
|
||||
{
|
||||
USART3->DR = data;
|
||||
while((USART3->SR&0x40)==0);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Function: Serial port 5 sends data
|
||||
Input : The data to send
|
||||
Output : none
|
||||
函数功能:串口5发送数据
|
||||
入口参数:要发送的数据
|
||||
返回 值:无
|
||||
**************************************************************************/
|
||||
void usart5_send(u8 data)
|
||||
{
|
||||
UART5->DR = data;
|
||||
while((UART5->SR&0x40)==0);
|
||||
}
|
||||
/**************************************************************************
|
||||
Function: Calculates the check bits of data to be sent/received
|
||||
Input : Count_Number: The first few digits of a check; Mode: 0-Verify the received data, 1-Validate the sent data
|
||||
Output : Check result
|
||||
函数功能:计算要发送/接收的数据校验结果
|
||||
入口参数:Count_Number:校验的前几位数;Mode:0-对接收数据进行校验,1-对发送数据进行校验
|
||||
返回 值:校验结果
|
||||
**************************************************************************/
|
||||
u8 Check_Sum(unsigned char Count_Number,unsigned char Mode)
|
||||
{
|
||||
unsigned char check_sum=0,k;
|
||||
|
||||
//Validate the data to be sent
|
||||
//对要发送的数据进行校验
|
||||
if(Mode==1)
|
||||
for(k=0;k<Count_Number;k++)
|
||||
{
|
||||
check_sum=check_sum^Send_Data.buffer[k];
|
||||
}
|
||||
|
||||
//Verify the data received
|
||||
//对接收到的数据进行校验
|
||||
if(Mode==0)
|
||||
for(k=0;k<Count_Number;k++)
|
||||
{
|
||||
check_sum=check_sum^Receive_Data.buffer[k];
|
||||
}
|
||||
return check_sum;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
85
HARDWARE/usartx.h
Normal file
85
HARDWARE/usartx.h
Normal file
@@ -0,0 +1,85 @@
|
||||
#ifndef __USRATX_H
|
||||
#define __USRATX_H
|
||||
|
||||
#include "stdio.h"
|
||||
#include "sys.h"
|
||||
#include "system.h"
|
||||
|
||||
#define DATA_STK_SIZE 512
|
||||
#define DATA_TASK_PRIO 4
|
||||
|
||||
#define FRAME_HEADER 0X7B //Frame_header //帧头
|
||||
#define FRAME_TAIL 0X7D //Frame_tail //帧尾
|
||||
#define SEND_DATA_SIZE 24
|
||||
#define RECEIVE_DATA_SIZE 11
|
||||
|
||||
/*****A structure for storing triaxial data of a gyroscope accelerometer*****/
|
||||
/*****用于存放陀螺仪加速度计三轴数据的结构体*********************************/
|
||||
typedef struct __Mpu6050_Data_
|
||||
{
|
||||
short X_data; //2 bytes //2个字节
|
||||
short Y_data; //2 bytes //2个字节
|
||||
short Z_data; //2 bytes //2个字节
|
||||
}Mpu6050_Data;
|
||||
|
||||
/*******The structure of the serial port sending data************/
|
||||
/*******串口发送数据的结构体*************************************/
|
||||
typedef struct _SEND_DATA_
|
||||
{
|
||||
unsigned char buffer[SEND_DATA_SIZE];
|
||||
struct _Sensor_Str_
|
||||
{
|
||||
unsigned char Frame_Header; //1个字节
|
||||
short X_speed; //2 bytes //2个字节
|
||||
short Y_speed; //2 bytes //2个字节
|
||||
short Z_speed; //2 bytes //2个字节
|
||||
short Power_Voltage; //2 bytes //2个字节
|
||||
Mpu6050_Data Accelerometer; //6 bytes //6个字节
|
||||
Mpu6050_Data Gyroscope; //6 bytes //6个字节
|
||||
unsigned char Frame_Tail; //1 bytes //1个字节
|
||||
}Sensor_Str;
|
||||
}SEND_DATA;
|
||||
|
||||
typedef struct _RECEIVE_DATA_
|
||||
{
|
||||
unsigned char buffer[RECEIVE_DATA_SIZE];
|
||||
struct _Control_Str_
|
||||
{
|
||||
unsigned char Frame_Header; //1 bytes //1个字节
|
||||
float X_speed; //4 bytes //4个字节
|
||||
float Y_speed; //4 bytes //4个字节
|
||||
float Z_speed; //4 bytes //4个字节
|
||||
unsigned char Frame_Tail; //1 bytes //1个字节
|
||||
}Control_Str;
|
||||
}RECEIVE_DATA;
|
||||
|
||||
|
||||
void data_task(void *pvParameters);
|
||||
void data_transition(void);
|
||||
void USART1_SEND(void);
|
||||
void USART3_SEND(void);
|
||||
void USART5_SEND(void);
|
||||
|
||||
void CAN_SEND(void);
|
||||
void uart1_init(u32 bound);
|
||||
void uart2_init(u32 bound);
|
||||
void uart3_init(u32 bound);
|
||||
void uart5_init(u32 bound);
|
||||
|
||||
int USART1_IRQHandler(void);
|
||||
int USART2_IRQHandler(void);
|
||||
int USART3_IRQHandler(void);
|
||||
int UART5_IRQHandler(void);
|
||||
|
||||
float Vz_to_Akm_Angle(float Vx, float Vz);
|
||||
float XYZ_Target_Speed_transition(u8 High,u8 Low);
|
||||
void usart1_send(u8 data);
|
||||
void usart2_send(u8 data);
|
||||
void usart3_send(u8 data);
|
||||
void usart5_send(u8 data);
|
||||
|
||||
u8 Check_Sum(unsigned char Count_Number,unsigned char Mode);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user