OpenEdv-开源电子网

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

翻转电平输出方波

[复制链接]

8

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
129
金钱
129
注册时间
2018-3-27
在线时间
28 小时
发表于 2018-8-7 16:00:01 | 显示全部楼层 |阅读模式
10金钱
  void IO_Toggle(GPIO_TypeDef* GPIOx,u16 GPIO_Pin)
{               
  GPIO_WriteBit(GPIOx, GPIO_Pin, (BitAction)((1-GPIO_ReadOutputDataBit(GPIOx, GPIO_Pin))));  
}


int main(void)
{GPIO_WriteBit(GPIOD,GPIO_Pin_0,Bit_RESET);
GPIO_WriteBit(GPIOD,GPIO_Pin_1,Bit_SET);
GPIO_WriteBit(GPIOD,GPIO_Pin_2,Bit_SET);
GPIO_WriteBit(GPIOD,GPIO_Pin_3,Bit_SET);

while(1)
        {
               
                 if(flag==1)
                 {
                        Toggle_Num++;
        switch(Toggle_Num)
        {
            case 1:  case 3:  case 5:  case 7:  case 9:  case 11:  case 13:  case 15:
                break;
            case 2:
            case 6:
            case 10:
            case 14:
                IO_Toggle(GPIOD,GPIO_Pin_0|GPIO_Pin_1);
                break;
            case 4:
            case 12:
                      IO_Toggle(GPIOD,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2);
                break;
            case 8:
            case 16:
                      IO_Toggle(GPIOD,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);
                Toggle_Num  =0;
                break;
        }

    flag=0;
}
}

IO初始化

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //éèÖÃÎaÄ£ÄaêäèëÄ£꽿éóÃóúÄ£ÄaμçÑ1μÄêäèë
        GPIO_Init(GPIOD, &GPIO_InitStructure);
        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //éèÖÃÎaÄ£ÄaêäèëÄ£꽿éóÃóúÄ£ÄaμçÑ1μÄêäèë
        GPIO_Init(GPIOD, &GPIO_InitStructure);               

我这样设定不应该是PD0和PD1为互补方波且频率相同,PD2和PD3分别为PD1频率的1/2和1/4吗?然而我用示波器测试,情况并不是这样,PD0和PD1完全一样,PD2和PD3变成了一条电平,哪位大佬能看看是我哪里设置的有问题吗?

PD0_and_PD1.PNG
PD0_and_PD2.PNG

最佳答案

查看完整内容[请看2#楼]

可以同时翻转多个IO口, 只不过我给你的提供的函数只是翻转一个IO的函数, 更不能像你这样使用或操作的方式来使用这个翻转函数。 因为这个函数是使用操作单个IO端口的寄存器来写的。 使用GPIOx_BSRR及GPIOx_BRR就可以随意同时设置多个IO端口, 这样就不会出现你后来的不严格对齐的问题。 但无论如何,你的这种程序都不是长久之计, 玩玩可以,要产生标准的波型,就要用到定时器,严格控制频率和要求的宽度。 如果你暂 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

31

主题

1955

帖子

3

精华

论坛元老

Rank: 8Rank: 8

积分
4524
金钱
4524
注册时间
2018-5-11
在线时间
947 小时
发表于 2018-8-7 16:00:02 | 显示全部楼层
繁星点点starry 发表于 2018-8-7 20:42
不能同时翻转多个IO口,一个一个的翻转IO就可以实现,虽然不知道为什么

可以同时翻转多个IO口,
只不过我给你的提供的函数只是翻转一个IO的函数,
更不能像你这样使用或操作的方式来使用这个翻转函数。
因为这个函数是使用操作单个IO端口的寄存器来写的。
使用GPIOx_BSRR及GPIOx_BRR就可以随意同时设置多个IO端口,
这样就不会出现你后来的不严格对齐的问题。

但无论如何,你的这种程序都不是长久之计,
玩玩可以,要产生标准的波型,就要用到定时器,严格控制频率和要求的宽度。
如果你暂时用定时器产生PWM有困难,
可以先试着学习使用SYSTICK来控制频率和宽度。
我的开源链接 https://github.com/ShuifaHe/STM32.git  请关注,点赞支持哦。
回复

使用道具 举报

11

主题

87

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
494
金钱
494
注册时间
2013-11-26
在线时间
113 小时
发表于 2018-8-7 16:36:35 | 显示全部楼层
没看明白你想干什么  也没看懂你这波形是怎么计算的  建议老老实实的把电平置高置低  调出一个你想要的波形 比如1Hz的波形  再研究其他的
回复

使用道具 举报

8

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
129
金钱
129
注册时间
2018-3-27
在线时间
28 小时
 楼主| 发表于 2018-8-7 20:21:41 | 显示全部楼层
Dayfly 发表于 2018-8-7 16:36
没看明白你想干什么  也没看懂你这波形是怎么计算的  建议老老实实的把电平置高置低  调出一个你想要的波形 ...

单独一个方波,可以实现,就是现在一下实现几个方波有问题,就是想问一下问题是在哪里,我是在采样中断里面设置电平翻转,实现采样和方波的同步。
回复

使用道具 举报

8

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
129
金钱
129
注册时间
2018-3-27
在线时间
28 小时
 楼主| 发表于 2018-8-7 20:42:46 | 显示全部楼层
本帖最后由 繁星点点starry 于 2018-8-8 09:50 编辑

不能同时翻转多个IO口,一个一个的翻转IO就可以实现,虽然不知道为什么
回复

使用道具 举报

64

主题

446

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1032
金钱
1032
注册时间
2017-7-26
在线时间
275 小时
发表于 2018-8-7 20:54:00 | 显示全部楼层
这种操作用stm32实现,请学会用定时器。。。。

难道普通stm32多达8个的定时器还不够你用。。。
回复

使用道具 举报

8

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
129
金钱
129
注册时间
2018-3-27
在线时间
28 小时
 楼主| 发表于 2018-8-8 09:48:28 | 显示全部楼层
a3748622 发表于 2018-8-7 20:54
这种操作用stm32实现,请学会用定时器。。。。

难道普通stm32多达8个的定时器还不够你用。。。

定时器是可以实现,而且定时器1可以输出互补方波,但使用定时器怎么严格确定采样和方波的输出同步呢,我要每方波每个周期内采样的点数都是固定的
回复

使用道具 举报

64

主题

446

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1032
金钱
1032
注册时间
2017-7-26
在线时间
275 小时
发表于 2018-8-8 11:22:17 | 显示全部楼层
繁星点点starry 发表于 2018-8-8 09:48
定时器是可以实现,而且定时器1可以输出互补方波,但使用定时器怎么严格确定采样和方波的输出同步呢,我 ...

你不是要输出跟采样波形相反的方波?

可以试试高级定时器的杀车功能。
回复

使用道具 举报

19

主题

246

帖子

0

精华

高级会员

Rank: 4

积分
608
金钱
608
注册时间
2017-9-21
在线时间
171 小时
发表于 2018-8-8 11:28:55 | 显示全部楼层
IO_Toggle函数有错
回复

使用道具 举报

8

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
129
金钱
129
注册时间
2018-3-27
在线时间
28 小时
 楼主| 发表于 2018-8-8 12:33:55 | 显示全部楼层

大佬怎么改,是封装的时候有问题?IO_Toggle不能同时翻转多个?怎么改呢?
回复

使用道具 举报

0

主题

113

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3321
金钱
3321
注册时间
2017-12-14
在线时间
406 小时
发表于 2018-8-8 14:29:32 | 显示全部楼层
还记得跑马灯的实验不?直接LED0=~LED0;这样翻转就好了
回复

使用道具 举报

8

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
129
金钱
129
注册时间
2018-3-27
在线时间
28 小时
 楼主| 发表于 2018-8-8 14:59:38 | 显示全部楼层
warship 发表于 2018-8-8 11:35
可以同时翻转多个IO口,
只不过我给你的提供的函数只是翻转一个IO的函数,
更不能像你这样使用或操作的 ...

谢谢,对于方波的标准状况要求不是很严格,我要的主要是同步,因为要用到解调,所以,必须要同步,谢谢您的耐心解答。
回复

使用道具 举报

26

主题

355

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1770
金钱
1770
注册时间
2017-4-1
在线时间
432 小时
发表于 2018-8-8 17:33:29 | 显示全部楼层
翻转的话还是直接操作寄存器较好
回复

使用道具 举报

31

主题

1955

帖子

3

精华

论坛元老

Rank: 8Rank: 8

积分
4524
金钱
4524
注册时间
2018-5-11
在线时间
947 小时
发表于 2018-8-8 19:08:30 | 显示全部楼层
繁星点点starry 发表于 2018-8-8 14:59
谢谢,对于方波的标准状况要求不是很严格,我要的主要是同步,因为要用到解调,所以,必须要同步,谢谢您 ...

看你比较着急,在其它论坛也发求助帖。
按照你的思路,
我帮你改写一下吧。
我的开源链接 https://github.com/ShuifaHe/STM32.git  请关注,点赞支持哦。
回复

使用道具 举报

31

主题

1955

帖子

3

精华

论坛元老

Rank: 8Rank: 8

积分
4524
金钱
4524
注册时间
2018-5-11
在线时间
947 小时
发表于 2018-8-8 19:33:30 | 显示全部楼层
本帖最后由 warship 于 2018-8-8 21:12 编辑

按照你的思路,不使用定时器,
直接操作端口IO,
使用BSRR寄存器,可以做到各波型无延时的完全同步。
替换你程序的对应部分,试试看吧。
while(1)
  {
            
   if(flag==1)
     {
        Toggle_Num++;
        switch(Toggle_Num)
        {
            case 1:  case 3:  case 5:  case 7:  case 9:  case 11:  case 13:  case 15:
                break;
            case 2:
            case 6:
            case 10:
            case 14:
                 GPIOD->BSRR=0x20001;  //或者写成GPIOD->BSRR=GPIO_BSRR_BR1 | GPIO_BSRR_BS0;
                break;
            case 4:
            case 12:
                 GPIOD->BSRR=0x50002;  //或者写成GPIOD->BSRR=GPIO_BSRR_BR2 | GPIO_BSRR_BS1 | GPIO_BSRR_BR0;
                break;
            case 8:
                 GPIOD->BSRR=0x90006; //或者写成GPIOD->BSRR=GPIO_BSRR_BR3 | GPIO_BSRR_BS2 | GPIO_BSRR_BS1 | GPIO_BSRR_BR0;
                break;
            case 16:
                 GPIOD->BSRR=0x1000E; //或者写成GPIOD->BSRR=GPIO_BSRR_BS3 | GPIO_BSRR_BS2 | GPIO_BSRR_BS1 | GPIO_BSRR_BR0;
                 Toggle_Num  =0;
                break;
        }

    flag=0;
}
我的开源链接 https://github.com/ShuifaHe/STM32.git  请关注,点赞支持哦。
回复

使用道具 举报

8

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
129
金钱
129
注册时间
2018-3-27
在线时间
28 小时
 楼主| 发表于 2018-8-9 10:12:41 | 显示全部楼层
warship 发表于 2018-8-8 19:33
按照你的思路,不使用定时器,
直接操作端口IO,
使用BSRR寄存器,可以做到各波型无延时的完全同步。

谢谢,因为这是个前端采集的程序,等着做信号处理,所以比较着急,对于单片机还不是很熟悉,非常感谢您
回复

使用道具 举报

31

主题

1955

帖子

3

精华

论坛元老

Rank: 8Rank: 8

积分
4524
金钱
4524
注册时间
2018-5-11
在线时间
947 小时
发表于 2018-8-9 10:51:05 | 显示全部楼层
繁星点点starry 发表于 2018-8-9 10:12
谢谢,因为这是个前端采集的程序,等着做信号处理,所以比较着急,对于单片机还不是很熟悉,非常感谢您

不用客气,改完后测试一下波形,有问题再贴上来一起讨论
我的开源链接 https://github.com/ShuifaHe/STM32.git  请关注,点赞支持哦。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-12 18:53

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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