[单片机芯片] 沁恒CH32V103 MCU的实际应用与代码实现

[复制链接]
3067|9
 楼主| 万图 发表于 2024-10-9 08:30 | 显示全部楼层 |阅读模式
沁恒电子的CH32V103 MCU因其高性能和低功耗在嵌入式应用中占据了重要位置,尤其是对于物联网、工业自动化等应用领域,CH32V103提供了足够的计算能力和丰富的外设接口。它基于RISC-V架构,具有开放性和灵活性,能够支持广泛的开发工具和应用场景。本文将介绍如何在实际项目中使用CH32V103 MCU,并通过代码实例展示其GPIO控制、ADC采集和UART通信的应用。

CH32V103简介CH32V103 MCU是一款基于RISC-V内核的32位低功耗微控制器,工作频率高达72MHz,拥有丰富的外设资源,如GPIO、USART、I2C、SPI、ADC、PWM等,且支持低功耗模式,非常适合用于需要高效数据处理的项目。其开发工具链也很完善,支持Keil、IAR和开放的RISC-V开发环境。

项目配置
  • 开发环境:Keil MDK
  • 芯片型号:CH32V103C8T6
  • 使用外设:GPIO、ADC、USART
  • 功能目标:实现基本的按键输入、LED控制、传感器数据采集以及串口通信功能

代码实现以下是基于CH32V103的代码示例,主要涉及GPIO初始化、ADC配置和UART串口通信的实现。
1. 系统初始化与外设配置
  1. #include "ch32v10x.h"

  2. void System_Init(void);
  3. void GPIO_Init(void);
  4. void ADC_Init(void);
  5. void UART_Init(void);

  6. int main(void) {
  7.     System_Init();
  8.     GPIO_Init();
  9.     ADC_Init();
  10.     UART_Init();

  11.     uint16_t adc_value;

  12.     while(1) {
  13.         // 获取ADC的模拟输入数据
  14.         ADC_SoftwareStartConvCmd(ADC1, ENABLE);
  15.         while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
  16.         adc_value = ADC_GetConversionValue(ADC1);

  17.         // 通过UART发送ADC数据
  18.         char buffer[20];
  19.         sprintf(buffer, "ADC Value: %d\n", adc_value);
  20.         USART_SendString(USART1, buffer);

  21.         // 按键按下时点亮LED
  22.         if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0) {
  23.             GPIO_SetBits(GPIOC, GPIO_Pin_13);
  24.         } else {
  25.             GPIO_ResetBits(GPIOC, GPIO_Pin_13);
  26.         }
  27.         Delay(500); // 延时500ms
  28.     }
  29. }

  30. void System_Init(void) {
  31.     SystemCoreClockUpdate(); // 更新系统时钟
  32. }

  33. void GPIO_Init(void) {
  34.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);

  35.     GPIO_InitTypeDef GPIO_InitStructure;

  36.     // 配置LED引脚(PC13)
  37.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
  38.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  39.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  40.     GPIO_Init(GPIOC, &GPIO_InitStructure);

  41.     // 配置按键引脚(PA0)
  42.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  43.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 输入上拉
  44.     GPIO_Init(GPIOA, &GPIO_InitStructure);
  45. }

  46. void ADC_Init(void) {
  47.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

  48.     ADC_InitTypeDef ADC_InitStructure;
  49.     ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  50.     ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  51.     ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  52.     ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  53.     ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  54.     ADC_InitStructure.ADC_NbrOfChannel = 1;
  55.     ADC_Init(ADC1, &ADC_InitStructure);

  56.     // 配置ADC通道
  57.     ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);

  58.     // 开启ADC
  59.     ADC_Cmd(ADC1, ENABLE);
  60. }

  61. void UART_Init(void) {
  62.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

  63.     GPIO_InitTypeDef GPIO_InitStructure;
  64.     USART_InitTypeDef USART_InitStructure;

  65.     // 配置PA9 (USART1 TX)
  66.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  67.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  68.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  69.     GPIO_Init(GPIOA, &GPIO_InitStructure);

  70.     // 配置PA10 (USART1 RX)
  71.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  72.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  73.     GPIO_Init(GPIOA, &GPIO_InitStructure);

  74.     // USART初始化配置
  75.     USART_InitStructure.USART_BaudRate = 115200;
  76.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  77.     USART_InitStructure.USART_StopBits = USART_StopBits_1;
  78.     USART_InitStructure.USART_Parity = USART_Parity_No;
  79.     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  80.     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  81.     USART_Init(USART1, &USART_InitStructure);

  82.     USART_Cmd(USART1, ENABLE); // 使能USART1
  83. }

  84. void USART_SendString(USART_TypeDef* USARTx, char* str) {
  85.     while (*str) {
  86.         USART_SendData(USARTx, *str++);
  87.         while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
  88.     }
  89. }

  90. void Delay(uint32_t time) {
  91.     while (time--) {
  92.         __NOP(); // 空操作,作为延时
  93.     }
  94. }

代码分析
  • 系统初始化:System_Init函数用于配置MCU的时钟系统,并确保所有外设时钟正常工作。
  • GPIO配置:GPIO引脚分别用于LED控制和按键输入,其中PA0连接按键,PC13连接LED。
  • ADC配置:ADC1配置为单通道连续采样模式,用于采集模拟信号,采样结果通过UART发送至主机。
  • UART通信:USART1用于串口通信,波特率设置为115200,配合使用串口助手可以接收到MCU发送的ADC数据。

项目扩展CH32V103系列MCU的强大功能不仅限于GPIO控制、ADC采集和UART通信,还可以通过其丰富的外设接口扩展更多功能:
  • I2C接口:与外部传感器模块或EEPROM通信,获取环境数据或存储配置信息。
  • SPI接口:用于高速数据传输,例如与显示屏或Flash存储器进行数据交互。
  • PWM控制:生成精确的PWM波形,用于电机控制、LED亮度调节等应用。
  • 低功耗模式:通过配置低功耗模式,可在不需要连续工作的场合延长电池供电设备的使用寿命。

总结本文通过代码实例展示了沁恒CH32V103 MCU在嵌入式系统中的应用,结合GPIO、ADC和UART外设,实现了简单的按键检测、LED控制和传感器数据采集与通信。该MCU具有高效、低功耗的特点,适用于物联网、工业自动化等多个领域。通过CH32V103丰富的外设接口和开放的开发环境,开发者可以轻松实现复杂的嵌入式系统设计。


周半梅 发表于 2024-10-9 08:31 | 显示全部楼层
这个ADC采样速率怎么样?够用不?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

179

主题

6271

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部