本帖最后由 shiyongzhu 于 2014-6-18 22:15 编辑
本人在使用笔记2中介绍了AS6.2自带的ChipID Example例程,该例程能够读取了芯片的ID等信息并通过串口进行发送,然而比较遗憾的是当时没有对该例程进行详细的分析,为了弥补这个缺憾本节将对该例程进行详细的分析。 1、例程的组成: 打开CHIPID_EXAMPLE1例程,如下图所示。
工程文件由四个部分组成:Dependencies、Output Files、Libraries、src。四部分作用如下: Dependencies——列举所依赖的头文件 Output Files——输出的文件 Libraries——需要的库文件 Src——程序代码 主要的编程代码存在于src中,而src又可以分成ASF(Atmel Software Framework)、config、asf.h、chipid_example.c。 ASF为Atmel程序框架,主要存放一些底层的库函数;config中存放配置文件,用于配置开发板;asf.h中存放所需要的ASF的头文件;chipid_example.c中存放最终的代码。以下将对chipid_example.c进行分析。 2、主程序chipid_example.c分析 为了便于分析,开启了程序代码的行号。 打开菜单栏Tools下的options,出现如下的窗口,勾选Line numbers,即可显示程序代码行号。
92~95行定义了需要的头文件。 99~101及396~398行,供编译所用,这一部分就是告诉编译器,如果定义了__cplusplus(即如果是cpp文件, extern "C"{ //因为cpp文件默认定义了该宏),则采用C语言方式进行编译 105~108行为两个宏定义 STRING_EOL定义为回车代表end of line。 STRING_HEADER定义为一组字符串用于输出报文的头。 111~117行定义数据类型chipidtype_t,随后利用该数据类型定义了如下的变量chipid_eproc(处理器类型)、chipid_nvpsize(第一个非易失性程序存储器大小)、chipid_nvpsize2(第二个非易失性程序存储器大小)、chipid_sramsize(sram大小)、chipid_archsize(架构)、chipid_nvptype(ROM类型)。 上述的 279行定义了如下函数 static bool chipid_find(const chipidtype_t*p_cid_types,uint32_t ul_size, uint32_t ul_id, chipidtype_t *p_cid_type) 该函数从p_cid_types找到对应ul_id的p_cid_type并利用指针返回。111~117行定义了许多chipidtype_t类型的数组,chipid_find就是为了从数组中找到对应项的字符串。 299行定义了如下的函数 static void chipid_print(chipid_data_t*p_chipid_data) 该函数根据p_chipid_data,输出chipidtype_t中字符串。 357行定义函数 static void configure_console(void) 该函数用于配置调试串口。 374行进入main函数
首先执行sysclk_init(),该函数将初始化时钟,函数定义在Sysclk.c 中 由于Conf_clock.h文件中定义 #define CONFIG_PLL0_SOURCE PLL_SRC_SLCK_XTAL #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK 所以sysclk_init()中if判断语句将运行如下语句 。。。。。 #ifdef CONFIG_PLL0_SOURCE elseif (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_PLLACK) { structpll_config pllcfg;
pll_enable_source(CONFIG_PLL0_SOURCE); //慢时钟源选择 pll_config_defaults(&pllcfg,0); // 配置PLL pll_enable(&pllcfg,0); //开启PLL pll_wait_for_lock(0); //等待锁定 pmc_switch_mck_to_pllack(CONFIG_SYSCLK_PRES); // 更改mck至pllack } #endif 。。。。。。 经过上述的一系列设定后,系统的时钟最终选择如下图红线所示。
得到经锁相后的 频率=32.768khz*1465=48005.12khz=48Mhz 设定完时钟,sysclk_init()函数基本完成。 随后开始执行board_init()函数,该函数的详细代码见board_init.c,该代码可以根据定义的不同外设功能来配置IO口。 如定义了调试串口功能,如下的代码将被执行 。。。 #if defined (CONF_BOARD_UART_CONSOLE) /*Configure UART pins */ ioport_set_port_peripheral_mode(PINS_UART0_PORT,PINS_UART0, PINS_UART0_MASK); #endif 。。。 随后执行configure_console()配置调试串口, puts(STRING_HEADER)输出报文头, chipid_read(CHIPID, &g_chipid_data)根据CHIPID读取相关芯片信息放入g_chipid_data指向的内存, chipid_print(&g_chipid_data)输出芯片信息。 最后进入while(1)死循环。
|