发新帖本帖赏金 50.00元(功能说明)我要提问
返回列表
打印
[技术讨论]

【每周分享】宏晶停产单片机程序移植保姆教程

[复制链接]
2690|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 地瓜patch 于 2024-9-12 22:48 编辑

#申请原创# @21小跑堂


宏晶
STC8A8K64S4A12单片机具备多路PWM、多路ADC等功能,适合进行GPIO操作、ADC采样等多种实验。该单片机还具有宽电压工作范围,能够在2.0V到5.5V之间正常工作,便宜且简单易用。已停产。囤货价格上翻10倍且居高不小。对于STC8A8K64S4A12单片机的停产,最直接的影响是现有产品生产的持续性和替换后产品的稳定性。需要寻找替代型号或者改变设计方案,导致开发成本的增加。咨询厂家建议使用STC8A8K64D4单片机替换,引脚pin对pin兼容。程序无需大改,问题是只要有改动,就会涉及到软件的修改、硬件设计的调整以及全面的系统测试以及老化。停车已经是现实,那么只能修改、替换再测试。
在移植前需要有个总体策划,主要包括硬件电路修改和软件移植两个部分。
硬件移植相对简单,主要是根据新单片机的引脚重新布线,核对了STC8A8K64S4A12与STC8A8K64D4两颗单片机果然pin对pin可替换。厂家没说谎
而软件移植则涉及底层库的替换比如特殊寄存器的修改,接口函数的定义,需要花不少时间;系统时钟一致不用修改;初始化函数修改也需要花不少时间。

主要工作量还是在软件移植方面,我的程序主要涉及串口通信、定时器和IO输入输出控制。下面一步一步来进行移植。

首先

1、替换所引用单片机对应型号的头文件

由#include    "STC8xxxx.h"替换为厂家提供的#include    "STC8A8K64D4.h"

2、串口移植,以串口1为例进行说明

替换所引用接口对应型号的头文件,更换头文件后编译会出现一系列错误。需要一一改正。

    #include "USART.h"替换为厂家提供的#include "STC8A_UART.h"

以串口1为例,需要修改初始化函数将

/******************初始化串口1******************/

void USART1_Init(u32 baudRate)

{

        COMx_InitDefine                COMx_InitStructure;                                        //结构定义

        COMx_InitStructure.UART_Mode      = UART_8bit_BRTx;                //模式,       UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx

        COMx_InitStructure.UART_BRT_Use   = BRT_Timer2;                        //使用波特率,  串口1可用BRT_Timer1/BRT_Timer2,串口2固定使用BRT_Timer2,串口3可用BRT_Timer2/BRT_Timer3,串口4可用        BRT_Timer2/BRT_Timer4

        COMx_InitStructure.UART_BaudRate  = baudRate;                        //波特率, 一般 110 ~ 115200

        COMx_InitStructure.UART_RxEnable  = ENABLE;                                //接收允许,   ENABLE或DISABLE

        COMx_InitStructure.BaudRateDouble = DISABLE;                        //波特率加倍, ENABLE或DISABLE

        COMx_InitStructure.UART_Interrupt = ENABLE;                                //中断允许,   ENABLE或DISABLE

        COMx_InitStructure.UART_Polity    = PolityHigh;                        //中断优先级, PolityLow,PolityHigh

        COMx_InitStructure.UART_P_SW      = UART1_SW_P30_P31;        //切换端口,   UART1_SW_P30_P31,UART1_SW_P36_P37,UART1_SW_P16_P17(必须使用内部时钟)

        COMx_InitStructure.UART_RXD_TXD_Short = DISABLE;                //内部短路RXD与TXD, 做中继, ENABLE,DISABLE

        USART_Configuration(USART1, &COMx_InitStructure);                //初始化串口1 USART1,USART2

//        PrintString1("USART1 is initialized!\r\n");        //SUART1发送一个字符串


}

编译出错

修改为

void USART1_Init(u32 baudRate)

{

        COMx_InitDefine                COMx_InitStructure;                                        //结构定义

        COMx_InitStructure.UART_Mode      = UART_8bit_BRTx;                //模式,       UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx

        COMx_InitStructure.UART_BRT_Use   = BRT_Timer2;                        //使用波特率,  串口1可用BRT_Timer1/BRT_Timer2,串口2固定使用BRT_Timer2,串口3可用BRT_Timer2/BRT_Timer3,串口4可用        BRT_Timer2/BRT_Timer4

        COMx_InitStructure.UART_BaudRate  = baudRate;                        //波特率, 一般 110 ~ 115200

        COMx_InitStructure.UART_RxEnable  = ENABLE;                                //接收允许,   ENABLE或DISABLE

        COMx_InitStructure.BaudRateDouble = DISABLE;                        //波特率加倍, ENABLE或DISABLE

        UART_Configuration(UART1, &COMx_InitStructure);                //初始化串口1 USART1,USART2

        NVIC_UART1_Init(ENABLE,Priority_1);                //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3


        UART1_SW(UART1_SW_P30_P31);                //UART1_SW_P30_P31,UART1_SW_P36_P37,UART1_SW_P16_P17,UART1_SW_P43_P44

//        PrintString1("USART1 is initialized!\r\n");        //SUART1发送一个字符串


}

注意,STC8A8K64S4A12与STC8A8K64D4两颗单片机的同名函数和宏定义略有区别修改如下

函数USART_Configuration();        改为   UART_Configuration();

接口端口的宏定义由USART1改为 UART1

编译后,会发现提示如下错误

error C202: 'NVIC_UART1_Init': undefined identifier

error C202: 'UART1_SW': undefined identifier


这两个函数分别对应两个不同头文件,调用以下头文件 解决该问题。

NVIC_UART1_Init()在#include "STC8A_NVIC.h"中

UART1_SW()在#include "STC8A_Switch.h"  中

编译后提示NULL  SUCCESS未定义如下错误,调用 #include "type_def.h" 后 解决。

error C202: 'NULL': undefined identifier

error C202: 'SUCCESS': undefined identifier

同时又出现如下错误,提示重复定义,在头文件中注释掉即可。

error C231: 'u8': redefinition

error C231: 'u16': redefinition

error C231: 'u32': redefinition

这是因为调用#include "type_def.h"文件导致的重复定义,修改后,该错误消失。

3.定时器的移植,以timer0为例

二话不说,先更换头文件

将#include        "Timer.h"  更换为#include        "STC8A_Timer.h"

编译以下初始化函数会出错

void Timer0_Init(u32 frequency)

{

        TIM_InitTypeDef                TIM_InitStructure;                                        //结构定义

        TIM_InitStructure.TIM_Mode      = TIM_16BitAutoReload;        //指定工作模式,   TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload,TIM_16BitAutoReloadNoMask

        TIM_InitStructure.TIM_Polity    = PolityLow;                        //指定中断优先级, PolityHigh,PolityLow               

        TIM_InitStructure.TIM_Interrupt = ENABLE;                                //中断是否允许,   ENABLE或DISABLE

        TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_12T;                        //指定时钟源,     TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext

        TIM_InitStructure.TIM_ClkOut    = DISABLE;                                //是否输出高速脉冲, ENABLE或DISABLE

        TIM_InitStructure.TIM_Value     = 65536UL - (MAIN_Fosc / (frequency*12));                //初值,

        TIM_InitStructure.TIM_Run       = ENABLE;                                //是否初始化后启动定时器, ENABLE或DISABLE

        Timer_Inilize(Timer0,&TIM_InitStructure);                                //初始化Timer0          Timer0,Timer1,Timer2

}

编译出错

error C204: 'TIM_Polity': undefined member

error C204: 'TIM_Interrupt': undefined member

将函数中的中断使能和优先级更换为函数NVIC_Timer0_Init()

NVIC_Timer0_Init(ENABLE,Priority_0);                //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3

定时器0初始化函数改为如下

void Timer0_Init(u32 frequency)

{

        TIM_InitTypeDef                TIM_InitStructure;                                        //结构定义

        TIM_InitStructure.TIM_Mode      = TIM_16BitAutoReload;        //指定工作模式,   TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload,TIM_16BitAutoReloadNoMask

        TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_12T;                        //指定时钟源,     TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext

        TIM_InitStructure.TIM_ClkOut    = DISABLE;                                //是否输出高速脉冲, ENABLE或DISABLE

        TIM_InitStructure.TIM_Value     = 65536UL - (MAIN_Fosc / (frequency*12));                //初值,

        TIM_InitStructure.TIM_Run       = ENABLE;                                //是否初始化后启动定时器, ENABLE或DISABLE

        Timer_Inilize(Timer0,&TIM_InitStructure);                                //初始化Timer0          Timer0,Timer1,Timer2

        NVIC_Timer0_Init(ENABLE,Priority_0);                //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3

}



4,最重要的放在最后,UART所用的IO需要定义

首先调用#include"STC8A_GPIO.h"

将原来的端口定义函数

void GPIO_Init(void)

{

P_SW2 = 0x80;

P1M1 = 0x1C;

P1M0 = 0x00;

P3M0 = 0x00;

P3M1 = 0x02;

P3PU = 0x02;

P4M1 = 0x10;

P4M0 = 0x00;

P_SW2 = 0x00;

}

修改为以下函数,这一步很重要

voidGPIO_config(void)

{

GPIO_InitTypeDefGPIO_InitStructure;//结构定义


GPIO_InitStructure.Pin  = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;//指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7

GPIO_InitStructure.Mode = GPIO_PullUp;//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP

GPIO_Inilize(GPIO_P0,&GPIO_InitStructure);//初始化

}

到这里,移植就基本结束了,编译成功,没有错误,下载到新的芯片中,运行正常。


小结:

在STC8A8K64S4A12中用到的接口、功能等,都需要进行修改移植为STC8A8K64D4对应的头文件,然后修改对应的函数调用。

在我的程序中用到了串口通信、定时器和IO输入输出控制,调用UART、TIMER、IO对应的头文件。修改的这些功能对应的函数。


在移植中出现的问题,请回帖留言讨论。


使用特权

评论回复

打赏榜单

21小跑堂 打赏了 50.00 元 2024-09-23
理由:恭喜通过原创审核!期待您更多的原创作品~

评论
21小跑堂 2024-9-23 17:10 回复TA
无论是否停产,二姨都认为换芯片最好重新写代码。号称的pin to pin,代码直接烧录不是可取之道。作者虽然是被迫重构项目,但是项目修改的过程描述的很是清晰,虽然每个人因为所用外设不同,修改位置不同,但是一通百通。 
dirtwillfly 2024-9-11 08:28 回复TA
感谢分享 

相关帖子

沙发
咕咕呱呱孤寡| | 2024-9-12 08:55 | 只看该作者
STC8A8K64S4A12与STC8A8K64D4这两款单片机我们公司都有在使用,S4系列停产了,只能只用D4拓展,基本性能与S4无他异,需要改一些库文件,感谢楼主分享

使用特权

评论回复
板凳
地瓜patch|  楼主 | 2024-9-12 20:09 | 只看该作者
咕咕呱呱孤寡 发表于 2024-9-12 08:55
STC8A8K64S4A12与STC8A8K64D4这两款单片机我们公司都有在使用,S4系列停产了,只能只用D4拓展,基本性能与S ...

替换中的问题可以相互交流啊

使用特权

评论回复
地板
咕咕呱呱孤寡| | 2024-9-13 08:38 | 只看该作者
地瓜patch 发表于 2024-9-12 20:09
替换中的问题可以相互交流啊

好的好的,感谢前辈

使用特权

评论回复
5
xinqicheng| | 2024-12-9 11:41 | 只看该作者
本帖最后由 xinqicheng 于 2024-12-9 11:42 编辑

您好,可以使用STC8A8K64D4系列,同样具备多路ADC和PWM,工作电压在1.9V到5.5V之间。

使用特权

评论回复
6
地瓜patch|  楼主 | 2024-12-9 13:48 | 只看该作者
xinqicheng 发表于 2024-12-9 11:41
您好,可以使用STC8A8K64D4系列,同样具备多路ADC和PWM,工作电压在1.9V到5.5V之间。 ...

就是用64D4替换64S4

使用特权

评论回复
发新帖 本帖赏金 50.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1262

主题

12561

帖子

27

粉丝