本帖最后由 Anlen 于 2015-5-12 16:49 编辑
有那位大侠帮我看一下我输出的波形是这样的,下面是我的代码:
#include "stm32f10x.h"
#include "stdlib.h"
#include <stdio.h>
#include "delay.h"
static s16 current_Count;
u8 flag;
uint16_t dma_buffer[100];
static uint16_t n_Count1,n_Count2 ; //定时器读取的值
static uint16_t last_Count1,last_Count2;
//static int16_t last_Count,n_Count; //上次计数器的值
static int16_t dpos,dpos1,dpos2;
int16_t last_dpos1,last_dpos2,last_dpos;
//const u16 da[12] = { 0,2,8,16,32,64,128,256,512,1024,2048};
#define MAXCOUNT 200
#define ENCODER_TIM_PERIOD 1000
#define Distance 600
#define DAC_DHR12R1_Address 0x00000008;
void RCC_Configuration(void)
{
ErrorStatus HSEStartUpStatus; //定义外部高速晶体启动状态枚举变量
RCC_DeInit(); //复位RCC外部设备寄存器到默认值
RCC_HSEConfig(RCC_HSE_ON); //打开外部高速晶振
HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待外部高速时钟准备好
if(HSEStartUpStatus == SUCCESS) //外部高速时钟已经准别好
{
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //开启FLASH预读缓冲功能,加速FLASH的读取。所有程序中必须的用法.位置:RCC初始化子函数里面,时钟起振之后
FLASH_SetLatency(FLASH_Latency_2); //flash操作的延时
RCC_HCLKConfig(RCC_SYSCLK_Div1); //配置AHB(HCLK)时钟等于==SYSCLK
RCC_PCLK2Config(RCC_HCLK_Div1); //配置APB2(PCLK2)钟==AHB时钟
RCC_PCLK1Config(RCC_HCLK_Div2); //配置APB1(PCLK1)钟==AHB1/2时钟
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //配置PLL时钟 == 外部高速晶体时钟 * 9 = 72MHz
RCC_PLLCmd(ENABLE); //使能PLL时钟
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) //等待PLL时钟就绪
{
}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //配置系统时钟 = PLL时钟
while(RCC_GetSYSCLKSource() != 0x08) //检查PLL时钟是否作为系统时钟
{
}
}
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //AFIO时钟
}
void TimConfig(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
//开放时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
//GPIO初始化 使用重映射的功能PC6对应TI1,PC7-TI2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure);
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3 ,ENABLE);
//编码器模式
TIM_DeInit(TIM3);
//GPIO初始化使用定时器4在PB6和PB7
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
TIM_DeInit(TIM4);
/**************设置TIM3CLK=72M,PREscale = 99;ARR=999
F=72M/((ARR+1)(PSC+1))*********************/
TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD; //(值要修改)
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //不分频
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
//外部接口模式
TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);
//编码器模式初始化
// TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_ICFilter = 0x06 ;
// TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; // 在TIM每次捕获到一个边沿执行一次
TIM_ICInit(TIM3,&TIM_ICInitStructure);
TIM_SetCounter(TIM3,0);
//使能TIM3计数器
TIM_Cmd(TIM3,ENABLE);
TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD; //(值要修改)
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //不分频
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);
TIM_EncoderInterfaceConfig(TIM4,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);
// TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_ICFilter = 0x06 ;
TIM_ICInit(TIM4,&TIM_ICInitStructure);
TIM_SetCounter(TIM4,0);
TIM_Cmd(TIM4,ENABLE);
//定时器2用来定时10ms
TIM_DeInit(TIM2);
TIM_TimeBaseStructure.TIM_Period = 100-1;
TIM_TimeBaseStructure.TIM_Prescaler = 7200-1;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //不分频
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_Update);
TIM_Cmd(TIM2,ENABLE);
TIM_ClearFlag(TIM2,TIM_FLAG_Update);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
}
/********因为定时器属于MCU的外设,所以中断配置应该配置为外部中断************/
void NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM2全局中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级最高
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //从优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void DAC_Config(void)
{
DAC_InitTypeDef DAC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_4);
DAC_InitStructure.DAC_Trigger = DAC_Trigger_T2_TRGO; //定时器2触发
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
DAC_DMACmd(DAC_Channel_1,ENABLE);
DAC_Init(DAC_Channel_1,&DAC_InitStructure) ;
DAC_Cmd(DAC_Channel_1,ENABLE);
}
void DMA_Configuration(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2,ENABLE);
DMA_DeInit(DMA2_Channel3);
DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR12R1_Address; //DAC地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&dma_buffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//外设作为数据的目的地
DMA_InitStructure.DMA_BufferSize = 100;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA2_Channel3,&DMA_InitStructure);
DMA_Cmd(DMA2_Channel3,ENABLE);
DMA_ITConfig(DMA2_Channel3,DMA_IT_TC,ENABLE);//传输完成中断屏蔽
}
int16_t Get_Count()
{
n_Count1 = TIM_GetCounter(TIM3);
n_Count2 = TIM_GetCounter(TIM4);
dpos1 = last_Count1 - n_Count1; //测量速度
dpos2 = last_Count2 - n_Count2;
if(dpos1 >= MAXCOUNT)
dpos1 = dpos1 - ENCODER_TIM_PERIOD ;
else if (dpos1 <= -MAXCOUNT)
dpos1 = dpos1 + ENCODER_TIM_PERIOD ;
if(dpos2 >= MAXCOUNT)
dpos2 = dpos2 - ENCODER_TIM_PERIOD ;
else if (dpos2 <= -MAXCOUNT)
dpos2 = dpos2 + ENCODER_TIM_PERIOD ;
dpos1 = abs(dpos1);
dpos2 = abs(dpos2);
if(dpos2 == 0)
{
if(TIM3->CR1 == 0x0011)
dpos = dpos1;
if(TIM3->CR1 == 0x0001)
dpos = -dpos1;
}
if(dpos1 == 0)
{
if(TIM4->CR1 == 0x0011)
dpos = dpos2;
if(TIM4->CR1 == 0x0001)
dpos = -dpos2;
}
if((dpos1 != 0) && (dpos2 != 0))
{
if(TIM4->CR1 == 0x0011)
dpos = dpos2;
if(TIM4->CR1 == 0x0001)
dpos = -dpos2;
}
last_Count1 = n_Count1;
last_Count2 = n_Count2;
last_dpos1 = dpos1;
last_dpos2 = dpos2;
last_dpos = dpos;
return dpos;
}
void TIM2_IRQHandler(void)
{
int16_t temp;
TIM_ClearFlag(TIM2,TIM_FLAG_Update);
temp = Get_Count();
current_Count = current_Count + temp;
flag = 1;
}
int main()
{
int16_t i;
RCC_Configuration();
TimConfig();
NVIC_Config() ;
DAC_Config();
DMA_Configuration();
while(1)
{
if(flag == 1)
{
flag = 0;
if(current_Count > Distance )
current_Count = Distance;
if(current_Count < -Distance )
current_Count = -Distance;
i = current_Count;
if(i & 0x8000 != 0)
{
i = abs(i);
i = i << 2 ;
// i= i + 2047 ;
// i = i << 4 ;
}
else
{
i = i << 2 ;
}
DAC_SetChannel1Data(DAC_Align_12b_R,i);
DAC_SoftwareTriggerCmd(DAC_Channel_1,ENABLE);
// }
}
}
}
然后输出的波形是这样的
|