|
各位大神,本人在用AT91SAM7SE512输出方波时,想在PB18脚上输出500KHz的方波,用的是外部4M晶振。现在输出的怎么是86MHz左右的波形而且不是方波,求教大神指点@
以下是代码部分:
#define __inline inline
#include "AT91SAM7SE512.h"
#include "AT91SAM7SE512.h"
void AT91F_LowLevelInit(void)
{
unsigned char i;
//* 1.Set MCK at 4 000 000Hz
// SCK = 1/32768 = 30.51 uSeconde
// Start up time = 8 * 6 / SCK = 56 * 30.51 = 1,46484375 ms
// Init PMC Step
//2. 配置PLL输出时钟 4 * (20+1)/21 = 4 MHz
///////////////////////////////////////////////////////////////////////////
//i.Embedded Flash Controller (EFC) Init
// Wait State necessary to work at 4MHz
//AT91C_BASE_MC->MC0_FMR = AT91C_MC_FWS_0FWS;// 2 Wait State to work at 4MHz
//AT91C_BASE_MC->MC1_FMR = AT91C_MC_FWS_0FWS;// 2 Wait State to work at 4MHz
///////////////////////////////////////////////////////////////////////////
// ii.Init PMC Step
//1. Enable Main Oscillator,使能主振荡器
// Main Oscillator startup time is board specific:
// Main Oscillator Startup Time worst case (3MHz) corresponds to 15ms
// (0x40 for AT91C_CKGR_OSCOUNT field)
//启动时间= 8 * OSCOUNT / SLCK = 56 慢时钟周期。
//因此,在56 慢时钟周期后,主振荡器将使能(MOSCS位置位)。
AT91C_BASE_PMC->PMC_MOR = (( AT91C_CKGR_OSCOUNT & (0x40 <<8) | AT91C_CKGR_MOSCEN ));
// Wait Main Oscillator stabilization
while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS));
//2. 校验主振荡器频率(可选):
//某些情况下用户需要精确测量主振荡器频率。测量通过CKGR_MCFR寄存器来完成。
//一旦CKGR_MCFR寄存器中的MAINRDY域置位,用户可读CKGR_MCFR寄存器的MAINF
//域。它提供16个慢时钟周期中主时钟周期数。
// Init PMC Step 3.设置PLL与分频器
//OUT域用来选择PLL B输出频率范围。
//MUL域为PLL乘数。该 参数可为0到2047间值。
//若MUL置为0,PLL将关闭,否则PLL输出频率为PLL输入频率与(MUL + 1)的乘积
//DIV域用来控制分频器本身。可为0到255间值
AT91C_BASE_PMC->PMC_PLLR = AT91C_CKGR_OUT_0 |
(16 << 8) |
(AT91C_CKGR_MUL & (20 << 16)) | //20倍
(AT91C_CKGR_DIV & 21); //(21-1)分频
// Wait for PLL stabilization
while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK) );
// Wait until the master clock is established for the case we already
// turn on the PLL
while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) );
// Init PMC Step 4. 选择主机时钟与处理器时钟
// 主机时钟与处理器时钟是通过PMC_MCKR寄存器配置的。
//CSS域用来选择主机时钟分频器源。默认的源为慢时钟。
//PRES域用来控制主机时钟预分频器。用户可选择不同的值(1、2、4、8、16、32、64)。
//主机输出为预分频输入被PRES分频后的值。PRES默认值为1,表示主机时钟等于慢时钟
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK; //1分频,主机时钟频率为4M=MCK
// Wait until the master clock is established
while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) );
//Note:若选择PLLx时钟作为主机时钟且用户决定通过写CKGR_PLLR来对其进行修改,MCKRDY标志
//将变低而PLL解锁。一旦PLL重新上锁,LOCK变高且MCKRDY置位。
//若PLL解锁,主机时钟自动选择变为主时钟
AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK; //选择主机时钟分频器源——》MAIN(外部4M晶振)
// Wait until the master clock is established
while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) );
//Init PMC Step 5. 可编程时钟选择
//可编程时钟通过PMC_SCER、PMC_SCDR及PMC_SCSR寄存器进行控制。
//根据系统需求,对3个可编程时钟进行使能或禁用。
//PMC_SCSR显示哪个可编程时钟使能。默认情况下所有可编程时钟全部禁用。
//PMC_PCKx 寄存器用来配置可编程时钟。
//CSS域用来选择可编程时钟分频源。有四个可选时钟:主时钟,慢时钟PLLCK。默认情况下选择慢时钟。
//PRES域用来控制可编程时钟预分频器。
//一旦PMC_PCKx寄存器编程,相应的可编程时钟必须使能且用户必须等待PMC_SR寄存器中的PCKRDYx位置位。
//设置PB18为PCK2;
AT91C_BASE_PIOB->PIO_PDR=AT91C_PB18_PCK2; // PIO Disable Register
AT91C_BASE_PIOB->PIO_BSR=AT91C_PB18_PCK2; // PIO Status Register
//关闭PCK2在改变设置前
AT91C_BASE_PMC->PMC_SCDR=AT91C_PMC_PCK2; //可编程时钟可通过PMC_SCER或PMC_SCDR 寄存器来使能或禁用。
//设置PCK2
AT91C_BASE_PMC->PMC_PCKR[2]=AT91C_PMC_PRES_CLK_8|(AT91C_PMC_CSS_MAIN_CLK);//PB18_PCK2,MCK 8分频-》500KHz
//使能PCK2
AT91C_BASE_PMC->PMC_SCER=AT91C_PMC_PCK2;
// Wait until the master clock is established
while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_PCK2RDY) );
AT91C_BASE_PIOB->PIO_PER=AT91C_PB18_PCK2; // PIO Enable Register
//Init PMC Step 6. 使能外设时钟
//一旦完成所有前面的步骤,可通过PMC_PCER或PMC_PCDR寄存器对外设时钟进行使
//能或禁用。
//根据系统需求对9个外设时钟进行使能或禁用。PMC_PCSR显示哪个外设时钟使能。
//例如如果要使能某一外设时钟时将PMC_PCER中对应位置位即可,而禁止这一外设的时钟时将PMC_PCDR内对应位置位即可。
//器件复位后可控时钟外设的时钟是处于关闭的 ,为此使用前必须打开
//AT91C_BASE_PMC->PMC_PCER=AT91C_PIO_PB18; // Peripheral Clock Enable Register
//AT91C_BASE_PMC->PMC_PCSR=AT91C_PIO_PB18; //PMC_PCSR显示哪个外设时钟使能。
//AT91F_PMC_EnablePeriphClock
///////////////////////////////////////////////////////////////////////////
// Disable Watchdog (write once register)
AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;
///////////////////////////////////////////////////////////////////////////
// Init AIC: assign corresponding handler for each interrupt source
AT91C_BASE_AIC->AIC_SVR[0] = (int) AT91F_Default_FIQ_handler ;
for (i = 1; i < 31; i++) {
AT91C_BASE_AIC->AIC_SVR[i] = (int) AT91F_Default_IRQ_handler ;
}
AT91C_BASE_AIC->AIC_SPU = (unsigned int) AT91F_Spurious_handler;
}
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。
|