本帖最后由 zhczlzhang 于 2022-7-16 21:42 编辑
实验现象:
当单片机接受到数据的时候,输出
环境搭建: keil的环境搭建大家都知道,我就不做过多解释,最主要的是我要讲一下为什么用keil。看过我上一篇的大家都知道,为了正版,我用的是vscode的开源软件来做开发,并花了不低的时间来调试,最终完成一次简单的点灯实验,但是中间踩的bug简直让人崩溃。
在实现了点灯程序并正常运行后,我本以为接下来就是一片坦途,但是在我接下来实现定时器串口接收数据的这个实验时,再次被bug击倒。我实现的代码在VSCODE上无论如何都运行不起来,环境变量设置好,头文件都包含好,最后我甚至采取了最简单的方式,只要能接受到数据就OK,但是不行,死活接受不了,鉴于vscode并不支持芯源的debug,使得我不得不一行行代码自查,但是代码我死活找不到问题,我怀疑是缺失了部分头文件,但是在我包含了所有官方提供的文件以及我所能找到的M0+架构的文件之后,程序还是没有运行起来。vscode没有提示,正常生成了hex文件。在花费了5天,每天从晚上9点开始搞到11点结束,花费10个工作时之后我不得不宣布放弃,长时间的钻研这个幽灵bug,实在是太折磨人了。继续下去,我肯定能解决这个问题,但是时间就不太保证了。所以为了效率,果断结束使用vscode来开发,后续如果有大神能接着使用vscode来开发,或者官方出教程,是最好的。
如果后续我有时间,空闲下来,我会接着使用vscode来开发,毕竟工作需要,碰见这个bug是肯定要解决的。
然后我转移到keil环境下之后,用时6分钟,实验完毕,实验结果如我所料,没有bug。一把辛酸泪,简直是从地狱模式转移到简单模式来。
原理图如下:
芯源的电路板上,并没有把串口与ch340连接起来,所以我们要飞线,把cn9的4个线都飞线接好,接到cn4的PA8,PA9上。
其中J24我们要把3.4短接,然后,我们就可以愉快的使用mini usb连接电脑来测试了。
在此吐槽一下,芯源能不能把mini usb换成type-c或micro usb,mini usb真是有点古老了。
代码讲解:
本次实验基于芯源的I:\芯源\CW32F030CxTx StartKit\cw32f030-stdperiph-lib\Examples\UART\UART_Interrupt实验,再次基础上进行了改造。
1:增加定时器功能
ATIM_InitStruct.BufferState = ENABLE; //使能缓存寄存器
ATIM_InitStruct.ClockSelect = ATIM_CLOCK_PCLK; //选择PCLK时钟计数
ATIM_InitStruct.CounterAlignedMode = ATIM_COUNT_MODE_EDGE_ALIGN; //边沿对齐
ATIM_InitStruct.CounterDirection = ATIM_COUNTING_UP; //向上计数;
ATIM_InitStruct.CounterOPMode = ATIM_OP_MODE_REPETITIVE; //连续运行模式
ATIM_InitStruct.OverFlowMask = DISABLE; // 重复计数器上溢出不屏蔽
ATIM_InitStruct.Prescaler = ATIM_Prescaler_DIV1; // 1分频
ATIM_InitStruct.ReloadValue = 9999; // 重载周期9999+1
ATIM_InitStruct.RepetitionCounter = 16; // 重复周期0
ATIM_InitStruct.UnderFlowMask = DISABLE; // 重复计数下溢出不屏蔽
ATIM_Init(&ATIM_InitStruct);
ATIM_ITConfig(ATIM_CR_IT_OVE, ENABLE); // 有重复计数器溢出产生进入中断
ATIM_Cmd(DISABLE);
定时器定时20ms,在初始化时关闭定时器。
void ATIM_IRQHandlerCallBack(void)
{
if (ATIM_GetITStatus(ATIM_IT_OVF))
{
ATIM_ClearITPendingBit(ATIM_IT_OVF);
Usart1_RxCompleted = 1;
ATIM_Cmd(DISABLE);
}
}
在定时中断里面置位Usart1_RxCompleted,表示当前定时器中断20ms无数据,清零并关闭定时器。
2:串口
串口基本没有大的改动,只是改变了串口中断函数。
void UART1_IRQHandler(void)
{
/* USER CODE BEGIN */
uint8_t TxRxBuffer;
if(USART_GetITStatus(CW_UART1, USART_IT_RC) != RESET)
{
Usart1_RxBuff[Usart1_RxCounter] = USART_ReceiveData_8bit(CW_UART1);
if(Usart1_RxCounter == 0){
ATIM_Cmd(ENABLE);
}else{
ATIM_SetReloadValue(0);
}
Usart1_RxCounter++;
// USART_SendData_8bit(CW_UART1, TxRxBuffer);
USART_ClearITPendingBit(CW_UART1, USART_IT_RC);
}
/* USER CODE END */
}
如果Usart1_RxCounter等于0,表示是接收的第1个数据,进入if分支,开启定时器,else分支,表示果Usart1_RxCounter不等于0,不是接收的第一个数据,每接收1个字节的数据,清零定时器重载值。Usart1_RxCounter加1,表示接收的数据总量+1。
再次吐槽,能不能提供一下固件库使用指南,或者在库函数中把每个函数都注释一下,讲解一下作用。部分函数什么注释都没有,纯靠猜。
编译并使用pwlink2下载程序。
可以在这里设置下载完成后自动启动程序。
实验现象:
总结:
没什么感想,就是换成keil之后,开发速度大增,各种debug,各种调试简直不要太好。但是我还要接着用vscode啊! 。
|