VSCode PlatformIO开发STC单片机注意事项

VSCode PlatformIO开发STC单片机注意事项


首先需要注意代码的语法

  • 附上本论坛一位网友总结的笔记
 其实开源的SDCC+code blocks也不错的。
 SDCC语法与keil C有一点点不同,记录如下:
 * 1 sbit * 
// keil c :
sbit LED1=P1^3 ;
// SDCC
#define LED1 P1_3 

* 2 中断  *
keil c 的中断
void SerialComm(void ) interrupt 4 ;
{
}

sdcc 的中断
void SerialComm(void) __interrupt 4;
{
}

* 3 _nop()_  *
sdcc 没有 _nop()_ , 可用如下自定义宏代替:
#define _nop()_ __asm NOP __endasm 

头文件包含

  • lint.h

里面定义了有关硬件相关寄存器的宏,没有包含的话,在直接使用单片机特殊功能寄存器的话都会出现波浪号,是一个很重要的头文件,在单片机的时候,务必首先将此头文件包含进去。


#ifndef _LINT_H
#define _LINT_H

  #if !defined(__SDCC_mcs51)

    #define __data
    #define __near
    #define __idata
    #define __xdata
    #define __far
    #define __pdata
    #define __code
    #define __bit bool
    #define __sfr volatile unsigned char
    #define __sbit volatile bool
    #define __critical
    #define __at(x)             /* use "__at (0xab)" instead of "__at 0xab" */
    #define __using(x)
    #define __interrupt(x)
    #define __naked

    #define data
    #define near 
    #define idata
    #define xdata
    #define far
    #define pdata
    #define code
    #define bit bool
    #define sfr volatile unsigned char
    #define sbit volatile bool
    #define critical
    #define at(x)
    #define using(x)
    #define interrupt(x)
    #define naked

    /* The tool Splint is available at http://www.splint.org
       Other tools might also be used for statically checking c-sources.
       Traditionally they could have "lint" in their name.
     */
    #if defined(S_SPLINT_S)

      /* Behaviour of splint can be modified by special comments.
         Some examples are shown below.

         Note 1: most probably you'll want to copy this complete file into
         your source directory, adapt the settings to your needs and use
         #include "lint.h" as the first include in your source file(s).
         You should then be able to either directly compile your file
         or to run a check with splint over it without other changes.

         Note 2: you need brackets around arguments for special
         keywords, so f.e. it's "interrupt (1)" instead of "interrupt 1".
       */

      /*@ +charindex @*/

    #endif

  #endif

#endif

  • stdio.h头文件在这里插入代码片

此头文件里面定义了有一个比较常用的printf函数,关于此头文件的内容比较多,就比贴出内容来了。

  • stdint.h头文件

此头文件里面定义了数据类型的简写。

#ifndef _STDINT_H
#define _STDINT_H

#include <crtdefs.h>

#define __need_wint_t
#define __need_wchar_t
#include <stddef.h>

/* 7.18.1.1  Exact-width integer types */
typedef signed char int8_t;
typedef unsigned char   uint8_t;
typedef short  int16_t;
typedef unsigned short  uint16_t;
typedef int  int32_t;
typedef unsigned   uint32_t;
__MINGW_EXTENSION typedef long long  int64_t;
__MINGW_EXTENSION typedef unsigned long long   uint64_t;

/* 7.18.1.2  Minimum-width integer types */
typedef signed char int_least8_t;
typedef unsigned char   uint_least8_t;
typedef short  int_least16_t;
typedef unsigned short  uint_least16_t;
typedef int  int_least32_t;
typedef unsigned   uint_least32_t;
__MINGW_EXTENSION typedef long long  int_least64_t;
__MINGW_EXTENSION typedef unsigned long long   uint_least64_t;

/*  7.18.1.3  Fastest minimum-width integer types
 *  Not actually guaranteed to be fastest for all purposes
 *  Here we use the exact-width types for 8 and 16-bit ints.
 */
typedef signed char int_fast8_t;
typedef unsigned char uint_fast8_t;
typedef short  int_fast16_t;
typedef unsigned short  uint_fast16_t;
typedef int  int_fast32_t;
typedef unsigned  int  uint_fast32_t;
__MINGW_EXTENSION typedef long long  int_fast64_t;
__MINGW_EXTENSION typedef unsigned long long   uint_fast64_t;

/* 7.18.1.5  Greatest-width integer types */
__MINGW_EXTENSION typedef long long  intmax_t;
__MINGW_EXTENSION typedef unsigned long long   uintmax_t;

/* 7.18.2  Limits of specified-width integer types */
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) ||	\
    defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L

/* 7.18.2.1  Limits of exact-width integer types */
#define INT8_MIN (-128)
#define INT16_MIN (-32768)
#define INT32_MIN (-2147483647 - 1)
#define INT64_MIN  (-9223372036854775807LL - 1)

#define INT8_MAX 127
#define INT16_MAX 32767
#define INT32_MAX 2147483647
#define INT64_MAX 9223372036854775807LL

#define UINT8_MAX 255
#define UINT16_MAX 65535
#define UINT32_MAX 0xffffffffU  /* 4294967295U */
#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */

/* 7.18.2.2  Limits of minimum-width integer types */
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST64_MIN INT64_MIN

#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MAX INT64_MAX

#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX

/* 7.18.2.3  Limits of fastest minimum-width integer types */
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST64_MIN INT64_MIN

#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MAX INT64_MAX

#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX

/* 7.18.2.4  Limits of integer types capable of holding
    object pointers */
#ifdef _WIN64
#define INTPTR_MIN INT64_MIN
#define INTPTR_MAX INT64_MAX
#define UINTPTR_MAX UINT64_MAX
#else
#define INTPTR_MIN INT32_MIN
#define INTPTR_MAX INT32_MAX
#define UINTPTR_MAX UINT32_MAX
#endif

/* 7.18.2.5  Limits of greatest-width integer types */
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX

/* 7.18.3  Limits of other integer types */
#ifdef _WIN64
#define PTRDIFF_MIN INT64_MIN
#define PTRDIFF_MAX INT64_MAX
#else
#define PTRDIFF_MIN INT32_MIN
#define PTRDIFF_MAX INT32_MAX
#endif

#define SIG_ATOMIC_MIN INT32_MIN
#define SIG_ATOMIC_MAX INT32_MAX

#ifndef SIZE_MAX
#ifdef _WIN64
#define SIZE_MAX UINT64_MAX
#else
#define SIZE_MAX UINT32_MAX
#endif
#endif

#ifndef WCHAR_MIN  /* also in wchar.h */
#define WCHAR_MIN 0U
#define WCHAR_MAX 0xffffU
#endif

/*
 * wint_t is unsigned short for compatibility with MS runtime
 */
#define WINT_MIN 0U
#define WINT_MAX 0xffffU

#endif /* !defined ( __cplusplus) || defined __STDC_LIMIT_MACROS */


/* 7.18.4  Macros for integer constants */
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) ||	\
    defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L

/* 7.18.4.1  Macros for minimum-width integer constants

    Accoding to Douglas Gwyn <gwyn@arl.mil>:
	"This spec was changed in ISO/IEC 9899:1999 TC1; in ISO/IEC
	9899:1999 as initially published, the expansion was required
	to be an integer constant of precisely matching type, which
	is impossible to accomplish for the shorter types on most
	platforms, because C99 provides no standard way to designate
	an integer constant with width less than that of type int.
	TC1 changed this to require just an integer constant
	*expression* with *promoted* type."

	The trick used here is from Clive D W Feather.
*/

#define INT8_C(val) (INT_LEAST8_MAX-INT_LEAST8_MAX+(val))
#define INT16_C(val) (INT_LEAST16_MAX-INT_LEAST16_MAX+(val))
#define INT32_C(val) (INT_LEAST32_MAX-INT_LEAST32_MAX+(val))
/*  The 'trick' doesn't work in C89 for long long because, without
    suffix, (val) will be evaluated as int, not intmax_t */
#define INT64_C(val) val##LL

#define UINT8_C(val) (val)
#define UINT16_C(val) (val)
#define UINT32_C(val) (val##U)
#define UINT64_C(val) val##ULL

/* 7.18.4.2  Macros for greatest-width integer constants */
#define INTMAX_C(val) val##LL
#define UINTMAX_C(val) val##ULL

#endif  /* !defined ( __cplusplus) || defined __STDC_CONSTANT_MACROS */

#endif  /* _STDINT_H */

以上头文件的加载的话根据个人使用按需加载,当然还有其他的头文件,可以自行到编译器所在目录下查看翻阅和了解。

我的VSCode PlatformIO SDCC编译器文件位置:C:\Users\Administrator\.platformio\packages\toolchain-sdcc\include
在这里插入图片描述

独立安装的SDCC编译

例如我安装的独立sdcc编译器路径:D:\Program Files\SDCC\include\mcs51
在这里插入图片描述

VSCode PlatformIO调用独立安装的的SDCC编译器进行编译方法

  • 在工程项目下的c_cpp_properties.json文件内添加如下语句:
// "compilerPath": "C:/Users/Administrator/.platformio/packages/toolchain-sdcc/bin/sdcc.exe",//这是默认使用平台提供的SDCC编译器位置
     "compilerPath":"D:/Program Files/SDCC/bin/sdcc.exe",//添加此独立安装的sdcc编译器位置
  • VSCode PlatformIO调用独立的SDCC编译工具进行编译

在这里插入图片描述

目前使用SDCC来开发STC单片机的人群不多,有许多暗坑,这里不对新手鼓励使用,比起Keil软件,这个工具毕竟是开源免费的编译器,对于个人和企业的话,可以免费使用。

目前发现的暗坑,在使用StC15开发的时候,想通过虚拟串口打印数据,发现编译后上传都没有问题,但是打印的信息是乱码,同样的代码在Keil里面编译上传没有问题,打印OK。

在这里插入图片描述
在这里插入图片描述

在VSCode PlatformIO平台使用SDCC编译的文件,虚拟串口就是打印的是乱码,刚开始我还以为使用VSCode PlatformIO是stcgal工具进行上传所导致的问题,后面我将编译生成的Hex文件使用STC-ISP工具进行单独烧录,也是不行。目前还没找到解决办法。

  • 虚拟串口打印主要涉及的就是一个位函数
//========================================================================
// 函数: void	BitTime(void)
// 描述: 位时间函数。
//========================================================================
void BitTime(void)
{
    u16 i;
    i = (16 * 104) / 13 - 1; //根据主时钟来计算位时间16
    while (--i)
        ;
}

版权声明:本文为CSDN博主「perseverance52」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42880082/article/details/122752648

生成海报
点赞 0

perseverance52

我还没有学会写个人说明!

暂无评论

相关推荐

VSCode PlatformIO开发STC单片机注意事项

VSCode PlatformIO开发STC单片机注意事项首先需要注意代码的语法 附上本论坛一位网友总结的笔记 其实开源的SDCCcode blocks也不错的。SDCC语法与keil C有一点点不同,记录如下:*

RT-Thread Studio移植LAN8720A驱动

RTT网络协议栈驱动移植(霸天虎) 1、新建工程 ​ 工程路径不含中文路径名,工程名用纯英文不含任何符号。 2、用CubeMx配置板子外设 2.1、配置时钟 ​ 按照自己板子配置相应时钟。