[讨论] TIM8的程序问题,设置好了但是没有输出

michael_llh   2015-3-11 00:06 楼主
  1. void TIM8_PWM_Init(u16 arr,u16 psc,u16 CCR1_VAL)
  2. {  
  3.          GPIO_InitTypeDef GPIO_InitStructure;
  4.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  5.         TIM_OCInitTypeDef  TIM_OCInitStructure;

  6.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);//
  7.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE);  //使能GPIO外设时钟使能                                                                                    

  8.    //设置该引脚为复用输出功能,输出TIM8 CH1的PWM脉冲波形
  9.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //TIM8_CH1
  10.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
  11.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  12.         GPIO_Init(GPIOC, &GPIO_InitStructure);

  13.        
  14.         TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         80K  
  15.                                                 //也就是设定信号周期
  16.         TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  不分频
  17.         TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
  18.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
  19.         TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位


  20.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1
  21.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能       
  22.         TIM_OCInitStructure.TIM_Pulse = CCR1_VAL; //设置待装入捕获比较寄存器的脉冲值
  23.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //当定时器的数值小于CCR1_VAL时为高电平
  24.         TIM_OC1Init(TIM8, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx

  25.   TIM_CtrlPWMOutputs(TIM8,ENABLE);        //MOE 主输出使能       

  26.         TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable);  //CH1预装载使能         
  27.        
  28.         TIM_ARRPreloadConfig(TIM8, ENABLE); //使能TIMx在ARR上的预装载寄存器
  29.        
  30.         TIM_Cmd(TIM8, ENABLE);  //使能TIM8
  31.    
  32. }

这是我的初始化代码,不知道有没有错,望大家帮忙看下。
然后主函数是用用了TIM8_PWM_Init(999,0,500);

回复评论 (19)

看程序比较头大,你可以参照一下STM8的库,再看看中断是否打开
我的博客
点赞  2015-3-11 10:05
LZ说的是TIM8,不是stm8,呵呵
点赞  2015-3-11 10:59
引用: zhaojun_xf 发表于 2015-3-11 10:05
看程序比较头大,你可以参照一下STM8的库,再看看中断是否打开

是需要打开中断?

点赞  2015-3-11 11:05
__enable_interrupt(); 打开总中断
我的博客
点赞  2015-3-11 11:30
引用: zhaojun_xf 发表于 2015-3-11 11:30
__enable_interrupt(); 打开总中断


我参考了下野火的,他的代码中没有打开中断。我上面的代码是需要打开吗?
很感谢你的回复,新手,见谅。



点赞  2015-3-11 12:52
我用的TIM1,但也始终不能输出PWM波,具体程序是这样的:
点赞  2015-3-14 08:50
我用TIM1也不能输出波形: #include "pwm_output.h" static void TIM1_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9| GPIO_Pin_10 | GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); } static void TIM1_Mode_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; u16 CCR1_Val = 50; u16 CCR2_Val = 50; u16 CCR3_Val = 50; u16 CCR4_Val = 50; TIM_TimeBaseStructure.TIM_Period = 999; //当定时器从0计数到999,即为1000次,为一个定时周期 TIM_TimeBaseStructure.TIM_Prescaler = 71; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ; //设置时钟分频系数:不分频 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式 TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //配置为PWM模式1 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR1_Val; //设置跳变值,当计数器计数到这个值时,电平发生跳变 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //当定时器计数值小于CCR1_Val时为高电平 TIM_OC1Init(TIM1, &TIM_OCInitStructure); //使能通道1 TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR2_Val; //设置通道2的电平跳变值,输出另外一个占空比的PWM TIM_OC2Init(TIM1, &TIM_OCInitStructure); //使能通道2 TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR3_Val; //设置通道3的电平跳变值,输出另外一个占空比的PWM TIM_OC3Init(TIM1, &TIM_OCInitStructure); //使能通道3 TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR4_Val; //设置通道4的电平跳变值,输出另外一个占空比的PWM TIM_OC4Init(TIM1, &TIM_OCInitStructure); //使能通道4 TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM1, ENABLE); // 使能TIM1重载寄存器ARR TIM_Cmd(TIM1, ENABLE); //使能定时器1 } void TIM1_PWM_Init(void) { TIM1_GPIO_Config(); TIM1_Mode_Config(); } 只知道TIM1的时钟和TIM2的时钟不一样 本帖最后由 幽灵公主 于 2015-3-14 09:03 编辑
点赞  2015-3-14 08:52
引用: 幽灵公主 发表于 2015-3-14 08:52
我用TIM1也不能输出波形:
#include "pwm_output.h"
static void TIM1_GPIO_Config(void)
{  
      GPIO_InitTypeDef GPIO_InitStructure;  
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);   
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);     

      GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_8 | GPIO_Pin_9| GPIO_Pin_10 | GPIO_Pin_11;   
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                    // 复用推挽输出  
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
      GPIO_Init(GPIOA, &GPIO_InitStructure);
  }
static void TIM1_Mode_Config(void)
{        
      TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;        
      TIM_OCInitTypeDef  TIM_OCInitStructure;      
      u16 CCR1_Val = 50;               
      u16 CCR2_Val = 50;      
      u16 CCR3_Val = 50;        
      u16 CCR4_Val = 50;
  
     TIM_TimeBaseStructure.TIM_Period = 999;       //当定时器从0计数到999,即为1000次,为一个定时周期  
     TIM_TimeBaseStructure.TIM_Prescaler = 71;            
     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;        //设置时钟分频系数:不分频           

     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数模式  
     TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);                  

     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;            //配置为PWM模式1   
     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;               
    // TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;         
     TIM_OCInitStructure.TIM_Pulse = CCR1_Val;           //设置跳变值,当计数器计数到这个值时,电平发生跳变
     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //当定时器计数值小于CCR1_Val时为高电平  
     TIM_OC1Init(TIM1, &TIM_OCInitStructure);         //使能通道1  
     TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);  

    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   
    TIM_OCInitStructure.TIM_Pulse = CCR2_Val;          //设置通道2的电平跳变值,输出另外一个占空比的PWM   
    TIM_OC2Init(TIM1, &TIM_OCInitStructure);          //使能通道2
    TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);         

    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   
    TIM_OCInitStructure.TIM_Pulse = CCR3_Val;        //设置通道3的电平跳变值,输出另外一个占空比的PWM   
    TIM_OC3Init(TIM1, &TIM_OCInitStructure);         //使能通道3   
    TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);   

    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = CCR4_Val;        //设置通道4的电平跳变值,输出另外一个占空比的PWM  
    TIM_OC4Init(TIM1, &TIM_OCInitStructure);        //使能通道4
    TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);  

    TIM_ARRPreloadConfig(TIM1, ENABLE);                         // 使能TIM1重载寄存器ARR  
    TIM_Cmd(TIM1, ENABLE);                   //使能定时器1     
}
void TIM1_PWM_Init(void)
{      
     TIM1_GPIO_Config();     
     TIM1_Mode_Config();      
  }
只知道TIM1的时钟和TIM2的时钟不一样
我的问题已经解决了。是端口复用的问题。你那边也可以查下是否存在端口复用,顺便把定时器的初始化放在所有的初始化之后试试看



点赞  2015-3-14 12:32
引用: michael_llh 发表于 2015-3-14 12:32
我的问题已经解决了。是端口复用的问题。你那边也可以查下是否存在端口复用,顺便把定时器的初始化放在所有的初始化之后试试看
我刚发现TIM1要打开        TIM_CtrlPWMOutputs(TIM1,ENABLE);//使能TIM1外设的主输出
现在也能输出PWM了,谢谢




点赞  2015-3-14 22:45
引用: 幽灵公主 发表于 2015-3-14 22:45
我刚发现TIM1要打开        TIM_CtrlPWMOutputs(TIM1,ENABLE);//使能TIM1外设的主输出
现在也能输出PWM了,谢谢

恩,互帮互助哈!


点赞  2015-3-14 23:02
引用: michael_llh 发表于 2015-3-14 23:02
恩,互帮互助哈!
你有用过STM32显示BMP图片没?
使用STM32的例程,可以显示图片,把图片换成其它BMP图片,修改Lcd_show_bmp(0, 0,"/tupian.bmp");,并把图片放到SD卡,液晶不能显示图片,那么图片的路径是如何设置的?
void Lcd_show_bmp(unsigned short int x, unsigned short int y,unsigned char *pic_name)
{
        int i, j, k;
        int width, height, l_width;
        BYTE red,green,blue;
        BITMAPFILEHEADER bitHead;
        BITMAPINFOHEADER bitInfoHead;
        WORD fileType;

        unsigned int read_num;
        unsigned char tmp_name[20];
        sprintf((char*)tmp_name,"0:%s",pic_name);

        f_mount(0, &bmpfs[0]);
        BMP_DEBUG_PRINTF("file mount ok \r\n");   
        bmpres = f_open( &bmpfsrc , (char *)tmp_name, FA_OPEN_EXISTING | FA_READ);        
        if(bmpres == FR_OK)
        {
                BMP_DEBUG_PRINTF("Open file success\r\n");         
                f_read(&bmpfsrc,&fileType,sizeof(WORD),&read_num);     
                if(fileType != 0x4d42)
                {
                        BMP_DEBUG_PRINTF("file is not .bmp file!\r\n");
                        return;
                }
                else
                {
                        BMP_DEBUG_PRINTF("Ok this is .bmp file\r\n");        
                }        
                f_read(&bmpfsrc,&bitHead,sizeof(tagBITMAPFILEHEADER),&read_num);        
                showBmpHead(&bitHead);
                f_read(&bmpfsrc,&bitInfoHead,sizeof(BITMAPINFOHEADER),&read_num);        
                showBmpInforHead(&bitInfoHead);
        }   
        else
        {
                BMP_DEBUG_PRINTF("file open fail!\r\n");
                return;
        }   
        width = bitInfoHead.biWidth;
        height = bitInfoHead.biHeight;
        l_width = WIDTHBYTES(width* bitInfoHead.biBitCount);        
        if(l_width > 960)
        {
                BMP_DEBUG_PRINTF("\n SORRY, PIC IS TOO BIG (<=320)\n");
                return;
        }
        Lcd_GramScan( 3 );
        LCD_OpenWindow(x, y, width, height);
        /* 判断是否是24bit真彩色图 */
        if(bitInfoHead.biBitCount >= 24)
        {
                for(i=0;i< height; i++)
                {         
                        /* 读取一行bmp的数据到数组pColorData里面 */
                        #if 0
                                for(j=0; j< l_width; j++)                                                                                                                 
                                {               
                                        f_read(&bmpfsrc,pColorData+j,1,&read_num);
                                }            
                        #elif 1                                
                                f_read(&bmpfsrc,pColorData,l_width/2,&read_num);
                                f_read(&bmpfsrc,pColorData+l_width/2,l_width/2,&read_num);
                        #else
                                f_read(&bmpfsrc,pColorData,l_width,&read_num);
                        #endif

                        for(j=0; j                         {
                                k = j*3;                                                                                                                                         //一行中第K个像素的起点
                                red = pColorData[k+2];
                                green = pColorData[k+1];
                                blue =         pColorData[k];
                                LCD_WR_Data(RGB24TORGB16(red,green,blue)); //写入LCD-GRAM
                        }            
                }                                                                                                                                                                                             
        }   
        else
        {        
                BMP_DEBUG_PRINTF("SORRY, THIS PIC IS NOT A 24BITS REAL COLOR");
                return ;
        }
        f_close(&bmpfsrc);   
}




点赞  2015-3-16 21:54
引用: 幽灵公主 发表于 2015-3-16 21:54
你有用过STM32显示BMP图片没?
使用STM32的例程,可以显示图片,把图片换成其它BMP图片,修改Lcd_show_bmp(0, 0,"/tupian.bmp");,并把图片放到SD卡,液晶不能显示图片,那么图片的路径是如何设置的?
void Lcd_show_bmp(unsigned short int x, unsigned short int y,unsigned char *pic_name)
{
        int i, j, k;
        int width, height, l_width;
        BYTE red,green,blue;
        BITMAPFILEHEADER bitHead;
        BITMAPINFOHEADER bitInfoHead;
        WORD fileType;

        unsigned int read_num;
        unsigned char tmp_name[20];
        sprintf((char*)tmp_name,"0:%s",pic_name);

        f_mount(0, &bmpfs[0]);
        BMP_DEBUG_PRINTF("file mount ok \r\n");   
        bmpres = f_open( &bmpfsrc , (char *)tmp_name, FA_OPEN_EXISTING | FA_READ);        
        if(bmpres == FR_OK)
        {
                BMP_DEBUG_PRINTF("Open file success\r\n");         
                f_read(&bmpfsrc,&fileType,sizeof(WORD),&read_num);     
                if(fileType != 0x4d42)
                {
                        BMP_DEBUG_PRINTF("file is not .bmp file!\r\n");
                        return;
                }
                else
                {
                        BMP_DEBUG_PRINTF("Ok this is .bmp file\r\n");        
                }        
                f_read(&bmpfsrc,&bitHead,sizeof(tagBITMAPFILEHEADER),&read_num);        
                showBmpHead(&bitHead);
                f_read(&bmpfsrc,&bitInfoHead,sizeof(BITMAPINFOHEADER),&read_num);        
                showBmpInforHead(&bitInfoHead);
        }   
        else
        {
                BMP_DEBUG_PRINTF("file open fail!\r\n");
                return;
        }   
        width = bitInfoHead.biWidth;
        height = bitInfoHead.biHeight;
        l_width = WIDTHBYTES(width* bitInfoHead.biBitCount);        
        if(l_width > 960)
        {
                BMP_DEBUG_PRINTF("\n SORRY, PIC IS TOO BIG (
这个暂时还没学到,你看看参考下原子或者野火的例程和讲解吧,网上应该有,没有你私信我,我发给你。



点赞  2015-3-16 22:24
SD卡的路径和PC中的路径是一致的。
我的博客
点赞  2015-3-17 11:56
引用: michael_llh 发表于 2015-3-16 22:24
这个暂时还没学到,你看看参考下原子或者野火的例程和讲解吧,网上应该有,没有你私信我,我发给你。我参考的是野火的例子  



点赞  2015-3-17 14:50
您好,你这个是怎么解决的呢,我的端口也没有复用啊
点赞  2016-5-29 20:18
引用: michael_llh 发表于 2015-3-14 12:32
我的问题已经解决了。是端口复用的问题。你那边也可以查下是否存在端口复用,顺便把定时器的初始化放在所有 ...

楼主您好,我也遇到了相同的问题,SYM32的TIM8_CH1 不管怎么样就是不输出PWM波,同样是高级定时器的TIM1_CH1相同的配置就可以输出PWM波。敬请指教!谢谢!
点赞  2018-4-13 11:31
引用: jinag2018 发表于 2018-4-13 11:31
楼主您好,我也遇到了相同的问题,SYM32的TIM8_CH1 不管怎么样就是不输出PWM波,同样是高级定时器的TIM1_ ...

你先看CNT有没有变化,再看通道有数值没有,再看管脚有输出没,再验频率和占空比
点赞  2018-4-13 12:00
引用: huo_hu 发表于 2018-4-13 12:00
你先看CNT有没有变化,再看通道有数值没有,再看管脚有输出没,再验频率和占空比

谢谢您的解答,关于您说的CNT,是中断定时器计数值吧。我在这里并没有用到中断呢
点赞  2018-4-13 13:33
引用: jinag2018 发表于 2018-4-13 13:33
谢谢您的解答,关于您说的CNT,是中断定时器计数值吧。我在这里并没有用到中断呢

是定时器计数寄存器,时钟一开cnt就会计数,是个最核心的寄存器,其它功能都围绕这cnt展开
点赞  2018-4-15 14:22
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复