武汉芯源半导体

近年来,各种型号的MCU爆发式面市,甚至有些SoC芯片主要的功能不是MCU,但是能实现部分MCU的功能,在大面积缺货的时期也被拿出来替代MCU来用了。那这些新涌现的芯片,和MCU有哪些区别呢?

根据计算机组成原理,具备运算器、控制器、存储器、输入和输出设备的,都算完整的现代计算机,都可以运行程序,实现一定的运算和控制功能。

1.png

但是呢,专业MCU厂家是有意见的,在MCU缺货大潮中,为了抢夺生意,有很多设计团队选择快速拼接一个MCU芯片出来,比如说选择某个能够提供eFlash的IP的工艺制程,然后购买ARM或者RISCV的处理器内核,再找一些RAM以及UART,SPI,I2C,GPIO的IP作为外设,粘贴上一些ADC和定时器的模块,一个像模像样的MCU貌似就大差不差了。也对,也不对。

对在哪里呢?对就对在常见的通用MCU看起来也就是这么些东西在里面,很多使用MCU的客户在选型的时候主要是看这些功能配置,所以当问他这么个产品是否符合他的使用要求的时候,他基本能说OK。

那不对在哪里呢?我们都知道,很多事情得实践才会出真知,一个芯片在电子系统中能不能用,那是得实际移植实际开发出产品,最后还要通过专业测试甚至是大批量挂机才能够确定的。

在实际工作中,往往会发生一些试了才知道的事情,比如:

1、 发现各种温度和电压环境下不能稳定工作。

2、 发现抗干扰性能不过关。

3、 发现不能加密,软件容易被盗读。

4、 发现RAM没有自检和校验功能,运行出错的时候程序发现不了。

5、 过安规认证的时候发现缺少相关的安全库和硬件电路。

6、 时钟停振的时候程序发现不了。

7、 量产的时候发现某个故障芯片来源不明,无法追溯。

等等等等

哦!我明白了,这些都是要踩坑了才会发现的一些问题!

对呀!MCU首先是芯片,目前芯片的软硬件技术迭代已经比以前快很多了,但是毕竟不是今天改明天就能有。每次发现芯片的使用问题的时候,都需要下一代产品来做软硬件升级的,这是一个需要长时间累积经验的过程。所以说,有些只具备账面功能的类似MCU的芯片产品,某种意义上来讲,不算是真正的专业MCU。

那怎么分辨出谁的芯片做得好做得专业呢?看品牌知名度吗?

那当然还不是绝对的啦,可以从一些细节看出来这家品牌的专业化程度的,比如:

1、 这家MCU的ESD、Latch UP等报告的测试成绩怎么样。

2、 这家MCU的各种保护措施怎么样,比如程序读保护、上下电保护、时钟保护、程序执行保护、防呆设计等等。

3、 这家MCU的安全自检功能,比如IEC60730以及IEC61508要求的自检库软硬件有没有支持。

4、 这家MCU的唯一ID及编程追溯功能齐全不齐全。

5、 这家MCU的文档升级记录是不是越来越不频繁。

哦,那品牌知名度也不是唯一的考虑要素了。

哈哈,不当第一个吃螃蟹的人是对的,这的确能够避开很多技术风险,但是你也错过了很多的技术机会不是吗?正所谓机遇和挑战都是并存的,什么东西都让别人先去试,那试的好坏别人也不告诉你,等你知道这颗芯片好的时候,黄花菜都凉了不是。

这说得也是,看来还是得多加学习,练就火眼金睛。

还有个思路推荐给你,选择一些背景深厚的品牌也可以,不一定非得是芯片品牌。比如大的分销品牌旗下的芯片品牌,因为分销品牌的客户群体大,也很珍视品牌口碑,他们搞出来的芯片品牌基本上就不会乱做产品,因为他不能说是捞一票就跑对吧。

有这样的品牌吗?给我推荐一下呗。

当然有啊,比如力源信息旗下的武汉芯源半导体就是这个情况。力源信息已经是国内排名前列的本土分销商,多年服务专业工程师。力源信息最早于2015年入局半导体事业,目前有全资的子公司武汉芯源半导体在做通用MCU系列产品,新推出的超低功耗系列反响非常好哦,似乎刚做不久就有设计非常成熟的产品问世。既然他都敢大批量地卖,咱们试试也无妨。

相关阅读:

快乐解说MCU:CW32的工作电压特性

快乐解说MCU:三分钟,带你了解低功耗MCU

来源:CW32生态社区

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 33

一、简介

半双工即Half duplex Communication,是指在通信过程的任意时刻,信息既可由A传到B,又能由B传A,但同时只有一个方向上的传输存在。由于这种方式要频繁变换信道方向,故效率低,但可以节约传输线路。半双工方式适用于终端与终端之间的会话式通信。

二、实际操作(以CW32L083为例)

设置 UARTx_CR2.SIGNAL 为 1 使 UART 工作于单线半双工工作模式。在该模式下,使用 UARTx_TXD 引脚进行数据的发送和接收,不占用 UARTx_RXD 引脚(UARTx_RXD 可作通用 IO 使用)。写数据到 UARTx_TDR 寄存器后,UARTx_TXD 引脚立即进入发送状态,输出 UARTx_TDR 寄存器中的数据。数据 发送完成后,UARTx_TXD 引脚恢复到常态的接收状态。没有发送数据时,UARTx_TXD 引脚处于接收状态,数据接收完成后,接收完成标志位 UARTx_ISR.RC 会被硬件置 位,此时应尽快读取 UARTx_RDR 寄存器,并清除 UARTx_ISR.RC 标志位。

1.png

UART工作在单线半双工模式时,UARTx_TXD引脚需要配置为开漏输出。另外用户应采取适当的应用层保护机制,以确保不会出现多主机同时向总线发送数据。

三、UART单线半双工通信示例

硬件采用CW32L083VxTx StartKit单板,用杜邦线连接PA08和PA06引脚。

UARTy查询方式发送TxBuffer1缓冲区中的数据,UARTz查询方式接收数据,并存储到RxBuffer2缓冲区。

UARTz查询方式发送TxBuffer2缓冲区中的数据,UARTy查询方式接收数据,并存储到RxBuffer1缓冲区。

比较TxBuffer1和RxBuffer2、TxBuffer2和RxBuffer1,如果数据一致,则LED1亮,否则LED2亮。

1、配置RCC

void RCC_Configuration(void) 
{ 
    RCC_HSI_Enable(RCC_HSIOSC_DIV6); //SYSCLK = HSI = 8MHz = HCLK = PCLK 
    RCC_AHBPeriphClk_Enable(UARTy_GPIO_CLK | UARTz_GPIO_CLK | 
    RCC_AHB_PERIPH_GPIOC, ENABLE); //外设时钟使能 
    UARTy_APBClkENx(UARTy_CLK, ENABLE); 
    UARTz_APBClkENx(UARTz_CLK, ENABLE); 
}

2、配置GPIO

void GPIO_Configuration(void) 
{ 
    GPIO_InitTypeDef GPIO_InitStructure = {0}; 
    UARTy_AFTX; //UART TX 复用 
    UARTz_AFTX; U
    ARTy_TXPUR; //UART TX PUR 
    UARTz_TXPUR; 
    GPIO_InitStructure.Pins = UARTy_TxPin; 
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD; //开漏输出
    GPIO_Init(UARTy_GPIO, &GPIO_InitStructure); 
    GPIO_InitStructure.Pins = UARTz_TxPin; 
    GPIO_Init(UARTz_GPIO, &GPIO_InitStructure); 
    
    GPIO_InitStructure.Pins = GPIO_PIN_3 | GPIO_PIN_2; //PC3 LED1 / PC2 LED2 
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; 
    GPIO_Init(CW_GPIOC, &GPIO_InitStructure); P
    C03_SETLOW();//LED灭 
    PC02_SETLOW(); 
}

3、配置UART

void UART_Configuration(void) 
{ 
    UART_InitTypeDef UART_InitStructure = {0}; 
    
    UART_InitStructure.UART_BaudRate = UARTyz_BaudRate; // 波特率 
    UART_InitStructure.UART_Over = UART_Over_16; // 采样方式 
    UART_InitStructure.UART_Source = UART_Source_PCLK; // 传输时钟源
    UCLK UART_InitStructure.UART_UclkFreq = UARTyz_UclkFreq; // 传输时钟UCLK频率 
    UART_InitStructure.UART_StartBit = UART_StartBit_FE; // 起始位判定方式 
    UART_InitStructure.UART_StopBits = UART_StopBits_1; // 停止位长度 
    UART_InitStructure.UART_Parity = UART_Parity_No ; // 校验方式 
    UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None; 
    UART_InitStructure.UART_Mode = UART_Mode_Rx | UART_Mode_Tx; // 发送/接收使能 
    UART_Init(UARTy, &UART_InitStructure); 
    UART_Init(UARTz, &UART_InitStructure); 
}

4、定义变量

//UARTy 
#define  UARTy                         CW_UART1 
#define  UARTy_CLK                   RCC_APB2_PERIPH_UART1 
#define  UARTy_APBClkENx               RCC_APBPeriphClk_Enable2 
#define  UARTy_GPIO_CLK                RCC_AHB_PERIPH_GPIOA 
#define  UARTy_GPIO                    CW_GPIOA 
#define  UARTy_TxPin                    GPIO_PIN_8 
#define  UARTy_AFTX                    PA08_AFx_UART1TXD() 
#define  UARTy_TXPUR                   PA08_PUR_ENABLE(); 

//UARTz 
#define  UARTz                         CW_UART2 
#define  UARTz_CLK                     RCC_APB1_PERIPH_UART2 
#define  UARTz_APBClkENx               RCC_APBPeriphClk_Enable1 
#define  UARTz_GPIO_CLK                RCC_AHB_PERIPH_GPIOA 
#define  UARTz_GPIO                    CW_GPIOA 
#define  UARTz_TxPin                    GPIO_PIN_6 
#define  UARTz_AFTX                    PA06_AFx_UART2TXD() 
#define  UARTz_TXPUR                   PA06_PUR_ENABLE() 
#define  UARTyz_BaudRate               9600 
#define  UARTyz_UclkFreq                8000000 
#define  TxBufferSize1                   (ARRAY_SZ(TxBuffer1) - 1) 
#define  TxBufferSize2                   (ARRAY_SZ(TxBuffer2) - 1) 
typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus; 
TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength); 
uint8_t TxBuffer1[] = "\r\nCW32L083 UART HalfDuplex: UARTy -> UARTz\r\n"; 
uint8_t TxBuffer2[] = "\r\nCW32L083 UART HalfDuplex: UARTz -> UARTy\r\n"; 
uint8_t RxBuffer1[TxBufferSize2]; uint8_t RxBuffer2[TxBufferSize1]; 
uint32_t NbrOfDataToRead1 = TxBufferSize2; 
uint32_t NbrOfDataToRead2 = TxBufferSize1; 
uint8_t TxCounter1 = 0, RxCounter1 = 0; 
uint8_t TxCounter2 = 0, RxCounter2 = 0; 
volatile TestStatus TransferStatus1 = FAILED, TransferStatus2 = FAILED;

5、主程序

int32_t main(void) 
{   
    RCC_Configuration();//配置RCC 
    GPIO_Configuration();//配置GPIO 
    UART_Configuration();//配置UART 
    UART_HalfDuplexCmd(UARTy, ENABLE); //单线半双工 UARTy 
    UART_HalfDuplexCmd(UARTz, ENABLE); //单线半双工 UARTz 
    while(NbrOfDataToRead2--)   //UARTy -> UARTz 
    { 
        //UARTy发送一个字节数据 
        UART_SendData_8bit(UARTy, TxBuffer1[TxCounter1++]); 
        while(UART_GetFlagStatus(UARTy, UART_FLAG_TXE) == RESET); 
        //UARTz 等待RC 
        while(UART_GetFlagStatus(UARTz, UART_FLAG_RC) == RESET); 
        UART_ClearFlag(UARTz, UART_FLAG_RC); 
        RxBuffer2[RxCounter2++] = UART_ReceiveData_8bit(UARTz); 
    } 
    while(NbrOfDataToRead1--)//UARTz -> UARTy 
    { 
        //UARTz发送一个字节数据 
        UART_SendData_8bit(UARTz, TxBuffer2[TxCounter2++]); 
        while(UART_GetFlagStatus(UARTz, UART_FLAG_TXE)== RESET); 
        //UARTy 等待RC 
        while(UART_GetFlagStatus(UARTy,UART_FLAG_RC) == RESET); 
        UART_ClearFlag(UARTy, UART_FLAG_RC); 
        RxBuffer1[RxCounter1++] = UART_ReceiveData_8bit(UARTy); 
    } 
    //检查收发数据一致性 
    TransferStatus1 = Buffercmp(TxBuffer1, RxBuffer2, TxBufferSize1); 
    TransferStatus2 = Buffercmp(TxBuffer2, RxBuffer1, TxBufferSize2); 
    if(TransferStatus1 == PASSED && TransferStatus2 == PASSED) //PASSED 
    { 
        //LED1亮 
        PC03_SETHIGH(); 
    } 
    else //FAILED 
    { 
        PC02_SETHIGH();//LED2亮 
    } 
    while(1) 
    { 
    } 
}

6、测试结果:UART半双工通信方式工作正常, LED1亮。

来源:武汉芯源半导体

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 130
订阅 RSS - 武汉芯源半导体