STM32 请大家帮我看看为什么串口输出的是乱码?

2019-07-21 02:56发布

对一个连续的波进行采样,采集250个点,我知道可以用DMA做,但是现在只想利用TIM中断来触发ADC进行采样,采集后输出的数据非常不理想,请大家帮我看看。
#include "timer.h"
#include "led.h"
#include "usart.h"
#include "adc.h"
#define ADC_Buff_LEN  250
extern int Buff[250];
extern int b;

定时器设置
//arr:自动重装值。
//psc:时钟预分频数

void TIM2_PWM_Init(u16 arr,u16 psc)
{  
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_OCInitTypeDef  TIM_OCInitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2|RCC_APB2Periph_GPIOA, ENABLE);        //使能定时器1时钟

   //设置该引脚为复用输出功能,输出TIM2 CH2的PWM脉冲波形        GPIOA.1
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //TIM2_CH2对应PA1
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO

   //初始化TIM2      
        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
        TIM_TimeBaseStructure.TIM_ClockDivision =0; //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式向上计数方式: CNT < CCRx ≤ ARR (特别地, 0 < CCRx),
        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
       
        //初始化TIM2 Channel2 PWM模式         
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
        TIM_OCInitStructure.TIM_Pulse = 500; //设置待装入捕获比较寄存器的脉冲值,高于脉冲值就会产生高电平
        TIM_OC2Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM2 OC2
        //设置中断
        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM2 中断
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级 2 级
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级 0 级
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道被使能
  NVIC_Init(&NVIC_InitStructure); //初始化外设 NVIC 寄存器
       
        TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//                CC1IE 捕获中断
        TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM2在CCR2上的预装载寄存器
        TIM_Cmd(TIM2, ENABLE);
  TIM_CtrlPWMOutputs(TIM2, ENABLE);
        //TIM_ARRPreloadConfig(TIM2,DISABLE); //预装载寄存器的内容被立即传送到影子寄存器
}
void TIM2_IRQHandler(void)
{  //  volatile int b=0;
  //   int a = 0;         
     static int x = 0;//用作给数组计数,记满250个为止
if (   TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)        //判断状态寄存器 TIM2_SR[2] 是否发生了更新中断
  {          
         TIM_ClearITPendingBit(TIM2, TIM_IT_Update );                  //软件清除状态寄存器 TIM2_SR[2] 捕获/比较2 中断中断标志   
   //       for(a=0;a<5;a++)                                       //串口输出
    //     {                                     //         USART_SendData(USART1,Buff[a] );
   //      printf("%d ",Buff[a]);                                                  
                //                 }
  //       if(a==5)                                 
        //                         printf(" ");
               
                if(x <= 249)
       {
            Buff[x]=ADC_GetConversionValue(ADC1);
            x++;
        }
        if(x > 249)
       {
                                 b=1;
                                 x=0;
    //      for(a=0;a<=249;a++)                                       //串口输出
     //    {                                     //         USART_SendData(USART1,Buff[a] );
    //        printf("%d ",Buff[a]);                                                  //关闭ADC1 DMA传输      
                //                 }   
    //        x=0;                                 //   
                                 }  
         }              
  }

接下来是ADC.C
void ADC_Configuration(void)        //ADC配置函数
{
        ADC_InitTypeDef ADC_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOA, ENABLE);        //使能ADC和GPIOA时钟  
        RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置时钟(12MHz),在RCC里面还应配置APB2=AHB时钟72MHz
       
       
//  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOA, ENABLE);        //使能ADC和GPIOA时钟                     
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;        //采集电压的引脚为PA管脚2
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;    //模拟输入模式
  GPIO_Init(GPIOA, &GPIO_InitStructure);     //GPIO组

        ADC_DeInit(ADC1);  //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
        ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
        ADC_InitStructure.ADC_ScanConvMode = ENABLE; //关闭通道扫描模式
        ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //注意不要使用持续转换模式,否则只要触发一次,//后续的转换就会永不停歇(除非CONT清0),这样第一次以后的ADC,就不是由TIM2_CC2来触发了
        ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2;//配置TIM2_CC2为触发源
       
//        ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;//配置TIM2_CC2为触发源
       
        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
        ADC_InitStructure.ADC_NbrOfChannel = 1;
        ADC_Init(ADC1, &ADC_InitStructure);
               
        ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_41Cycles5);
        ADC_DMACmd(ADC1, ENABLE);
       
        ADC_Cmd(ADC1,ENABLE);
        ADC_ExternalTrigConvCmd(ADC1, ENABLE);                        //设置外部触发模式使能(这个“外部“其实仅仅是相//对于ADC模块的外部,实际上还是在STM32内部)
       
        ADC_ResetCalibration(ADC1);
        while(ADC_GetResetCalibrationStatus(ADC1));
        ADC_StartCalibration(ADC1);                                          //Start Calibration register
        while(ADC_GetCalibrationStatus(ADC1));                         //waiting for finishing the calibration       
       
}

主函数
#include "usart.h"
#include "delay.h"
#include "key.h"
#include "dma.h"
#include "timer.h"
#include "adc.h"

int Buff[250];
//extern uint16_t ADC_RegularConvertedValueTab[32];
//这里可以使用两种定时器触发模式,一种是TIM2 CH2对应PA1,一种是TIM_CH1对应PA8
u8 flag=0;
int b;                    //标志位
int main(void)
{
  int a;     
        delay_init();                     //延时函数初始化
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
        uart_init(9600);                 //串口初始化为115200
        LED_Init();                                  //初始化与LED连接的硬件接口
//        LCD_Init();                                   //初始化LCD        
        KEY_Init();                                //按键初始化       
  ADC_Configuration();
//  ADC_DMA_Config();       
TIM2_PWM_Init(1439,0);
   while(1)
         {
                 if(b==1)
                 {
                         for(a=0;a<=249;a++)                                       //串口输出
        {                                     //         USART_SendData(USART1,Buff[a] );
            printf("%d ",Buff[a]);
            a=0;                                        //关闭ADC1 DMA传输      
                                 }                                       
                 }
         }
}

结果file:///C:Users杨AppDataRoamingTencentUsers2918317304QQWinTempRichOleL6A@6P0WSTAMSGQKR83D8~L.png

关系到毕设,求大家找找毛病
0条回答

一周热门 更多>