打印
[其他]

【MM32 eMiniBoard测评报告】从零建工程、简单OS测试、UART回声

[复制链接]
860|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
一、开箱
今天中午收到了快递,开箱,总体感觉做工还是很工整的。上电嘀的一声,彩色LED就交替闪了起来。
彩色LED是板子的亮点之一,可见厂家用心了。









二、保存出厂固件
这几年有个习惯:拿到开发板,首先把出厂固件保存起来,这次也不例外:





三、从零开始建一个带RTOS应用的MDK工程
我用的是Keil MDK v5.29。在菜单中new一个project,名为MM32Test:

选中板载MCU型号:MM32L073PF

在接下来的页面,勾选这几项:

然后用模板生成一个main.c文件:

点击上图ADD按钮后,生成的main.c如下:

系统的应用,其实挺简单的。无非就是创建线程(即任务;以及其它系统对象),然后交给系统调度它们。
main.c只有一个线程app_main,我们复制一下,建成线程app_2、app_3、app_4,同时在各个线程里填写代码。
我们每个任务让它定时翻转LED:

/*----------------------------------------------------------------------------
* Application main thread
*---------------------------------------------------------------------------*/
void app_main (void *argument) {

  // ...
  for (;;)
        {
                LED1_TOGGLE();
                osDelay(100);
        }
}
/*----------------------------------------------------------------------------
* Application thread 2
*---------------------------------------------------------------------------*/
void app_2 (void *argument) {

  // ...
  for (;;)
        {
                LED2_TOGGLE();
                osDelay(200);
        }
}
/*----------------------------------------------------------------------------
* Application thread 3
*---------------------------------------------------------------------------*/
void app_3 (void *argument) {

  // ...
  for (;;)
        {
                LED3_TOGGLE();
                osDelay(500);
        }
}
/*----------------------------------------------------------------------------
* Application thread 4
*---------------------------------------------------------------------------*/
void app_4 (void *argument) {

  // ...
  for (;;)
        {
                LED4_TOGGLE();
                osDelay(1000);
        }
}

LED的配置、以及翻转命令,直接从官方提供的例程里复制一下:


#include "HAL_Device.h"


#define LED4_ON()            GPIOA->BRR=0x8000;// PA15
#define LED4_OFF()    GPIOA->BSRR = 0x8000// PA15
#define LED4_TOGGLE()  (GPIOA->ODR&0x8000)?(GPIOA->BRR=0x8000):(GPIOA->BSRR = 0x8000)


#define LED3_ON()          GPIOB->BRR=0x0008// PB3
#define LED3_OFF()         GPIOB->BSRR = 0x0008;// PB3
#define LED3_TOGGLE()  (GPIOB->ODR&0x0008)?(GPIOB->BRR=0x0008):(GPIOB->BSRR = 0x0008)


#define LED2_ON()          GPIOB->BRR=0x0010// PB4
#define LED2_OFF()         GPIOB->BSRR = 0x0010// PB4
#define LED2_TOGGLE()  (GPIOB->ODR&0x0010)?(GPIOB->BRR=0x0010):(GPIOB->BSRR = 0x0010)


#define LED1_ON()   GPIOB->BRR=0x0020// PB5
#define LED1_OFF()         GPIOB->BSRR=0x0020// PB5
#define LED1_TOGGLE()  (GPIOB->ODR&0x0020)?(GPIOB->BRR=0x0020):(GPIOB->BSRR = 0x0020)


void LED_Init(void)
{
    RCC->AHBENR|=RCC_AHBENR_GPIOAEN|RCC_AHBENR_GPIOBEN;   
   
    GPIOA->CRH|=GPIO_CRH_MODE15;                  
    GPIOA->ODR|=GPIO_ODR_ODR15;        
   
    GPIOB->CRL|=GPIO_CRL_MODE3|GPIO_CRL_MODE4|GPIO_CRL_MODE5;      
    GPIOB->ODR|=GPIO_ODR_ODR3|GPIO_ODR_ODR4|GPIO_ODR_ODR5;         
   
    LED1_OFF();
    LED2_OFF();
    LED3_OFF();
    LED4_OFF();
}

时钟配置函数,也从官方例程里直接复制粘贴。

void SystemCoreClockUpdate(u8 PLL)
{
    unsigned char temp=0;   
    RCC->CR|=RCC_CR_HSEON;  //外部高速时钟使能HSEON
    while(!(RCC->CR&RCC_CR_HSERDY));//等待外部时钟就绪
    RCC->CFGR=RCC_CFGR_PPRE1_2; //APB1=DIV2;APB2=DIV1;AHB=DIV1;
   
    RCC->CFGR|=RCC_CFGR_PLLSRC;          //PLLSRC ON
    RCC->CR &=~(RCC_CR_PLLON);                //清PLL//        RCC->CR &=~(7<<20);                //清PLL
   
    RCC->CR &=~(0x1f<<26);       
    RCC->CR|=(PLL - 1) << 26;   //设置PLL值 2~16
   
    FLASH->ACR|=FLASH_ACR_LATENCY_1|FLASH_ACR_PRFTBE|FLASH_ACR_PRFTBS;          //FLASH 2个延时周期
   
    RCC->CR|=RCC_CR_PLLON;  //PLLON
    while(!(RCC->CR&RCC_CR_PLLRDY));//等待PLL锁定
    RCC->CFGR|=RCC_CFGR_SW_PLL;//PLL作为系统时钟         
    while(temp!=0x02)     //等待PLL作为系统时钟设置成功
    {   
        temp=RCC->CFGR>>2;
        temp&=0x03;
    }   
}



别忘记在main函数里调用LED_Init():
  SystemCoreClockUpdate(8);
  LED_Init();

最后是工程的几处设置改一下:




OK,编译下载到开发板,就可以看到4个LED以不同的频率闪烁起来了。在这里我就不上效果动图了。


此例即附件中的“MM32Test.rar”


四、在工程里应用库函数
上面的工程,使用了寄存器操作。怎么使用库函数呢?也容易。
首先,从官网下载例程包,里面有一个Device文件夹,这个就是我们要找的东西:


把它复制到某个位置,比如可以直接放到工程文件夹下:


把库函数c文件添加到工程中去:


在工程选项里添加一个宏,以及包含头文件的搜索路径:


OK,现在就可以使用库函数了:

#include "HAL_Device.h"


#define LED4_ON()  GPIO_ResetBits(GPIOA,GPIO_Pin_15)        // PA15
#define LED4_OFF()  GPIO_SetBits(GPIOA,GPIO_Pin_15)        // PA15
#define LED4_TOGGLE()  (GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_15))?(GPIO_ResetBits(GPIOA,GPIO_Pin_15)):(GPIO_SetBits(GPIOA,GPIO_Pin_15))        // PA15


#define LED3_ON()  GPIO_ResetBits(GPIOB,GPIO_Pin_3)        // PB3
#define LED3_OFF()  GPIO_SetBits(GPIOB,GPIO_Pin_3)        // PB3
#define LED3_TOGGLE()  (GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_3))?(GPIO_ResetBits(GPIOB,GPIO_Pin_3)):(GPIO_SetBits(GPIOB,GPIO_Pin_3))        // PB3


#define LED2_ON()  GPIO_ResetBits(GPIOB,GPIO_Pin_4)        // PB4
#define LED2_OFF()  GPIO_SetBits(GPIOB,GPIO_Pin_4)        // PB4
#define LED2_TOGGLE()  (GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_4))?(GPIO_ResetBits(GPIOB,GPIO_Pin_4)):(GPIO_SetBits(GPIOB,GPIO_Pin_4))        // PB4


#define LED1_ON()  GPIO_ResetBits(GPIOB,GPIO_Pin_5)        // PB5
#define LED1_OFF()  GPIO_SetBits(GPIOB,GPIO_Pin_5)        // PB5
#define LED1_TOGGLE()  (GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_5))?(GPIO_ResetBits(GPIOB,GPIO_Pin_5)):(GPIO_SetBits(GPIOB,GPIO_Pin_5))        // PB5


void LED_Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
   
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA|RCC_AHBPeriph_GPIOB, ENABLE);  //开启GPIOA,GPIOB时钟
   
    GPIO_InitStructure.GPIO_Pin  =  GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
   
    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
   
    LED1_OFF();
    LED2_OFF();
    LED3_OFF();
    LED4_OFF();
}

是不是像极了STM32的标准库?实话说,这几年用惯了STM32CubeMX,已经淡忘的标准库函数有些陌生了。

此例即附件中的“MM32Test2.7z”


五、做一个UART回声测试
然后再试一试串口。
简单地添加了一段UART2收到字符随即发出的功能。
是在UART2的接收中断里立即发出。效果图如下,代码就不贴了。
此例即附件中的“MM32Test3.7z”


六、本人对MM32的第一个体验报告就到此吧。祝愿MM公司有好的发展。

以下是上面提到的工程,3个阶段,保存成了3个压缩包:

MM32Test3.rar (2.5 MB)


MM32Test2.rar (2.49 MB)


MM32Test.rar (327.87 KB)




使用特权

评论回复
沙发
lihuasoft|  楼主 | 2020-4-25 23:03 | 只看该作者
Win7电脑安装USB驱动时,官方提示应禁用驱动签名。方法整理如下图(来自互联网):


另外,更正一下,贴子里提到的“7z”压缩包,应为“rar”。
还有main()函数代码忘记贴了:

int main (void) {

  // System Initialization
  SystemCoreClockUpdate(8);
        LED_Init();
        Uart_Init();
  // ...

  osKernelInitialize();                 // Initialize CMSIS-RTOS
  osThreadNew(app_main, NULL, NULL);    // Create application main thread
  osThreadNew(app_2, NULL, NULL);    // Create application thread 2
  osThreadNew(app_3, NULL, NULL);    // Create application thread 3
  osThreadNew(app_4, NULL, NULL);    // Create application thread 4
  osKernelStart();                      // Start thread execution
  for (;;) {}
}


使用特权

评论回复
板凳
lihuasoft|  楼主 | 2020-4-26 07:05 | 只看该作者
原谅我的语气看起来像“教程”,的确是希望对刚刚接触单片机的人有一点用。高手请见谅

使用特权

评论回复
评论
lihuasoft 2020-4-26 12:01 回复TA
@wziyi :谢谢! 
wziyi 2020-4-26 07:43 回复TA
我感觉这挺好的呀 
地板
Cjy_JDxy| | 2020-4-26 08:11 | 只看该作者
看看,很不错

使用特权

评论回复
5
lihuasoft|  楼主 | 2020-4-26 12:06 | 只看该作者
据论坛体验贴介绍,此板的CAN电路有问题。收板后检查了一下,果然MCU的CAN_TX和RX脚画反了。
修复方法也不难,直接把R30、R31这两个电阻焊掉,利用电阻的焊盘,用导线交叉焊接一下就可以了:


修改后,测试CAN通信正常:


使用特权

评论回复
6
Cjy_JDxy| | 2020-4-26 13:04 | 只看该作者
lihuasoft 发表于 2020-4-26 12:06
据论坛体验贴介绍,此板的CAN电路有问题。收板后检查了一下,果然MCU的CAN_TX和RX脚画反了。
修复方法也不 ...

还有这事,真想不到

使用特权

评论回复
7
zhaor| | 2020-4-29 10:45 | 只看该作者
例子很好,参考一下

使用特权

评论回复
8
caizhiwei| | 2020-4-29 11:01 | 只看该作者
Cjy_JDxy 发表于 2020-4-26 13:04
还有这事,真想不到

小辣椒

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

19

主题

272

帖子

3

粉丝