搜索
bottom↓
回复: 13

大侠救命呀!PICC奇怪的问题!

[复制链接]

出0入0汤圆

发表于 2010-4-13 20:36:28 | 显示全部楼层 |阅读模式
我以前是用其他单片机的,对PIC单片机不是很熟悉,应为项目的原因这次要使用PIC16F73和PIC16F74单片机,编辑器是使用PICC9.7  现在我遇到了两个特殊功能寄存器赋值的问题!



第一个问题是在PIC16F74上,我是在中断程序中处理ADC,下面的程序是想循环改变ADC通道,程序中无法通过变量给ADCON0赋值,只能通过立即数给ADCON0赋值,如:

方式1://这种方法是可以的

                 ++AdcChLoop;
                 if (AdcChLoop>7){ AdcChLoop=0; }

                 if (AdcChLoop==0){ ADCON0=0b10000001; }
                 else if (AdcChLoop==1){ ADCON0=0b10001001; }
                 else if (AdcChLoop==2){ ADCON0=0b10010001; }
                 else if (AdcChLoop==3){ ADCON0=0b10011001; }
                 else if (AdcChLoop==4){ ADCON0=0b10100001; }
                 else if (AdcChLoop==5){ ADCON0=0b10101001; }
                 else if (AdcChLoop==6){ ADCON0=0b10110001; }
                 else if (AdcChLoop==7){ ADCON0=0b10111001; }


方式2://这种方法就不行了,无法对ADCON0进行改变(Temp和AdcChLoop都是全局uchar变量)。

                 ++AdcChLoop;
                 if (AdcChLoop>7){ AdcChLoop=0; }

                 if (AdcChLoop==0){ Temp=0b10000001; }
                 else if (AdcChLoop==1){ Temp=0b10001001; }
                 else if (AdcChLoop==2){ Temp=0b10010001; }
                 else if (AdcChLoop==3){ Temp=0b10011001; }
                 else if (AdcChLoop==4){ Temp=0b10100001; }
                 else if (AdcChLoop==5){ Temp=0b10101001; }
                 else if (AdcChLoop==6){ Temp=0b10110001; }
                 else if (AdcChLoop==7){ Temp=0b10111001; }

                ADCON0=Temp;

编译中没有发现任何问题,就是程序下载到单片机后“方式2”就不行了!我也看了“方式2”的汇编代码没有发现什么问题。



第二个问题是在PIC16F73上,我是想改变端口状态,无法通过位操作改变端口引脚,只能通过给整个端口赋值才能改变引脚状态!如:


方式1://这种方法是可以的

        PORTA=0b00100000;//没问题
        PORTA=0b00010000;//没问题

方式2://这3种方法都不行了,
        #define VolumeA123 RA4
        #define VolumeA234 RA5

        PORTA=0b00011000;//不行(注意是两个置为1就不行了)

        VolumeA123=1;//不行

        VolumeA234=1;//不行

在编译和仿真(IDE软件仿真)的时候都没有发现什么问题,就是下载到单片机时出问题,RA4和RA5引脚是悬空的且置为输出状态!




我以前用C51没有遇到过这样奇怪的问题,是不是PICC或者这两款单片机在编程中有什么特殊要处理的地方呢?现在时间比较紧,很急呀!高手们给指点一下!小弟万分感谢!

出0入0汤圆

 楼主| 发表于 2010-4-13 20:38:24 | 显示全部楼层
大牛快来哦!自己先顶顶啦!

出0入0汤圆

发表于 2010-4-14 01:39:23 | 显示全部楼层
‘PORTA.4’只能作为输入。

出0入0汤圆

发表于 2010-4-14 05:14:22 | 显示全部楼层
第一个问题,你的代码写得好复杂……

//该行保留
++AdcChLoop;

//该行改写为:AdcChLoop &= 0x07;
if (AdcChLoop>7){ AdcChLoop=0; }

//以下8行改写为:ADCON0 = 0x81|(AdcChLoop<<3);
if (AdcChLoop==0){ ADCON0=0b10000001; }
else if (AdcChLoop==1){ ADCON0=0b10001001; }
else if (AdcChLoop==2){ ADCON0=0b10010001; }
else if (AdcChLoop==3){ ADCON0=0b10011001; }
else if (AdcChLoop==4){ ADCON0=0b10100001; }
else if (AdcChLoop==5){ ADCON0=0b10101001; }
else if (AdcChLoop==6){ ADCON0=0b10110001; }
else if (AdcChLoop==7){ ADCON0=0b10111001; }

所以,只要些如下3行代码就可以了:
++AdcChLoop;
AdcChLoop &= 0x07;
ADCON0 = 0x81|(AdcChLoop<<3);
另外,可以把上面的“0x81”定义成一个宏,增强代码的可移植性。

出0入0汤圆

发表于 2010-4-14 09:45:17 | 显示全部楼层
mark!

出0入0汤圆

 楼主| 发表于 2010-4-14 15:26:43 | 显示全部楼层
第一个问题已经解决了!
   谢谢“eduhf_123 经历”的解答!因为想查查问题在那里所以代码写的很简明些!现在发现这个原因是这个单片机ADC通道切换要延时才行!现在的代码给大家贴出来看看!(比“eduhf_123 经历”的代码还要少用10几条指令)

AdcChLoop = AdcChLoop+0X08;
        if (AdcChLoop > 0XB9){ AdcChLoop = 0X81; }
        ADCON0 = AdcChLoop;

出0入0汤圆

发表于 2010-4-14 15:28:40 | 显示全部楼层
用个定时器定时触发中断,切换通道简单明了

出0入0汤圆

 楼主| 发表于 2010-4-14 15:29:25 | 显示全部楼层
第一个问题已经解决了!
   谢谢“eduhf_123 经历”的解答!因为想查查问题在那里所以代码写的很简明些!现在发现这个原因是这个单片机ADC通道切换要延时才行!现在的代码给大家贴出来看看!(比“eduhf_123 经历”的代码还要少用10几条指令)

AdcChLoop = AdcChLoop+0X08;
if (AdcChLoop > 0XB9){ AdcChLoop = 0X81; }
ADCON0 = AdcChLoop;


第二个问题还没有来得及解决,我自己再努力努力先!

出0入0汤圆

发表于 2010-4-22 17:05:11 | 显示全部楼层
回复【5楼】wingis
第一个问题已经解决了!
   谢谢“eduhf_123 经历”的解答!因为想查查问题在那里所以代码写的很简明些!现在发现这个原因是这个单片机ADC通道切换要延时才行!现在的代码给大家贴出来看看!(比“eduhf_123 经历”的代码还要少用10几条指令)
AdcChLoop = AdcChLoop+0X08;  
if (AdcChLoop > 0XB9){ AdcChLoop = 0X81; }
ADCON0 = AdcChLoop;
-----------------------------------------------------------------------
你试下这样写如何:
ADCON0 = 0x81|((++AdcChLoop,AdcChLoop&=0x07)<<3);
或者:
ADCON0 = 0x81|(++AdcChLoop, (AdcChLoop&0x07)<<3);

出0入0汤圆

发表于 2010-4-23 09:48:56 | 显示全部楼层
请问关于PIC16F1937单片机的ADC通道切换问题:
1。这个延时是否必需,如无延时只会影响准确度还是其他异常(如不产生中断)
2。如需延时,多久合适?
3。我现在切换通道没有延时,转换出来数值没问题,但有不稳定现象,有时GO/DONE位不会清零,没有中断,ADC就死在那边了,其他如定时器、外部中断还是正常的。

出0入0汤圆

发表于 2010-4-26 20:49:29 | 显示全部楼层
查TACQ时间。象早期的18F452/16F877A这样,这个时间是必须靠软件延时来做的,后面出的芯片,很多都加上了对这个时间的设置。就是采样保持时间的设置。

出0入0汤圆

发表于 2010-4-27 09:16:14 | 显示全部楼层
LS我查了一下16f1936算是比较新的吧,TACQ也没有什么地方设置的啊,应该都要看这个数字值后做软件延时吧?!

出0入0汤圆

发表于 2010-4-27 14:30:51 | 显示全部楼层
是没地方设置,只能去延时了。
TACQ = 2ΜS + 1.12ΜS + [(50°C- 25°C)(0.05ΜS/°C)]
= 4.42ΜS
超过这个时间就好。

出0入0汤圆

发表于 2010-4-27 19:16:21 | 显示全部楼层
嗯,谢谢!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-9 22:20

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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