GD32串口接收字符串总结

GD32串口怎么接收字符串这个问题在之前困扰了我很长时间,可以通过轮询和中断两种方式,中断方式接收字符串目前还不知道怎么实现,轮询主要代码如下:

/*!
    \file  main.c
    \brief USART printf demo
*/

/*
    Copyright (C) 2017 GigaDevice

    2017-06-23, V1.0.0, demo for GD32F30x
*/

#include "gd32f30x.h"
#include "gd32f303c_eval.h"
#include "systick.h"
#include <stdio.h>
#include "gd32f30x_it.h"
#include "string.h"

uint16_t i;
float adc_value[16];
float vref_value[16];
uint16_t j;
void led_init(void);
void led_flash(int times);
void rcu_config(void);
void gpio_config(void);
void adc_config();
uint16_t adc_channel_sample(uint8_t channel);
unsigned char recv_cont=0;
unsigned char recvdata[5]={0};
		//	unsigned char i=0;

/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/

int main(void)
{
    /* initialize the LEDs */
    led_init();
    /* configure systick */
    systick_config();       //系统滴答定时器配置 
    
    /* flash the LEDs for 1 time */
    led_flash(1);
    
    /* configure EVAL_COM1 */
    gd_eval_com_init(EVAL_COM1); 

   rcu_config();
	 
	  gpio_config();
	
	  adc_config();
    /* configure WAKEUP key */
    gd_eval_key_init(KEY_WAKEUP, KEY_MODE_GPIO);
    
    /* output a message on hyperterminal using printf function */
    printf("\r\n USART receive example: please transmit a number \r\n");
    
    /* wait for completion of USART transmission */
		    adc_value[0]=adc_channel_sample(ADC_CHANNEL_0);
			  adc_value[1]=adc_channel_sample(ADC_CHANNEL_1);
        adc_value[2]=adc_channel_sample(ADC_CHANNEL_2);
        adc_value[3]=adc_channel_sample(ADC_CHANNEL_3);
        adc_value[4]=adc_channel_sample(ADC_CHANNEL_4);
			  adc_value[5]=adc_channel_sample(ADC_CHANNEL_5);
			  adc_value[6]=adc_channel_sample(ADC_CHANNEL_6);
			  adc_value[7]=adc_channel_sample(ADC_CHANNEL_7);
			  adc_value[8]=adc_channel_sample(ADC_CHANNEL_8);
			  adc_value[9]=adc_channel_sample(ADC_CHANNEL_9);
			  adc_value[10]=adc_channel_sample(ADC_CHANNEL_10);
			  adc_value[11]=adc_channel_sample(ADC_CHANNEL_11);
			  adc_value[12]=adc_channel_sample(ADC_CHANNEL_12);
			  adc_value[13]=adc_channel_sample(ADC_CHANNEL_13);
			  adc_value[14]=adc_channel_sample(ADC_CHANNEL_14);
			  adc_value[15]=adc_channel_sample(ADC_CHANNEL_15);
		while(1){
	
					for ( i =0;i<16;i++) {
			    vref_value[i]=adc_value[i]*3.3/4096;
					}
					//printf("请输入一个数\r\n");
					//scanf("%d\r\n",&j);
		   if(usart_flag_get(USART0,USART_FLAG_RBNE)==1)
		   {  
			 
			for(i=0;i<5;i++)
			{
				while(usart_flag_get(USART0,USART_FLAG_RBNE)==0);//等待接收
				recvdata[i]=usart_data_receive(USART0);//读取数据到数组
			}
	
			if(recvdata[0]=='A'&&recvdata[1]=='D'&&recvdata[2]=='C')
			{  
				switch((recvdata[3]-'0'))
				{
					case 0://0通道
					//ADC采集相应通道
					printf("ADC通道0的值是%5.3f\r\n",vref_value[0]);
					break;
					case 1://1通道
					//ADC采集相应通道
					printf("ADC通道1的值是%5.3f\r\n",vref_value[1]);
					break;
					//2通道
					//ADC采集相应通道
					case 2:
						//
					printf("ADC通道2的值是%5.3f\r\n",vref_value[2]);
					break;
					case 3:
					printf("ADC通道3的值是%5.3f\r\n",vref_value[3]);
					break;
          case 4:
					printf("ADC通道4的值是%5.3f\r\n",vref_value[4]);
					break;
          case 5:
					printf("ADC通道5的值是%5.3f\r\n",vref_value[5]);
					break;
          case 6:
					printf("ADC通道6的值是%5.3f\r\n",vref_value[6]);
					break;	
          case 7:
					printf("ADC通道7的值是%5.3f\r\n",vref_value[7]);
					break;
          case 8:
					printf("ADC通道8的值是%5.3f\r\n",vref_value[8]);
					break;	
          case 9:
					printf("ADC通道9的值是%5.3f\r\n",vref_value[9]);
					break;	
				}
			}
			
		
	}	
}
		}
void rcu_config(void)
{
    /* enable GPIOA clock */
    rcu_periph_clock_enable(RCU_GPIOA);
	  rcu_periph_clock_enable(RCU_GPIOB);
	  rcu_periph_clock_enable(RCU_GPIOC);
    /* enable ADC clock */
    rcu_periph_clock_enable(RCU_ADC0);
    /* config ADC clock */
    rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV6);
}

void gpio_config(void)
{
    /* config the GPIO as analog mode */
	  gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_10MHZ, GPIO_PIN_0);
    gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_10MHZ, GPIO_PIN_1);
    gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_10MHZ, GPIO_PIN_2);
    gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_10MHZ, GPIO_PIN_3);
    gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_10MHZ, GPIO_PIN_4);
	  gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_10MHZ, GPIO_PIN_5);
	  gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_10MHZ, GPIO_PIN_6);
	  gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_10MHZ, GPIO_PIN_7);
	  gpio_init(GPIOB, GPIO_MODE_AIN, GPIO_OSPEED_10MHZ, GPIO_PIN_0);
	  gpio_init(GPIOB, GPIO_MODE_AIN, GPIO_OSPEED_10MHZ, GPIO_PIN_1);
	  gpio_init(GPIOC, GPIO_MODE_AIN, GPIO_OSPEED_10MHZ, GPIO_PIN_0);
	  gpio_init(GPIOC, GPIO_MODE_AIN, GPIO_OSPEED_10MHZ, GPIO_PIN_1);
	  gpio_init(GPIOC, GPIO_MODE_AIN, GPIO_OSPEED_10MHZ, GPIO_PIN_2);
    gpio_init(GPIOC, GPIO_MODE_AIN, GPIO_OSPEED_10MHZ, GPIO_PIN_3);
	  gpio_init(GPIOC, GPIO_MODE_AIN, GPIO_OSPEED_10MHZ, GPIO_PIN_4);
	  gpio_init(GPIOC, GPIO_MODE_AIN, GPIO_OSPEED_10MHZ, GPIO_PIN_5);
	  
	  
}
void adc_config(void)
{
    /* ADC mode config */
    adc_mode_config(ADC_MODE_FREE);
    /* ADC data alignment config */
    adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
    /* ADC channel length config */
    adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1U);
    
    /* ADC trigger config */
    adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE); 
    /* ADC external trigger config */
    adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);

    /* enable ADC interface */
    adc_enable(ADC0);
    delay_1ms(1U);
    /* ADC calibration and reset calibration */
    adc_calibration_enable(ADC0);
}
uint16_t adc_channel_sample(uint8_t channel)
{
    /* ADC regular channel config */
    adc_regular_channel_config(ADC0, 0U, channel, ADC_SAMPLETIME_7POINT5);      //adc规则通道配置
    /* ADC software trigger enable */
    adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);                     //adc软件触发使能

    /* wait the end of conversion flag */
    while(!adc_flag_get(ADC0, ADC_FLAG_EOC));                              //等待转换完成标志
    /* clear the end of conversion flag */
    adc_flag_clear(ADC0, ADC_FLAG_EOC);                                     //清除转换完成标志
    /* return regular channel sample value */
    return (adc_regular_data_read(ADC0));                                    //返回规则通道样品值
}
/*!
    \brief      initialize the LEDs
    \param[in]  none
    \param[out] none
    \retval     none
*/
void led_init(void)
{
    gd_eval_led_init(LED2);
    gd_eval_led_init(LED3);
    gd_eval_led_init(LED4);
    gd_eval_led_init(LED5);
}

/*!
    \brief      flash the LEDs for test
    \param[in]  times: times to flash the LEDs
    \param[out] none
    \retval     none
*/
void led_flash(int times)
{
    int i;
    for(i=0; i<times; i++){
        /* delay 400 ms */
        delay_1ms(400);

        /* turn on LEDs */
        gd_eval_led_on(LED2);
        gd_eval_led_on(LED3);
        gd_eval_led_on(LED4);
        gd_eval_led_on(LED5);

        /* delay 400 ms */
        delay_1ms(400);
        /* turn off LEDs */
        gd_eval_led_off(LED2);
        gd_eval_led_off(LED3);
        gd_eval_led_off(LED4);
        gd_eval_led_off(LED5);
    }
}

/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
    usart_data_transmit(EVAL_COM1, (uint8_t)ch);
    while(RESET == usart_flag_get(EVAL_COM1, USART_FLAG_TBE));
    return ch;
}

GD32E230 C8T6是一款基于ARM Cortex-M4的微控制器,它支持多种中断功能,包括串口通信中断。在处理串口(UART)的数据接收时,你可以设置一个中断服务程序(ISR)来接收字符串。 首先,你需要配置串口的工作模式,通常选择异步模式,并设置适当的波特率、数据位数、停止位和奇偶校验。然后,在中断向量表中启用串口接收完成中断(例如USART_IRQHandler),并在对应的中断处理函数中实现以下步骤: 1. 检查中断标志寄存器(如USART_FLAG_RXNE),确认是否有新的接收数据可用。 2. 使用USART_Receive函数读取接收到的单个字符,将其存储到缓冲区或临时变量中。 3. 如果接收到的是'\0'(空字符),表示字符串结束,可以在这里处理字符串并返回。 4. 如果不是'\0',继续循环接收直到遇到该字符。 5. 确保在处理完中断后,清除接收完成标志(USART_ClearFlag(USARTx, USART_FLAG_RXNE)),以便下一次接收操作。 ```c void USART_IRQHandler(void) { if (USART_GetITStatus(USARTx, USART_IT_RXNE)) // x代表USARTx,即实际的USART模块 { char received_char = USART_Receive(USARTx); // 接收一个字符 // 将字符添加到缓冲区 buffer[index++] = received_char; // 检查是否达到字符串长度限制或接收到'\0' if (index == max_string_length || received_char == '\0') { // 处理接收到的完整字符串 process_received_string(buffer); index = 0; // 重置索引 USART_ClearITPendingBit(USARTx, USART_IT_RXNE); // 清除中断标志 } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值