找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
12
返回列表 发新帖
楼主: xxll
打印 上一主题 下一主题
收起左侧

PIC单片机输出不了占空比50%的方波——帮扶一把学单片机的60后

  [复制链接]
41#
ID:27513 发表于 2021-12-2 08:22 | 只看该作者
大家好,由于这几天忙没有及时跟帖。在这里谢谢大家对我学习的支持,尤其是@ 188610329 和@ Y_G_G 两位网友老师。在你们细心的引导下,使我的问题得到正确的答案:端口没有正确的初始化!是我没有认真细心的阅读说明书,造成的后果。只要在IO_init()函数内加入ANSEL=0X00;与CMCON0=0x07;(尤其是CMCON0这个寄存器绝对不能不初始化)我的问题基本就解决了……

GPIO端口.jpg (196.11 KB, 下载次数: 219)

GPIO端口.jpg
回复

使用道具 举报

42#
ID:27513 发表于 2021-12-2 08:45 | 只看该作者
taotie 发表于 2021-11-28 00:10
相差无几
时钟8Mhz,标志判断的内容由死循环转到中断子程序中。
初值设置为225    ...

你的程序我也测试了,示波器上的波形不稳定,一会正常一会跳变成窄宽不等的波形。还有你这种方式我个人觉得不妥,如果在主程序中加入按键扫描和指示灯闪烁,这种方式就更无法正常输出频率稳定的方波了。你认为呢?
回复

使用道具 举报

43#
ID:27513 发表于 2021-12-2 11:05 | 只看该作者
这个波形图是中断子程序
void interrupt isr(void)   //中断子程序
{
TMR0=224;
T0IF=0;
GP1=!GP1;
GP2=!GP1;
}
之图

GP1正脉宽为24.8us,负脉宽为25.4us,正负之差0.6uS;GP2比GP1滞后3us
这时GP1与GP2合成的波形即示波器探头接GP1地夹GP2


下面是网友 Y_G_G 提供的子程序波形图
void interrupt isr(void)   //中断子程序
                {
                TMR0=224; //定时器0置初值25us               
                T0IF=0;    //清中断标志                               
                if(ON)
                        {
                        GP2=0;       
                        GP1=1;
               
                        ON=0;
                        }

                else
                        {
                       
                        GP1=0;
                        GP2=1;
                        ON=1;                       
                        }



GP1正负脉宽差也是0.6us,但GP1与GP2合成波延时时差不明显



下面是一款小产品上测得的波形它的正负脉宽差只有0.2us


合成波形很顺滑没有中间的延迟现象


到此我又有新的问题要问了:这个产品的波形是怎样做到呢?

回复

使用道具 举报

44#
ID:401564 发表于 2021-12-2 11:26 | 只看该作者
xxll 发表于 2021-12-2 11:05
这个波形图是中断子程序
void interrupt isr(void)   //中断子程序
{

这GP1和GP0是在同一个端口的吗?没有看数据手册,不知道
不同端口的话,那是要两条指令,那是肯定要有延时的
如果是同一个端口,那就是一条指令就行了if(ON)
                        {
                       PORTD=0x01;//假设是RD端口输出
               
                        ON=0;
                        }

                else
                        {
                       
                        PORTD=0x02;
                        ON=1;                       
                        }
回复

使用道具 举报

45#
ID:27513 发表于 2021-12-2 11:43 | 只看该作者
本帖最后由 xxll 于 2021-12-2 12:03 编辑
Y_G_G 发表于 2021-12-2 11:26
这GP1和GP0是在同一个端口的吗?没有看数据手册,不知道
不同端口的话,那是要两条指令,那是肯定要有延时的 ...

不是同一端口,原来是GP0与GP1,现在改为GP1与GP2了,其实道理是一样的厅
是我理解错了是同一个端口寄存器,因为只有8个引脚的单片机。
回复

使用道具 举报

46#
ID:401564 发表于 2021-12-2 12:03 | 只看该作者
xxll 发表于 2021-12-2 11:43
不是同一端口,原来是GP0与GP1,现在改为GP1与GP2了,其实道理是一样的

GPIO就是一个端口的好不好,直接赋值GPIO端口应该就可以得到你要波形了{
                       GPIO=0x01;//GP0   GP1输出,自己也可以改其它的IO,如果不想影响其它IO,可以用&
               
                        ON=0;
                        }

                else
                        {
                       
                        GPIO=0x02;
                        ON=1;                       
                        }
回复

使用道具 举报

47#
ID:624769 发表于 2021-12-2 13:40 | 只看该作者
老哥,如果你要实现 产品副本.jpg 那样的波形的话,你改写端口的指令必须修改。

void interrupt isr(void)   //中断子程序
{
TMR0=224;
T0IF=0;
GPIO |= 0x06;      // 要用字节改写 GPIO总线, 而不是用位改写 IO
}
回复

使用道具 举报

48#
ID:27513 发表于 2021-12-2 17:44 | 只看该作者
188610329 发表于 2021-12-2 13:40
老哥,如果你要实现 产品副本.jpg 那样的波形的话,你改写端口的指令必须修改。

void interrupt isr(voi ...

你好,这个或运算是如何实现的,我不懂啦。如0x06=0b00000110,若原GPIO=0b00000010或运算后它不还是0b00000110吗?
回复

使用道具 举报

49#
ID:401564 发表于 2021-12-2 17:49 | 只看该作者
xxll 发表于 2021-12-2 17:44
你好,这个或运算是如何实现的,我不懂啦。如0x06=0b00000110,若原GPIO=0b00000010或运算后它不还是0b000 ...

GPIO |= 0x06;
这个是不行的,或指令不能输出低电平的
你自己也要思考一下的嘛
肯定是要用&的嘛
回复

使用道具 举报

50#
ID:624769 发表于 2021-12-2 17:56 来自手机 | 只看该作者
Y_G_G 发表于 2021-12-2 17:49
GPIO |= 0x06;
这个是不行的,或指令不能输出低电平的
你自己也要思考一下的嘛

打错了gpio^=0x06
回复

使用道具 举报

51#
ID:27513 发表于 2021-12-2 17:58 | 只看该作者
Y_G_G 发表于 2021-12-2 17:49
GPIO |= 0x06;
这个是不行的,或指令不能输出低电平的
你自己也要思考一下的嘛

我不说过我是个门外汉吗!与我也不会呀
回复

使用道具 举报

52#
ID:624769 发表于 2021-12-2 18:03 来自手机 | 只看该作者
xxll 发表于 2021-12-2 17:44
你好,这个或运算是如何实现的,我不懂啦。如0x06=0b00000110,若原GPIO=0b00000010或运算后它不还是0b000 ...

抱歉,是我的锅,没复验就发了。
应该是
gpio ^= 0x06;   与或计算,即1变0,0变1。手机发帖排版大小写就不修改了。
回复

使用道具 举报

53#
ID:139866 发表于 2021-12-2 18:04 | 只看该作者
xxll 发表于 2021-12-2 17:44
你好,这个或运算是如何实现的,我不懂啦。如0x06=0b00000110,若原GPIO=0b00000010或运算后它不还是0b000 ...

GPIO |= 0x06;//这个1,2位输出高电平,不改变其他位
GPIO &= 0XF9;//这个1,2位输出低电平,同样不改变其他位
回复

使用道具 举报

54#
ID:401564 发表于 2021-12-2 18:54 | 只看该作者
xxll 发表于 2021-12-2 17:58
我不说过我是个门外汉吗!与我也不会呀

门外汉不是理由
与或非编程基础类知道,不管是你半路出家还是科班出身,不管你专业人士还业余爱好,也不管你是长期爱好还是一时性起
这基础知道是肯定要学的,如果不想学,那就不要搞单片机了
不是打击你,而是没有基础的话,那这单片机玩起来实在太累了,还浪费时间
从你这个问题就可以看出来了,如果当初,你多花一个小时的时间去看一下端口设置,那你就不会在这50%占空比上面花那么多的时间和精力
个人感觉,很多时候,一个自己几天甚至半个月都搞不定的东西,很有可能只是一个简单的东西而已,只是自己没有严谨认真的去看相关的资料而已
我之前就经常碰到这样的问题,一个小小的东西,搞几天都搞不好,怎么找都找不到问题,最后干脆之前的代码都不要,从头再看资料,一步一步的来,一下子就发现问题了,而且,不过是一个很基础很简的问题而已,只是自己老是钻牛角尖而已
所以,基础很重要,不管你多大年纪,不管你是出什么目的学单片机,多看一下基础,不会有坏处
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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