AT32L021单片机自身提供了两组SPI外设,本打算使用其中一组用来驱动一个2.0寸的TFT显示屏。
但由于接口中还存在其它控制线,诸如DC、RST、BL等,为了稳妥起见,打算先使用软件模拟方式完成驱动。整个程序依旧在使用ti_fullduplex_dma例程的基础上进行修改。测试中没有使用显示屏上的中文字库,所以接口中的SDO(相当于SPI接口中的MISO)就没有使用。这块SPI显示屏和开发板的连接如下:
开发板
| 显示屏
| 引脚功能
| PA1
| RST
| 硬件复位显示屏
0有效
| PA2
| DC
| 命令寄存器/数据寄存器选择
命令寄存器
数据寄存器
| PA3
| BL
| 显示屏背景灯
1有效,打开背景灯
| PA4
| CS
| 片选择,0有效
写入数据或者指令时,需要提前设置为0
| PA5
| SCK
| SPI通讯时钟
| PA7
| MOSI
| 输出给显示屏的数据
|
#define TFT_PORT GPIOA
#define TFT_PORT_PERIPH_CLOCK CRM_GPIOA_PERIPH_CLOCK
#define TFT_RST_PIN GPIO_PINS_1
#define TFT_DC_PIN GPIO_PINS_2
#define TFT_BL_PIN GPIO_PINS_3
#define TFT_CS_PIN GPIO_PINS_4
#define TFT_SCK_PIN GPIO_PINS_5
#define TFT_MISO_PIN GPIO_PINS_6
#define TFT_MOSI_PIN GPIO_PINS_7
主程序中的处理的代码如下:
int main(void) {
uint32_t cnt=0;
system_clock_config(); // 配置系统时钟
at32_board_init(); // 板级初始化
uart_print_init(115200);
delay_us(100); // 延迟
TFT_Init();
TFT_Clear(BLACK);
TFT_ShowString(0, 0, 16, "Hello 21ic & Artery" , 0);
while(cnt<10) {
cnt++;
TFT_ShowNum(0, 16, cnt, 8 , 16);
}
while(1) {
gpio_bits_toggle(TFT_PORT, TFT_SCK_PIN);
}
}
在完成初始化后,显示一段字符串,以及变化的数据。然后利用死循环检测GPIO口翻转的速度。测试结果:
之所以追加第二部分循环的处理,本来是为了看看在模拟方式下驱动SPI驱动显示屏时,能快到什么程度,能不能接近使用SPI外设方式驱动的速度,结果最后被用来测试AT32L021单片机的超频了。按照说明书,AT32L021的最高工作主频是80MHz,这一点在雅特力提供的设计工具WorkBench上可以得到证明,如下图,当做主频设置超过80MHz的时候,显示出红色“X”,标明已经是错误了。
事实上在选择AT32L021单片机时,工具已经做出了限制,
在这个错误的方式下,是没有办法得到系统时钟的设置代码的,会提示
于是我在设置为80MHz时得到代码样本
将这段代码替换到例程中设置系统时钟的代码中,然后修改倍频设置,将20倍频逐步提高,最终提高到35倍时,编译后的程序,才无法被正常执行。
函数system_clock_config中,倍频设置部分的代码的测试经历
/* config pll clock resource */
//crm_pll_config(CRM_PLL_SOURCE_HICK, CRM_PLL_MULT_20); // 80MHz,systick=10MHz OK
//crm_pll_config(CRM_PLL_SOURCE_HICK, CRM_PLL_MULT_25); // 100MHz,systick=12.5MHz OK
//crm_pll_config(CRM_PLL_SOURCE_HICK, CRM_PLL_MULT_30); // 120MHz,systick=15MHz OK
//crm_pll_config(CRM_PLL_SOURCE_HICK, CRM_PLL_MULT_32); // 128MHz,systick=16MHz OK
//crm_pll_config(CRM_PLL_SOURCE_HICK, CRM_PLL_MULT_33); // 132MHz,systick=16.5MHz OK
crm_pll_config(CRM_PLL_SOURCE_HICK, CRM_PLL_MULT_34); // 136MHz,systick=17MHz OK
//crm_pll_config(CRM_PLL_SOURCE_HICK, CRM_PLL_MULT_35); // 140MHz,systick=17MHz NG
因此这块开发板在以能正常驱动显示屏的前提下,显示可以被超频到136MHz,比手册规定的设置,足足提高了70%,表现十分惊异啊。下图是在132MHz下经过逻辑分析仪检测的结果:
约771ms之前是复位显示屏、驱动显示字符串以及变换的数字的波形;约771ms之后是单纯测试GPIO口翻转速度的波形。
在132MHz主频下,模拟SPI的时钟周期是260ns,GPIO口的翻转周期是140ns。在136MHz下,模拟SPI的时钟周期也依旧是260ns(估计是已经超出我的逻辑分析仪的检测能力了)。
按照260ns计算,在这种超频状态下,软件模拟SPI的通讯速度可以达到3.8MHz(按位计算的)。
这个超频的处理,在使用原来例程中的主频设置中,
/* reset crm */
crm_reset();
/* config flash psr register */
flash_psr_set(FLASH_WAIT_CYCLE_2);
/* enable pwc periph clock */
crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);
/* config ldo voltage */
pwc_ldo_output_voltage_set(PWC_LDO_OUTPUT_1V2);
crm_clock_source_enable(CRM_CLOCK_SOURCE_HEXT, TRUE);
/* wait till hext is ready */
while(crm_hext_stable_wait() == ERROR)
{
}
/* config pll clock resource */
//crm_pll_config(CRM_PLL_SOURCE_HEXT, CRM_PLL_MULT_10); // 80MHz
//crm_pll_config(CRM_PLL_SOURCE_HEXT, CRM_PLL_MULT_12); // 96MHz OK 可以运行 100nS
//crm_pll_config(CRM_PLL_SOURCE_HEXT, CRM_PLL_MULT_15); // 120MHz OK 可以运行 80nS
crm_pll_config(CRM_PLL_SOURCE_HEXT, CRM_PLL_MULT_17); // 136MHz OK 可以运行
//crm_pll_config(CRM_PLL_SOURCE_HEXT, CRM_PLL_MULT_18); // 144MHz 不能运行
/* enable pll */
crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE);
/* wait till pll is ready */
while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET)
{
}
/* config ahbclk */
crm_ahb_div_set(CRM_AHB_DIV_1);
/* config apb2clk, the maximum frequency of APB1/APB2 clock is 80 MHz */
crm_apb2_div_set(CRM_APB2_DIV_1);
/* config apb1clk, the maximum frequency of APB1/APB2 clock is 80 MHz */
crm_apb1_div_set(CRM_APB1_DIV_1);
/* select pll as system clock source */
crm_sysclk_switch(CRM_SCLK_PLL);
/* wait till pll is used as system clock source */
while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL)
{
}
/* update system_core_clock global variable */
system_core_clock_update();
最高是可以使用17倍倍频的,和前面的测试结果是一致的。
以前,经常有人乐忠于对计算机的CPU进行超频,但无论怎么超频,也没有我这次对AT32L021的超频这么抢眼。AT32L021的表现超乎想象,看来手册标记的最高工作主频的上限是有点保守了。
|