【RISC-V MCU CH32V103测评】UART串行通讯
<p>CH32V103有3个串口,分别是USART1、USART2及USART3,所占用的引脚如下:</p><p>USART1 TX-->A.9 RX-->A.10</p>
<p>USART2 TX-->A.2 RX-->A.3</p>
<p>USART3 TX-->B.10 RX-->B.11</p>
<p>在通常的情况下,USART1作调试信息输出口,其它2个串口作通讯功能用。</p>
<p>此外,在使用过程它又分为以查询方式接受和以中断方式接收。</p>
<p>最近在一个朋友的项目中要用到3个串行口,且需要以中断方式进行接收,为此打算以CH32V103来解决它。</p>
<p>作为中断方式接收在例程中有使用2个串口的示例,因此关键的是解决第3个串口的中断接收问题,也就是解决USART1中断接收的问题。</p>
<p>经过努力,该问题得到了较好地解决,其测试连接和效果如图1至图3所示。</p>
<p></p>
<p>图1 测试线路连接</p>
<p> </p>
<p></p>
<p>图2 双串口通信测试</p>
<p> </p>
<p></p>
<p>图3 UART1中断接收测试</p>
<p> </p>
<p>3个串口的中断接收初始化函数为:</p>
<div aria-label="代码段 小部件" contenteditable="false" role="region" tabindex="-1">
<pre data-widget="codesnippet">
<code class="hljs language-cpp"><span class="hljs-keyword">void</span> USART_Printf_Init(uint32_t baudrate)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
<span class="hljs-preprocessor">#if (DEBUG == DEBUG_UART1)</span>
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
<span class="hljs-preprocessor">#elif (DEBUG == DEBUG_UART2)</span>
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
<span class="hljs-preprocessor">#elif (DEBUG == DEBUG_UART3)</span>
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
<span class="hljs-preprocessor">#endif</span>
USART_InitStructure.USART_BaudRate = baudrate;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx;
<span class="hljs-preprocessor">#if (DEBUG == DEBUG_UART1)</span>
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
<span class="hljs-preprocessor">#elif (DEBUG == DEBUG_UART2)</span>
USART_Init(USART2, &USART_InitStructure);
USART_Cmd(USART2, ENABLE);
<span class="hljs-preprocessor">#elif (DEBUG == DEBUG_UART3)</span>
USART_Init(USART3, &USART_InitStructure);
USART_Cmd(USART3, ENABLE);
<span class="hljs-preprocessor">#endif</span>
}</code></pre>
<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" /><span style="background: url("https://bbs.eeworld.com.cn/static/editor/plugins/widget/images/handle.png") rgba(220, 220, 220, 0.5); top: -15px; left: 0px; display: block;"><img height="15" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" /></span></div>
<p>3个串口的中断接收引脚配置化函数为:</p>
<div aria-label="代码段 小部件" contenteditable="false" role="region" tabindex="-1">
<pre data-widget="codesnippet">
<code class="hljs language-cpp"><span class="hljs-keyword">void</span> USARTx_CFG(<span class="hljs-keyword">void</span>)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2|RCC_APB1Periph_USART3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB , ENABLE);
<span class="hljs-comment">/* USART1 TX-->A.9 RX-->A.10 */</span>
<span class="hljs-comment">//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;</span>
<span class="hljs-comment">//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;</span>
<span class="hljs-comment">//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;</span>
<span class="hljs-comment">//GPIO_Init(GPIOA, &GPIO_InitStructure);</span>
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
<span class="hljs-comment">/* USART2 TX-->A.2 RX-->A.3 */</span>
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
<span class="hljs-comment">/* USART3 TX-->B.10 RX-->B.11 */</span>
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = <span class="hljs-number">115200</span>;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART1, &USART_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_Init(USART2, &USART_InitStructure);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
USART_Init(USART3, &USART_InitStructure);
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=<span class="hljs-number">0</span>;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = <span class="hljs-number">0</span>;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=<span class="hljs-number">1</span>;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = <span class="hljs-number">1</span>;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=<span class="hljs-number">2</span>;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = <span class="hljs-number">2</span>;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd(USART1, ENABLE);
USART_Cmd(USART2, ENABLE);
USART_Cmd(USART3, ENABLE);
}
</code></pre>
<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" /><span style="background: url("https://bbs.eeworld.com.cn/static/editor/plugins/widget/images/handle.png") rgba(220, 220, 220, 0.5); top: -15px; left: 0px; display: block;"><img height="15" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" /></span></div>
<p>主程序的内容为:</p>
<pre>
<code class="language-cpp">int main(void)
{
uint8_t i;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
Delay_Init();
USART_Printf_Init(115200);//115200
printf("SystemClk:%d\r\n",SystemCoreClock);
printf("USART Interrupt TEST! \r\n");
USARTx_CFG();
Rxfinish0=0;
while(1)
{
if(Rxfinish0==1)
{
Rxfinish0=0;
TxCnt0=0;
while(TxCnt0<10)
{
USART_SendData(USART1, RxBuffer0);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
RxCnt0=0;
//USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}
}
}
</code></pre>
<p> </p>
<p>串口的设置应该都是一样的吧,抄来改改就好了。</p>
freebsder 发表于 2021-2-25 22:30
串口的设置应该都是一样的吧,抄来改改就好了。
<p>但必须去实践和测试!</p>
页:
[1]