项目来源
协会和武汉芯源公司合作开展的对CW32进行的讲座和宣传活动,作为乙方会针对CW32系列进行教学,并最终完成一系列开源项目
最终成果
完成若干CW32的小项目,包括但不限于流水灯、温湿度传感器、OLED屏幕等外设的教学,以及单片机原理:GPIO配置、定时器、中断、I2C、SPI等等原理和使用方法。并且针对4月份的船模比赛,完成一套完成的船模控制器系统。
目前计划
逐步在bbs进行简单外设的教学,在4月前完成对协会的船模控制器的讲座和硬件制作教学
这次一定不咕咕咕
这次一定不咕咕咕
CW32的package导入
先把芯源官网贴出来芯源官网,在官网的产品中心找到MCU,然后打开Cortex-M0系列,并选择CW32F030C8,这里给一个传送门,在技术文档里面的固件库里面,就可以下载到CW32F030的库了
给一个一步到位链接
双击固件包“IdeSupport\MDK”目录下的 WHXY.CW32F030_DFP.pack 文件, 在弹出
的界面下点击“Next”进行安装 Pack
打开刚才安装好的Keil MDK-ARM 微控制器集成开发环境
在左上角的file->open打开一个例程看看
选择工具栏的“Option”按钮,以显示“Option”对话框,选择“Device”标签,在器件列表中选择“WHXY”目录下的相应器件(以 CW32F030C8 为例),并点击“OK”确定
然后在debug框里找到Use,将下载器型号设置为CMSIS-DAP
打开旁边的setting,将左边的Adapter改成你的下载器,右边的的SW Device显示当前有没有连上设备,我这里接好了下载器和芯片,所以有显示设备。没有连上的话会显示failure
在左上角工具栏,第一个选项是编译,第二是bulid工程,第三个红圈是下载,一般我们通过编译确定程序是否有错,没有问题后点击build构建程序,然后通过下载按钮下载到程序中
那环境安装教程就结束啦
然后是官方教程链接
keil的安装中的百度云文件我已经上传在协会cloud中:https://cloud.scumaker.org/s/SeqJCbnjYtQMdPp
good
一直流传着这样一段话:过年了,家里的大学生一天不务正业,就知道用他的什么板各种点灯,也不知道他在干什么,反正电费哗哗地掉
什么是标准库和HAL库呢?
如果你有一个开发板,那肯定第一步要配置好环境,然后找到一个标准的模板(template)进行开发,通常我们都是找到一个能用的模板,然后各种修改。所以一个空的模板,含有对应芯片型号的库函数,这样的模板工程,我们叫他标准库;后来st公司(意法半导体)自己做了一个软件,叫做stm32cubemx,使用者可以在软件里选择自己的芯片型号,并且在软件里面进行初始化,这就是HAL库
单片机里面的时间就是通过时钟(RCC)产生的,时钟的产生流程有点像一个树状图,所以叫做“时钟树”,简而言之,就是你通过代码配置频率,最后完成时间的配置。因为频率是通过晶振产生的(振动频率),所以需要用代码将晶振的频率改为你想要的频率。
void RCC_Config()
{
//使能HSI
RCC_HSI_Enable(RCC_HSIOSC_DIV6);
//设置HCLK和PCLK
RCC_HCLKPRS_Config(RCC_HCLK_DIV8);
RCC_PCLKPRS_Config(RCC_PCLK_DIV8);
//使能PLL分频到64Mhz
RCC_PLL_Enable(RCC_PLLSOURCE_HSI,8000000,8);
//使用PLL时钟
RCC_SysClk_Switch(RCC_SYSCLKSRC_PLL);
RCC_SystemCoreClockUpdate(64000000);
}
单片机上的GPIO(俗称引脚),需要初始化后才能使用,就是相当于你要告诉它,它的任务是什么,它才会照做,具体的步骤就是在引脚的结构体中进行初始化就行
void GPIO_Config()
{
//初始化结构体
GPIO_InitTypeDef GPIO_InitStruct;
//__RCC_GPIOA_CLK_ENABLE();
//打开GPIO_C的时钟
__RCC_GPIOC_CLK_ENABLE();
//中断配置为无
GPIO_InitStruct.IT = GPIO_IT_NONE;
//模式设置为开漏输出: 只能输出低电平,外部不接上拉电阻时,所以要想输出高电平必须要外接上拉电阻
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
//此时设置为LED的引脚
GPIO_InitStruct.Pins = LED_GPIO_PINS;
//速率设置为高速
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
//赋值完毕后,运行初始化函数
GPIO_Init(LED_GPIO_PORT, &GPIO_InitStruct);
//初始给LED赋值为0
GPIO_WritePin(LED_GPIO_PORT, LED_GPIO_PINS,GPIO_Pin_RESET);
}
int32_t main(void)
{
RCC_Config();//时钟初始化
GPIO_Config();//GPIO初始化
while (1)
{
//翻转LED
GPIO_TogglePin(LED_GPIO_PORT, LED_GPIO_PINS);
//延时
Delay(0XFFFF);
}
}
之后演示图片和源程序也会相应给出
我是一个单片机,我要怎么才能让其他人知道我说了什么呢?
偶不知道哦
你会发出声音或者比手势吗?这样别人就能知道你想干什么了嗷
这些东西对于我来说太复杂了,我希望有更简单的方式
oh我的朋友,为什么不试试神奇的串口发送呢?
这是什么东西,好像很厉害
好的,请容许我介绍伟大的串口通信,这是一种设备之间互相通信的方式,我们可以将它分为硬件层面和协议层面:
这里左边是你的下载器,右边是你的单片机,注意连接时,RXD和TXD要交错着接线,毕竟A发送的消息,B来接收,也就对应着RXD对应TXD,很合理吧。
协议层:
传输的信号大概呈现出下图的样子:起始位,数据位,校验位,停止位
然后是具体的操作流程,这里就不过多介绍了
厉不厉害你鸡哥
谢谢你,现在我正在尝试生成代码
//UARTx
#define DEBUG_USARTx CW_UART1//选择串口1
#define DEBUG_USART_CLK RCC_APB2_PERIPH_UART1//配置串口时钟
#define DEBUG_USART_APBClkENx RCC_APBPeriphClk_Enable2//使能时钟
#define DEBUG_USART_BaudRate 115200//设置波特率为115200
#define DEBUG_USART_UclkFreq 8000000//串口传输评率
//UARTx GPIO
#define DEBUG_USART_GPIO_CLK RCC_AHB_PERIPH_GPIOA//设置GPIOA时钟
#define DEBUG_USART_TX_GPIO_PORT CW_GPIOA//设置TX管脚
#define DEBUG_USART_TX_GPIO_PIN GPIO_PIN_8
#define DEBUG_USART_RX_GPIO_PORT CW_GPIOA//设置RX管脚
#define DEBUG_USART_RX_GPIO_PIN GPIO_PIN_9
//GPIO AF
#define DEBUG_USART_AFTX PA08_AFx_UART1TXD()//串口1的TXD
#define DEBUG_USART_AFRX PA09_AFx_UART1RXD()//串口1的RXD
void RCC_Configuration(void)
{
//SYSCLK = HSI = 8MHz = HCLK = PCLK
RCC_HSI_Enable(RCC_HSIOSC_DIV6);
//外设时钟使能
RCC_AHBPeriphClk_Enable(DEBUG_USART_GPIO_CLK, ENABLE);
DEBUG_USART_APBClkENx(DEBUG_USART_CLK, ENABLE);
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//UART TX RX 复用
DEBUG_USART_AFTX;
DEBUG_USART_AFRX;
GPIO_InitStructure.Pins = DEBUG_USART_TX_GPIO_PIN;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.Pins = DEBUG_USART_RX_GPIO_PIN;
GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP;
GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);
}
void UART_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = DEBUG_USART_BaudRate;
USART_InitStructure.USART_Over = USART_Over_16;
USART_InitStructure.USART_Source = USART_Source_PCLK;//配置时钟源
USART_InitStructure.USART_UclkFreq = DEBUG_USART_UclkFreq;
USART_InitStructure.USART_StartBit = USART_StartBit_FE;
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_Rx | USART_Mode_Tx;//串口模式选择
USART_Init(DEBUG_USARTx, &USART_InitStructure);//串口初始化
}
int32_t main(void)
{
//配置RCC
RCC_Configuration();
//配置GPIO
GPIO_Configuration();
//配置UART
UART_Configuration();
printf("\r\nCW32F030 UART Printf Example\r\n");
while(1)
{
printf("hello\n");
}
}
在这种情况下我就可以一直说“hello”啦!
等一等我的朋友,你忘记了一件关键的事情,那就是串口中断!
PUTCHAR_PROTOTYPE
{
USART_SendData_8bit(DEBUG_USARTx, (uint8_t)ch);
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);
return ch;
}
串口对应着一个中断,你需要配置它的功能,在这里就是反复发送一个字符串,然后把中断的标志位给清理掉,如果不清理的话,你就只能说一次“hello”了,所以一定要清理标志位哦。
程序下载中
hello,hello,hello,hello…
:
:
hello,hello,hello,hello…