这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » dawnjeanh的四轴飞行器进程

共19条 2/2 1 2 跳转至
菜鸟
2014-06-16 11:43:51     打赏
11楼
3q

菜鸟
2014-06-16 11:49:36     打赏
12楼

基础实验-LED指示灯实验

本以为这个会很简单,分分钟解决的,但是没想到会遇到问题,而且困扰了一晚上,详见http://forum.eepw.com.cn/thread/256935/1

在之前工程模板的基础上再BSP分组中增加LED.c和LED.h,并将LED.h包含到common.h中

LED IO配置


/************************************************************************\
*	函数名:LED_Initialization
*	函数功能概述:LED初始化
*	参数说明:
*	返回值说明:
\************************************************************************/
void LED_Initialization(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);//使能时钟
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
	//PB3:D1
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	//PC13:Dx
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	
	LED_D1_OFF();
	LED_Dx_OFF();
}



添加宏定义


#define LED_D1_ON()    GPIO_ResetBits(GPIOB, GPIO_Pin_3)
#define LED_D1_OFF()   GPIO_SetBits(GPIOB, GPIO_Pin_3)

#define LED_Dx_OFF()   GPIO_ResetBits(GPIOC, GPIO_Pin_13)
#define LED_Dx_ON()    GPIO_SetBits(GPIOC, GPIO_Pin_13)



这样就可以控制LED了


菜鸟
2014-06-22 14:24:56     打赏
13楼

关于时钟

在串口之前,先说说时钟配置。时钟很重要,尤其对于通讯来说,比如串口的波特率。

在启动代码中(startup_stm32f10x_md.s)复位的程序入口Reset_Handler:

程序首先进入SystemInit函数,在跳转到main函数。右键SystemInit再选择goto definition可以看到跳转到system_stm32f10x.c中的SystemInit函数,这个函数就是进行时钟配置。但是库中默认外部晶振为8MHz,但是四轴外部晶振为16MHZ,所以我们最好还是自己重新配置时钟。

/************************************************************************\
*	函数名:RCC_Configuration
*	函数功能概述:时钟配置
*	参数说明:
*	返回值说明:
\************************************************************************/
void RCC_Configuration(void)//时钟配置
{
	ErrorStatus HSEStartUpStatus;//判断标志变量
	RCC_ClocksTypeDef RCC_ClocksStructure;
	RCC_DeInit();
	RCC_HSEConfig(RCC_HSE_ON);//使用外部时钟
	HSEStartUpStatus = RCC_WaitForHSEStartUp();//等待外部时钟稳定
	if(HSEStartUpStatus== SUCCESS)//如果外部晶振启动成功
	{
		RCC_HCLKConfig(RCC_SYSCLK_Div1);//HCLK(AHB时钟)值等于系统时钟
		RCC_PCLK1Config(RCC_HCLK_Div2);//PCLK1(APB1时钟)值等于HCLK的一半,最高不超过36MHz
		RCC_PCLK2Config(RCC_HCLK_Div1);//PCLK2(APB2时钟)值等于HCLK,最高可是72MHz
		FLASH_SetLatency(FLASH_Latency_2);//FLASH时序控制,SYSCLK0~24MHz Latency=0.SYSCLK25~48MHz Latency =1.SYSCLk 48~72MHz  Latency=2
		FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//开启FLASH预取指功能
		RCC_PLLConfig(RCC_PLLSource_HSE_Div2,RCC_PLLMul_9);//HSE提供系统时钟,9倍频,也就是72MHz
		RCC_PLLCmd(ENABLE);//启动PLL
		while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);//等待PLL稳定
		RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//系统时钟来自PLL输出
		while(RCC_GetSYSCLKSource()!=0x08);//等待系统时钟稳定
	}
	
	
	//检测
	RCC_GetClocksFreq(&RCC_ClocksStructure);
}


这是在网上找到的程序,使用外部时钟通过PLL到72MHz,也分享给大家。


但是还有一个问题,通过RCC_GetClocksFreq函数程序认为的系统时钟是36MHz,如果这样使用库函数配置波特率实际会与设定差一倍。这是因为在stm32f10x.h中宏定义了HSE_VALUE,这个值是8M,所以用我们要把这个宏定义改为16000000,这样就可以了。注意修改这个文件需要先将文件的只读属性去掉


菜鸟
2014-06-22 14:34:23     打赏
14楼

基础实验-UART串口通讯实验

给出关键函数

/************************************************************************\
*	函数名:USART1_Initialization
*	函数功能概述:串口1初始化
*	参数说明:baud-波特率
*	返回值说明:
\************************************************************************/
void USART1_Initialization(uint32_t baud)
{
	USART_InitTypeDef USART_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);//使能时钟
	//PA9-TXD
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	//PA10-RXD
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	USART_InitStructure.USART_BaudRate = baud;
	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(USART1, &USART_InitStructure);
	USART_Cmd(USART1, ENABLE);
}

/************************************************************************\
*	函数名:USART1_SendByte
*	函数功能概述:串口1发送字节
*	参数说明:data-数据
*	返回值说明:
\************************************************************************/
void USART1_SendByte(uint8_t data)
{
	USART_SendData(USART1, data);
	while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
	{}
}

 

主要是配置好IO复用,USART的波特率,数据位,停止位等等,就可以了


院士
2014-06-22 17:31:21     打赏
15楼
楼主的 jlink v8真是漂亮啊~~

菜鸟
2014-06-27 15:06:00     打赏
16楼

基础实验-PWM电机驱动实验

PWM是电机驱动的基础,也是控制的基础。简单来说就是改变占空比来改变方波的等效电压,所以占空比越大,等效电压越大,电机也就转的越快。

下面给出配置代码


/************************************************************************\
*	函数名:TIM2_Initialization
*	函数功能概述:PWM初始化
*	参数说明:
*	返回值说明:
\************************************************************************/
void TIM2_Initialization(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	
	//PA0-1-2-3:PWM
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	/* Time base configuration */
  TIM_TimeBaseStructure.TIM_Period = 100;
  TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)((36000000 / 1000000) - 1);//1MHz
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
	
	/* PWM1 Mode configuration: Channel1 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 0;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

  TIM_OC1Init(TIM2, &TIM_OCInitStructure);

  TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);
	/* PWM1 Mode configuration: Channel2 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 0;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

  TIM_OC2Init(TIM2, &TIM_OCInitStructure);

  TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
	/* PWM1 Mode configuration: Channel3 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 0;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

  TIM_OC3Init(TIM2, &TIM_OCInitStructure);

  TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);
	/* PWM1 Mode configuration: Channel4 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 0;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

  TIM_OC4Init(TIM2, &TIM_OCInitStructure);

  TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);
	
	TIM_ARRPreloadConfig(TIM2, ENABLE);
	
	TIM_Cmd(TIM2, ENABLE);
}

 

PWM是通过定时器模块产生的,首先配置定时器的基础部分,分频、计数模式、溢出值等等,在配置各个通道的输出方式,初始的比较值等等,因为是上电初始化,所以TIM_Pulse = 0;

通过TIM_SetCompare1等函数就可以改变通道的比较值,也就改变了PWM的占空比。

int main(void)
{
	int32_t i;
	Hardware_Initialization();
	
	USART1_SendStr(" QuadCopter DIY\r\n");
	
	while(1)
	{
		LED_Dx_ON();
		LED_D1_OFF();
		Wait_for(100);
		LED_Dx_OFF();
		LED_D1_ON();
		Wait_for(100);
		USART1_SendNum(i++);USART1_SendStr("\r\n");
		TIM_SetCompare1(TIM2, i % 30);
		TIM_SetCompare2(TIM2, i % 30);
		TIM_SetCompare3(TIM2, i % 30);
		TIM_SetCompare4(TIM2, i % 30);
	}
}

 



菜鸟
2014-06-27 15:10:09     打赏
17楼
关于电机控制用的PWM的频率以及对计数的细分我没有太多想法,我现在使用的是10KHz的PWM,最小改变1%的占空比,不知道这样的控制精度能不能达到要求?

高工
2014-06-27 22:57:08     打赏
18楼
 百分之一有点小。改成千分之一吧

菜鸟
2014-06-29 16:18:13     打赏
19楼

MPU6050的官方网站地址

http://www.invensense.com/mems/gyro/mpu6050.html

可以在上面下载数据手册还有寄存器地址(竟然还把两个分开,最开始下载数据手册里没有找到寄存器说明还很纳闷呢)


共19条 2/2 1 2 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]