打印
[应用相关]

pwm+串口

[复制链接]
2865|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
fhguo1990|  楼主 | 2015-4-24 21:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
奇怪的我把这个代码烧到板子里面去,我只点亮了一个灯,为什么四个灯都亮了,还有的就是我改变串口的值,但是占空比还是没有变,想不通,编译没有错,也许是我对配置还不完全理解,但是我再看了手册,是这么配置的, 希望那位大哥可以帮我看看, 上次也谢谢原子哥,他说得很对,我根据他说的,解决了那个问题

串口中断代码void USART1_IRQHandler(void)
{
uint16_t USART1_RxBuffer;
uint16_t CCR3_Val;
TIM_OCInitTypeDef  TIM_OCInitStructure;
  //配置Channel 1,2,3为PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;  //设置PWM方式  分为1,2   脉宽调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  //  PWM功能使能
// TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;   //

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;   //  输出比较 极性
// TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;   //同向输出
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;    //
// TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;  //
//接收中断
if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET)
{
  USART_ClearITPendingBit(USART1,USART_IT_RXNE);
  
  USART1_RxBuffer = USART_ReceiveData(USART1);

  CCR3_Val = USART1_RxBuffer;
   // 设置待装入捕获比较寄存器 占空比
  if(CCR3_Val != CCR3_Val)
  {
      TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
   TIM_OC3Init(TIM4, &TIM_OCInitStructure);
   GPIO_SetBits(GPIOD , GPIO_Pin_1);
  }
        TIM_Cmd(TIM4, ENABLE);    //使能TIM1
   
   TIM_CtrlPWMOutputs(TIM4, ENABLE);//使能TIM1的主输出
}
}
主函数

#include "stm32f10x.h"
#include <stdio.h>
#include "usart.h"
void PWM_Configuration(void);
void GPIO_Configuration(void);
/*Private variables---------------------------------------------------------------------*/
uint16_t CCR3_Val ;

/****************************************************************************************
函数名: main
输  入: void
输  出: int
功  能: 程序入口
*****************************************************************************************/
int main(void)
{
SystemInit();
USART_Configuration();
PWM_Configuration();
GPIO_Configuration();

USART1_SendString("USART1");
USART1_SendString("ping");

while(1)
{
}
}



/*****************************************************************************************
函数名: PWM_Configuration
输  入: void
输  出: void
功  能: 配置PWM,
说  明: TIM4_CH3  PB8   
   
*****************************************************************************************/
void PWM_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
// TIM_OCInitTypeDef  TIM_OCInitStructure;
//打开时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB |RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
//配置PWM波输出端口
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/*------------------------------------------------------------------------------------
  配置TIM1,产生6路三种不同占空比的PWM;
  TIM1CLK = 72 MHz, Prescaler = 0, TIM1 counter clock = 72 MHz
  TIM1 frequency = TIM1CLK/(TIM1_Period + 1) = 17.57 KHz
  - TIM1 Channel1 & Channel1N duty cycle = TIM1->CCR1 / (TIM1_Period + 1) = 50%
  - TIM1 Channel2 & Channel2N duty cycle = TIM1->CCR2 / (TIM1_Period + 1) = 37.5%
  - TIM1 Channel3 & Channel3N duty cycle = TIM1->CCR3 / (TIM1_Period + 1) = 25%
--------------------------------------------------------------------------------------*/
//配置Time Base
TIM_TimeBaseStructure.TIM_Prescaler = 0;  //   预分频因子
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;   // 定时器记数模式 向上记数模式
TIM_TimeBaseStructure.TIM_Period = 4095; //   定时周期值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; // 设置时钟分割
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;  //指定重新计时的值   t=(TIM_Prescaler+1)*(TIM_Period+1)/(72*106)

TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); // 根据 TIM_TimeBaseInitStruct 中指定的参数初始化 TIMx 的时间基数单位
/*
//配置Channel 1,2,3为PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;  //设置PWM方式  分为1,2   脉宽调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  //  PWM功能使能
// TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;   //

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;   //  输出比较 极性
// TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;   //同向输出
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;    //
// TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;  //
        // 设置待装入捕获比较寄存器 占空比
TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
TIM_OC3Init(TIM4, &TIM_OCInitStructure);


TIM_Cmd(TIM4, ENABLE);    //使能TIM1

TIM_CtrlPWMOutputs(TIM4, ENABLE);//使能TIM1的主输出   
*/
}

void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO结构体 打开时钟总线,D端口
  
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOD , ENABLE);        
  /**
  *  LED1 -> PD8 , LED2 -> PD9 , LED3 -> PD10 , LED4 -> PD11
  */   
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_0; //选手端口
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     //标志速度
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; ;   //配置模式  推免输出
  GPIO_Init(GPIOD, &GPIO_InitStructure);      //让数据生效,把那些初始化数据写到寄存器里面去,
}



沙发
我思故我在12345| | 2015-4-24 21:36 | 只看该作者
要善于利用软件仿真.
1,你只想亮一个灯,四个灯都亮了,明显是软件上的配置有问题,或者其他配置影响了之前的配置,软件仿真立马找出原因.
2,串口改变PWM脉宽不行.很简单,你去掉串口,直接修改程序,能改变PWM宽度么?不行就是你PWM配置有问题,行就是你串口有问题.排除法嘛.

使用特权

评论回复
板凳
fhguo1990|  楼主 | 2015-4-24 21:37 | 只看该作者
我思故我在12345 发表于 2015-4-24 21:36
要善于利用软件仿真.
1,你只想亮一个灯,四个灯都亮了,明显是软件上的配置有问题,或者其他配置影响了之前的 ...

嗯,可以的

使用特权

评论回复
地板
fhguo1990|  楼主 | 2015-4-24 21:37 | 只看该作者
点一个灯就为了测试那个串口的消息,而且这个代码都是单个测试了的, extern uint16_t CCR3_Val;
extern uint8_t USART1_Flag;
uint16_t data1 = 0;
uint16_t data2 = 0;
uint8_t flag=0;

void USART1_IRQHandler(void)
{
data1 = 0;
data2 = 0;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
  USART_ClearITPendingBit(USART1,USART_IT_RXNE);
  flag++;
  if(flag == 1)
  {
   data1 = USART_ReceiveData(USART1);
//   data1 |= 0x00ff;
   data1  = data1 << 8;
   USART_SendData(USART1,CCR3_Val);  //从串口1USARTx发送数据
//  while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET){}
  }
  if(flag==2)
  {
    flag = 0;
   data2 = USART_ReceiveData(USART1);
      CCR3_Val = data1|data2;
  // USART1_Flag = 1;
   USART_SendData(USART1,CCR3_Val);  //从串口1USARTx发送数据
  // while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET){};
   USART1_Flag = 1;


  }
}
//溢出-如果发生溢出需要先读SR,再读DR寄存器则可清除不断入中断的问题
if(USART_GetFlagStatus(USART1,USART_FLAG_ORE)==SET)
{
  USART_ClearFlag(USART1,USART_FLAG_ORE); //读SR其实就是清除标志
  USART_ReceiveData(USART1);              //读DR
}





我把串口中断程序改成这个样子了,还是没有把法啊 我照原子哥说的把这个PWM和串口测试了,没有什么问题,但是现在就是 我要串口发送两个数据后 这个pwm才启动,还有的是 我deug模式下,就有Pwm输出,但是在我的板子里面初始化就没有,而且电脑向他发送两串数据后,就有PWM输出,但是我改变串口的数值之后,这个输出的PWM的波形没有一点变化

使用特权

评论回复
5
fhguo1990|  楼主 | 2015-4-24 21:38 | 只看该作者
我的不知道怎么搞的 很难把这个附件添加进去,所以无法把整个工程附加上去

使用特权

评论回复
6
fhguo1990|  楼主 | 2015-4-24 21:38 | 只看该作者
我思故我在12345 发表于 2015-4-24 21:36
要善于利用软件仿真.
1,你只想亮一个灯,四个灯都亮了,明显是软件上的配置有问题,或者其他配置影响了之前的 ...

我根据你说的改了,但是现在这个中断处理代码这里出了问题,想请你看看

使用特权

评论回复
7
我思故我在12345| | 2015-4-24 21:39 | 只看该作者
怎么大家都喜欢用库呢?
现在出了问题没办法找了....

用我的usmart测试下吧.
可惜论坛貌似用我这个东东的人不多,这么好的东西,怎么就没人用呢?呵呵,看来下次得推广下.

串口中断出了问题,就重点针对中断,修改.而且你这中断函数里面也太乱了点.
void USART1_IRQHandler(void)
{
u8 res;     
if(USART1->SR&(1<<5))//接收到数据
{  
  res=USART1->DR;
  if((USART_RX_STA&0x8000)==0)//接收未完成
  {
   if(USART_RX_STA&0x4000)//接收到了0x0d
   {
    if(res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
    else USART_RX_STA|=0x8000; //接收完成了
   }else //还没收到0X0D
   {
    if(res==0x0d)
     USART_RX_STA|=0x4000;
    else
    {
     USART_RX_BUF[USART_RX_STA&0X3FFF]=res;
     USART_RX_STA++;
     if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收   
    }   
   }
  }                  
}              
}
看看我的中断函数

使用特权

评论回复
8
fhguo1990|  楼主 | 2015-4-24 21:39 | 只看该作者
我思故我在12345 发表于 2015-4-24 21:39
怎么大家都喜欢用库呢?
现在出了问题没办法找了....

我去测试一下

使用特权

评论回复
9
fhguo1990|  楼主 | 2015-4-24 21:39 | 只看该作者
我思故我在12345 发表于 2015-4-24 21:39
怎么大家都喜欢用库呢?
现在出了问题没办法找了....

USART_RX_STA 这个变量是什么意思啊?
我去找下资料

使用特权

评论回复
10
我思故我在12345| | 2015-4-24 21:40 | 只看该作者
fhguo1990 发表于 2015-4-24 21:39
USART_RX_STA 这个变量是什么意思啊?
我去找下资料

自己定义的一个变量.

使用特权

评论回复
11
fhguo1990|  楼主 | 2015-4-24 21:40 | 只看该作者
我一个一个的测试没有问题,为什么放到一起就问题来了

使用特权

评论回复
12
fhguo1990|  楼主 | 2015-4-24 21:41 | 只看该作者
还是有问题,不知道是不是配置的问题,所以希望把工程贴上来看看




/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"

uint16_t CCR3_Val;
uint16_t flag1;
typedef union taguiDATA{
uint16_t uidata;
struct{
  unsigned char data_Hi;
  unsigned char data_Lo;
}bytes;   
}uiDATA;

uiDATA COM_data;

uint16_t USART_RX_BUF[64];     //接收缓冲,最大64个字节.
//接收状态
//bit7,接收完成标志
//bit6,接收到0x0d
//bit5~0,接收到的有效字节数目
uint16_t USART_RX_STA=0;       //接收状态标记
/* Private functions ---------------------------------------------------------*/
void GPIO_Configuration(void);  //
void PWM_Configuration(void);
void USART_Configuration(void);

/*******************************************************************************
* Function Name  : Delay
* Description    : Delay Time
* Input          : - nCount: Delay Time
* Output         : None
* Return         : None
* Attention   : None
*******************************************************************************/
void  Delay (uint32_t nCount)
{
  for(; nCount != 0; nCount--);
}


/*******************************************************************************
* Function Name  : main
* Description    : Main Programme
* Input          : None
* Output         : None
* Return         : None
* Attention   : None
*******************************************************************************/
int main(void)
{
uint16_t len;
GPIO_Configuration();
  PWM_Configuration();
  USART_Configuration();
    /* Infinite loop */
    while (1)
{   
  if(USART_RX_STA&0x80)
   {        
    len=USART_RX_STA&0x3f;//得到此次接收到的数据长度
    if(len == 2)
    {
      
       COM_data.bytes.data_Lo =USART_RX_BUF[0];
       COM_data.bytes.data_Hi =USART_RX_BUF[1];
       USART_RX_STA = 0;
      CCR3_Val = COM_data.uidata;
      TIM_SetCompare4(TIM4,CCR3_Val);
      Delay(5000);
      PWM_Configuration();
    }
    if(len > 2)
    USART_RX_STA = 0;   

   }
    }
}

/*******************************************************************************
* Function Name  : GPIO_Configuration
* Description    : Configure GPIO Pin
* Input          : None
* Output         : None
* Return         : None
* Attention   : None
*******************************************************************************/
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO结构体 打开时钟总线,D端口
  
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOD , ENABLE);        
  /**
  *  LED1 -> PD8 , LED2 -> PD9 , LED3 -> PD10 , LED4 -> PD11
  */   
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_0; //选手端口
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     //标志速度
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; ;   //配置模式  推免输出
  GPIO_Init(GPIOD, &GPIO_InitStructure);      //让数据生效,把那些初始化数据写到寄存器里面去,
}


void PWM_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;

//打开时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB |RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

  //配置PWM波输出端口
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);

TIM_TimeBaseStructure.TIM_Period = 4095;                                  //周期
TIM_TimeBaseStructure.TIM_Prescaler = 0;              //分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0;                             //时钟分割
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);                    //初始TIM3

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
TIM_OC3Init(TIM4, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);


TIM_ARRPreloadConfig(TIM4, ENABLE);                        //
TIM_Cmd(TIM4, ENABLE);

}




void USART_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

  //打开时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

  //配置USART1,USART2引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;   //USART1 Rx
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;   //USART1 Tx
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);

  //配置USART1,
USART_InitStructure.USART_BaudRate = 9600;
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_ITConfig(USART1, USART_IT_RXNE, ENABLE);//接收中断使能
  //USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

  //配置NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;  //使能USART1中断
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

USART_Cmd(USART1, ENABLE);   //使能USART1


}



#ifdef  USE_FULL_ASSERT



中断服务函数是

extern uint8_t USART_RX_BUF[64];     //接收缓冲,最大64个字节.
//接收状态
//bit7,接收完成标志
//bit6,接收到0x0d
//bit5~0,接收到的有效字节数目
extern uint8_t USART_RX_STA;       //接收状态标记
void USART1_IRQHandler(void)
{
uint8_t Res;
//STM_EVAL_LEDToggle(LED2);
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
  {
  Res =USART_ReceiveData(USART1);//(USART1->DR); //读取接收到的数据
  
  if((USART_RX_STA&0x80)==0)//接收未完成
   {
   if(USART_RX_STA&0x40)//接收到了0x0d
    {
    if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
    else USART_RX_STA|=0x80; //接收完成了
    }
   else //还没收到0X0D
    {
    if(Res==0x0d)USART_RX_STA|=0x40;
    else
     {
      USART_RX_BUF[USART_RX_STA&0X3F]=Res ;
      USART_RX_STA++;
      if(USART_RX_STA>63)USART_RX_STA=0;//接收数据错误,重新开始接收   
     }   
    }
   }     
这里实在是不知道对不对,那个没有去控制这个PWM

使用特权

评论回复
13
fhguo1990|  楼主 | 2015-4-24 21:41 | 只看该作者
原来是我的三极管烧了 ,悲催的事情啊

使用特权

评论回复
14
我思故我在12345| | 2015-4-24 21:41 | 只看该作者

原来是硬件问题。。。

使用特权

评论回复
15
FAQ| | 2015-4-24 23:34 | 只看该作者
fhguo1990 发表于 2015-4-24 21:41
原来是我的三极管烧了 ,悲催的事情啊

三极管怎么会烧呢

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

23

主题

254

帖子

2

粉丝