OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4564|回复: 8

关于f407输出两路 pwm dac 的疑惑

[复制链接]

28

主题

171

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
437
金钱
437
注册时间
2017-2-13
在线时间
110 小时
发表于 2017-3-8 13:18:28 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 爱奔跑的IT 于 2017-3-8 13:34 编辑

我之前做的输出一路pwm dac输出模拟电压已经成功。但是现在发现同样的方法再输出一路模拟电压却不能成功。代码如下,望有识之士能不吝赐教。谢谢。
以下是pwmdac.c文件。成功的是TIM9同样的方法用在TIM14不成功,换TIM12也是这样。
void TIM9_CH2_PWM_Init(u16 arr,u16 psc)
{        
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;
   
   
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9,ENABLE);      //TIM9ʱÖÓʹÄÜ   
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //ʹÄ&#220ORTAʱÖÓ   
   
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //GPIOA3
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//¸´Óù¦ÄÜ
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;    //ËÙ¶È100MHz
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //ÍÆÍ츴ÓÃÊä³ö
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//ÉÏÀ­
    GPIO_Init(GPIOA,&GPIO_InitStructure); //³õʼ»&#175A3

    GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_TIM9); //GPIOA3¸´ÓÃλ¶¨Ê±Æ÷9 AF3

    TIM_TimeBaseStructure.TIM_Prescaler=psc;  //¶¨Ê±Æ÷·ÖƵ
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //ÏòÉϼÆÊýģʽ
    TIM_TimeBaseStructure.TIM_Period=arr;   //×Ô¶¯ÖØ×°ÔØÖµ
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_TimeBaseInit(TIM9,&TIM_TimeBaseStructure);//³õʼ»¯¶¨Ê±Æ÷9

    //³õʼ»¯TIM9 Channel1 PWMģʽ     
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //Ñ¡Ôñ¶¨Ê±Æ÷ģʽ:TIMÂö³å¿í¶Èµ÷ÖÆÄ£Ê½2
     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //±È½ÏÊä³öʹÄÜ
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //Êä³ö¼«ÐÔ:TIMÊä³ö±È½Ï¼«ÐÔ¸ß
    TIM_OCInitStructure.TIM_Pulse=0;
    TIM_OC2Init(TIM9, &TIM_OCInitStructure);  //¸ù¾ÝTÖ¸¶¨µÄ²ÎÊý³õʼ»¯ÍâÉèTIM9 OC2

    TIM_OC2PreloadConfig(TIM9, TIM_OCPreload_Enable);  //ʹÄÜTIM9ÔÚCCR2ÉϵÄÔ¤×°ÔØ¼Ä´æÆ÷

  TIM_ARRPreloadConfig(TIM9,ENABLE);//ARPEʹÄÜ
   
    TIM_Cmd(TIM9, ENABLE);  //ʹÄÜTIM9
}
void TIM14_CH2_PWM_Init(u16 arr,u16 psc)
{        
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;
   
   
    RCC_APB2PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);      //TIM9ʱÖÓʹÄÜ   
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE); //ʹÄ&#220ORTAʱÖÓ   
   
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //GPIOA3
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//¸´Óù¦ÄÜ
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;    //ËÙ¶È100MHz
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //ÍÆÍ츴ÓÃÊä³ö
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//ÉÏÀ­
    GPIO_Init(GPIOG,&GPIO_InitStructure); //³õʼ»&#175A3

    GPIO_PinAFConfig(GPIOG,GPIO_PinSource4,GPIO_AF_TIM14); //GPIOA3¸´ÓÃλ¶¨Ê±Æ÷9 AF3

    TIM_TimeBaseStructure.TIM_Prescaler=psc;  //¶¨Ê±Æ÷·ÖƵ
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //ÏòÉϼÆÊýģʽ
    TIM_TimeBaseStructure.TIM_Period=arr;   //×Ô¶¯ÖØ×°ÔØÖµ
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_TimeBaseInit(TIM14,&TIM_TimeBaseStructure);//³õʼ»¯¶¨Ê±Æ÷9

    //³õʼ»¯TIM14 Channel1 PWMģʽ     
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //Ñ¡Ôñ¶¨Ê±Æ÷ģʽ:TIMÂö³å¿í¶Èµ÷ÖÆÄ£Ê½2
     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //±È½ÏÊä³öʹÄÜ
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //Êä³ö¼«ÐÔ:TIMÊä³ö±È½Ï¼«ÐÔ¸ß
    TIM_OCInitStructure.TIM_Pulse=0;
    TIM_OC2Init(TIM14, &TIM_OCInitStructure);  //¸ù¾ÝTÖ¸¶¨µÄ²ÎÊý³õʼ»¯ÍâÉèTIM9 OC2

    TIM_OC2PreloadConfig(TIM14, TIM_OCPreload_Enable);  //ʹÄÜTIM9ÔÚCCR2ÉϵÄÔ¤×°ÔØ¼Ä´æÆ÷

  TIM_ARRPreloadConfig(TIM14,ENABLE);//ARPEʹÄÜ
   
    TIM_Cmd(TIM14, ENABLE);  //ʹÄÜTIM9
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

28

主题

171

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
437
金钱
437
注册时间
2017-2-13
在线时间
110 小时
 楼主| 发表于 2017-3-8 13:31:13 | 显示全部楼层
@正点原子 原子哥,能不能帮忙看看,视频里没有说到双定时器,看了手册,也不是很明白。谢谢了,卡在这好久了
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2017-3-8 21:33:29 | 显示全部楼层
看波形,看电路
回复

使用道具 举报

28

主题

171

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
437
金钱
437
注册时间
2017-2-13
在线时间
110 小时
 楼主| 发表于 2017-3-9 08:34:30 | 显示全部楼层

不是太懂您的意思,我是通过adc测试dac输出电压的,但是总是有一路输不出来,是不是两个定时器不能同时输出两路pwm波呢?
回复

使用道具 举报

3

主题

105

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
297
金钱
297
注册时间
2013-12-24
在线时间
28 小时
发表于 2017-3-9 08:38:36 | 显示全部楼层
看一下引脚,时钟,定时器的配置是否都对应了
回复

使用道具 举报

28

主题

171

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
437
金钱
437
注册时间
2017-2-13
在线时间
110 小时
 楼主| 发表于 2017-3-9 09:19:18 | 显示全部楼层
wmaxwell 发表于 2017-3-9 08:38
看一下引脚,时钟,定时器的配置是否都对应了

引脚,时钟,定时器的配置上面的代码就是,应该没问题吧,我用dac可以实现,但是不知道为什么pwm dac就有一路实现不了
回复

使用道具 举报

28

主题

171

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
437
金钱
437
注册时间
2017-2-13
在线时间
110 小时
 楼主| 发表于 2017-3-9 11:44:51 | 显示全部楼层
爱奔跑的IT 发表于 2017-3-9 08:34
不是太懂您的意思,我是通过adc测试dac输出电压的,但是总是有一路输不出来,是不是两个定时器不能同时输 ...

原子哥。另外请教一个问题,我昨晚用dac双通道输出两路模拟电压0-3V,测试一遍是正常的,
今天上电之后发现我给Dac1_Set_Vol(speed)函数的值为0-3000范围,每次+/-375,但是中间会有一些数值不能正常输出应该输出的值,基本上变成趋近于0V,我是按照dac例程同样设置的两个通道,都是12右对齐。您觉得是什么地方影响到电压输出吗?但是我把官方的dac例程同样改成双通道输出,就是正常的。能给予一点建议吗?
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2017-3-13 22:02:20 | 显示全部楼层
爱奔跑的IT 发表于 2017-3-9 11:44
原子哥。另外请教一个问题,我昨晚用dac双通道输出两路模拟电压0-3V,测试一遍是正常的,
今天上电之后 ...

你下载我们例程,测试下看看正常么?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

28

主题

171

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
437
金钱
437
注册时间
2017-2-13
在线时间
110 小时
 楼主| 发表于 2017-3-14 10:40:42 | 显示全部楼层
本帖最后由 爱奔跑的IT 于 2017-3-14 11:10 编辑
正点原子 发表于 2017-3-13 22:02
你下载我们例程,测试下看看正常么?

例程用的按键,我是直接串口发送数据,但是只要连续发送数据的时间间隔短到一定程度输出的dac值就会响应不过来,或者直接就是接近0的值,但是数据收发都是正常的就是dac的值不正常。这种情况可能会是拿些原因导致的呢,部分代码我会粘贴上,麻烦原子哥给看看,一直找不出原因,,,
数据分析的代码如下:
[mw_shl_code=c,true]while(1)
                        {
                                if(timex)timex--;
                                if(timex==1)LCD_Fill(30+54,100,239,112,WHITE);
                                t++;
                                delay_ms(10);
                                if(USART3_RX_STA&0X8000)                //接收到一次数据
                                {
                                        rlen=USART3_RX_STA&0X7FFF;        //得到接收数据的长度
                                        USART3_RX_BUF[rlen]=0;                //添加结束符
                                        strncpy(USART3_SEND_BUF_DATE,&USART3_RX_BUF[12],5);//得到其他控制符
                                        date= atoi(USART3_SEND_BUF_DATE);
                                        strncpy(USART3_SEND_BUF_LEFT,&USART3_RX_BUF[17],4);//得到左电机速度值
                                        left = atoi(USART3_SEND_BUF_LEFT);
                                        strncpy(USART3_SEND_BUF_RIGHT,&USART3_RX_BUF[21],4);//得到右电机速度值
                                        right= atoi(USART3_SEND_BUF_RIGHT);
                                        if((date/10000)==1)        //µç»úÆô¶¯
                                        {
                                                        GPIO_SetBits(GPIOG,GPIO_Pin_12);   //左电机使能
                                                if(((date/1000)%10)==1)//左电机正转
                                                {
                                                        GPIO_SetBits(GPIOG,GPIO_Pin_11);
                                                        if(date/100%10==1)
                                                        {
                                                                GPIO_SetBits(GPIOG,GPIO_Pin_2);//右电机正转
                                                        }
                                                        else
                                                        {
                                                                GPIO_ResetBits(GPIOG,GPIO_Pin_2);//右电机反转
                                                        }
                                                }
                                                else                                                                         //左电机反转
                                                {
                                                        GPIO_ResetBits(GPIOG,GPIO_Pin_11);
                                                        if(date/100%10==1)
                                                        {
                                                                GPIO_SetBits(GPIOG,GPIO_Pin_2);////右电机正转
                                                        }
                                                        else //if(date/100%10==0)
                                                        {
                                                                GPIO_ResetBits(GPIOG,GPIO_Pin_2);//右电机反转
                                                        }
                                                }               
                                                if(USART3_RX_STA&0X8000)
                                                {
                                                        Dac1_Set_Vol(left);                //左电机dac输出
                                                        left=0;               
                                                        Dac2_Set_Vol(right);        //右电机dac输出
                                                        right=0;               
                                                }                                                               
                                        }
                                        printf("%d\n",&USART3_RX_BUF[12]);        //发送到串口
                                       
                                        sprintf((char*)p,"接收了%d字节,内容如下",rlen-12);//接收到的数据长度
                                        LCD_Fill(30+54,115,239,130,WHITE);
                                        POINT_COLOR=BRED;
                                        Show_Str(30+54,115,156,12,p,12,0);                         //显示接收的数据长度
                                        POINT_COLOR=BLUE;
                                        LCD_Fill(30,130,239,319,WHITE);
                                        Show_Str(30,130,180,190,&USART3_RX_BUF[12],12,0);//显示接收的数据                                                                       
                                        USART3_RX_STA=0;
                                        if(constate!='+')t=1000;                //状态还未连接,立即更新
                                        else t=0;                   //状态已连接                                       
                                }
                               
                                if(t==3000)//30s检查一次连接是否存在
                                {
                                        LCD_Fill(30+54,125,239,130,WHITE);
                                        LCD_Fill(60,80,120,92,WHITE);
                                        constate=atk_8266_consta_check();//得到连接状态
                                        if(constate=='+')Show_Str(30+30,80,200,12,"连接成功",12,0);  //连接状态
                                        else Show_Str(30+30,80,200,12,"连接失败",12,0);          
                                        t=0;
                                }
                                if((t%20)==0)LED0=!LED0;
                                atk_8266_at_response(1);
                }[/mw_shl_code]
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-19 00:06

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表