我正在尝试编程PIC12C508A来做一个简单的LED学习电路。我已经阅读了一些示例,Microchip数据表,pic12c508a.h和pic12c508a.inc。我试图使用C程序和ASM程序设置TRIS寄存器,但它不需要。使用MPLAB X,XC8编译器和内置仿真器来检查SFR寄存器,我可以看到即使WREG保持正确的值,TRIS也不会更新。如果有人有这方面的经验,请查看我的代码,看看我是否做错了。
#include <xc.h>
// -- CONFIG
#pragma config MCLRE = ON // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD)
#pragma config WDT = OFF // Turn Watchdog Timer Off.
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
#pragma config OSC = IntRC // Internal RC Oscillator
// -- Internal Frequency
#define _XTAL_FREQ 400000
int main()
{
TRIS = 0b111010; // 0x3A
//---0-0 Set GP0 and GP2 as outputs
GPIO = 0b000100; // 0x04
//---1-0 Set GP2 as HIGH and GP0 as LOW
for(int countdown = 10; countdown > 0; --countdown) {
__delay_ms(60000); // Delay 1 minute.
}
GPIO = 0b000001; // 0x01
//---0-1 Set GP2 as LOW and GP0 as HIGH
while(1)
NOP();
}
我还尝试了一个与基线PIC模型的Gooligum教程完全相同的程序集。
list p=12c508a
#include <p12c508a.inc>
__CONFIG _MCLRE_ON & _CP_OFF & _WDT_OFF & _IntRC_OSC
RCCAL CODE 0x0FF ; Processor Reset Vector
res 1 ; Hold internal RC cal value, as a movlw k
RESET CODE 0x000 ; RESET VECTOR
movwf OSCCAL ; Factory Calibration
start
movlw b'111010' ; Configure GP0/GP2 as outputs
tris GPIO ;
movlw b'000100' ; Set GP2 HIGH - GREEN LED
movwf GPIO
goto $ ; loop forever
END
这一切看起来都非常简单但是当我使用断点并检查模拟器中的SFR寄存器时,我可以看到GPIO和TRIS寄存器永远不会改变,即使WREG将保持正确的值。我已经检查了XC8编译器生成的ASM输出,它几乎与我在设置寄存器时编写的ASM相同。
我也尝试过使用HEX值和直线整数值,结果是一样的。
答案 0 :(得分:2)
首先,为了使用GP2作为输出,你需要清除OPTION寄存器中的T0CS吗?
其次,我在手册中观察到了这一点:
注意:读取端口会读取引脚,而不是输出数据锁存器。 也就是说,如果引脚上的输出驱动器被使能并被驱动为高电平,那么 外部系统保持低电平,读取端口将 表明引脚很低。
但我想模拟器会假设外部系统没有压住引脚。
第三,BCF
和BSF
指令看起来像是一种更好的方式来摆弄GP2和GP0,与GPIO中正在发生的其他事情无关。
对不起,除此之外,我不知道该建议什么。
答案 1 :(得分:2)
答案是程序顶部定义的晶体频率远远超出实际值
#define _XTAL_FREQ 400000 //that's 400KHz INTOSC, impossible
相反它应该是
#define _XTAL_FREQ 4000000 //That's 4MHz INTOSC
@Justin在下面的评论中指出了它的原始帖子。
答案 2 :(得分:1)
您可以尝试不同的GPIO,因为根据文档,GP2可能由选项寄存器控制。