查看: 2360|回复: 11
|
PIC C coding 里很简单,但很奇怪的问题 [已解决]
[复制链接]
|
|
本帖最后由 电子达人 于 23-5-2011 09:18 AM 编辑
PIC programmer 高手们,我有一个问题想要请教你们。。。
PORTC,2 和 PORTC,3 各连接着一个LEDto GND。ANSEL bit = 0 , TRISC2,TRISC3 = 0
我用的是HI-TECH C , PIC 16F616.请见下面的code:
1.
-
- #define bitset(var,bitno) ((var)|=1UL<<(bitno))
- while(1)
- {
- bitset(PORTC,2);
- bitset(PORTC,3);
- }
复制代码
2.
-
- #define bitset(var,bitno) ((var)|=1UL<<(bitno))
- while(1)
- {
- PORTC=0b1100;
- }
复制代码
3.
-
- #define bitset(var,bitno) ((var)|=1UL<<(bitno))
- while(1)
- {
- bitset(PORTC,2);
- }
复制代码
好,问题来了。
“1. ”里的code run的时候,LED是一直在闪的,proteus oscilloscope 显示LED high 1us, 然后就turn off ,不断这样重复。
“2.”里的code,LED 是完全亮着,没有闪。(没问题)
“3”里的code, PORTC,2 的LED 一直亮着,PORTC,3则暗。(没问题)
为什么1。的code 会弄到LED一直在闪?是不是compiler optimization 的问题?两个bitset不能接在一起吗?
[update 23may 2011]
解决方案如下:
- #include <htc.h>
- #define bitset(var,bitno) ((var)|=1UL<<(bitno))
- #define bitclr(var,bitno) ((var)&=~(1UL<<(bitno)))
- #define _XTAL_FREQ 4000000
- __CONFIG(0X44);
- //BOREN_OFF & IOSCFS_ON & CP_OFF & MCLRE_OFF & PWRTE_ON & WDTE_OFF & FOSC_INTOSCIO
- void init(void)
- {
- TRISA=0XFF;
- TRISC=0B11110011;
- ADCON0=0B00000001; //set adc format, reference source, channel select, turn on adc
- ANSEL=1; //only enable ADC input AN0
- ADCON1=0b01110000; //set conversion clock =Frc
- PORTC=0;
- }
- void main(void)
- {
- init();
- while(1)
- {
- bitset(PORTC,2);
- bitset(PORTC,3);
- }
- }
复制代码
以后做ANALOG INPUT的时候要千万记得set对 。。。。。谢谢大家对此主题的关注,这次的经验我将永记不忘。。 |
|
|
|
|
|
|
|
发表于 13-5-2011 07:06 PM
|
显示全部楼层
本帖最后由 canonforest 于 13-5-2011 07:09 PM 编辑
回复 1# 电子达人
请去DATASHEET 看看 I/O REGISTER 的资料,2 和3 很名显是HI 和LO 你的PORTC,你有INIT 你的PORTC AS OUPUT 吗?第一的是TOGGLE PORTC。
((var)|=1UL<<(bitno))这句话代表你SET 的PIN,一斑有八个PIN,当你ON PIN2 的同时,你MASK PIN3去LOW,
相同的,当你ON PIN3 是,你MASK PIN2 去LOW,
所以造成了ONOFF的现象。 |
|
|
|
|
|
|
|

楼主 |
发表于 13-5-2011 07:17 PM
|
显示全部楼层
回复 2# canonforest
谢谢点出我忘了写TRIS 和ANSEL 的setting, 其实都set 对了。
可是,对于你的解释,or 的operation 怎会mask别的bit 呢? PORTC |=0b100; 只会影响bit 2,不是吗? |
|
|
|
|
|
|
|
发表于 14-5-2011 05:27 PM
|
显示全部楼层
回复 3# 电子达人
我想BITSET 是在LIBRAR里的FUNCTION,请问可以给我看看那FUNCTION在做身摸东东吗?XIEXIE! |
|
|
|
|
|
|
|
发表于 17-5-2011 07:08 PM
|
显示全部楼层
回复 1# 电子达人
在回答你的问题之前,我想要知道你的LED是不是没有接任何resistor的?
如果接了resistor,是不是就没有问题了? |
|
|
|
|
|
|
|
发表于 18-5-2011 12:31 AM
|
显示全部楼层
本帖最后由 loolee 于 18-5-2011 12:32 AM 编辑
试试这个:
bitset(LATC,2);output 应该用LATC 吧。 |
|
|
|
|
|
|
|

楼主 |
发表于 18-5-2011 06:51 PM
|
显示全部楼层
回复 5# waiweng83:
LED 当然有接resistor 啊!直接 连接会弄坏output driver,不是吗?
回复 6# loolee
LATC ->undefined identifier....LATC不能用。。 |
|
|
|
|
|
|
|
发表于 18-5-2011 10:14 PM
|
显示全部楼层
本帖最后由 pic 于 18-5-2011 10:17 PM 编辑
回复 5# waiweng83:
LED 当然有接resistor 啊!直接 连接会弄坏output driver,不是吗?
电子达人 发表于 18-5-2011 06:51 PM 
PIC MCU 是可以直接驱动LED 的, 限流25mA。
不过习惯上, 我们还是会加resistor。
但是如果是要很小, 很省零件的话, 我是没有放了。 |
|
|
|
|
|
|
|
发表于 20-5-2011 09:55 AM
|
显示全部楼层
回复 7# 电子达人
那就奇怪了。因为这种情况通常只有在没有接电阻时才会出现。
PORTC |= 0b100 是一个 Read-Modify-Write Operation。意思是MCU会先读取PORTC的value,OR跟0b100,然后再写回去PORTC。
你的code简化后是这样的:
PORTC |= 0b0100;
PORTC |= 0b1000;
当作一开始,PORTC是0的。所以第一行的code,MCU会读取PORTC,拿到的value是0,然后OR跟0b0100,得到0b0100,再写回去PORTC。所以RC2的LED就会亮了。
第二行的code时,MCU也是一样读取PORTC的value。可是问题来了。如果LED没有接电阻的话,PIC就会限流25mA。这会导致PIC output pin的voltage drop到LED的VF。由于LED的VF通常只有1V++,所以当MCU read PORTC的时候,它会读到RC2是0,所以拿到PORTC的value是0。过后MCU会OR跟0b1000,拿到0b1000,然后写回去PORTC。这点亮RC3的LED,但也导致RC2的LED被关掉。
当MCU loop回去第一行的code时,RC2会on,但RC3又会被off掉。你看到LED会闪就是因为这样。
其实这种情况不是只有用OR的时候会发生,就算是用assembly的bitset时也是会遇到,因为PIC的bitset不是atomic的,也是 read-modify-write 的operation 来的。 |
|
|
|
|
|
|
|

楼主 |
发表于 22-5-2011 06:58 PM
|
显示全部楼层
那两个LED都有680ohm in series, 应该不会影响到internal voltage level 吧。况且,PIC 不是有output buffer 的吗?load buffer output怎会load 到input 的voltage level 呢? |
|
|
|
|
|
|
|
发表于 22-5-2011 09:10 PM
|
显示全部楼层
PIC programmer 高手们,我有一个问题想要请教你们。。。
PORTC,2 和 PORTC,3 各连接着一个LEDto GND。A ...
电子达人 发表于 12-5-2011 09:42 PM 
很有趣的问题。 你把你的code, project , simulation schematics 放上来让人下载, 会更好。 可以知道是你的code 问题, project setting问题,还是simulation schematics的问题。 |
|
|
|
|
|
|
|

楼主 |
发表于 23-5-2011 09:09 AM
|
显示全部楼层
本帖最后由 电子达人 于 23-5-2011 09:24 AM 编辑
原本的code已经删除掉了,今天我再次写过,发现了这个问题不是hardware 或compiler 的问题。。。原来我上次写code时,忘了ANSEL的default value = 0xff,就是说全部enable analog input,导致unexpected behaviour...
解决方案见 帖#1。 |
|
|
|
|
|
|
| |
本周最热论坛帖子
|