这篇学习笔记仅围绕ATMEL官方提供的例程,做板卡功能测试,感兴趣的可以看一下。 拿到板卡第一件事情就是上电,测试功能,但是除了按键按下相应指示灯点亮,没有发现大家分享的串口终端打印的一些消息。 今天早上仔细过官方实例程序后,恍然大悟,程序有2种模式,一种是execute_demo_mode,另一种是execute_terminal_mode; 第一种execute_demo_mode,在上电后什么都不做进入的该模式,只初始化IO端口、触摸和中断功能; 第二种execute_terminal_mode,上电后按下SW1键和RESET键,松开RESET键,进入该模式,通过程序可以看到该模式有IO、串口、AD、中断初始化,进入该模式4个指示灯LED0-LED3闪烁,打开串口终端或串口调试助手(串口波特率为57600)后屏幕显示以下信息: 输入相应功能,屏幕会打印出相关信息,如下: 官方实例程序主函数部分代码如下: int main(void) { #if defined(__GNUC__ ) /* Setup stdout to point to the correctusart (USART1). This is needed to *use the fdev_setup_stream() macro in GCC. */ stdout = &usart1_str; #endif // Make sure to use lowest possible powerconsumption power_reduction_enable(); // Enter terminal mode if SW1 is pressed,按下SW1进入终端模式 if (!(PINB & (1 << PORTB1))) { execute_terminal_mode(); } else { execute_demo_mode(); } } Demo_mode模式代码如下: static voidexecute_demo_mode(void) { // Status flags to indicate the re-burstfor touch library uint16_t status_flag = 0; uint16_t burst_flag = 0; io_init_demo_mode(); touch_init(); sei(); while (1) { if (time_to_measure_touch) { time_to_measure_touch =false; MCUCR |= (1 << PUD); do { // One time measuretouch sensors status_flag =qt_measure_sensors(current_time_ms_touch); burst_flag =status_flag & QTLIB_BURST_AGAIN; if (QT_KEY_DETECT()){ PORTB &=~(1 << PORTB3); } else { PORTB |= (1<< PORTB3); } } while (burst_flag); MCUCR &= ~(1 << PUD); } if (!(PINB & (1 <<PINB0))) { // Turn LED0 on to indicateactive mode DDRB |= (1 << DDB3) |(1 << DDB0); DDRB &= ~((1 <<DDB2) | (1 << DDB1)); PORTB &= ~(1 <<PORTB0); PORTB |= (1 <<PORTB2) | (1 << PORTB1); } if (!(PINB & (1 <<PINB1))){ // Turn LED2 on to indicatepower-save mode DDRB |= (1 << DDB3) |(1 << DDB1); DDRB &= ~((1 <<DDB2) | (1 << DDB0)); PORTB &= ~(1 <<PORTB1); PORTB |= (1 <<PORTB2) | (1 << PORTB0); /* * Start asynchronous clocking of Timer/Counter2 using * 32.768kHz crystal as clock source. */ start32crystal(); enter_sleep(POWER_SAVE); stop32crystal(); } if (!(PINB & (1 <<PINB2))) { // Turn LED3 on to indicatepower-down mode DDRB |= (1 << DDB3) |(1 << DDB2); DDRB &= ~(1 <<DDB1) & ~(1 << DDB0); PORTB &= ~(1 <<PORTB2); PORTB |= (1 <<PORTB1) | (1 << PORTB0); enter_sleep(POWER_DOWN); } if (!(PINB & (1 <<PINB6))) { // Disable pinchangeinterrupts (SW0:2) PCICR = (0 << PCIE1); adc_init(); timer1_lightdemo_init(); // Enable output for LEDcontrol of LED0:3 DDRB |= (1 << DDB3) |(1 << DDB2) | (1 << DDB1) | (1 << DDB0); // Run light sensor demo aslong as PORTB6 is pulled low while (!(PINB & (1<< PINB6))) { /* * Update compare B value to adjust PWMaccording * to light sensor value */ OCR1B =read_adc(LIGHT_SENSOR); } stop_timer1_lightdemo(); // Set back to input fordemo mode DDRB &= ~(1 <<DDB2) & ~(1 << DDB1) & ~(1 << DDB0); touch_init(); // Clear Pin ChangeInterrupt flag 1 PCIFR= (1 << PCIF1); // Enable pinchangeinterrupts (SW0:2) PCICR = (1 << PCIE1); } } } 终端模式代码如下: static voidexecute_terminal_mode(void) { // Variable used for USART communication uint8_t data = 0; // Command buffer pointer used for USARTcommunication uint8_t cmd_buf_ptr = 0; // Command buffer used for USARTcommunication char cmd_buffer[MAX_CMD_BUFFER_LEN]; // misc initialization io_init_terminal_mode(); usart1_init(); adc_init(); // Enable interrupts sei(); flash_leds(20); //进入该模式后,指示灯闪烁 print_help(); //串口输出显示信息 printf(CMD_PROMPT); //串口输出命令符 while (1) { // Read and handle incomming dataon usart1 data = usart1_getchar(); //获取串口输入字符 switch (data) { case ASCII_CR: if (cmd_buf_ptr > 0) { usart1_putchar('\n'); cmd_buffer[cmd_buf_ptr]= '\0'; process_command(cmd_buffer); cmd_buf_ptr = 0; } printf(CMD_PROMPT); break; case ASCII_BACKSPACE: if (cmd_buf_ptr == 0) { break; } printf("\b \b"); cmd_buf_ptr--; break; default: if (cmd_buf_ptr >=MAX_CMD_BUFFER_LEN || data < ASCII_SPACE ) { // Break if commandstring is too long/ignore non-printable characters break; } cmd_buffer[cmd_buf_ptr++] =data; usart1_putchar(data); break; } } } 关于IO、串口、AD、中断初始化程序在init.c文件,官方例程蛮有学习意义的,建议大家仔细看一下,官方例程见附件:
AVR370_MEGA_1284P_Xplained_Example_Application.zip
(830.76 KB, 下载次数: 13)
|