实验芯片:stm32f103CBT6
串口3初始化收发函数
初始化函数
void Initial_UART3(u32 baudrate)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = baudrate;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART3, &USART_InitStructure);
USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);
USART_Cmd(USART3, ENABLE);
U3NVIC_Configuration();
}
做初始化函数有点小插曲
RCC_APB2Periph_GPIOB 的时钟 放到了 RCC_APB1PerphClockCmd()的函数中了
也就是说 RCC_APB2Periph 时钟总线用 RCC_APB1Perph 的使能函数使能了。这是不对的 。
造成的结果是串口3可以接收到数据,但是不能发送。 这个结果不知道是为什么。
中断优先级分组
void U3NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the USART3 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//Enable DMA1 Channel3 Interrupt
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
串口3DMA配置
void DMA_UART3Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_DeInit(DMA1_Channel3);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)SRC_USART3_DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)USART3_DMA_Recieve_Buf;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = UART3_RECIEVE_LENDTH;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel3, &DMA_InitStructure);
DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, ENABLE);
DMA_Cmd(DMA1_Channel3, ENABLE);
USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);
}
串口3发送函数
void UART3_Put_Char(unsigned char DataToSend)
{
USART_SendData(USART3, DataToSend);
while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET){}
}
void UART3_Send_Buf(unsigned char *buf,unsigned char len)
{
unsigned char i ;
for(i=0;i<len;i++,buf++)
{
UART3_Put_Char(*buf);
}
}
串口3 接收函数
void DMA1_Channel3_IRQHandler(void)
{
uint16_t length;
if(DMA_GetITStatus(DMA1_IT_TC3)==SET)
{
DMA_Cmd(DMA1_Channel3, DISABLE); //¹Ø±ÕDMA£¬·ÀÖ¹´¦ÀíÆÚ¼äÓÐÊý¾Ý
length = UART3_RECIEVE_LENDTH - DMA_GetCurrDataCounter(DMA1_Channel3);
if(length != 0)
{
}
DMA_SetCurrDataCounter(DMA1_Channel3, UART3_RECIEVE_LENDTH);
DMA_Cmd(DMA1_Channel3, ENABLE);
DMA_ClearITPendingBit(DMA1_IT_TC3);
}
}
- [x] 测试这个函数需不需要
可以不要
//------------------------------------------------------
void USART3_IRQHandler(void)
{
uint8_t data;
uint16_t length,check;
if(USART_GetITStatus(USART3, USART_IT_IDLE) != RESET)//¿ÕÏÐÖжÏ
{
DMA_Cmd(DMA1_Channel3, DISABLE);
data = data;
data = USART3->SR;
data = USART3->DR;
length = UART3_RECIEVE_LENDTH - DMA_GetCurrDataCounter(DMA1_Channel3);
if(length != 0)
{
}
DMA_SetCurrDataCounter(DMA1_Channel3, UART3_RECIEVE_LENDTH);
DMA_Cmd(DMA1_Channel3, ENABLE); //´ò¿ªDMA,
DMA_ClearITPendingBit(DMA1_IT_TC3);
}
}
加入打印函数 重定向至串口1
记住就行, 直接就能用
#if 1// 串口1打印
#pragma import(__use_no_semihosting)
struct __FILE
{
int handle;
};
FILE __stdout;
_sys_exit(int x)
{
x = x;
}
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//Ñ»··¢ËÍ,Ö±µ½·¢ËÍÍê±Ï
USART1->DR = (u8) ch;
return ch;
}
#endif
需要打开? 实际测试 不打开也没事
传感器数据解析
传感器发送的数据协议
协议
以解析欧拉角x为例
// ´«¸ÐÆ÷½â¶ÁµÄÅ·À½Ç
typedef struct
{
float x;
float y;
float z;
}Euler_T;
typedef struct
{
uint8_t x[4];
uint8_t y[4];
uint8_t z[4];
}Euler_32bit_T;
if (USART3_DMA_Recieve_Buf[0]== 0x3A&&USART3_DMA_Recieve_Buf[1]== 0x01&&USART3_DMA_Recieve_Buf[2]== 0x00&&
USART3_DMA_Recieve_Buf[3]== 0x09&&USART3_DMA_Recieve_Buf[4]== 0x00&&USART3_DMA_Recieve_Buf[5]== 0x50&&
USART3_DMA_Recieve_Buf[6]== 0x00 )
{
// 传感器32位数据 低位在前
Euler_32bit.x[0] = USART3_DMA_Recieve_Buf[63];
Euler_32bit.x[1] = USART3_DMA_Recieve_Buf[64];
Euler_32bit.x[2] = USART3_DMA_Recieve_Buf[65];
Euler_32bit.x[3] = USART3_DMA_Recieve_Buf[66];
Euler.x = *((float*)Euler_32bit.x);
}
手册上写了 数据是低位在前的
但是在通过 指针然后强制转换时 将数据 改成高位在前后不对了
- [ ] 可能指针强制转换就是低位在前?也可能数据发的就是高位在前
- [ ] 反正换了下顺序对了
Euler.x = ((float)Euler_32bit.x)
打印测试
printf("Euler.x = %f \r\n ", Euler.x/DEG2RAD);
按轴移动后没有问题
把其它变量也解算出来
和以解析欧拉角x 一样,解析了 欧拉角y 欧拉角z
其中x和y 静态飘移 较小 z轴飘移很大 向一方向一直飘 可能是没有 校准的原因
//// 传感器线加速度数据
typedef struct
{
float x;
float y;
float z;
}LinearAcceleration_T;
typedef struct
{
uint8_t x[4];
uint8_t y[4];
uint8_t z[4];
}LinearAcceleration_32bit_T;;
LinearAcceleration_32bit.x[0] = USART3_DMA_Recieve_Buf[75];
LinearAcceleration_32bit.x[1] = USART3_DMA_Recieve_Buf[76];
LinearAcceleration_32bit.x[2] = USART3_DMA_Recieve_Buf[77];
LinearAcceleration_32bit.x[3] = USART3_DMA_Recieve_Buf[78];
LinearAcceleration_32bit.y[0] = USART3_DMA_Recieve_Buf[79];
LinearAcceleration_32bit.y[1] = USART3_DMA_Recieve_Buf[80];
LinearAcceleration_32bit.y[2] = USART3_DMA_Recieve_Buf[81];
LinearAcceleration_32bit.y[3] = USART3_DMA_Recieve_Buf[82];
LinearAcceleration_32bit.z[0] = USART3_DMA_Recieve_Buf[83];
LinearAcceleration_32bit.z[1] = USART3_DMA_Recieve_Buf[84];
LinearAcceleration_32bit.z[2] = USART3_DMA_Recieve_Buf[85];
LinearAcceleration_32bit.z[3] = USART3_DMA_Recieve_Buf[86];
LinearAcceleration.x= *((float*)LinearAcceleration_32bit.x);
LinearAcceleration.y= *((float*)LinearAcceleration_32bit.y);
LinearAcceleration.z= *((float*)LinearAcceleration_32bit.z);
打印加速度数据不能有延迟
做传感器碰撞检测
简答做就根据 欧拉角和加速度判断
变化大于阈值时 则 串口1发送当前值
void CollisionCheck(float LinearAccelerationThreshold, float EulerThreshold)
{
if (fabs(Euler_Last.x- Euler.x)>LinearAccelerationThreshold &&fabs(Euler_Last.y- Euler.y)>LinearAccelerationThreshold&&fabs(Euler_Last.z- Euler.z)>LinearAccelerationThreshold
&&fabs(LinearAcceleration_Last.x- LinearAcceleration.x)>EulerThreshold
&&fabs(LinearAcceleration_Last.x- LinearAcceleration.x)>EulerThreshold
)
{
Euler_Last.x = Euler.x ;
Euler_Last.y = Euler.y ;
Euler_Last.z = Euler.z ;
LinearAcceleration_Last.x = LinearAcceleration.x;
LinearAcceleration_Last.y = LinearAcceleration.y;
LinearAcceleration_Last.z = LinearAcceleration.z;
UART1_ALARM_DATA[0] = 0x01;
UART1_ALARM_DATA[1] = LinearAcceleration_32bit.x[0];
UART1_ALARM_DATA[2] = LinearAcceleration_32bit.x[1];
UART1_ALARM_DATA[3] = LinearAcceleration_32bit.x[2];
UART1_ALARM_DATA[4] = LinearAcceleration_32bit.x[3];
UART1_ALARM_DATA[5] = LinearAcceleration_32bit.y[0];
UART1_ALARM_DATA[6] = LinearAcceleration_32bit.y[1];
UART1_ALARM_DATA[7] = LinearAcceleration_32bit.y[2];
UART1_ALARM_DATA[8] = LinearAcceleration_32bit.y[3];
UART1_ALARM_DATA[9] = Euler_32bit.x[0];
UART1_ALARM_DATA[10] = Euler_32bit.x[1];
UART1_ALARM_DATA[11] = Euler_32bit.x[2];
UART1_ALARM_DATA[12] = Euler_32bit.x[3];
UART1_ALARM_DATA[13] = Euler_32bit.y[0];
UART1_ALARM_DATA[14] = Euler_32bit.y[1];
UART1_ALARM_DATA[15] = Euler_32bit.y[2];
UART1_ALARM_DATA[16] = Euler_32bit.y[3];
UART1_ALARM_DATA[17] = Euler_32bit.z[0];
UART1_ALARM_DATA[18] = Euler_32bit.z[1];
UART1_ALARM_DATA[19] = Euler_32bit.z[2];
UART1_ALARM_DATA[20] = Euler_32bit.z[3];
UART1_Send_Buf(UART1_ALARM_DATA,21);
}
}