本帖最后由 vincentwang 于 2014-9-16 12:38 编辑
刚开始用PIC单片机,看DATASHEET有些地方还是不太明白,再这里请教各位大侠,先谢谢了!
单片机型号是PIC18F87K22,外接8M晶振,开启PLL(PLLX4),问题来了:
1.手册上有个Fosc,此处的Fosc是指外接的8M还是开启PLL后的8X4=32M?
2.使用定时器时(如TIMER0),T0的时钟由Fosc/4和预分频器来决定,那么这里的Fosc/4是指8/4=2M还是32/4=8M?
3.用Protues仿真是,单片机属性中的Processor Clock frequency应该设置成8M还是PLL后的32M?(如图)
求高手指点!
补充:
用protues进行仿真,timer0每1ms中断一次,在1ms中断里面计数200(即200ms)翻转一次LED1的电平。
用示波器测试波形如下图:
当Processor Clock frequency设置为32M时,示波器显示的波形是50ms翻转一次,而当Processor Clock frequency设置为8M时才是200ms翻转一次,才和预期的对得上。
因此有点不解,这个Processor Clock frequency到底是外接晶振的8M还是PLL之后的32M?
实验结果貌似就是外接的8M晶振的频率,求高手指点一下!
仿真图如下:
部分代码如下:
//MPLAB X IDE + XC8
//部分配置字设置
// CONFIG1L
#pragma config RETEN = ON // VREG Sleep Enable bit (Enabled)
#pragma config INTOSCSEL = HIGH // LF-INTOSC Low-power Enable bit (LF-INTOSC in High-power mode during Sleep)
#pragma config SOSCSEL = HIGH // SOSC Power Selection and mode Configuration bits (High Power SOSC circuit selected)
#pragma config XINST = ON // Extended Instruction Set (Enabled)
// CONFIG1H
#pragma config FOSC = HS1 // Oscillator (HS oscillator (Medium power, 4 MHz - 16 MHz))
#pragma config PLLCFG = ON // PLL x4 Enable bit (Enabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor (Disabled)
#pragma config IESO = OFF // Internal External Oscillator Switch Over Mode (Disabled)
// CONFIG2L
#pragma config PWRTEN = OFF // Power Up Timer (Disabled)
#pragma config BOREN = SBORDIS // Brown Out Detect (Enabled in hardware, SBOREN disabled)
#pragma config BORV = 3 // Brown-out Reset Voltage bits (1.8V)
#pragma config BORPWR = ZPBORMV // BORMV Power level (ZPBORMV instead of BORMV is selected)
// CONFIG2H
#pragma config WDTEN = OFF // Watchdog Timer (WDT disabled in hardware; SWDTEN bit disabled)
#pragma config WDTPS = 1048576 // Watchdog Postscaler (1:1048576)
// timer0初始化
void Tmr0_Init(void)
{
T0CON = 0X45; //8bit mode , F = (Fosc/4)/64 = 32MHz/256 = 125000HZ, T = 1000000/125000 = 8us
TMR0L = 125; //125*8us = 1ms
INTCONbits.INT0IF = 0; // clear intterrupt flag
INTCON2bits.TMR0IP = 0; // low Priority
INTCONbits.TMR0IE = 1; // enable Timer0 overflow interrupt
INTCONbits.PEIE = 1; //enable low Priority interrupt
T0CONbits.TMR0ON = 1;
}
// timer0中断函数
void interrupt low_priority Low_ISR()
{
static u16 i = 0;
if(TMR0IF & TMR0IE) //Timer0 interrupt
{
TMR0IF = 0; //clear flag
TMR0L = 125;
if(++i >=200)
{
LATAbits.LATA1 = !LATAbits.LATA1; // led1
i = 0;
}
}
}
// main
int main(int argc, char** argv)
{
DevInit();
while(1)
{
LATAbits.LATA2 = 1; // led2
}
} |