【GD32VW553-EVAL试用评测】UASRT串口例程学习
<p>GD32VW553-EVAL学习笔记(四)</p><p><strong>简介</strong></p>
<p> </p>
<p> </p>
<p><strong>模块内部框图</strong></p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p><strong>1、查看最简单的串口打印例程</strong></p>
<p>首先导入例程至gd32eclipse</p>
<p>右键build project</p>
<p> </p>
<p>在项目目录下找到生成的bin文件</p>
<p> </p>
<p>使用 GD_LINK_CLI.exe 工具进行烧录</p>
<p> </p>
<p>运行结果:USART 将输出“please press the Tamper key”到超级终端。按下按键Tamper 键,串口继续输出“USART printf example”。</p>
<p> </p>
<p>查看代码结构</p>
<pre>
<code class="language-cpp">int main(void)
{
systick_config();
/* initialize test status LED */
test_status_led_init();
/* flash LED for test */
flash_led(2);
/* test key initialize */
test_key_init();
/* USART initialize */
gd_eval_com_init(EVAL_COM0);
/* output a message on hyperterminal using printf function */
printf("\n\rplease press the Tamper/Wakeup Key\n\r");
/* the software must wait until TC=1. the TC flag remains cleared during all data
transfers and it is set by hardware at the last frame end of transmission */
while(RESET == usart_flag_get(EVAL_COM0 , USART_FLAG_TC));
while(1){
if(0 == gd_eval_key_state_get(KEY_TAMPER_WAKEUP)){
delay_1ms(50);
if(0 == gd_eval_key_state_get(KEY_TAMPER_WAKEUP)){
delay_1ms(50);
if(0 == gd_eval_key_state_get(KEY_TAMPER_WAKEUP)){
/* turn on LED1 */
gd_eval_led_on(LED1);
delay_1ms(200);
/* output a message on hyperterminal using printf function */
printf("\n\rUSART printf example \n\r");
/* the software must wait until TC=1. the TC flag remains cleared during all data
transfers and it is set by hardware at the last frames end of transmission */
while(RESET == usart_flag_get(USART0 , USART_FLAG_TC));
/* wait until the button is released */
while(0 == gd_eval_key_state_get(KEY_TAMPER_WAKEUP));
}else{
/* turn off LED1 */
gd_eval_led_off(LED1);
}
}else{
/* turn off LED1 */
gd_eval_led_off(LED1);
}
}else{
/* turn off LED1 */
gd_eval_led_off(LED1);
}
}
}</code></pre>
<p>gd_eval_key_state_get(KEY_TAMPER_WAKEUP)方法检测按键状态,延迟50ms按键消抖,连续检测三次以确保按键按下有效。</p>
<p>如果检测为有效,则打开 LED1 (gd_eval_led_on(LED1)),延时 200 毫秒。</p>
<p>再次向上位机输出信息,表明这是一个 USART 打印示例。</p>
<p>等待串口数据发送完成 (while(RESET == usart_flag_get(USART0 , USART_FLAG_TC)))。</p>
<p>循环等待按键松开 (while(0 == gd_eval_key_state_get(KEY_TAMPER_WAKEUP)))</p>
<p>如果按键未检测有效LED1就会熄灭。</p>
<p> </p>
<p><strong>2、按键中断USART</strong><br />
烧录例程</p>
<p>运行结果:首先,所有灯亮灭一次用于测试。然后USART0 将输出数组tx_buffer 的内容(从0x00 到0xFF)<br />
到支持hex 格式的超级终端并等待接收由超级终端发送的BUFFER_SIZE 个字节的数据。MCU<br />
将接收到的超级终端发来的数据存放在数组rx_buffer 中。在发送和接收完成后,将比较<br />
tx_buffer 和rx_buffer 的值,如果结果相同,LED1,LED2 点亮,LED3 灭;如果结果不相同,<br />
LED3 点亮,LED1,LED2 灭。</p>
<p>这是串口的自发自收嘛</p>
<p>显示十六进制</p>
<p> </p>
<p>代码先初始化 LED 和串口,然后发送一组数据到串口。接着,程序等待接收数据并将其与发送的数据进行比较。如果数据传输成功,则程序会打开 LED1 和 LED2,关闭 LED3;如果数据传输失败,则程序会关闭 LED1 和 LED2,打开 LED3。最后,程序进入一个死循环,等待用户操作。</p>
<p>主程序</p>
<pre>
<code class="language-cpp">int main(void)
{
/* initialize the LEDs */
led_init();
/* USART interrupt configuration */
eclic_irq_enable(USART0_IRQn, 1, 0);
systick_config();
/* flash the LEDs for 1 time */
led_flash(1);
/* initialize the USART */
gd_eval_com_init(EVAL_COM0);
/* enable USART TBE interrupt */
usart_interrupt_enable(EVAL_COM0, USART_INT_TBE);
/* wait until USART send the tx_buffer */
while(tx_count < tx_buffer_size);
while(RESET == usart_flag_get(EVAL_COM0, USART_FLAG_TC));
/* enable USART RBNE interrupt */
usart_interrupt_enable(EVAL_COM0, USART_INT_RBNE);
/* wait until USART receive the rx_buffer */
while(rx_count < rx_buffer_size);
/* compare the transmitted buffer and the received buffer */
transfer_result = memory_compare(tx_buffer, rx_buffer, BUFFER_SIZE);
if (SUCCESS == transfer_result){
/* if success, turn on LED1 and LED2, turn off LED3*/
gd_eval_led_on(LED1);
gd_eval_led_on(LED2);
gd_eval_led_off(LED3);
}else{
/* if not, turn off LED1 and LED2, turn on LED3*/
gd_eval_led_off(LED1);
gd_eval_led_off(LED2);
gd_eval_led_on(LED3);
}
while(1){
}
}</code></pre>
<p>内存比较</p>
<pre>
<code class="language-cpp">ErrStatus memory_compare(uint8_t* src, uint8_t* dst, uint16_t length)
{
while (length--){
if (*src++ != *dst++){
return ERROR;
}
}
return SUCCESS;
}</code></pre>
<p><strong>3、使用串口DMA功能发送和接收</strong></p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p>烧录相关代码</p>
<p>功能和前面接收发送差不多,但使用DMA功能</p>
<p> </p>
<p>具体过程:</p>
<ol data-sourcepos="5:1-13:17">
<li data-sourcepos="5:1-5:15">初始化 LED 和串口。</li>
<li data-sourcepos="6:1-6:14">配置 DMA 控制器。</li>
<li data-sourcepos="7:1-7:22">配置 USART 发送和接收 DMA。</li>
<li data-sourcepos="8:1-8:18">等待 DMA 发送和接收完成。</li>
<li data-sourcepos="9:1-9:13">比较发送和接收数据。</li>
<li data-sourcepos="10:1-12:36">根据比较结果控制 LED:
<ul data-sourcepos="11:5-12:36">
<li data-sourcepos="11:5-11:36">数据传输成功:打开 LED1 和 LED2,关闭 LED3。</li>
<li data-sourcepos="12:5-12:36">数据传输失败:关闭 LED1 和 LED2,打开 LED3。</li>
</ul>
</li>
<li data-sourcepos="13:1-13:17">进入无限循环,等待用户操作。</li>
</ol>
<pre>
<code class="language-cpp">int main(void)
{
/* initialize the LEDs */
led_init();
systick_config();
/* flash the LEDs for 3 times */
led_flash(3);
/* initialize the USART */
gd_eval_com_init(EVAL_COM0);
/* configure USART DMA */
dma_config();
/* USART DMA enable for transmission and reception */
usart_dma_transmit_config(EVAL_COM0, USART_TRANSMIT_DMA_ENABLE);
usart_dma_receive_config(EVAL_COM0, USART_RECEIVE_DMA_ENABLE);
/* wait DMA channel7 transfer complete */
while(RESET == dma_flag_get(DMA_CH7, DMA_FLAG_FTF));
/* wait DMA channel2 receive complete */
while(RESET == dma_flag_get(DMA_CH2, DMA_FLAG_FTF));
/* compare the transmitted buffer and the received buffer */
transfer_result = memory_compare(tx_buffer, rx_buffer, BUFFER_SIZE);
if (SUCCESS == transfer_result){
/* if success, turn on LED1 and LED2, turn off LED3 */
gd_eval_led_on(LED1);
gd_eval_led_on(LED2);
gd_eval_led_off(LED3);
}else{
/* if not, turn off LED1 and LED2, turn on LED3 */
gd_eval_led_off(LED1);
gd_eval_led_off(LED2);
gd_eval_led_on(LED3);
}
while(1){
}
}</code></pre>
<p>DMA配置</p>
<pre>
<code class="language-cpp">void dma_config(void)
{
dma_single_data_parameter_struct dma_init_struct;
/* enable the DMA clock */
rcu_periph_clock_enable(RCU_DMA);
/* configure the DMA channe7 */
dma_deinit(DMA_CH7);
dma_single_data_para_struct_init(&dma_init_struct);
dma_init_struct.direction = DMA_MEMORY_TO_PERIPH;
dma_init_struct.memory0_addr = (uint32_t)tx_buffer;
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_init_struct.periph_memory_width = DMA_MEMORY_WIDTH_8BIT;
dma_init_struct.number = BUFFER_SIZE;
dma_init_struct.periph_addr = USART0_TDATA_ADDRESS;
dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
dma_single_data_mode_init(DMA_CH7, &dma_init_struct);
dma_channel_subperipheral_select(DMA_CH7, DMA_SUBPERI4);
dma_circulation_disable(DMA_CH7);
/* enable DMA channel7 */
dma_channel_enable(DMA_CH7);
/* configure the DMA channel2 */
dma_deinit(DMA_CH2);
dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
dma_init_struct.memory0_addr = (uint32_t)rx_buffer;
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_init_struct.periph_memory_width = DMA_MEMORY_WIDTH_8BIT;
dma_init_struct.number = BUFFER_SIZE;
dma_init_struct.periph_addr = USART0_RDATA_ADDRESS;
dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
dma_single_data_mode_init(DMA_CH2, &dma_init_struct);
dma_channel_subperipheral_select(DMA_CH2, DMA_SUBPERI4);
dma_circulation_disable(DMA_CH2);
/* enable DMA channel2 */
dma_channel_enable(DMA_CH2);
}</code></pre>
<p> </p>
发送一组数据到串口。接着,程序等待接收数据并将其与发送的数据进行比较
页:
[1]